Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f71d619 authored by Nikita Ioffe's avatar Nikita Ioffe Committed by Gerrit Code Review
Browse files

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

parents 8fa4d6c3 bee7b8c8
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -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;
}
+3 −1
Original line number Diff line number Diff line
@@ -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
+11 −7
Original line number Diff line number Diff line
@@ -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) {