Merge "userdata_checkpoint_remount: delete all devices in dm-stack under /data"

This commit is contained in:
Nikita Ioffe 2019-12-11 18:40:21 +00:00 committed by Gerrit Code Review
commit da776c394d

View file

@ -91,6 +91,7 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
using android::base::Basename;
using android::base::GetBoolProperty;
using android::base::Realpath;
using android::base::StartsWith;
using android::base::unique_fd;
@ -1357,14 +1358,33 @@ int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) {
return ret;
}
static std::string GetBlockDeviceForMountPoint(const std::string& mount_point) {
Fstab mounts;
if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
LERROR << "Can't read /proc/mounts";
return "";
}
auto entry = GetEntryForMountPoint(&mounts, mount_point);
if (entry == nullptr) {
LWARNING << mount_point << " is not mounted";
return "";
}
return entry->blk_device;
}
// 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) {
std::string block_device = GetBlockDeviceForMountPoint("/data");
if (block_device.empty()) {
LERROR << "/data is not mounted";
return -1;
}
auto fstab_entry = GetMountedEntryForUserdata(fstab);
if (fstab_entry == nullptr) {
LERROR << "Can't find /data in fstab";
return -1;
}
if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) {
if (!fstab_entry->fs_mgr_flags.checkpoint_blk && !fstab_entry->fs_mgr_flags.checkpoint_fs) {
LINFO << "Userdata doesn't support checkpointing. Nothing to do";
return 0;
}
@ -1373,34 +1393,43 @@ int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
LINFO << "Checkpointing not needed. Don't remount";
return 0;
}
if (entry->fs_mgr_flags.checkpoint_fs) {
bool force_umount_for_f2fs =
GetBoolProperty("sys.init.userdata_remount.force_umount_f2fs", false);
if (fstab_entry->fs_mgr_flags.checkpoint_fs && !force_umount_for_f2fs) {
// Userdata is f2fs, simply remount it.
if (!checkpoint_manager.Update(&(*entry))) {
if (!checkpoint_manager.Update(fstab_entry)) {
LERROR << "Failed to remount userdata in checkpointing mode";
return -1;
}
if (mount(entry->blk_device.c_str(), entry->mount_point.c_str(), "none",
MS_REMOUNT | entry->flags, entry->fs_options.c_str()) != 0) {
if (mount(block_device.c_str(), fstab_entry->mount_point.c_str(), "none",
MS_REMOUNT | fstab_entry->flags, fstab_entry->fs_options.c_str()) != 0) {
PERROR << "Failed to remount userdata in checkpointing mode";
return -1;
}
} else {
// 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;
}
LINFO << "Unmounting /data before remounting into checkpointing mode";
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;
while (dm.IsDmBlockDevice(block_device)) {
auto next_device = dm.GetParentBlockDeviceByPath(block_device);
auto name = dm.GetDmDeviceNameByPath(block_device);
if (!name) {
LERROR << "Failed to get dm-name for " << block_device;
return -1;
}
LINFO << "Deleting " << block_device << " named " << *name;
if (!dm.DeleteDevice(*name, 3s)) {
return -1;
}
if (!next_device) {
LERROR << "Failed to find parent device for " << block_device;
}
block_device = *next_device;
}
LINFO << "Remounting /data";
// 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;