Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 5 | #ifndef CROS_DISKS_DISK_MANAGER_H_ |
| 6 | #define CROS_DISKS_DISK_MANAGER_H_ |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 7 | |
| 8 | #include <libudev.h> |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 9 | |
Ben Chan | cc3145d | 2011-04-28 14:50:05 -0700 | [diff] [blame] | 10 | #include <map> |
Eric Caruso | 99d04cb | 2017-03-06 17:43:32 -0800 | [diff] [blame] | 11 | #include <memory> |
Ben Chan | 4288836 | 2011-06-09 18:16:24 -0700 | [diff] [blame] | 12 | #include <set> |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 13 | #include <string> |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 14 | #include <vector> |
| 15 | |
Ben Chan | 86a9cee | 2014-07-14 12:17:12 -0700 | [diff] [blame] | 16 | #include <base/callback.h> |
Ben Chan | 3b832b9 | 2014-09-02 19:39:57 -0700 | [diff] [blame] | 17 | #include <base/macros.h> |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 18 | #include <gtest/gtest_prod.h> |
| 19 | |
Ben Chan | ff92fa3 | 2017-10-17 16:17:15 -0700 | [diff] [blame] | 20 | #include "cros-disks/disk.h" |
Ben Chan | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 21 | #include "cros-disks/mount_manager.h" |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 22 | |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 23 | namespace cros_disks { |
| 24 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 25 | class DeviceEjector; |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 26 | class DiskMonitor; |
Sergei Datsenko | 3cf72cb | 2019-04-01 11:27:50 +1100 | [diff] [blame] | 27 | class MounterCompat; |
Ben Chan | 29be915 | 2011-07-25 14:39:48 -0700 | [diff] [blame] | 28 | class Platform; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 29 | |
Ben Chan | 55c2022 | 2017-11-10 13:35:58 -0800 | [diff] [blame] | 30 | struct Filesystem; |
| 31 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 32 | // The DiskManager is responsible for mounting removable media. |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 33 | // |
| 34 | // This class is designed to run within a single-threaded GMainLoop application |
| 35 | // and should not be considered thread safe. |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 36 | class DiskManager : public MountManager { |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 37 | public: |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 38 | DiskManager(const std::string& mount_root, |
| 39 | Platform* platform, |
| 40 | Metrics* metrics, |
Sergei Datsenko | a910bba | 2019-06-18 13:31:59 +1000 | [diff] [blame^] | 41 | brillo::ProcessReaper* process_reaper, |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 42 | DiskMonitor* disk_monitor, |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 43 | DeviceEjector* device_ejector); |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 44 | ~DiskManager() override; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 45 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 46 | // Initializes the disk manager and registers default filesystems. |
| 47 | // Returns true on success. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 48 | bool Initialize() override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 49 | |
| 50 | // Returns true if mounting |source_path| is supported. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 51 | bool CanMount(const std::string& source_path) const override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 52 | |
| 53 | // Returns the type of mount sources supported by the manager. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 54 | MountSourceType GetMountSourceType() const override { |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 55 | return MOUNT_SOURCE_REMOVABLE_DEVICE; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 56 | } |
| 57 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 58 | // Unmounts all mounted paths. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 59 | bool UnmountAll() override; |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 60 | |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 61 | // 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 Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 68 | protected: |
| 69 | // Mounts |source_path| to |mount_path| as |filesystem_type| with |options|. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 70 | MountErrorType DoMount(const std::string& source_path, |
| 71 | const std::string& filesystem_type, |
| 72 | const std::vector<std::string>& options, |
Tatsuhisa Yamaguchi | 5a6a303 | 2016-08-19 20:03:54 +0900 | [diff] [blame] | 73 | const std::string& mount_path, |
| 74 | MountOptions* applied_options) override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 75 | |
| 76 | // Unmounts |path| with |options|. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 77 | MountErrorType DoUnmount(const std::string& path, |
| 78 | const std::vector<std::string>& options) override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 79 | |
| 80 | // Returns a suggested mount path for a source path. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 81 | std::string SuggestMountPath(const std::string& source_path) const override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 82 | |
Ben Chan | f869288 | 2011-08-21 10:15:30 -0700 | [diff] [blame] | 83 | // Returns true to reserve a mount path on errors due to unknown or |
| 84 | // unsupported filesystems. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 85 | bool ShouldReserveMountPathOnError(MountErrorType error_type) const override; |
Ben Chan | f869288 | 2011-08-21 10:15:30 -0700 | [diff] [blame] | 86 | |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 87 | private: |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 88 | // Creates an appropriate mounter object for a given filesystem. |
Sergei Datsenko | 3cf72cb | 2019-04-01 11:27:50 +1100 | [diff] [blame] | 89 | std::unique_ptr<MounterCompat> CreateMounter( |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 90 | const Disk& disk, |
| 91 | const Filesystem& filesystem, |
| 92 | const std::string& target_path, |
| 93 | const std::vector<std::string>& options) const; |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 94 | |
Ben Chan | 29be915 | 2011-07-25 14:39:48 -0700 | [diff] [blame] | 95 | // Returns a Filesystem object if a given filesystem type is supported. |
Eric Caruso | e25c4a5 | 2017-03-06 15:49:04 -0800 | [diff] [blame] | 96 | // Otherwise, it returns NULL. This pointer is owned by the DiskManager. |
Ben Chan | 29be915 | 2011-07-25 14:39:48 -0700 | [diff] [blame] | 97 | const Filesystem* GetFilesystem(const std::string& filesystem_type) const; |
| 98 | |
Ben Chan | b5d7122 | 2012-10-03 12:55:16 -0700 | [diff] [blame] | 99 | // If |disk| should be ejected on unmount, add |mount_path| and the device |
| 100 | // file of |disk| to |devices_to_eject_on_unmount_| and returns true. Returns |
| 101 | // false otherwise. |
| 102 | bool ScheduleEjectOnUnmount(const std::string& mount_path, const Disk& disk); |
| 103 | |
| 104 | // Ejects media from a device mounted at |mount_path|. Return true if the |
| 105 | // eject process has started, or false if the |mount_path| is not in |
| 106 | // |devices_to_eject_on_unmount_| or |eject_device_on_unmount_| is set to |
| 107 | // false. |
| 108 | bool EjectDeviceOfMountPath(const std::string& mount_path); |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 109 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 110 | DiskMonitor* const disk_monitor_; |
| 111 | DeviceEjector* const device_ejector_; |
Ben Chan | cc3145d | 2011-04-28 14:50:05 -0700 | [diff] [blame] | 112 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 113 | // Set to true if devices should be ejected upon unmount. |
| 114 | bool eject_device_on_unmount_; |
| 115 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 116 | // A mapping from a mount path to the corresponding device that should |
Ben Chan | b5d7122 | 2012-10-03 12:55:16 -0700 | [diff] [blame] | 117 | // be ejected on unmount. |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 118 | std::map<std::string, Disk> devices_to_eject_on_unmount_; |
Ben Chan | 4288836 | 2011-06-09 18:16:24 -0700 | [diff] [blame] | 119 | |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 120 | // A set of supported filesystems indexed by filesystem type. |
| 121 | std::map<std::string, Filesystem> filesystems_; |
| 122 | |
Ben Chan | af455a0 | 2013-01-08 15:29:22 -0800 | [diff] [blame] | 123 | FRIEND_TEST(DiskManagerTest, CreateExFATMounter); |
Ben Chan | b1ac5a8 | 2011-08-02 17:53:55 -0700 | [diff] [blame] | 124 | FRIEND_TEST(DiskManagerTest, CreateNTFSMounter); |
Anand K Mistry | 6b19a97 | 2018-09-11 11:14:59 +1000 | [diff] [blame] | 125 | FRIEND_TEST(DiskManagerTest, CreateVFATSystemMounter); |
| 126 | FRIEND_TEST(DiskManagerTest, CreateExt4SystemMounter); |
Ben Chan | 29be915 | 2011-07-25 14:39:48 -0700 | [diff] [blame] | 127 | FRIEND_TEST(DiskManagerTest, GetFilesystem); |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 128 | FRIEND_TEST(DiskManagerTest, RegisterFilesystem); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 129 | FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath); |
| 130 | FRIEND_TEST(DiskManagerTest, DoUnmountDiskWithInvalidUnmountOptions); |
Ben Chan | b5d7122 | 2012-10-03 12:55:16 -0700 | [diff] [blame] | 131 | FRIEND_TEST(DiskManagerTest, ScheduleEjectOnUnmount); |
| 132 | FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPath); |
| 133 | FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenEjectFailed); |
| 134 | FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenExplicitlyDisabled); |
| 135 | FRIEND_TEST(DiskManagerTest, EjectDeviceOfMountPathWhenMountPathExcluded); |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 136 | |
| 137 | DISALLOW_COPY_AND_ASSIGN(DiskManager); |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 138 | }; |
| 139 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 140 | } // namespace cros_disks |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 141 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 142 | #endif // CROS_DISKS_DISK_MANAGER_H_ |