Add basic support for remounting ext4 userdata into checkpoint
Metadata encrypted ext4 userdata and v2 encryption keys will be
supported in follow up CLs.
Test: adb shell /system/bin/vdc checkpoint startCheckpoint 1
Test: adb reboot userspace
Bug: 135984674
Bug: 143970043
Change-Id: I8dbf3bddd811cf54d3f2b2ee2c1ea64159d8c6e0
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index cb69037..2dc47bb 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1118,6 +1118,12 @@
continue;
}
+ // Terrible hack to make it possible to remount /data.
+ // TODO: refact fs_mgr_mount_all and get rid of this.
+ if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") {
+ continue;
+ }
+
// Translate LABEL= file system labels into block devices.
if (is_extfs(current_entry.fs_type)) {
if (!TranslateExtLabels(¤t_entry)) {
@@ -1351,6 +1357,7 @@
return ret;
}
+// TODO(b/143970043): return different error codes based on which step failed.
int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
auto entry = GetMountedEntryForUserdata(fstab);
if (entry == nullptr) {
@@ -1374,12 +1381,29 @@
}
if (mount(entry->blk_device.c_str(), entry->mount_point.c_str(), "none",
MS_REMOUNT | entry->flags, entry->fs_options.c_str()) != 0) {
- LERROR << "Failed to remount userdata in checkpointing mode";
+ PERROR << "Failed to remount userdata in checkpointing mode";
return -1;
}
} else {
- // STOPSHIP(b/143970043): support remounting for ext4.
- LWARNING << "Remounting into checkpointing is not supported for ex4. Proceed with caution";
+ // STOPSHIP(b/143970043): support remounting for ext4 + metadata encryption.
+ if (should_use_metadata_encryption(*entry)) {
+ LWARNING << "Remounting into checkpointing is not supported for metadata encrypted "
+ << "ext4 userdata. Proceed with caution";
+ return 0;
+ }
+ if (umount2("/data", UMOUNT_NOFOLLOW) != 0) {
+ PERROR << "Failed to umount /data";
+ return -1;
+ }
+ DeviceMapper& dm = DeviceMapper::Instance();
+ // TODO(b/143970043): need to delete every dm-device under the one userdata is mounted on.
+ if (!dm.DeleteDeviceIfExists("bow")) {
+ LERROR << "Failed to delete dm-bow";
+ return -1;
+ }
+ // TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored.
+ int result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
+ return result == FS_MGR_MNTALL_FAIL ? -1 : 0;
}
return 0;
}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index ca67f37..9bc38f9 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -46,7 +46,9 @@
enum mount_mode {
MOUNT_MODE_DEFAULT = 0,
MOUNT_MODE_EARLY = 1,
- MOUNT_MODE_LATE = 2
+ MOUNT_MODE_LATE = 2,
+ // TODO(b/135984674): remove this after refactoring fs_mgr_mount_all.
+ MOUNT_MODE_ONLY_USERDATA = 3
};
#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
diff --git a/init/reboot.cpp b/init/reboot.cpp
index c9b521a..b04db7f 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -186,17 +186,17 @@
}
}
-static Result<void> ShutdownVold() {
- const char* vdc_argv[] = {"/system/bin/vdc", "volume", "shutdown"};
+static Result<void> CallVdc(const std::string& system, const std::string& cmd) {
+ const char* vdc_argv[] = {"/system/bin/vdc", system.c_str(), cmd.c_str()};
int status;
if (logwrap_fork_execvp(arraysize(vdc_argv), vdc_argv, &status, false, LOG_KLOG, true,
nullptr) != 0) {
- return ErrnoError() << "Failed to call 'vdc volume shutdown'";
+ return ErrnoError() << "Failed to call '/system/bin/vdc " << system << " " << cmd << "'";
}
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
return {};
}
- return Error() << "'vdc volume shutdown' failed : " << status;
+ return Error() << "'/system/bin/vdc " << system << " " << cmd << "' failed : " << status;
}
static void LogShutdownTime(UmountStat stat, Timer* t) {
@@ -658,7 +658,7 @@
// 3. send volume shutdown to vold
Service* vold_service = ServiceList::GetInstance().FindService("vold");
if (vold_service != nullptr && vold_service->IsRunning()) {
- ShutdownVold();
+ CallVdc("volume", "shutdown");
vold_service->Stop();
} else {
LOG(INFO) << "vold not running, skipping vold shutdown";
@@ -774,8 +774,12 @@
// TODO(b/135984674): store information about offending services for debugging.
return Error() << r << " post-data services are still running";
}
- // TODO(b/143970043): in case of ext4 we probably we will need to restart vold and kill zram
- // backing device.
+ if (auto result = KillZramBackingDevice(); !result) {
+ return result;
+ }
+ if (auto result = CallVdc("volume", "reset"); !result) {
+ return result;
+ }
if (int r = StopServicesAndLogViolations(GetDebuggingServices(true /* only_post_data */), 5s,
false /* SIGKILL */);
r > 0) {