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 | |
Eric Caruso | 99d04cb | 2017-03-06 17:43:32 -0800 | [diff] [blame] | 10 | #include <memory> |
Ben Chan | 4288836 | 2011-06-09 18:16:24 -0700 | [diff] [blame] | 11 | #include <set> |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 12 | #include <string> |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 13 | #include <unordered_map> |
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 | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 17 | #include <gtest/gtest_prod.h> |
| 18 | |
Ben Chan | ff92fa3 | 2017-10-17 16:17:15 -0700 | [diff] [blame] | 19 | #include "cros-disks/disk.h" |
Ben Chan | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 20 | #include "cros-disks/mount_manager.h" |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 21 | |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 22 | namespace cros_disks { |
| 23 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 24 | class DeviceEjector; |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 25 | class DiskMonitor; |
Sergei Datsenko | 199f4f4 | 2020-10-08 10:47:12 +1100 | [diff] [blame] | 26 | class Mounter; |
Ben Chan | 29be915 | 2011-07-25 14:39:48 -0700 | [diff] [blame] | 27 | class Platform; |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 28 | class SandboxedProcessFactory; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 29 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 30 | // The DiskManager is responsible for mounting removable media. |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 31 | // |
| 32 | // This class is designed to run within a single-threaded GMainLoop application |
| 33 | // and should not be considered thread safe. |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 34 | class DiskManager : public MountManager { |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 35 | public: |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 36 | DiskManager(const std::string& mount_root, |
| 37 | Platform* platform, |
| 38 | Metrics* metrics, |
Sergei Datsenko | a910bba | 2019-06-18 13:31:59 +1000 | [diff] [blame] | 39 | brillo::ProcessReaper* process_reaper, |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 40 | DiskMonitor* disk_monitor, |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 41 | DeviceEjector* device_ejector, |
| 42 | const SandboxedProcessFactory* test_sandbox_factory = nullptr); |
Qijiang Fan | 6bc59e1 | 2020-11-11 02:51:06 +0900 | [diff] [blame] | 43 | DiskManager(const DiskManager&) = delete; |
| 44 | DiskManager& operator=(const DiskManager&) = delete; |
| 45 | |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 46 | ~DiskManager() override; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 47 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 48 | // Initializes the disk manager and registers default filesystems. |
| 49 | // Returns true on success. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 50 | bool Initialize() override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 51 | |
| 52 | // Returns true if mounting |source_path| is supported. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 53 | bool CanMount(const std::string& source_path) const override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 54 | |
| 55 | // Returns the type of mount sources supported by the manager. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 56 | MountSourceType GetMountSourceType() const override { |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 57 | return MOUNT_SOURCE_REMOVABLE_DEVICE; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 58 | } |
| 59 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 60 | // Unmounts all mounted paths. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 61 | bool UnmountAll() override; |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 62 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 63 | protected: |
| 64 | // Mounts |source_path| to |mount_path| as |filesystem_type| with |options|. |
Anand K Mistry | d0a0523 | 2020-01-24 14:04:18 +1100 | [diff] [blame] | 65 | std::unique_ptr<MountPoint> DoMount(const std::string& source_path, |
| 66 | const std::string& filesystem_type, |
| 67 | const std::vector<std::string>& options, |
| 68 | const base::FilePath& mount_path, |
Anand K Mistry | d0a0523 | 2020-01-24 14:04:18 +1100 | [diff] [blame] | 69 | MountErrorType* error) override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 70 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 71 | // Returns a suggested mount path for a source path. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 72 | std::string SuggestMountPath(const std::string& source_path) const override; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 73 | |
Ben Chan | f869288 | 2011-08-21 10:15:30 -0700 | [diff] [blame] | 74 | // Returns true to reserve a mount path on errors due to unknown or |
| 75 | // unsupported filesystems. |
Ben Chan | 1c6c194 | 2014-08-12 09:48:29 -0700 | [diff] [blame] | 76 | bool ShouldReserveMountPathOnError(MountErrorType error_type) const override; |
Ben Chan | f869288 | 2011-08-21 10:15:30 -0700 | [diff] [blame] | 77 | |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 78 | private: |
Anand K Mistry | c7eba32 | 2020-01-15 17:45:38 +1100 | [diff] [blame] | 79 | // MountPoint implementation that ejects the device on unmount. |
| 80 | class EjectingMountPoint; |
| 81 | |
Anand K Mistry | c7eba32 | 2020-01-15 17:45:38 +1100 | [diff] [blame] | 82 | // Ejects media for the device |device_file|. Return true if the eject process |
| 83 | // has started or |eject_device_on_unmount_| is false, or false if the eject |
| 84 | // process failed. |
| 85 | bool EjectDevice(const std::string& device_file); |
Ben Chan | b5d7122 | 2012-10-03 12:55:16 -0700 | [diff] [blame] | 86 | |
Anand K Mistry | c7eba32 | 2020-01-15 17:45:38 +1100 | [diff] [blame] | 87 | // If |disk| is an optical disk, wrap |mount_point| in a wrapper that ejects |
| 88 | // the disk on a successful unmount. If |disk| is not an optical disk, returns |
| 89 | // |mount_point|. This is exposed as a function to allow ejecting behaviour to |
| 90 | // be tested. |
| 91 | std::unique_ptr<MountPoint> MaybeWrapMountPointForEject( |
| 92 | std::unique_ptr<MountPoint> mount_point, const Disk& disk); |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 93 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 94 | DiskMonitor* const disk_monitor_; |
| 95 | DeviceEjector* const device_ejector_; |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 96 | const SandboxedProcessFactory* const test_sandbox_factory_; |
Ben Chan | cc3145d | 2011-04-28 14:50:05 -0700 | [diff] [blame] | 97 | |
Ben Chan | 1e5a0cb | 2012-03-22 00:41:52 -0700 | [diff] [blame] | 98 | // Set to true if devices should be ejected upon unmount. |
| 99 | bool eject_device_on_unmount_; |
| 100 | |
Sergei Datsenko | 1682189 | 2019-04-05 11:26:38 +1100 | [diff] [blame] | 101 | // A mapping from a mount path to the corresponding device that should |
Ben Chan | b5d7122 | 2012-10-03 12:55:16 -0700 | [diff] [blame] | 102 | // be ejected on unmount. |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 103 | std::unordered_map<std::string, Disk> devices_to_eject_on_unmount_; |
Ben Chan | 4288836 | 2011-06-09 18:16:24 -0700 | [diff] [blame] | 104 | |
Sergei Datsenko | 68cd43a | 2020-11-16 22:57:16 +1100 | [diff] [blame] | 105 | // Mapping of filesystem types to corresponding mounters. |
| 106 | std::unordered_map<std::string, std::unique_ptr<Mounter>> mounters_; |
Ben Chan | e31d2aa | 2011-06-15 13:52:59 -0700 | [diff] [blame] | 107 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 108 | FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath); |
Anand K Mistry | c7eba32 | 2020-01-15 17:45:38 +1100 | [diff] [blame] | 109 | FRIEND_TEST(DiskManagerTest, EjectDevice); |
| 110 | FRIEND_TEST(DiskManagerTest, EjectDeviceWhenUnmountFailed); |
| 111 | FRIEND_TEST(DiskManagerTest, EjectDeviceWhenExplicitlyDisabled); |
| 112 | FRIEND_TEST(DiskManagerTest, EjectDeviceWhenReleased); |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 113 | }; |
| 114 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 115 | } // namespace cros_disks |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 116 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 117 | #endif // CROS_DISKS_DISK_MANAGER_H_ |