blob: 9413ba0da5c7dec48b4b252c659c1f844c4ad072 [file] [log] [blame]
Ben Chan1e5a0cb2012-03-22 00:41:52 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Ryan Cairnsea6505f2011-04-10 19:54:53 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Chanbdc39742011-05-11 17:51:26 -07005#ifndef CROS_DISKS_DISK_MANAGER_H_
6#define CROS_DISKS_DISK_MANAGER_H_
Ryan Cairnsea6505f2011-04-10 19:54:53 -07007
8#include <libudev.h>
Ben Chanbdc39742011-05-11 17:51:26 -07009
Ben Chancc3145d2011-04-28 14:50:05 -070010#include <map>
Eric Caruso99d04cb2017-03-06 17:43:32 -080011#include <memory>
Ben Chan42888362011-06-09 18:16:24 -070012#include <set>
Ben Chanf51ff002011-04-25 12:41:57 -070013#include <string>
Ryan Cairnsea6505f2011-04-10 19:54:53 -070014#include <vector>
15
Ben Chan86a9cee2014-07-14 12:17:12 -070016#include <base/callback.h>
Ben Chan3b832b92014-09-02 19:39:57 -070017#include <base/macros.h>
Ben Chane31d2aa2011-06-15 13:52:59 -070018#include <gtest/gtest_prod.h>
19
Ben Chanff92fa32017-10-17 16:17:15 -070020#include "cros-disks/disk.h"
Ben Chan5ccd9fe2013-11-13 18:28:27 -080021#include "cros-disks/mount_manager.h"
Ben Chan6e726922011-06-28 15:54:32 -070022
Ryan Cairnsea6505f2011-04-10 19:54:53 -070023namespace cros_disks {
24
Ben Chan1e5a0cb2012-03-22 00:41:52 -070025class DeviceEjector;
Sergei Datsenko16821892019-04-05 11:26:38 +110026class DiskMonitor;
Sergei Datsenko3cf72cb2019-04-01 11:27:50 +110027class MounterCompat;
Ben Chan29be9152011-07-25 14:39:48 -070028class Platform;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070029
Ben Chan55c20222017-11-10 13:35:58 -080030struct Filesystem;
31
Sergei Datsenko16821892019-04-05 11:26:38 +110032// The DiskManager is responsible for mounting removable media.
Ryan Cairnsea6505f2011-04-10 19:54:53 -070033//
34// This class is designed to run within a single-threaded GMainLoop application
35// and should not be considered thread safe.
Sergei Datsenko16821892019-04-05 11:26:38 +110036class DiskManager : public MountManager {
Ryan Cairnsea6505f2011-04-10 19:54:53 -070037 public:
Ben Chande0e3f62017-09-26 06:28:39 -070038 DiskManager(const std::string& mount_root,
39 Platform* platform,
40 Metrics* metrics,
Sergei Datsenkoa910bba2019-06-18 13:31:59 +100041 brillo::ProcessReaper* process_reaper,
Sergei Datsenko16821892019-04-05 11:26:38 +110042 DiskMonitor* disk_monitor,
Ben Chande0e3f62017-09-26 06:28:39 -070043 DeviceEjector* device_ejector);
Ben Chan1c6c1942014-08-12 09:48:29 -070044 ~DiskManager() override;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070045
Ben Chan8dcede82011-07-25 20:56:13 -070046 // Initializes the disk manager and registers default filesystems.
47 // Returns true on success.
Ben Chan1c6c1942014-08-12 09:48:29 -070048 bool Initialize() override;
Ben Chan8dcede82011-07-25 20:56:13 -070049
50 // Returns true if mounting |source_path| is supported.
Ben Chan1c6c1942014-08-12 09:48:29 -070051 bool CanMount(const std::string& source_path) const override;
Ben Chan8dcede82011-07-25 20:56:13 -070052
53 // Returns the type of mount sources supported by the manager.
Ben Chan1c6c1942014-08-12 09:48:29 -070054 MountSourceType GetMountSourceType() const override {
Ben Chan6d0b2722011-11-18 08:24:14 -080055 return MOUNT_SOURCE_REMOVABLE_DEVICE;
Ben Chan8dcede82011-07-25 20:56:13 -070056 }
57
Ben Chan1e5a0cb2012-03-22 00:41:52 -070058 // Unmounts all mounted paths.
Ben Chan1c6c1942014-08-12 09:48:29 -070059 bool UnmountAll() override;
Ben Chan1e5a0cb2012-03-22 00:41:52 -070060
Ben Chane31d2aa2011-06-15 13:52:59 -070061 // Registers a set of default filesystems to the disk manager.
62 void RegisterDefaultFilesystems();
63
64 // Registers a filesystem to the disk manager.
65 // Subsequent registrations of the same filesystem type are ignored.
66 void RegisterFilesystem(const Filesystem& filesystem);
67
Ben Chan8dcede82011-07-25 20:56:13 -070068 protected:
69 // Mounts |source_path| to |mount_path| as |filesystem_type| with |options|.
Anand K Mistryd0a05232020-01-24 14:04:18 +110070 std::unique_ptr<MountPoint> DoMount(const std::string& source_path,
71 const std::string& filesystem_type,
72 const std::vector<std::string>& options,
73 const base::FilePath& mount_path,
74 MountOptions* applied_options,
75 MountErrorType* error) override;
Ben Chan8dcede82011-07-25 20:56:13 -070076
Anand K Mistry5a6d5fa2019-11-05 17:21:48 +110077 // Unmounts |path|.
78 MountErrorType DoUnmount(const std::string& path) override;
Ben Chan8dcede82011-07-25 20:56:13 -070079
80 // Returns a suggested mount path for a source path.
Ben Chan1c6c1942014-08-12 09:48:29 -070081 std::string SuggestMountPath(const std::string& source_path) const override;
Ben Chan8dcede82011-07-25 20:56:13 -070082
Ben Chanf8692882011-08-21 10:15:30 -070083 // Returns true to reserve a mount path on errors due to unknown or
84 // unsupported filesystems.
Ben Chan1c6c1942014-08-12 09:48:29 -070085 bool ShouldReserveMountPathOnError(MountErrorType error_type) const override;
Ben Chanf8692882011-08-21 10:15:30 -070086
Ryan Cairnsea6505f2011-04-10 19:54:53 -070087 private:
Anand K Mistryc7eba322020-01-15 17:45:38 +110088 // MountPoint implementation that ejects the device on unmount.
89 class EjectingMountPoint;
90
Ben Chane31d2aa2011-06-15 13:52:59 -070091 // Creates an appropriate mounter object for a given filesystem.
Sergei Datsenko3cf72cb2019-04-01 11:27:50 +110092 std::unique_ptr<MounterCompat> CreateMounter(
Ben Chande0e3f62017-09-26 06:28:39 -070093 const Disk& disk,
94 const Filesystem& filesystem,
95 const std::string& target_path,
96 const std::vector<std::string>& options) const;
Ben Chane31d2aa2011-06-15 13:52:59 -070097
Ben Chan29be9152011-07-25 14:39:48 -070098 // Returns a Filesystem object if a given filesystem type is supported.
Eric Carusoe25c4a52017-03-06 15:49:04 -080099 // Otherwise, it returns NULL. This pointer is owned by the DiskManager.
Ben Chan29be9152011-07-25 14:39:48 -0700100 const Filesystem* GetFilesystem(const std::string& filesystem_type) const;
101
Anand K Mistryc7eba322020-01-15 17:45:38 +1100102 // Ejects media for the device |device_file|. Return true if the eject process
103 // has started or |eject_device_on_unmount_| is false, or false if the eject
104 // process failed.
105 bool EjectDevice(const std::string& device_file);
Ben Chanb5d71222012-10-03 12:55:16 -0700106
Anand K Mistryc7eba322020-01-15 17:45:38 +1100107 // If |disk| is an optical disk, wrap |mount_point| in a wrapper that ejects
108 // the disk on a successful unmount. If |disk| is not an optical disk, returns
109 // |mount_point|. This is exposed as a function to allow ejecting behaviour to
110 // be tested.
111 std::unique_ptr<MountPoint> MaybeWrapMountPointForEject(
112 std::unique_ptr<MountPoint> mount_point, const Disk& disk);
Ben Chan1e5a0cb2012-03-22 00:41:52 -0700113
Sergei Datsenko16821892019-04-05 11:26:38 +1100114 DiskMonitor* const disk_monitor_;
115 DeviceEjector* const device_ejector_;
Ben Chancc3145d2011-04-28 14:50:05 -0700116
Ben Chan1e5a0cb2012-03-22 00:41:52 -0700117 // Set to true if devices should be ejected upon unmount.
118 bool eject_device_on_unmount_;
119
Sergei Datsenko16821892019-04-05 11:26:38 +1100120 // A mapping from a mount path to the corresponding device that should
Ben Chanb5d71222012-10-03 12:55:16 -0700121 // be ejected on unmount.
Sergei Datsenko16821892019-04-05 11:26:38 +1100122 std::map<std::string, Disk> devices_to_eject_on_unmount_;
Ben Chan42888362011-06-09 18:16:24 -0700123
Ben Chane31d2aa2011-06-15 13:52:59 -0700124 // A set of supported filesystems indexed by filesystem type.
125 std::map<std::string, Filesystem> filesystems_;
126
Ben Chanaf455a02013-01-08 15:29:22 -0800127 FRIEND_TEST(DiskManagerTest, CreateExFATMounter);
Ben Chanb1ac5a82011-08-02 17:53:55 -0700128 FRIEND_TEST(DiskManagerTest, CreateNTFSMounter);
Anand K Mistry6b19a972018-09-11 11:14:59 +1000129 FRIEND_TEST(DiskManagerTest, CreateVFATSystemMounter);
130 FRIEND_TEST(DiskManagerTest, CreateExt4SystemMounter);
Ben Chan29be9152011-07-25 14:39:48 -0700131 FRIEND_TEST(DiskManagerTest, GetFilesystem);
Ben Chane31d2aa2011-06-15 13:52:59 -0700132 FRIEND_TEST(DiskManagerTest, RegisterFilesystem);
Ben Chan8dcede82011-07-25 20:56:13 -0700133 FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath);
Anand K Mistry43575af2019-11-05 13:41:41 +1100134 FRIEND_TEST(DiskManagerTest, DoUnmountDiskWithBusyRetry);
Anand K Mistryc7eba322020-01-15 17:45:38 +1100135 FRIEND_TEST(DiskManagerTest, EjectDevice);
136 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenUnmountFailed);
137 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenExplicitlyDisabled);
138 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenReleased);
Ben Chane31d2aa2011-06-15 13:52:59 -0700139
140 DISALLOW_COPY_AND_ASSIGN(DiskManager);
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700141};
142
Ben Chanbdc39742011-05-11 17:51:26 -0700143} // namespace cros_disks
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700144
Ben Chanbdc39742011-05-11 17:51:26 -0700145#endif // CROS_DISKS_DISK_MANAGER_H_