blob: a1145267bcd7dfbd650d9e985626f96f26c0f14d [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
Eric Caruso99d04cb2017-03-06 17:43:32 -080010#include <memory>
Ben Chan42888362011-06-09 18:16:24 -070011#include <set>
Ben Chanf51ff002011-04-25 12:41:57 -070012#include <string>
Sergei Datsenko68cd43a2020-11-16 22:57:16 +110013#include <unordered_map>
Ryan Cairnsea6505f2011-04-10 19:54:53 -070014#include <vector>
15
Ben Chan86a9cee2014-07-14 12:17:12 -070016#include <base/callback.h>
Ben Chane31d2aa2011-06-15 13:52:59 -070017#include <gtest/gtest_prod.h>
18
Ben Chanff92fa32017-10-17 16:17:15 -070019#include "cros-disks/disk.h"
Ben Chan5ccd9fe2013-11-13 18:28:27 -080020#include "cros-disks/mount_manager.h"
Ben Chan6e726922011-06-28 15:54:32 -070021
Ryan Cairnsea6505f2011-04-10 19:54:53 -070022namespace cros_disks {
23
Ben Chan1e5a0cb2012-03-22 00:41:52 -070024class DeviceEjector;
Sergei Datsenko16821892019-04-05 11:26:38 +110025class DiskMonitor;
Sergei Datsenko199f4f42020-10-08 10:47:12 +110026class Mounter;
Ben Chan29be9152011-07-25 14:39:48 -070027class Platform;
Sergei Datsenko68cd43a2020-11-16 22:57:16 +110028class SandboxedProcessFactory;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070029
Sergei Datsenko16821892019-04-05 11:26:38 +110030// The DiskManager is responsible for mounting removable media.
Ryan Cairnsea6505f2011-04-10 19:54:53 -070031//
32// This class is designed to run within a single-threaded GMainLoop application
33// and should not be considered thread safe.
Sergei Datsenko16821892019-04-05 11:26:38 +110034class DiskManager : public MountManager {
Ryan Cairnsea6505f2011-04-10 19:54:53 -070035 public:
Ben Chande0e3f62017-09-26 06:28:39 -070036 DiskManager(const std::string& mount_root,
37 Platform* platform,
38 Metrics* metrics,
Sergei Datsenkoa910bba2019-06-18 13:31:59 +100039 brillo::ProcessReaper* process_reaper,
Sergei Datsenko16821892019-04-05 11:26:38 +110040 DiskMonitor* disk_monitor,
Sergei Datsenko68cd43a2020-11-16 22:57:16 +110041 DeviceEjector* device_ejector,
42 const SandboxedProcessFactory* test_sandbox_factory = nullptr);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090043 DiskManager(const DiskManager&) = delete;
44 DiskManager& operator=(const DiskManager&) = delete;
45
Ben Chan1c6c1942014-08-12 09:48:29 -070046 ~DiskManager() override;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070047
Ben Chan8dcede82011-07-25 20:56:13 -070048 // Initializes the disk manager and registers default filesystems.
49 // Returns true on success.
Ben Chan1c6c1942014-08-12 09:48:29 -070050 bool Initialize() override;
Ben Chan8dcede82011-07-25 20:56:13 -070051
52 // Returns true if mounting |source_path| is supported.
Ben Chan1c6c1942014-08-12 09:48:29 -070053 bool CanMount(const std::string& source_path) const override;
Ben Chan8dcede82011-07-25 20:56:13 -070054
55 // Returns the type of mount sources supported by the manager.
Ben Chan1c6c1942014-08-12 09:48:29 -070056 MountSourceType GetMountSourceType() const override {
Ben Chan6d0b2722011-11-18 08:24:14 -080057 return MOUNT_SOURCE_REMOVABLE_DEVICE;
Ben Chan8dcede82011-07-25 20:56:13 -070058 }
59
Ben Chan1e5a0cb2012-03-22 00:41:52 -070060 // Unmounts all mounted paths.
Ben Chan1c6c1942014-08-12 09:48:29 -070061 bool UnmountAll() override;
Ben Chan1e5a0cb2012-03-22 00:41:52 -070062
Ben Chan8dcede82011-07-25 20:56:13 -070063 protected:
64 // Mounts |source_path| to |mount_path| as |filesystem_type| with |options|.
Anand K Mistryd0a05232020-01-24 14:04:18 +110065 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 Mistryd0a05232020-01-24 14:04:18 +110069 MountErrorType* error) override;
Ben Chan8dcede82011-07-25 20:56:13 -070070
Ben Chan8dcede82011-07-25 20:56:13 -070071 // Returns a suggested mount path for a source path.
Ben Chan1c6c1942014-08-12 09:48:29 -070072 std::string SuggestMountPath(const std::string& source_path) const override;
Ben Chan8dcede82011-07-25 20:56:13 -070073
Ben Chanf8692882011-08-21 10:15:30 -070074 // Returns true to reserve a mount path on errors due to unknown or
75 // unsupported filesystems.
Ben Chan1c6c1942014-08-12 09:48:29 -070076 bool ShouldReserveMountPathOnError(MountErrorType error_type) const override;
Ben Chanf8692882011-08-21 10:15:30 -070077
Ryan Cairnsea6505f2011-04-10 19:54:53 -070078 private:
Anand K Mistryc7eba322020-01-15 17:45:38 +110079 // MountPoint implementation that ejects the device on unmount.
80 class EjectingMountPoint;
81
Anand K Mistryc7eba322020-01-15 17:45:38 +110082 // 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 Chanb5d71222012-10-03 12:55:16 -070086
Anand K Mistryc7eba322020-01-15 17:45:38 +110087 // 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 Chan1e5a0cb2012-03-22 00:41:52 -070093
Sergei Datsenko16821892019-04-05 11:26:38 +110094 DiskMonitor* const disk_monitor_;
95 DeviceEjector* const device_ejector_;
Sergei Datsenko68cd43a2020-11-16 22:57:16 +110096 const SandboxedProcessFactory* const test_sandbox_factory_;
Ben Chancc3145d2011-04-28 14:50:05 -070097
Ben Chan1e5a0cb2012-03-22 00:41:52 -070098 // Set to true if devices should be ejected upon unmount.
99 bool eject_device_on_unmount_;
100
Sergei Datsenko16821892019-04-05 11:26:38 +1100101 // A mapping from a mount path to the corresponding device that should
Ben Chanb5d71222012-10-03 12:55:16 -0700102 // be ejected on unmount.
Sergei Datsenko68cd43a2020-11-16 22:57:16 +1100103 std::unordered_map<std::string, Disk> devices_to_eject_on_unmount_;
Ben Chan42888362011-06-09 18:16:24 -0700104
Sergei Datsenko68cd43a2020-11-16 22:57:16 +1100105 // Mapping of filesystem types to corresponding mounters.
106 std::unordered_map<std::string, std::unique_ptr<Mounter>> mounters_;
Ben Chane31d2aa2011-06-15 13:52:59 -0700107
Ben Chan8dcede82011-07-25 20:56:13 -0700108 FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath);
Anand K Mistryc7eba322020-01-15 17:45:38 +1100109 FRIEND_TEST(DiskManagerTest, EjectDevice);
110 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenUnmountFailed);
111 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenExplicitlyDisabled);
112 FRIEND_TEST(DiskManagerTest, EjectDeviceWhenReleased);
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700113};
114
Ben Chanbdc39742011-05-11 17:51:26 -0700115} // namespace cros_disks
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700116
Ben Chanbdc39742011-05-11 17:51:26 -0700117#endif // CROS_DISKS_DISK_MANAGER_H_