From 08ec39ecc68674c18cd11bc4d75b30309d6d970f Mon Sep 17 00:00:00 2001 From: Ken Sumrall Date: Tue, 17 Apr 2012 17:20:16 -0700 Subject: [PATCH] Change init to use libfs_mgr to mount filesystems. The new fs_mgr library moves much of the knowledge of what filesystems to mount into a new fstab. file, and just calls one function to mount all the filesystems. Change-Id: If3db37530a0676000cba3e679db27aca734227e5 --- init/Android.mk | 4 +- init/builtins.c | 115 +++++++++++++++++++++++---------------------- init/init_parser.c | 1 + init/keywords.h | 2 + 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/init/Android.mk b/init/Android.mk index b456e4390..7dae9df89 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -32,11 +32,11 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) -LOCAL_STATIC_LIBRARIES := libcutils libc +LOCAL_STATIC_LIBRARIES := libfs_mgr libcutils libc ifeq ($(HAVE_SELINUX),true) LOCAL_STATIC_LIBRARIES += libselinux -LOCAL_C_INCLUDES := external/libselinux/include +LOCAL_C_INCLUDES += external/libselinux/include LOCAL_CFLAGS += -DHAVE_SELINUX endif diff --git a/init/builtins.c b/init/builtins.c index 661c9b180..ac9585e83 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -29,9 +29,11 @@ #include #include #include +#include #include #include #include +#include #ifdef HAVE_SELINUX #include @@ -433,72 +435,71 @@ int do_mount(int nargs, char **args) if (wait) wait_for_file(source, COMMAND_RETRY_TIMEOUT); if (mount(source, target, system, flags, options) < 0) { - /* If this fails, it may be an encrypted filesystem - * or it could just be wiped. If wiped, that will be - * handled later in the boot process. - * We only support encrypting /data. Check - * if we're trying to mount it, and if so, - * assume it's encrypted, mount a tmpfs instead. - * Then save the orig mount parms in properties - * for vold to query when it mounts the real - * encrypted /data. - */ - if (!strcmp(target, DATA_MNT_POINT) && !partition_wiped(source)) { - const char *tmpfs_options; - - tmpfs_options = property_get("ro.crypto.tmpfs_options"); - - if (mount("tmpfs", target, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV, - tmpfs_options) < 0) { - return -1; - } - - /* Set the property that triggers the framework to do a minimal - * startup and ask the user for a password - */ - property_set("ro.crypto.state", "encrypted"); - property_set("vold.decrypt", "1"); - } else { - return -1; - } + return -1; } - if (!strcmp(target, DATA_MNT_POINT)) { - char fs_flags[32]; - - /* Save the original mount options */ - property_set("ro.crypto.fs_type", system); - property_set("ro.crypto.fs_real_blkdev", source); - property_set("ro.crypto.fs_mnt_point", target); - if (options) { - property_set("ro.crypto.fs_options", options); - } - snprintf(fs_flags, sizeof(fs_flags), "0x%8.8x", flags); - property_set("ro.crypto.fs_flags", fs_flags); - } } exit_success: - /* If not running encrypted, then set the property saying we are - * unencrypted, and also trigger the action for a nonencrypted system. - */ - if (!strcmp(target, DATA_MNT_POINT)) { - const char *prop; - - prop = property_get("ro.crypto.state"); - if (! prop) { - prop = "notset"; - } - if (strcmp(prop, "encrypted")) { - property_set("ro.crypto.state", "unencrypted"); - action_for_each_trigger("nonencrypted", action_add_queue_tail); - } - } - return 0; } +int do_mount_all(int nargs, char **args) +{ + pid_t pid; + int ret = -1; + int child_ret = -1; + int status; + const char *prop; + + if (nargs != 2) { + return -1; + } + + /* + * Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and + * do the call in the child to provide protection to the main init + * process if anything goes wrong (crash or memory leak), and wait for + * the child to finish in the parent. + */ + pid = fork(); + if (pid > 0) { + /* Parent. Wait for the child to return */ + waitpid(pid, &status, 0); + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + } else { + ret = -1; + } + } else if (pid == 0) { + /* child, call fs_mgr_mount_all() */ + klog_set_level(6); /* So we can see what fs_mgr_mount_all() does */ + child_ret = fs_mgr_mount_all(args[1]); + if (child_ret == -1) { + ERROR("fs_mgr_mount_all returned an error\n"); + } + exit(child_ret); + } else { + /* fork failed, return an error */ + return -1; + } + + /* ret is 1 if the device is encrypted, 0 if not, and -1 on error */ + if (ret == 1) { + property_set("ro.crypto.state", "encrypted"); + property_set("vold.decrypt", "1"); + } else if (ret == 0) { + property_set("ro.crypto.state", "unencrypted"); + /* If fs_mgr determined this is an unencrypted device, then trigger + * that action. + */ + action_for_each_trigger("nonencrypted", action_add_queue_tail); + } + + return ret; +} + int do_setcon(int nargs, char **args) { #ifdef HAVE_SELINUX if (is_selinux_enabled() <= 0) diff --git a/init/init_parser.c b/init/init_parser.c index f53845091..5393e526c 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -122,6 +122,7 @@ int lookup_keyword(const char *s) break; case 'm': if (!strcmp(s, "kdir")) return K_mkdir; + if (!strcmp(s, "ount_all")) return K_mount_all; if (!strcmp(s, "ount")) return K_mount; break; case 'o': diff --git a/init/keywords.h b/init/keywords.h index 307c0845d..97d4950a8 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -12,6 +12,7 @@ int do_hostname(int nargs, char **args); int do_ifup(int nargs, char **args); int do_insmod(int nargs, char **args); int do_mkdir(int nargs, char **args); +int do_mount_all(int nargs, char **args); int do_mount(int nargs, char **args); int do_restart(int nargs, char **args); int do_restorecon(int nargs, char **args); @@ -60,6 +61,7 @@ enum { KEYWORD(import, SECTION, 1, 0) KEYWORD(keycodes, OPTION, 0, 0) KEYWORD(mkdir, COMMAND, 1, do_mkdir) + KEYWORD(mount_all, COMMAND, 1, do_mount_all) KEYWORD(mount, COMMAND, 3, do_mount) KEYWORD(on, SECTION, 0, 0) KEYWORD(oneshot, OPTION, 0, 0)