make checkpointing work on ext4
Test: Test script passes
Change-Id: Iafa337947f2fd456aa692ecb112ccc56638f7947
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index d29ccf4..c89a541 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -840,7 +840,7 @@
}
bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
- if (fs_mgr_is_checkpoint(rec)) {
+ if (fs_mgr_is_checkpoint_fs(rec)) {
if (!strcmp(rec->fs_type, "f2fs")) {
std::string opts(rec->fs_options);
@@ -850,9 +850,42 @@
} else {
LERROR << rec->fs_type << " does not implement checkpoints.";
}
- } else if (rec->fs_mgr_flags & MF_CHECKPOINT_BLK) {
- LERROR << "Block based checkpoint not implemented.";
- return false;
+ } 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) {
+ PERROR << "Cannot open device " << rec->blk_device;
+ return false;
+ }
+
+ uint64_t size = get_block_device_size(fd) / 512;
+ if (!size) {
+ PERROR << "Cannot get device size";
+ return false;
+ }
+
+ android::dm::DmTable table;
+ if (!table.AddTarget(
+ std::make_unique<android::dm::DmTargetBow>(0, size, rec->blk_device))) {
+ LERROR << "Failed to add Bow target";
+ return false;
+ }
+
+ DeviceMapper& dm = DeviceMapper::Instance();
+ if (!dm.CreateDevice("bow", table)) {
+ PERROR << "Failed to create bow device";
+ return false;
+ }
+
+ std::string name;
+ if (!dm.GetDmDevicePathByName("bow", &name)) {
+ PERROR << "Failed to get bow device name";
+ return false;
+ }
+
+ rec->blk_device = strdup(name.c_str());
}
return true;
}
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index 3fde95a..175b0f0 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -156,6 +156,8 @@
std::string target_string_;
};
+// dm-bow is the backup on write target that can provide checkpoint capability
+// for file systems that do not support checkpoints natively
class DmTargetBow final : public DmTarget {
public:
DmTargetBow(uint64_t start, uint64_t length, const std::string& target_string)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index f39ea7c..2a70a4a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -400,6 +400,7 @@
# 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