Loading fs_mgr/fs_mgr.cpp +108 −60 Original line number Diff line number Diff line Loading @@ -850,7 +850,61 @@ bool fs_mgr_update_logical_partition(struct fstab_rec* rec) { return true; } bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { class CheckpointManager { public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} bool Update(struct fstab_rec* rec) { if (!fs_mgr_is_checkpoint(rec)) { return true; } if (fs_mgr_is_checkpoint_blk(rec)) { call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device}); } if (needs_checkpoint_ == UNKNOWN && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &needs_checkpoint_)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; needs_checkpoint_ = NO; } if (needs_checkpoint_ != YES) { return true; } if (!UpdateCheckpointPartition(rec)) { LERROR << "Could not set up checkpoint partition, skipping!"; return false; } return true; } bool Revert(struct fstab_rec* rec) { if (!fs_mgr_is_checkpoint(rec)) { return true; } if (device_map_.find(rec->blk_device) == device_map_.end()) { return true; } std::string bow_device = rec->blk_device; free(rec->blk_device); rec->blk_device = strdup(device_map_[bow_device].c_str()); device_map_.erase(bow_device); DeviceMapper& dm = DeviceMapper::Instance(); if (!dm.DeleteDevice("bow")) { PERROR << "Failed to remove bow device"; } return true; } private: bool UpdateCheckpointPartition(struct fstab_rec* rec) { if (fs_mgr_is_checkpoint_fs(rec)) { if (!strcmp(rec->fs_type, "f2fs")) { std::string opts(rec->fs_options); Loading @@ -862,8 +916,6 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { LERROR << rec->fs_type << " does not implement checkpoints."; } } else if (fs_mgr_is_checkpoint_blk(rec)) { call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device}); android::base::unique_fd fd( TEMP_FAILURE_RETRY(open(rec->blk_device, O_RDONLY | O_CLOEXEC))); if (!fd) { Loading @@ -880,7 +932,7 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { android::dm::DmTable table; if (!table.AddTarget( std::make_unique<android::dm::DmTargetBow>(0, size, rec->blk_device))) { LERROR << "Failed to add Bow target"; LERROR << "Failed to add bow target"; return false; } Loading @@ -896,11 +948,18 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { return false; } device_map_[name] = rec->blk_device; free(rec->blk_device); rec->blk_device = strdup(name.c_str()); } return true; } enum { UNKNOWN = -1, NO = 0, YES = 1 }; int needs_checkpoint_; std::map<std::string, std::string> device_map_; }; /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. Loading @@ -913,7 +972,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { int mret = -1; int mount_errno = 0; int attempted_idx = -1; int need_checkpoint = -1; CheckpointManager checkpoint_manager; FsManagerAvbUniquePtr avb_handle(nullptr); if (!fstab) { Loading Loading @@ -960,17 +1019,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } } if (fs_mgr_is_checkpoint(&fstab->recs[i])) { if (need_checkpoint == -1 && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; need_checkpoint = 0; } if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) { LERROR << "Could not set up checkpoint partition, skipping!"; if (!checkpoint_manager.Update(&fstab->recs[i])) { continue; } } if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) { Loading Loading @@ -1052,6 +1103,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { << " is wiped and " << fstab->recs[top_idx].mount_point << " " << fstab->recs[top_idx].fs_type << " is formattable. Format it."; checkpoint_manager.Revert(&fstab->recs[top_idx]); if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY); Loading Loading @@ -1172,11 +1226,12 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec) * in turn, and stop on 1st success, or no more match. */ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, int need_checkpoint) { char* tmp_mount_point, int needs_checkpoint) { int i = 0; int mount_errors = 0; int first_mount_errno = 0; char* mount_point; CheckpointManager checkpoint_manager(needs_checkpoint); FsManagerAvbUniquePtr avb_handle(nullptr); if (!fstab) { Loading Loading @@ -1205,17 +1260,10 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ } } if (fs_mgr_is_checkpoint(&fstab->recs[i])) { if (need_checkpoint == -1 && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; need_checkpoint = 0; } if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) { if (!checkpoint_manager.Update(&fstab->recs[i])) { LERROR << "Could not set up checkpoint partition, skipping!"; continue; } } /* First check the filesystem if requested */ if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) { Loading Loading @@ -1291,8 +1339,8 @@ int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* } int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, bool needs_cp) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_cp); bool needs_checkpoint) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint); } /* Loading rootdir/init.rc +4 −2 Original line number Diff line number Diff line Loading @@ -398,6 +398,10 @@ on late-fs class_start early_hal on post-fs-data # Start checkpoint before we touch data start vold exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint # We chown/chmod /data again so because mount is run as root + defaults chown system system /data chmod 0771 /data Loading @@ -405,8 +409,6 @@ on post-fs-data restorecon /data # Make sure we have the device encryption key. start vold exec - system system -- /system/bin/vdc checkpoint prepareDriveForCheckpoint /data installkey /data # Start bootcharting as soon as possible after the data partition is Loading Loading
fs_mgr/fs_mgr.cpp +108 −60 Original line number Diff line number Diff line Loading @@ -850,7 +850,61 @@ bool fs_mgr_update_logical_partition(struct fstab_rec* rec) { return true; } bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { class CheckpointManager { public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} bool Update(struct fstab_rec* rec) { if (!fs_mgr_is_checkpoint(rec)) { return true; } if (fs_mgr_is_checkpoint_blk(rec)) { call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device}); } if (needs_checkpoint_ == UNKNOWN && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &needs_checkpoint_)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; needs_checkpoint_ = NO; } if (needs_checkpoint_ != YES) { return true; } if (!UpdateCheckpointPartition(rec)) { LERROR << "Could not set up checkpoint partition, skipping!"; return false; } return true; } bool Revert(struct fstab_rec* rec) { if (!fs_mgr_is_checkpoint(rec)) { return true; } if (device_map_.find(rec->blk_device) == device_map_.end()) { return true; } std::string bow_device = rec->blk_device; free(rec->blk_device); rec->blk_device = strdup(device_map_[bow_device].c_str()); device_map_.erase(bow_device); DeviceMapper& dm = DeviceMapper::Instance(); if (!dm.DeleteDevice("bow")) { PERROR << "Failed to remove bow device"; } return true; } private: bool UpdateCheckpointPartition(struct fstab_rec* rec) { if (fs_mgr_is_checkpoint_fs(rec)) { if (!strcmp(rec->fs_type, "f2fs")) { std::string opts(rec->fs_options); Loading @@ -862,8 +916,6 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { LERROR << rec->fs_type << " does not implement checkpoints."; } } else if (fs_mgr_is_checkpoint_blk(rec)) { call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device}); android::base::unique_fd fd( TEMP_FAILURE_RETRY(open(rec->blk_device, O_RDONLY | O_CLOEXEC))); if (!fd) { Loading @@ -880,7 +932,7 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { android::dm::DmTable table; if (!table.AddTarget( std::make_unique<android::dm::DmTargetBow>(0, size, rec->blk_device))) { LERROR << "Failed to add Bow target"; LERROR << "Failed to add bow target"; return false; } Loading @@ -896,11 +948,18 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { return false; } device_map_[name] = rec->blk_device; free(rec->blk_device); rec->blk_device = strdup(name.c_str()); } return true; } enum { UNKNOWN = -1, NO = 0, YES = 1 }; int needs_checkpoint_; std::map<std::string, std::string> device_map_; }; /* When multiple fstab records share the same mount_point, it will * try to mount each one in turn, and ignore any duplicates after a * first successful mount. Loading @@ -913,7 +972,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { int mret = -1; int mount_errno = 0; int attempted_idx = -1; int need_checkpoint = -1; CheckpointManager checkpoint_manager; FsManagerAvbUniquePtr avb_handle(nullptr); if (!fstab) { Loading Loading @@ -960,17 +1019,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } } if (fs_mgr_is_checkpoint(&fstab->recs[i])) { if (need_checkpoint == -1 && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; need_checkpoint = 0; } if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) { LERROR << "Could not set up checkpoint partition, skipping!"; if (!checkpoint_manager.Update(&fstab->recs[i])) { continue; } } if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) { Loading Loading @@ -1052,6 +1103,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { << " is wiped and " << fstab->recs[top_idx].mount_point << " " << fstab->recs[top_idx].fs_type << " is formattable. Format it."; checkpoint_manager.Revert(&fstab->recs[top_idx]); if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY); Loading Loading @@ -1172,11 +1226,12 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec) * in turn, and stop on 1st success, or no more match. */ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, int need_checkpoint) { char* tmp_mount_point, int needs_checkpoint) { int i = 0; int mount_errors = 0; int first_mount_errno = 0; char* mount_point; CheckpointManager checkpoint_manager(needs_checkpoint); FsManagerAvbUniquePtr avb_handle(nullptr); if (!fstab) { Loading Loading @@ -1205,17 +1260,10 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ } } if (fs_mgr_is_checkpoint(&fstab->recs[i])) { if (need_checkpoint == -1 && !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) { LERROR << "Failed to find if checkpointing is needed. Assuming no."; need_checkpoint = 0; } if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) { if (!checkpoint_manager.Update(&fstab->recs[i])) { LERROR << "Could not set up checkpoint partition, skipping!"; continue; } } /* First check the filesystem if requested */ if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) { Loading Loading @@ -1291,8 +1339,8 @@ int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* } int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, bool needs_cp) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_cp); bool needs_checkpoint) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint); } /* Loading
rootdir/init.rc +4 −2 Original line number Diff line number Diff line Loading @@ -398,6 +398,10 @@ on late-fs class_start early_hal on post-fs-data # Start checkpoint before we touch data start vold exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint # We chown/chmod /data again so because mount is run as root + defaults chown system system /data chmod 0771 /data Loading @@ -405,8 +409,6 @@ on post-fs-data restorecon /data # Make sure we have the device encryption key. start vold exec - system system -- /system/bin/vdc checkpoint prepareDriveForCheckpoint /data installkey /data # Start bootcharting as soon as possible after the data partition is Loading