blob: 3b5d095c09d34831d7a2cb6da9408b3a20b07457 [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|.
Ben Chan1c6c1942014-08-12 09:48:29 -070070 MountErrorType DoMount(const std::string& source_path,
71 const std::string& filesystem_type,
72 const std::vector<std::string>& options,
Tatsuhisa Yamaguchi5a6a3032016-08-19 20:03:54 +090073 const std::string& mount_path,
74 MountOptions* applied_options) override;
Ben Chan8dcede82011-07-25 20:56:13 -070075
76 // Unmounts |path| with |options|.
Ben Chan1c6c1942014-08-12 09:48:29 -070077 MountErrorType DoUnmount(const std::string& path,
78 const std::vector<std::string>& options) 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:
Ben Chane31d2aa2011-06-15 13:52:59 -070088 // Creates an appropriate mounter object for a given filesystem.
Sergei Datsenko3cf72cb2019-04-01 11:27:50 +110089 std::unique_ptr<MounterCompat> CreateMounter(
Ben Chande0e3f62017-09-26 06:28:39 -070090 const Disk& disk,
91 const Filesystem& filesystem,
92 const std::string& target_path,
93 const std::vector<std::string>& options) const;
Ben Chane31d2aa2011-06-15 13:52:59 -070094
Ben Chan29be9152011-07-25 14:39:48 -070095 // Returns a Filesystem object if a given filesystem type is supported.
Eric Carusoe25c4a52017-03-06 15:49:04 -080096 // Otherwise, it returns NULL. This pointer is owned by the DiskManager.
Ben Chan29be9152011-07-25 14:39:48 -070097 const Filesystem* GetFilesystem(const std::string& filesystem_type) const;
98
Ben Chanb5d71222012-10-03 12:55:16 -070099 // 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 Chan1e5a0cb2012-03-22 00:41:52 -0700109
Sergei Datsenko16821892019-04-05 11:26:38 +1100110 DiskMonitor* const disk_monitor_;
111 DeviceEjector* const device_ejector_;
Ben Chancc3145d2011-04-28 14:50:05 -0700112
Ben Chan1e5a0cb2012-03-22 00:41:52 -0700113 // Set to true if devices should be ejected upon unmount.
114 bool eject_device_on_unmount_;
115
Sergei Datsenko16821892019-04-05 11:26:38 +1100116 // A mapping from a mount path to the corresponding device that should
Ben Chanb5d71222012-10-03 12:55:16 -0700117 // be ejected on unmount.
Sergei Datsenko16821892019-04-05 11:26:38 +1100118 std::map<std::string, Disk> devices_to_eject_on_unmount_;
Ben Chan42888362011-06-09 18:16:24 -0700119
Ben Chane31d2aa2011-06-15 13:52:59 -0700120 // A set of supported filesystems indexed by filesystem type.
121 std::map<std::string, Filesystem> filesystems_;
122
Ben Chanaf455a02013-01-08 15:29:22 -0800123 FRIEND_TEST(DiskManagerTest, CreateExFATMounter);
Ben Chanb1ac5a82011-08-02 17:53:55 -0700124 FRIEND_TEST(DiskManagerTest, CreateNTFSMounter);
Anand K Mistry6b19a972018-09-11 11:14:59 +1000125 FRIEND_TEST(DiskManagerTest, CreateVFATSystemMounter);
126 FRIEND_TEST(DiskManagerTest, CreateExt4SystemMounter);
Ben Chan29be9152011-07-25 14:39:48 -0700127 FRIEND_TEST(DiskManagerTest, GetFilesystem);
Ben Chane31d2aa2011-06-15 13:52:59 -0700128 FRIEND_TEST(DiskManagerTest, RegisterFilesystem);
Ben Chan8dcede82011-07-25 20:56:13 -0700129 FRIEND_TEST(DiskManagerTest, DoMountDiskWithNonexistentSourcePath);
130 FRIEND_TEST(DiskManagerTest, DoUnmountDiskWithInvalidUnmountOptions);
Ben Chanb5d71222012-10-03 12:55:16 -0700131 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 Chane31d2aa2011-06-15 13:52:59 -0700136
137 DISALLOW_COPY_AND_ASSIGN(DiskManager);
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700138};
139
Ben Chanbdc39742011-05-11 17:51:26 -0700140} // namespace cros_disks
Ryan Cairnsea6505f2011-04-10 19:54:53 -0700141
Ben Chanbdc39742011-05-11 17:51:26 -0700142#endif // CROS_DISKS_DISK_MANAGER_H_