summaryrefslogtreecommitdiffstats
path: root/fs_mgr
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2014-07-02 13:16:04 -0700
committerJP Abgrall <jpa@google.com>2014-07-02 13:39:44 -0700
commitf22b7452940c99b830749cabdd929f9f7cfdaacc (patch)
tree13f98c8609576ffe9116ddfda3ee5955b7f61dbe /fs_mgr
parent686bce6390db802bfd2cb4e78f9270596b6decb2 (diff)
downloadsystem_core-f22b7452940c99b830749cabdd929f9f7cfdaacc.zip
system_core-f22b7452940c99b830749cabdd929f9f7cfdaacc.tar.gz
system_core-f22b7452940c99b830749cabdd929f9f7cfdaacc.tar.bz2
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')
-rw-r--r--fs_mgr/fs_mgr.c151
-rw-r--r--fs_mgr/include/fs_mgr.h4
2 files changed, 95 insertions, 60 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index e9b4125..f01c562 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;
}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index b8bb5aa..ab3f828 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -53,6 +53,10 @@ struct fstab_rec {
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
void fs_mgr_free_fstab(struct fstab *fstab);
+
+#define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 2
+#define FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED 1
+#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 0
int fs_mgr_mount_all(struct fstab *fstab);
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
char *tmp_mount_point);