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.<device> file, and just calls one function to
mount all the filesystems.
Change-Id: If3db37530a0676000cba3e679db27aca734227e5
diff --git a/init/Android.mk b/init/Android.mk
index b456e43..7dae9df 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -32,11 +32,11 @@
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 0b9c0cf..a7e34a6 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -29,9 +29,11 @@
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/resource.h>
+#include <sys/wait.h>
#include <linux/loop.h>
#include <cutils/partition_utils.h>
#include <sys/system_properties.h>
+#include <fs_mgr.h>
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
@@ -432,72 +434,71 @@
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 f538450..5393e52 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -122,6 +122,7 @@
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 307c084..97d4950 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -12,6 +12,7 @@
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 @@
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)