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
This commit is contained in:
Ken Sumrall 2012-04-17 17:20:16 -07:00
parent 7574c035b2
commit 08ec39ecc6
4 changed files with 63 additions and 59 deletions

View File

@ -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

View File

@ -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>
@ -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)

View File

@ -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':

View File

@ -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)