diff options
author | JP Abgrall <jpa@google.com> | 2014-07-02 13:16:04 -0700 |
---|---|---|
committer | JP Abgrall <jpa@google.com> | 2014-07-02 13:39:44 -0700 |
commit | f22b7452940c99b830749cabdd929f9f7cfdaacc (patch) | |
tree | 13f98c8609576ffe9116ddfda3ee5955b7f61dbe /fs_mgr/fs_mgr.c | |
parent | 686bce6390db802bfd2cb4e78f9270596b6decb2 (diff) | |
download | core-f22b7452940c99b830749cabdd929f9f7cfdaacc.tar.gz core-f22b7452940c99b830749cabdd929f9f7cfdaacc.tar.bz2 core-f22b7452940c99b830749cabdd929f9f7cfdaacc.zip |
fs_mrg: clean up multi-type mount_all
Move the code that attempts to mount alternative fstab entries
into its own function.
Clarify return codes.
Suggest wipe via recovery in error messages.
Bug: 15747366
Change-Id: I3634477cd4d1d73f974f3e906c53285f0d9e0eac
Signed-off-by: JP Abgrall <jpa@google.com>
Diffstat (limited to 'fs_mgr/fs_mgr.c')
-rw-r--r-- | fs_mgr/fs_mgr.c | 151 |
1 files changed, 91 insertions, 60 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index e9b41252b..f01c56207 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -245,31 +245,89 @@ static int device_is_debuggable() { return strcmp(value, "1") ? 0 : 1; } -void wipe_data_via_recovery() +/* + * Tries to mount any of the consecutive fstab entries that match + * the mountpoint of the one given by fstab->recs[start_idx]. + * + * end_idx: On return, will be the last rec that was looked at. + * attempted_idx: On return, will indicate which fstab rec + * succeeded. In case of failure, it will be the start_idx. + * Returns + * -1 on failure with errno set to match the 1st mount failure. + * 0 on success. + */ +static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx) { - mkdir("/cache/recovery", 0700); - int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600); - if (fd >= 0) { - write(fd, "--wipe_data", strlen("--wipe_data") + 1); - close(fd); - } else { - ERROR("could not open /cache/recovery/command\n"); + int i; + int mount_errno = 0; + int mounted = 0; + + if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { + errno = EINVAL; + if (end_idx) *end_idx = start_idx; + if (attempted_idx) *end_idx = start_idx; + return -1; + } + + /* Hunt down an fstab entry for the same mount point that might succeed */ + for (i = start_idx; + /* We required that fstab entries for the same mountpoint be consecutive */ + i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point); + i++) { + /* + * Don't try to mount/encrypt the same mount point again. + * Deal with alternate entries for the same point which are required to be all following + * each other. + */ + if (mounted) { + ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__, + fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type); + continue; + } + + if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { + check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, + fstab->recs[i].mount_point); + } + if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { + *attempted_idx = i; + mounted = 1; + if (i != start_idx) { + ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__, + fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type, + fstab->recs[start_idx].fs_type); + } + } else { + /* back up errno for crypto decisions */ + mount_errno = errno; + } } - property_set(ANDROID_RB_PROPERTY, "reboot,recovery"); + + /* Adjust i for the case where it was still withing the recs[] */ + if (i < fstab->num_entries) --i; + + *end_idx = i; + if (!mounted) { + *attempted_idx = start_idx; + errno = mount_errno; + return -1; + } + return 0; } /* 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. + * Returns -1 on error, and FS_MGR_MNTALL_* otherwise. */ int fs_mgr_mount_all(struct fstab *fstab) { - int i = 0, j = 0; - int encryptable = 0; + int i = 0; + int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; int error_count = 0; int mret = -1; int mount_errno = 0; - const char *last_ok_mount_point = NULL; + int attempted_idx = -1; if (!fstab) { return -1; @@ -299,55 +357,27 @@ int fs_mgr_mount_all(struct fstab *fstab) continue; } } - - /* - * Don't try to mount/encrypt the same mount point again. - * Deal with alternate entries for the same point which are required to be all following - * each other. - */ - if (last_ok_mount_point && !strcmp(last_ok_mount_point, fstab->recs[i].mount_point)) { - INFO("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted.\n", __func__, - last_ok_mount_point, i, fstab->recs[i].fs_type); - continue; - } - /* Hunt down an fstab entry for the same mount point that might succeed */ - for (j = i; - /* We required that fstab entries for the same mountpoint be consecutive */ - j < fstab->num_entries && !strcmp(fstab->recs[i].mount_point, fstab->recs[j].mount_point); - j++) { - if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { - check_fs(fstab->recs[j].blk_device, fstab->recs[j].fs_type, - fstab->recs[j].mount_point); - } - mret = __mount(fstab->recs[j].blk_device, fstab->recs[j].mount_point, &fstab->recs[j]); - if (!mret) { - last_ok_mount_point = fstab->recs[j].mount_point; - if (i != j) { - INFO("%s(): some alternate mount worked for mount_point=%s fs_type=%s instead of fs_type=%s\n", __func__, - last_ok_mount_point, fstab->recs[j].fs_type, fstab->recs[i].fs_type); - i = j; /* We advance the recs index to the working entry */ - } - break; - } else { - /* back up errno for crypto decisions */ - mount_errno = errno; - } - } + int last_idx_inspected; + mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); + i = last_idx_inspected; + mount_errno = errno; /* Deal with encryptability. */ if (!mret) { /* If this is encryptable, need to trigger encryption */ - if ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT)) { - if (umount(fstab->recs[i].mount_point) == 0) { - if (!encryptable) { - encryptable = 2; + if ((fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)) { + if (umount(fstab->recs[attempted_idx].mount_point) == 0) { + if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { + ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_type); + encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION; } else { ERROR("Only one encryptable/encrypted partition supported\n"); - encryptable = 1; + encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } } else { INFO("Could not umount %s - allow continue unencrypted\n", - fstab->recs[i].mount_point); + fstab->recs[attempted_idx].mount_point); continue; } } @@ -358,27 +388,28 @@ int fs_mgr_mount_all(struct fstab *fstab) /* mount(2) returned an error, check if it's encryptable and deal with it */ if (mret && mount_errno != EBUSY && mount_errno != EACCES && fs_mgr_is_encryptable(&fstab->recs[i])) { - if(partition_wiped(fstab->recs[i].blk_device) && fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) { - ERROR("Found an encryptable wiped partition with force encrypt. Formating via recovery.\n"); - wipe_data_via_recovery(); /* This is queue up a reboot */ + if (partition_wiped(fstab->recs[i].blk_device)) { + ERROR("%s(): Encryptable wiped partition %s. Recommend wiping via recovery. Fail for now.\n", __func__, fstab->recs[i].mount_point); ++error_count; continue; } else { /* Need to mount a tmpfs at this mountpoint for now, and set * properties that vold will query later for decrypting */ - if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) { + ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__, + fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_type); + if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { ++error_count; continue; } - last_ok_mount_point = fstab->recs[i].mount_point; } - encryptable = 1; + encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; } else { ERROR("Failed to mount an un-encryptable or wiped partition on" "%s at %s options: %s error: %s\n", - fstab->recs[i].blk_device, fstab->recs[i].mount_point, - fstab->recs[i].fs_options, strerror(mount_errno)); + fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, + fstab->recs[attempted_idx].fs_options, strerror(mount_errno)); ++error_count; continue; } |