blob: d73dbc8cc9b6383beaf26bf7a24d07aca1e2cbf1 [file] [log] [blame]
Ryan Cairnsea6505f2011-04-10 19:54:53 -07001// 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 Chan5ccd9fe2013-11-13 18:28:27 -08005#include "cros-disks/cros_disks_server.h"
Ben Chan6e726922011-06-28 15:54:32 -07006
Ben Chan445852f2017-10-02 23:00:16 -07007#include <utility>
8
Ben Chanf51ff002011-04-25 12:41:57 -07009#include <base/logging.h>
Ben Chan6d0b2722011-11-18 08:24:14 -080010#include <chromeos/dbus/service_constants.h>
Ryan Cairnsea6505f2011-04-10 19:54:53 -070011
Ben Chan5ccd9fe2013-11-13 18:28:27 -080012#include "cros-disks/archive_manager.h"
13#include "cros-disks/device_event.h"
Ben Chanbdc39742011-05-11 17:51:26 -070014#include "cros-disks/disk.h"
Ben Chan5ccd9fe2013-11-13 18:28:27 -080015#include "cros-disks/disk_manager.h"
16#include "cros-disks/format_manager.h"
Ben Chan8dcede82011-07-25 20:56:13 -070017#include "cros-disks/platform.h"
Klemen Kozjekb0658852017-08-15 13:03:48 +090018#include "cros-disks/rename_manager.h"
Szymon Sidor2733b512011-06-30 18:00:51 -070019
Ben Chan190d3cf2011-07-07 09:38:48 -070020using std::string;
21using std::vector;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070022
Ben Chan460439f2011-09-13 09:16:28 -070023namespace cros_disks {
Ryan Cairnsea6505f2011-04-10 19:54:53 -070024
Ben Chan445852f2017-10-02 23:00:16 -070025CrosDisksServer::CrosDisksServer(scoped_refptr<dbus::Bus> bus,
Ben Chan8dcede82011-07-25 20:56:13 -070026 Platform* platform,
Ben Chan8dcede82011-07-25 20:56:13 -070027 DiskManager* disk_manager,
Klemen Kozjekb0658852017-08-15 13:03:48 +090028 FormatManager* format_manager,
29 RenameManager* rename_manager)
Ben Chan445852f2017-10-02 23:00:16 -070030 : org::chromium::CrosDisksAdaptor(this),
31 dbus_object_(nullptr, bus, dbus::ObjectPath(kCrosDisksServicePath)),
Ben Chan8dcede82011-07-25 20:56:13 -070032 platform_(platform),
Ben Chan6e726922011-06-28 15:54:32 -070033 disk_manager_(disk_manager),
Klemen Kozjekb0658852017-08-15 13:03:48 +090034 format_manager_(format_manager),
35 rename_manager_(rename_manager) {
Ben Chan8dcede82011-07-25 20:56:13 -070036 CHECK(platform_) << "Invalid platform object";
Ben Chanb092d752011-07-13 11:44:38 -070037 CHECK(disk_manager_) << "Invalid disk manager object";
38 CHECK(format_manager_) << "Invalid format manager object";
Klemen Kozjekb0658852017-08-15 13:03:48 +090039 CHECK(rename_manager_) << "Invalid rename manager object";
Szymon Sidor2733b512011-06-30 18:00:51 -070040
Ben Chanc1e766c2011-11-21 12:56:59 -080041 format_manager_->set_observer(this);
Klemen Kozjekb0658852017-08-15 13:03:48 +090042 rename_manager_->set_observer(this);
Ben Chanf51ff002011-04-25 12:41:57 -070043}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070044
Ben Chan445852f2017-10-02 23:00:16 -070045void CrosDisksServer::RegisterAsync(
46 const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
47 RegisterWithDBusObject(&dbus_object_);
48 dbus_object_.RegisterAsync(cb);
49}
50
Ben Chanf47fc352013-05-03 11:28:57 -070051void CrosDisksServer::RegisterMountManager(MountManager* mount_manager) {
52 CHECK(mount_manager) << "Invalid mount manager object";
53 mount_managers_.push_back(mount_manager);
54}
55
Ben Chanc1e766c2011-11-21 12:56:59 -080056void CrosDisksServer::Format(const string& path,
57 const string& filesystem_type,
Ben Chan445852f2017-10-02 23:00:16 -070058 const vector<string>& options) {
Ben Chanc833a522012-09-27 23:47:00 -070059 FormatErrorType error_type = FORMAT_ERROR_NONE;
60 Disk disk;
61 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
62 error_type = FORMAT_ERROR_INVALID_DEVICE_PATH;
Ben Chanff92fa32017-10-17 16:17:15 -070063 } else if (disk.is_on_boot_device) {
Ben Chanc833a522012-09-27 23:47:00 -070064 error_type = FORMAT_ERROR_DEVICE_NOT_ALLOWED;
65 } else {
Ben Chanff92fa32017-10-17 16:17:15 -070066 error_type = format_manager_->StartFormatting(path, disk.device_file,
Ben Chande0e3f62017-09-26 06:28:39 -070067 filesystem_type);
Ben Chanc833a522012-09-27 23:47:00 -070068 }
69
Ben Chanc1e766c2011-11-21 12:56:59 -080070 if (error_type != FORMAT_ERROR_NONE) {
Ben Chande0e3f62017-09-26 06:28:39 -070071 LOG(ERROR) << "Could not format device '" << path << "' as filesystem '"
72 << filesystem_type << "'";
Ben Chan445852f2017-10-02 23:00:16 -070073 SendFormatCompletedSignal(error_type, path);
Szymon Sidor2733b512011-06-30 18:00:51 -070074 }
Szymon Sidor2733b512011-06-30 18:00:51 -070075}
76
Ben Chan445852f2017-10-02 23:00:16 -070077void CrosDisksServer::Rename(const string& path, const string& volume_name) {
Klemen Kozjekb0658852017-08-15 13:03:48 +090078 RenameErrorType error_type = RENAME_ERROR_NONE;
79 Disk disk;
80 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
81 error_type = RENAME_ERROR_INVALID_DEVICE_PATH;
Ben Chanff92fa32017-10-17 16:17:15 -070082 } else if (disk.is_on_boot_device || disk.is_read_only) {
Klemen Kozjekb0658852017-08-15 13:03:48 +090083 error_type = RENAME_ERROR_DEVICE_NOT_ALLOWED;
84 } else {
Ben Chande0e3f62017-09-26 06:28:39 -070085 error_type = rename_manager_->StartRenaming(
Ben Chanff92fa32017-10-17 16:17:15 -070086 path, disk.device_file, volume_name, disk.filesystem_type);
Klemen Kozjekb0658852017-08-15 13:03:48 +090087 }
88
89 if (error_type != RENAME_ERROR_NONE) {
Ben Chande0e3f62017-09-26 06:28:39 -070090 LOG(ERROR) << "Could not rename device '" << path << "' as '" << volume_name
91 << "'";
Ben Chan445852f2017-10-02 23:00:16 -070092 SendRenameCompletedSignal(error_type, path);
Klemen Kozjekb0658852017-08-15 13:03:48 +090093 }
94}
95
Tatsuhisa Yamaguchib670bd12016-09-28 23:06:44 +090096MountManager* CrosDisksServer::FindMounter(const string& source_path) const {
97 for (const auto& manager : mount_managers_) {
98 if (manager->CanMount(source_path)) {
99 return manager;
100 }
101 }
102 return nullptr;
103}
104
Ben Chand3fdc722011-07-21 18:15:22 -0700105void CrosDisksServer::Mount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700106 const string& filesystem_type,
Ben Chan445852f2017-10-02 23:00:16 -0700107 const vector<string>& options) {
Ben Chanfcb2fc02011-11-21 09:44:07 -0800108 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan6d0b2722011-11-18 08:24:14 -0800109 MountSourceType source_type = MOUNT_SOURCE_INVALID;
Ben Chanadc5d002014-03-12 15:02:26 -0700110 string source_path;
Ben Chand3fdc722011-07-21 18:15:22 -0700111 string mount_path;
Ben Chan8dcede82011-07-25 20:56:13 -0700112
Ben Chanadc5d002014-03-12 15:02:26 -0700113 if (platform_->GetRealPath(path, &source_path)) {
Tatsuhisa Yamaguchib670bd12016-09-28 23:06:44 +0900114 MountManager* mounter = FindMounter(source_path);
115 if (mounter) {
116 source_type = mounter->GetMountSourceType();
117 error_type =
118 mounter->Mount(source_path, filesystem_type, options, &mount_path);
Ben Chan8dcede82011-07-25 20:56:13 -0700119 }
120 }
121
Ben Chanfcb2fc02011-11-21 09:44:07 -0800122 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700123 LOG(ERROR) << "Failed to mount '" << path << "'";
Ben Chand3fdc722011-07-21 18:15:22 -0700124 }
Ben Chan445852f2017-10-02 23:00:16 -0700125 SendMountCompletedSignal(error_type, path, source_type, mount_path);
Ben Chand3fdc722011-07-21 18:15:22 -0700126}
127
Ben Chan445852f2017-10-02 23:00:16 -0700128bool CrosDisksServer::Unmount(brillo::ErrorPtr* error,
129 const string& path,
130 const vector<string>& options) {
Ben Chanfcb2fc02011-11-21 09:44:07 -0800131 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan63ec9c42014-04-21 19:13:23 -0700132 for (const auto& manager : mount_managers_) {
Ben Chan8dcede82011-07-25 20:56:13 -0700133 if (manager->CanUnmount(path)) {
134 error_type = manager->Unmount(path, options);
135 break;
136 }
137 }
138
Ben Chan445852f2017-10-02 23:00:16 -0700139 if (error_type == MOUNT_ERROR_NONE) {
140 return true;
Ben Chand3fdc722011-07-21 18:15:22 -0700141 }
Ben Chan445852f2017-10-02 23:00:16 -0700142
143 string message = "Failed to unmount '" + path + "'";
144 brillo::Error::AddTo(error, FROM_HERE, brillo::errors::dbus::kDomain,
145 kCrosDisksServiceError, message);
146 return false;
Ben Chand3fdc722011-07-21 18:15:22 -0700147}
148
Ben Chan445852f2017-10-02 23:00:16 -0700149void CrosDisksServer::UnmountAll() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700150 for (const auto& manager : mount_managers_) {
Ben Chan8f513762011-11-14 12:44:42 -0800151 manager->UnmountAll();
152 }
153}
154
Ben Chan190d3cf2011-07-07 09:38:48 -0700155vector<string> CrosDisksServer::DoEnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700156 bool auto_mountable_only) const {
Ben Chan190d3cf2011-07-07 09:38:48 -0700157 vector<Disk> disks = disk_manager_->EnumerateDisks();
158 vector<string> devices;
Ben Chanf51ff002011-04-25 12:41:57 -0700159 devices.reserve(disks.size());
Ben Chan63ec9c42014-04-21 19:13:23 -0700160 for (const auto& disk : disks) {
Ben Chanff92fa32017-10-17 16:17:15 -0700161 if (!auto_mountable_only || disk.is_auto_mountable) {
162 devices.push_back(disk.native_path);
Ben Chan490319f2011-05-06 14:00:42 -0700163 }
164 }
Ben Chanf51ff002011-04-25 12:41:57 -0700165 return devices;
166}
167
Ben Chan445852f2017-10-02 23:00:16 -0700168vector<string> CrosDisksServer::EnumerateDevices() {
Ben Chan490319f2011-05-06 14:00:42 -0700169 return DoEnumerateDevices(false);
170}
171
Ben Chan445852f2017-10-02 23:00:16 -0700172vector<string> CrosDisksServer::EnumerateAutoMountableDevices() {
Ben Chan490319f2011-05-06 14:00:42 -0700173 return DoEnumerateDevices(true);
174}
175
Ben Chan445852f2017-10-02 23:00:16 -0700176vector<CrosDisksServer::DBusMountEntry>
177CrosDisksServer::EnumerateMountEntries() {
Ben Chan0214e302017-10-17 15:39:16 -0700178 vector<DBusMountEntry> dbus_mount_entries;
Ben Chan8fb742b2014-04-28 23:46:57 -0700179 for (const auto& manager : mount_managers_) {
Ben Chan7dfb8102017-10-17 15:47:37 -0700180 for (const auto& mount_entry : manager->GetMountEntries()) {
Ben Chan0214e302017-10-17 15:39:16 -0700181 dbus_mount_entries.push_back(
Ben Chan445852f2017-10-02 23:00:16 -0700182 std::make_tuple(static_cast<uint32_t>(mount_entry.error_type),
183 mount_entry.source_path,
184 static_cast<uint32_t>(mount_entry.source_type),
185 mount_entry.mount_path));
Ben Chan8fb742b2014-04-28 23:46:57 -0700186 }
187 }
188 return dbus_mount_entries;
189}
190
Ben Chan445852f2017-10-02 23:00:16 -0700191bool CrosDisksServer::GetDeviceProperties(
192 brillo::ErrorPtr* error,
Ben Chanff92fa32017-10-17 16:17:15 -0700193 const string& device_path,
Ben Chan445852f2017-10-02 23:00:16 -0700194 brillo::VariantDictionary* properties) {
Ben Chanf51ff002011-04-25 12:41:57 -0700195 Disk disk;
196 if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) {
Ben Chan190d3cf2011-07-07 09:38:48 -0700197 string message = "Could not get the properties of device " + device_path;
Ben Chanf51ff002011-04-25 12:41:57 -0700198 LOG(ERROR) << message;
Ben Chan445852f2017-10-02 23:00:16 -0700199 brillo::Error::AddTo(error, FROM_HERE, brillo::errors::dbus::kDomain,
200 kCrosDisksServiceError, message);
201 return false;
Ben Chanf51ff002011-04-25 12:41:57 -0700202 }
Ben Chanff92fa32017-10-17 16:17:15 -0700203
Ben Chan445852f2017-10-02 23:00:16 -0700204 brillo::VariantDictionary temp_properties;
205 temp_properties[kDeviceIsDrive] = disk.is_drive;
206 temp_properties[kDevicePresentationHide] = disk.is_hidden;
207 temp_properties[kDeviceIsMounted] = disk.IsMounted();
208 temp_properties[kDeviceIsMediaAvailable] = disk.is_media_available;
209 temp_properties[kDeviceIsOnBootDevice] = disk.is_on_boot_device;
210 temp_properties[kDeviceIsOnRemovableDevice] = disk.is_on_removable_device;
211 temp_properties[kDeviceIsVirtual] = disk.is_virtual;
212 temp_properties[kNativePath] = disk.native_path;
213 temp_properties[kDeviceFile] = disk.device_file;
214 temp_properties[kIdUuid] = disk.uuid;
215 temp_properties[kIdLabel] = disk.label;
216 temp_properties[kVendorId] = disk.vendor_id;
217 temp_properties[kVendorName] = disk.vendor_name;
218 temp_properties[kProductId] = disk.product_id;
219 temp_properties[kProductName] = disk.product_name;
220 temp_properties[kDriveModel] = disk.drive_model;
221 temp_properties[kDriveIsRotational] = disk.is_rotational;
222 temp_properties[kDeviceMediaType] = static_cast<uint32_t>(disk.media_type);
223 temp_properties[kDeviceSize] = disk.device_capacity;
224 temp_properties[kDeviceIsReadOnly] = disk.is_read_only;
225 temp_properties[kFileSystemType] = disk.filesystem_type;
226 temp_properties[kDeviceMountPaths] = disk.mount_paths;
227 *properties = std::move(temp_properties);
228 return true;
Ben Chanf51ff002011-04-25 12:41:57 -0700229}
230
Ben Chanc1e766c2011-11-21 12:56:59 -0800231void CrosDisksServer::OnFormatCompleted(const string& device_path,
232 FormatErrorType error_type) {
Ben Chan445852f2017-10-02 23:00:16 -0700233 SendFormatCompletedSignal(error_type, device_path);
Ben Chanc1e766c2011-11-21 12:56:59 -0800234}
235
Klemen Kozjekb0658852017-08-15 13:03:48 +0900236void CrosDisksServer::OnRenameCompleted(const string& device_path,
237 RenameErrorType error_type) {
Ben Chan445852f2017-10-02 23:00:16 -0700238 SendRenameCompletedSignal(error_type, device_path);
Klemen Kozjekb0658852017-08-15 13:03:48 +0900239}
240
Ben Chan5988f292012-09-18 08:32:42 -0700241void CrosDisksServer::OnScreenIsLocked() {
242 // no-op
243}
244
245void CrosDisksServer::OnScreenIsUnlocked() {
246 // no-op
247}
248
Ben Chanb3bf8d12013-04-23 13:57:55 -0700249void CrosDisksServer::OnSessionStarted() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700250 for (const auto& manager : mount_managers_) {
Ben Chanb3bf8d12013-04-23 13:57:55 -0700251 manager->StartSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700252 }
Ben Chan6e726922011-06-28 15:54:32 -0700253}
254
Ben Chanb3bf8d12013-04-23 13:57:55 -0700255void CrosDisksServer::OnSessionStopped() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700256 for (const auto& manager : mount_managers_) {
Ben Chanb3bf8d12013-04-23 13:57:55 -0700257 manager->StopSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700258 }
Ben Chan6e726922011-06-28 15:54:32 -0700259}
260
261void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
262 switch (event.event_type) {
263 case DeviceEvent::kDeviceAdded:
Ben Chan445852f2017-10-02 23:00:16 -0700264 SendDeviceAddedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700265 break;
266 case DeviceEvent::kDeviceScanned:
Ben Chan445852f2017-10-02 23:00:16 -0700267 SendDeviceScannedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700268 break;
269 case DeviceEvent::kDeviceRemoved:
Ben Chan445852f2017-10-02 23:00:16 -0700270 SendDeviceRemovedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700271 break;
272 case DeviceEvent::kDiskAdded:
Ben Chan445852f2017-10-02 23:00:16 -0700273 SendDiskAddedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700274 break;
Ben Chan6e726922011-06-28 15:54:32 -0700275 case DeviceEvent::kDiskChanged:
Ben Chan445852f2017-10-02 23:00:16 -0700276 SendDiskChangedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700277 break;
278 case DeviceEvent::kDiskRemoved:
Ben Chan445852f2017-10-02 23:00:16 -0700279 SendDiskRemovedSignal(event.device_path);
Ben Chan6e726922011-06-28 15:54:32 -0700280 break;
281 default:
282 break;
283 }
284}
285
Ben Chanbdc39742011-05-11 17:51:26 -0700286} // namespace cros_disks