fs_mgr: Support checkpoints
Adds support for partitions with checkpointing enabled. If the
checkpoint= fs_mgr flag is set, and the system has checkpointing on,
the partition will be mounted in checkpointing mode.
Test: Use vdc checkpoint commands, the checkpoint=fs fs_mgr flag
in the fstab, and a kernel containing the f2fs checkpoint
changes. https://lkml.org/lkml/2018/8/21/22
Change-Id: I3ea8da932de06fcfd2eed06b8640a8b1df837f1f
This commit is contained in:
parent
3da42a6c05
commit
4c93b256f6
5 changed files with 124 additions and 34 deletions
|
|
@ -805,6 +805,23 @@ static bool call_vdc(const std::vector<std::string>& args) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool call_vdc_ret(const std::vector<std::string>& args, int* ret) {
|
||||
std::vector<char const*> argv;
|
||||
argv.emplace_back("/system/bin/vdc");
|
||||
for (auto& arg : args) {
|
||||
argv.emplace_back(arg.c_str());
|
||||
}
|
||||
LOG(INFO) << "Calling: " << android::base::Join(argv, ' ');
|
||||
int err = android_fork_execvp(argv.size(), const_cast<char**>(argv.data()), ret, false, true);
|
||||
if (err != 0) {
|
||||
LOG(ERROR) << "vdc call failed with error code: " << err;
|
||||
return false;
|
||||
}
|
||||
LOG(DEBUG) << "vdc finished successfully";
|
||||
*ret = WEXITSTATUS(*ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
|
||||
// Logical partitions are specified with a named partition rather than a
|
||||
// block device, so if the block device is a path, then it has already
|
||||
|
|
@ -823,6 +840,24 @@ bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
|
||||
if (fs_mgr_is_checkpoint(rec)) {
|
||||
if (!strcmp(rec->fs_type, "f2fs")) {
|
||||
std::string opts(rec->fs_options);
|
||||
|
||||
opts += ",checkpoint=disable";
|
||||
free(rec->fs_options);
|
||||
rec->fs_options = strdup(opts.c_str());
|
||||
} 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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
|
@ -836,6 +871,7 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
|
|||
int mret = -1;
|
||||
int mount_errno = 0;
|
||||
int attempted_idx = -1;
|
||||
int need_checkpoint = -1;
|
||||
FsManagerAvbUniquePtr avb_handle(nullptr);
|
||||
|
||||
if (!fstab) {
|
||||
|
|
@ -882,6 +918,18 @@ int fs_mgr_mount_all(struct 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!";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
|
||||
!fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
|
||||
LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
|
||||
|
|
@ -1081,9 +1129,8 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec)
|
|||
* If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
|
||||
* in turn, and stop on 1st success, or no more match.
|
||||
*/
|
||||
int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
|
||||
char *tmp_mount_point)
|
||||
{
|
||||
static int fs_mgr_do_mount_helper(struct fstab* fstab, const char* n_name, char* n_blk_device,
|
||||
char* tmp_mount_point, int need_checkpoint) {
|
||||
int i = 0;
|
||||
int mount_errors = 0;
|
||||
int first_mount_errno = 0;
|
||||
|
|
@ -1116,6 +1163,18 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
|
|||
}
|
||||
}
|
||||
|
||||
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!";
|
||||
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)) {
|
||||
LERROR << "Skipping mounting '" << n_blk_device << "'";
|
||||
|
|
@ -1185,6 +1244,16 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
|
|||
return FS_MGR_DOMNT_FAILED;
|
||||
}
|
||||
|
||||
int fs_mgr_do_mount(struct fstab* fstab, const char* n_name, char* n_blk_device,
|
||||
char* tmp_mount_point) {
|
||||
return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, -1);
|
||||
}
|
||||
|
||||
int fs_mgr_do_mount(struct 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* mount a tmpfs filesystem at the given point.
|
||||
* return 0 on success, non-zero on failure.
|
||||
|
|
|
|||
|
|
@ -80,37 +80,39 @@ static struct flag_list mount_flags[] = {
|
|||
};
|
||||
|
||||
static struct flag_list fs_mgr_flags[] = {
|
||||
{"wait", MF_WAIT},
|
||||
{"check", MF_CHECK},
|
||||
{"encryptable=", MF_CRYPT},
|
||||
{"forceencrypt=", MF_FORCECRYPT},
|
||||
{"fileencryption=", MF_FILEENCRYPTION},
|
||||
{"forcefdeorfbe=", MF_FORCEFDEORFBE},
|
||||
{"keydirectory=", MF_KEYDIRECTORY},
|
||||
{"nonremovable", MF_NONREMOVABLE},
|
||||
{"voldmanaged=", MF_VOLDMANAGED},
|
||||
{"length=", MF_LENGTH},
|
||||
{"recoveryonly", MF_RECOVERYONLY},
|
||||
{"swapprio=", MF_SWAPPRIO},
|
||||
{"zramsize=", MF_ZRAMSIZE},
|
||||
{"max_comp_streams=", MF_MAX_COMP_STREAMS},
|
||||
{"verifyatboot", MF_VERIFYATBOOT},
|
||||
{"verify", MF_VERIFY},
|
||||
{"avb", MF_AVB},
|
||||
{"noemulatedsd", MF_NOEMULATEDSD},
|
||||
{"notrim", MF_NOTRIM},
|
||||
{"formattable", MF_FORMATTABLE},
|
||||
{"slotselect", MF_SLOTSELECT},
|
||||
{"nofail", MF_NOFAIL},
|
||||
{"latemount", MF_LATEMOUNT},
|
||||
{"reservedsize=", MF_RESERVEDSIZE},
|
||||
{"quota", MF_QUOTA},
|
||||
{"eraseblk=", MF_ERASEBLKSIZE},
|
||||
{"logicalblk=", MF_LOGICALBLKSIZE},
|
||||
{"sysfs_path=", MF_SYSFS},
|
||||
{"defaults", 0},
|
||||
{"logical", MF_LOGICAL},
|
||||
{0, 0},
|
||||
{"wait", MF_WAIT},
|
||||
{"check", MF_CHECK},
|
||||
{"encryptable=", MF_CRYPT},
|
||||
{"forceencrypt=", MF_FORCECRYPT},
|
||||
{"fileencryption=", MF_FILEENCRYPTION},
|
||||
{"forcefdeorfbe=", MF_FORCEFDEORFBE},
|
||||
{"keydirectory=", MF_KEYDIRECTORY},
|
||||
{"nonremovable", MF_NONREMOVABLE},
|
||||
{"voldmanaged=", MF_VOLDMANAGED},
|
||||
{"length=", MF_LENGTH},
|
||||
{"recoveryonly", MF_RECOVERYONLY},
|
||||
{"swapprio=", MF_SWAPPRIO},
|
||||
{"zramsize=", MF_ZRAMSIZE},
|
||||
{"max_comp_streams=", MF_MAX_COMP_STREAMS},
|
||||
{"verifyatboot", MF_VERIFYATBOOT},
|
||||
{"verify", MF_VERIFY},
|
||||
{"avb", MF_AVB},
|
||||
{"noemulatedsd", MF_NOEMULATEDSD},
|
||||
{"notrim", MF_NOTRIM},
|
||||
{"formattable", MF_FORMATTABLE},
|
||||
{"slotselect", MF_SLOTSELECT},
|
||||
{"nofail", MF_NOFAIL},
|
||||
{"latemount", MF_LATEMOUNT},
|
||||
{"reservedsize=", MF_RESERVEDSIZE},
|
||||
{"quota", MF_QUOTA},
|
||||
{"eraseblk=", MF_ERASEBLKSIZE},
|
||||
{"logicalblk=", MF_LOGICALBLKSIZE},
|
||||
{"sysfs_path=", MF_SYSFS},
|
||||
{"defaults", 0},
|
||||
{"logical", MF_LOGICAL},
|
||||
{"checkpoint=block", MF_CHECKPOINT_BLK},
|
||||
{"checkpoint=fs", MF_CHECKPOINT_FS},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
#define EM_AES_256_XTS 1
|
||||
|
|
@ -1004,3 +1006,15 @@ int fs_mgr_has_sysfs_path(const struct fstab_rec *fstab)
|
|||
int fs_mgr_is_logical(const struct fstab_rec* fstab) {
|
||||
return fstab->fs_mgr_flags & MF_LOGICAL;
|
||||
}
|
||||
|
||||
int fs_mgr_is_checkpoint(const struct fstab_rec* fstab) {
|
||||
return fstab->fs_mgr_flags & (MF_CHECKPOINT_FS | MF_CHECKPOINT_BLK);
|
||||
}
|
||||
|
||||
int fs_mgr_is_checkpoint_fs(const struct fstab_rec* fstab) {
|
||||
return fstab->fs_mgr_flags & MF_CHECKPOINT_FS;
|
||||
}
|
||||
|
||||
int fs_mgr_is_checkpoint_blk(const struct fstab_rec* fstab) {
|
||||
return fstab->fs_mgr_flags & MF_CHECKPOINT_BLK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@
|
|||
#define MF_KEYDIRECTORY 0X4000000
|
||||
#define MF_SYSFS 0X8000000
|
||||
#define MF_LOGICAL 0x10000000
|
||||
#define MF_CHECKPOINT_BLK 0x20000000
|
||||
#define MF_CHECKPOINT_FS 0x40000000
|
||||
// clang-format on
|
||||
|
||||
#define DM_BUF_SIZE 4096
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode);
|
|||
|
||||
int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
|
||||
char *tmp_mount_point);
|
||||
int fs_mgr_do_mount(struct fstab* fstab, const char* n_name, char* n_blk_device,
|
||||
char* tmp_mount_point, bool need_cp);
|
||||
int fs_mgr_do_mount_one(struct fstab_rec *rec);
|
||||
int fs_mgr_do_tmpfs_mount(const char *n_name);
|
||||
struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab);
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ int fs_mgr_is_nofail(const struct fstab_rec* fstab);
|
|||
int fs_mgr_is_latemount(const struct fstab_rec* fstab);
|
||||
int fs_mgr_is_quota(const struct fstab_rec* fstab);
|
||||
int fs_mgr_is_logical(const struct fstab_rec* fstab);
|
||||
int fs_mgr_is_checkpoint(const struct fstab_rec* fstab);
|
||||
int fs_mgr_is_checkpoint_fs(const struct fstab_rec* fstab);
|
||||
int fs_mgr_is_checkpoint_blk(const struct fstab_rec* fstab);
|
||||
int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab);
|
||||
|
||||
std::string fs_mgr_get_slot_suffix();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue