Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 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 | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 5 | #include "cros-disks/cros_disks_server.h" |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 6 | |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 7 | #include <base/logging.h> |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 8 | #include <chromeos/dbus/service_constants.h> |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 9 | |
Ben Chan | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 10 | #include "cros-disks/archive_manager.h" |
| 11 | #include "cros-disks/device_event.h" |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 12 | #include "cros-disks/disk.h" |
Ben Chan | 5ccd9fe | 2013-11-13 18:28:27 -0800 | [diff] [blame] | 13 | #include "cros-disks/disk_manager.h" |
| 14 | #include "cros-disks/format_manager.h" |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 15 | #include "cros-disks/platform.h" |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 16 | #include "cros-disks/rename_manager.h" |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 17 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 18 | using std::string; |
| 19 | using std::vector; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 20 | |
Ben Chan | 460439f | 2011-09-13 09:16:28 -0700 | [diff] [blame] | 21 | namespace cros_disks { |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 22 | |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 23 | CrosDisksServer::CrosDisksServer(DBus::Connection& connection, // NOLINT |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 24 | Platform* platform, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 25 | DiskManager* disk_manager, |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 26 | FormatManager* format_manager, |
| 27 | RenameManager* rename_manager) |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 28 | : DBus::ObjectAdaptor(connection, kCrosDisksServicePath), |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 29 | platform_(platform), |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 30 | disk_manager_(disk_manager), |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 31 | format_manager_(format_manager), |
| 32 | rename_manager_(rename_manager) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 33 | CHECK(platform_) << "Invalid platform object"; |
Ben Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 34 | CHECK(disk_manager_) << "Invalid disk manager object"; |
| 35 | CHECK(format_manager_) << "Invalid format manager object"; |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 36 | CHECK(rename_manager_) << "Invalid rename manager object"; |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 37 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 38 | format_manager_->set_observer(this); |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 39 | rename_manager_->set_observer(this); |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 40 | } |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 41 | |
Ben Chan | f47fc35 | 2013-05-03 11:28:57 -0700 | [diff] [blame] | 42 | void CrosDisksServer::RegisterMountManager(MountManager* mount_manager) { |
| 43 | CHECK(mount_manager) << "Invalid mount manager object"; |
| 44 | mount_managers_.push_back(mount_manager); |
| 45 | } |
| 46 | |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 47 | bool CrosDisksServer::IsAlive(DBus::Error& error) { // NOLINT |
| 48 | return true; |
| 49 | } |
| 50 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 51 | void CrosDisksServer::Format(const string& path, |
| 52 | const string& filesystem_type, |
| 53 | const vector<string>& options, |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 54 | DBus::Error& error) { // NOLINT |
Ben Chan | c833a52 | 2012-09-27 23:47:00 -0700 | [diff] [blame] | 55 | FormatErrorType error_type = FORMAT_ERROR_NONE; |
| 56 | Disk disk; |
| 57 | if (!disk_manager_->GetDiskByDevicePath(path, &disk)) { |
| 58 | error_type = FORMAT_ERROR_INVALID_DEVICE_PATH; |
| 59 | } else if (disk.is_on_boot_device()) { |
| 60 | error_type = FORMAT_ERROR_DEVICE_NOT_ALLOWED; |
| 61 | } else { |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 62 | error_type = format_manager_->StartFormatting(path, disk.device_file(), |
| 63 | filesystem_type); |
Ben Chan | c833a52 | 2012-09-27 23:47:00 -0700 | [diff] [blame] | 64 | } |
| 65 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 66 | if (error_type != FORMAT_ERROR_NONE) { |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 67 | LOG(ERROR) << "Could not format device '" << path << "' as filesystem '" |
| 68 | << filesystem_type << "'"; |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 69 | FormatCompleted(error_type, path); |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 70 | } |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 71 | } |
| 72 | |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 73 | void CrosDisksServer::Rename(const string& path, |
| 74 | const string& volume_name, |
| 75 | DBus::Error& error) { // NOLINT |
| 76 | RenameErrorType error_type = RENAME_ERROR_NONE; |
| 77 | Disk disk; |
| 78 | if (!disk_manager_->GetDiskByDevicePath(path, &disk)) { |
| 79 | error_type = RENAME_ERROR_INVALID_DEVICE_PATH; |
| 80 | } else if (disk.is_on_boot_device() || disk.is_read_only()) { |
| 81 | error_type = RENAME_ERROR_DEVICE_NOT_ALLOWED; |
| 82 | } else { |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 83 | error_type = rename_manager_->StartRenaming( |
| 84 | path, disk.device_file(), volume_name, disk.filesystem_type()); |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | if (error_type != RENAME_ERROR_NONE) { |
Ben Chan | de0e3f6 | 2017-09-26 06:28:39 -0700 | [diff] [blame] | 88 | LOG(ERROR) << "Could not rename device '" << path << "' as '" << volume_name |
| 89 | << "'"; |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 90 | RenameCompleted(error_type, path); |
| 91 | } |
| 92 | } |
| 93 | |
Tatsuhisa Yamaguchi | b670bd1 | 2016-09-28 23:06:44 +0900 | [diff] [blame] | 94 | MountManager* CrosDisksServer::FindMounter(const string& source_path) const { |
| 95 | for (const auto& manager : mount_managers_) { |
| 96 | if (manager->CanMount(source_path)) { |
| 97 | return manager; |
| 98 | } |
| 99 | } |
| 100 | return nullptr; |
| 101 | } |
| 102 | |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 103 | void CrosDisksServer::Mount(const string& path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 104 | const string& filesystem_type, |
| 105 | const vector<string>& options, |
| 106 | DBus::Error& error) { // NOLINT |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 107 | MountErrorType error_type = MOUNT_ERROR_INVALID_PATH; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 108 | MountSourceType source_type = MOUNT_SOURCE_INVALID; |
Ben Chan | adc5d00 | 2014-03-12 15:02:26 -0700 | [diff] [blame] | 109 | string source_path; |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 110 | string mount_path; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 111 | |
Ben Chan | adc5d00 | 2014-03-12 15:02:26 -0700 | [diff] [blame] | 112 | if (platform_->GetRealPath(path, &source_path)) { |
Tatsuhisa Yamaguchi | b670bd1 | 2016-09-28 23:06:44 +0900 | [diff] [blame] | 113 | MountManager* mounter = FindMounter(source_path); |
| 114 | if (mounter) { |
| 115 | source_type = mounter->GetMountSourceType(); |
| 116 | error_type = |
| 117 | mounter->Mount(source_path, filesystem_type, options, &mount_path); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 118 | } |
| 119 | } |
| 120 | |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 121 | if (error_type != MOUNT_ERROR_NONE) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 122 | LOG(ERROR) << "Failed to mount '" << path << "'"; |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 123 | } |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 124 | MountCompleted(error_type, path, source_type, mount_path); |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | void CrosDisksServer::Unmount(const string& path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 128 | const vector<string>& options, |
| 129 | DBus::Error& error) { // NOLINT |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 130 | MountErrorType error_type = MOUNT_ERROR_INVALID_PATH; |
Ben Chan | 63ec9c4 | 2014-04-21 19:13:23 -0700 | [diff] [blame] | 131 | for (const auto& manager : mount_managers_) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 132 | if (manager->CanUnmount(path)) { |
| 133 | error_type = manager->Unmount(path, options); |
| 134 | break; |
| 135 | } |
| 136 | } |
| 137 | |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 138 | if (error_type != MOUNT_ERROR_NONE) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 139 | string message = "Failed to unmount '" + path + "'"; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 140 | error.set(kCrosDisksServiceError, message.c_str()); |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 141 | } |
| 142 | } |
| 143 | |
Ben Chan | 8f51376 | 2011-11-14 12:44:42 -0800 | [diff] [blame] | 144 | void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT |
| 145 | DoUnmountAll(); |
| 146 | } |
| 147 | |
| 148 | void CrosDisksServer::DoUnmountAll() { |
Ben Chan | 63ec9c4 | 2014-04-21 19:13:23 -0700 | [diff] [blame] | 149 | for (const auto& manager : mount_managers_) { |
Ben Chan | 8f51376 | 2011-11-14 12:44:42 -0800 | [diff] [blame] | 150 | manager->UnmountAll(); |
| 151 | } |
| 152 | } |
| 153 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 154 | vector<string> CrosDisksServer::DoEnumerateDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 155 | bool auto_mountable_only) const { |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 156 | vector<Disk> disks = disk_manager_->EnumerateDisks(); |
| 157 | vector<string> devices; |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 158 | devices.reserve(disks.size()); |
Ben Chan | 63ec9c4 | 2014-04-21 19:13:23 -0700 | [diff] [blame] | 159 | for (const auto& disk : disks) { |
| 160 | if (!auto_mountable_only || disk.is_auto_mountable()) { |
| 161 | devices.push_back(disk.native_path()); |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 162 | } |
| 163 | } |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 164 | return devices; |
| 165 | } |
| 166 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 167 | vector<string> CrosDisksServer::EnumerateDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 168 | DBus::Error& error) { // NOLINT |
| 169 | return DoEnumerateDevices(false); |
| 170 | } |
| 171 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 172 | vector<string> CrosDisksServer::EnumerateAutoMountableDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 173 | DBus::Error& error) { // NOLINT |
| 174 | return DoEnumerateDevices(true); |
| 175 | } |
| 176 | |
Ben Chan | 0214e30 | 2017-10-17 15:39:16 -0700 | [diff] [blame^] | 177 | vector<CrosDisksServer::DBusMountEntry> CrosDisksServer::EnumerateMountEntries( |
Ben Chan | 8fb742b | 2014-04-28 23:46:57 -0700 | [diff] [blame] | 178 | DBus::Error& error) { // NOLINT |
Ben Chan | 0214e30 | 2017-10-17 15:39:16 -0700 | [diff] [blame^] | 179 | vector<DBusMountEntry> dbus_mount_entries; |
Ben Chan | 8fb742b | 2014-04-28 23:46:57 -0700 | [diff] [blame] | 180 | for (const auto& manager : mount_managers_) { |
| 181 | vector<MountEntry> mount_entries; |
| 182 | manager->GetMountEntries(&mount_entries); |
| 183 | for (const auto& mount_entry : mount_entries) { |
Ben Chan | 0214e30 | 2017-10-17 15:39:16 -0700 | [diff] [blame^] | 184 | dbus_mount_entries.push_back( |
| 185 | {mount_entry.error_type, mount_entry.source_path, |
| 186 | mount_entry.source_type, mount_entry.mount_path}); |
Ben Chan | 8fb742b | 2014-04-28 23:46:57 -0700 | [diff] [blame] | 187 | } |
| 188 | } |
| 189 | return dbus_mount_entries; |
| 190 | } |
| 191 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 192 | DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 193 | DBus::Error& error) { // NOLINT |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 194 | Disk disk; |
| 195 | if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) { |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 196 | string message = "Could not get the properties of device " + device_path; |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 197 | LOG(ERROR) << message; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 198 | error.set(kCrosDisksServiceError, message.c_str()); |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 199 | } |
| 200 | return disk.ToDBusFormat(); |
| 201 | } |
| 202 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 203 | void CrosDisksServer::OnFormatCompleted(const string& device_path, |
| 204 | FormatErrorType error_type) { |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 205 | FormatCompleted(error_type, device_path); |
| 206 | } |
| 207 | |
Klemen Kozjek | b065885 | 2017-08-15 13:03:48 +0900 | [diff] [blame] | 208 | void CrosDisksServer::OnRenameCompleted(const string& device_path, |
| 209 | RenameErrorType error_type) { |
| 210 | RenameCompleted(error_type, device_path); |
| 211 | } |
| 212 | |
Ben Chan | 5988f29 | 2012-09-18 08:32:42 -0700 | [diff] [blame] | 213 | void CrosDisksServer::OnScreenIsLocked() { |
| 214 | // no-op |
| 215 | } |
| 216 | |
| 217 | void CrosDisksServer::OnScreenIsUnlocked() { |
| 218 | // no-op |
| 219 | } |
| 220 | |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame] | 221 | void CrosDisksServer::OnSessionStarted() { |
Ben Chan | 63ec9c4 | 2014-04-21 19:13:23 -0700 | [diff] [blame] | 222 | for (const auto& manager : mount_managers_) { |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame] | 223 | manager->StartSession(); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 224 | } |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 225 | } |
| 226 | |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame] | 227 | void CrosDisksServer::OnSessionStopped() { |
Ben Chan | 63ec9c4 | 2014-04-21 19:13:23 -0700 | [diff] [blame] | 228 | for (const auto& manager : mount_managers_) { |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame] | 229 | manager->StopSession(); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 230 | } |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) { |
| 234 | switch (event.event_type) { |
| 235 | case DeviceEvent::kDeviceAdded: |
| 236 | DeviceAdded(event.device_path); |
| 237 | break; |
| 238 | case DeviceEvent::kDeviceScanned: |
| 239 | DeviceScanned(event.device_path); |
| 240 | break; |
| 241 | case DeviceEvent::kDeviceRemoved: |
| 242 | DeviceRemoved(event.device_path); |
| 243 | break; |
| 244 | case DeviceEvent::kDiskAdded: |
| 245 | DiskAdded(event.device_path); |
| 246 | break; |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 247 | case DeviceEvent::kDiskChanged: |
| 248 | DiskChanged(event.device_path); |
| 249 | break; |
| 250 | case DeviceEvent::kDiskRemoved: |
| 251 | DiskRemoved(event.device_path); |
| 252 | break; |
| 253 | default: |
| 254 | break; |
| 255 | } |
| 256 | } |
| 257 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 258 | } // namespace cros_disks |