Merge "Add basic support for remounting ext4 userdata into checkpoint"

This commit is contained in:
Nikita Ioffe 2019-12-04 19:22:50 +00:00 committed by Gerrit Code Review
commit 9f71d6193a
3 changed files with 41 additions and 11 deletions

View file

@ -1118,6 +1118,12 @@ int fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
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(&current_entry)) {
@ -1351,6 +1357,7 @@ int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) {
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 @@ int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
}
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;
}

View file

@ -46,7 +46,9 @@ enum verity_mode {
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

View file

@ -186,17 +186,17 @@ static void TurnOffBacklight() {
}
}
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 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
// 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 @@ static Result<void> DoUserspaceReboot() {
// 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) {