Merge "Handle retry count correctly" am: a1bb191541
am: 06834e3094
Change-Id: Ib8932b3b6964d833dcd5549444e28855b41db04f
This commit is contained in:
commit
0e93896806
2 changed files with 112 additions and 62 deletions
|
|
@ -851,56 +851,115 @@ bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
|
class CheckpointManager {
|
||||||
if (fs_mgr_is_checkpoint_fs(rec)) {
|
public:
|
||||||
if (!strcmp(rec->fs_type, "f2fs")) {
|
CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {}
|
||||||
std::string opts(rec->fs_options);
|
|
||||||
|
|
||||||
opts += ",checkpoint=disable";
|
bool Update(struct fstab_rec* rec) {
|
||||||
free(rec->fs_options);
|
if (!fs_mgr_is_checkpoint(rec)) {
|
||||||
rec->fs_options = strdup(opts.c_str());
|
return true;
|
||||||
} else {
|
|
||||||
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(
|
if (fs_mgr_is_checkpoint_blk(rec)) {
|
||||||
TEMP_FAILURE_RETRY(open(rec->blk_device, O_RDONLY | O_CLOEXEC)));
|
call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device});
|
||||||
if (!fd) {
|
}
|
||||||
PERROR << "Cannot open device " << 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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t size = get_block_device_size(fd) / 512;
|
return true;
|
||||||
if (!size) {
|
}
|
||||||
PERROR << "Cannot get device size";
|
|
||||||
return false;
|
bool Revert(struct fstab_rec* rec) {
|
||||||
|
if (!fs_mgr_is_checkpoint(rec)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
android::dm::DmTable table;
|
if (device_map_.find(rec->blk_device) == device_map_.end()) {
|
||||||
if (!table.AddTarget(
|
return true;
|
||||||
std::make_unique<android::dm::DmTargetBow>(0, size, rec->blk_device))) {
|
|
||||||
LERROR << "Failed to add Bow target";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
DeviceMapper& dm = DeviceMapper::Instance();
|
||||||
if (!dm.CreateDevice("bow", table)) {
|
if (!dm.DeleteDevice("bow")) {
|
||||||
PERROR << "Failed to create bow device";
|
PERROR << "Failed to remove bow device";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name;
|
return true;
|
||||||
if (!dm.GetDmDevicePathByName("bow", &name)) {
|
|
||||||
PERROR << "Failed to get bow device name";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rec->blk_device = strdup(name.c_str());
|
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
||||||
|
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 (fs_mgr_is_checkpoint_blk(rec)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
/* When multiple fstab records share the same mount_point, it will
|
||||||
* try to mount each one in turn, and ignore any duplicates after a
|
* try to mount each one in turn, and ignore any duplicates after a
|
||||||
|
|
@ -914,7 +973,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
|
||||||
int mret = -1;
|
int mret = -1;
|
||||||
int mount_errno = 0;
|
int mount_errno = 0;
|
||||||
int attempted_idx = -1;
|
int attempted_idx = -1;
|
||||||
int need_checkpoint = -1;
|
CheckpointManager checkpoint_manager;
|
||||||
FsManagerAvbUniquePtr avb_handle(nullptr);
|
FsManagerAvbUniquePtr avb_handle(nullptr);
|
||||||
|
|
||||||
if (!fstab) {
|
if (!fstab) {
|
||||||
|
|
@ -961,16 +1020,8 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_mgr_is_checkpoint(&fstab->recs[i])) {
|
if (!checkpoint_manager.Update(&fstab->recs[i])) {
|
||||||
if (need_checkpoint == -1 &&
|
continue;
|
||||||
!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 &&
|
if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
|
||||||
|
|
@ -1053,6 +1104,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
|
||||||
<< " is wiped and " << fstab->recs[top_idx].mount_point
|
<< " is wiped and " << fstab->recs[top_idx].mount_point
|
||||||
<< " " << fstab->recs[top_idx].fs_type
|
<< " " << fstab->recs[top_idx].fs_type
|
||||||
<< " is formattable. Format it.";
|
<< " is formattable. Format it.";
|
||||||
|
|
||||||
|
checkpoint_manager.Revert(&fstab->recs[top_idx]);
|
||||||
|
|
||||||
if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
|
if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
|
||||||
strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
|
strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
|
||||||
int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
|
int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
|
||||||
|
|
@ -1173,11 +1227,12 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec)
|
||||||
* in turn, and stop on 1st success, or no more match.
|
* 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,
|
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 i = 0;
|
||||||
int mount_errors = 0;
|
int mount_errors = 0;
|
||||||
int first_mount_errno = 0;
|
int first_mount_errno = 0;
|
||||||
char* mount_point;
|
char* mount_point;
|
||||||
|
CheckpointManager checkpoint_manager(needs_checkpoint);
|
||||||
FsManagerAvbUniquePtr avb_handle(nullptr);
|
FsManagerAvbUniquePtr avb_handle(nullptr);
|
||||||
|
|
||||||
if (!fstab) {
|
if (!fstab) {
|
||||||
|
|
@ -1206,16 +1261,9 @@ 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 (!checkpoint_manager.Update(&fstab->recs[i])) {
|
||||||
if (need_checkpoint == -1 &&
|
LERROR << "Could not set up checkpoint partition, skipping!";
|
||||||
!call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) {
|
continue;
|
||||||
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 */
|
/* First check the filesystem if requested */
|
||||||
|
|
@ -1292,8 +1340,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,
|
int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
|
||||||
bool needs_cp) {
|
bool needs_checkpoint) {
|
||||||
return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_cp);
|
return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,10 @@ on late-fs
|
||||||
class_start early_hal
|
class_start early_hal
|
||||||
|
|
||||||
on post-fs-data
|
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
|
# We chown/chmod /data again so because mount is run as root + defaults
|
||||||
chown system system /data
|
chown system system /data
|
||||||
chmod 0771 /data
|
chmod 0771 /data
|
||||||
|
|
@ -405,8 +409,6 @@ on post-fs-data
|
||||||
restorecon /data
|
restorecon /data
|
||||||
|
|
||||||
# Make sure we have the device encryption key.
|
# Make sure we have the device encryption key.
|
||||||
start vold
|
|
||||||
exec - system system -- /system/bin/vdc checkpoint prepareDriveForCheckpoint /data
|
|
||||||
installkey /data
|
installkey /data
|
||||||
|
|
||||||
# Start bootcharting as soon as possible after the data partition is
|
# Start bootcharting as soon as possible after the data partition is
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue