Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 752923c1 authored by Ken Sumrall's avatar Ken Sumrall
Browse files

Changes to init to support encrypted filesystems.

These are the changes to init and init.rc necessary to
support booting with and encrypted /data filesystem.
A corresponding change to init.<device>.rc goes along
with this change.

Change-Id: I0c7e2cc39568358014a82e317735c0eae14dd683
parent 36f93f01
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -162,6 +162,12 @@ int do_class_stop(int nargs, char **args)
    return 0;
}

int do_class_reset(int nargs, char **args)
{
    service_for_each_class(args[1], service_reset);
    return 0;
}

int do_domainname(int nargs, char **args)
{
    return write_file("/proc/sys/kernel/domainname", args[1]);
@@ -269,6 +275,8 @@ static struct {
    { 0,            0 },
};

#define DATA_MNT_POINT "/data"

/* mount <type> <device> <path> <flags ...> <options> */
int do_mount(int nargs, char **args)
{
@@ -359,9 +367,51 @@ 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.
             * 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)) {
                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("vold.decrypt", "1");
            } else {
                return -1;
            }
        } else {
            if (!strcmp(target, DATA_MNT_POINT)) {
                /* We succeeded in mounting /data, so it's not encrypted */
                action_for_each_trigger("nonencrypted", action_add_queue_tail);
            }
        }

        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);
        }
        return 0;
    }
}
+21 −5
Original line number Diff line number Diff line
@@ -150,11 +150,11 @@ void service_start(struct service *svc, const char *dynamic_args)
    int needs_console;
    int n;

        /* starting a service removes it from the disabled
        /* starting a service removes it from the disabled or reset
         * state and immediately takes it out of the restarting
         * state if it was in there
         */
    svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING));
    svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET));
    svc->time_started = 0;
    
        /* running processes require no additional work -- if
@@ -300,27 +300,42 @@ void service_start(struct service *svc, const char *dynamic_args)
        notify_service_state(svc->name, "running");
}

void service_stop(struct service *svc)
/* The how field should be either SVC_DISABLED or SVC_RESET */
static void service_stop_or_reset(struct service *svc, int how)
{
        /* we are no longer running, nor should we
         * attempt to restart
         */
    svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING));

    if ((how != SVC_DISABLED) && (how != SVC_RESET)) {
        /* Hrm, an illegal flag.  Default to SVC_DISABLED */
        how = SVC_DISABLED;
    }
        /* if the service has not yet started, prevent
         * it from auto-starting with its class
         */
    svc->flags |= SVC_DISABLED;
    svc->flags |= how;

    if (svc->pid) {
        NOTICE("service '%s' is being killed\n", svc->name);
        kill(-svc->pid, SIGTERM);
        kill(-svc->pid, SIGKILL);
        notify_service_state(svc->name, "stopping");
    } else {
        notify_service_state(svc->name, "stopped");
    }
}

void service_reset(struct service *svc)
{
    service_stop_or_reset(svc, SVC_RESET);
}

void service_stop(struct service *svc)
{
    service_stop_or_reset(svc, SVC_DISABLED);
}

void property_changed(const char *name, const char *value)
{
    if (property_triggers_enabled)
@@ -725,6 +740,7 @@ int main(int argc, char **argv)
    action_for_each_trigger("early-fs", action_add_queue_tail);
    action_for_each_trigger("fs", action_add_queue_tail);
    action_for_each_trigger("post-fs", action_add_queue_tail);
    action_for_each_trigger("post-fs-data", action_add_queue_tail);

    queue_builtin_action(property_service_init_action, "property_service_init");
    queue_builtin_action(signal_init_action, "signal_init");
+3 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ struct svcenvinfo {
#define SVC_RESTARTING  0x08  /* waiting to restart */
#define SVC_CONSOLE     0x10  /* requires console */
#define SVC_CRITICAL    0x20  /* will reboot into recovery if keeps crashing */
#define SVC_RESET       0x40  /* Use when stopping a process, but not disabling
                                 so it can be restarted with its class */

#define NR_SVC_SUPP_GIDS 12    /* twelve supplementary groups */

@@ -121,6 +123,7 @@ void service_for_each_class(const char *classname,
void service_for_each_flags(unsigned matchflags,
                            void (*func)(struct service *svc));
void service_stop(struct service *svc);
void service_reset(struct service *svc);
void service_start(struct service *svc, const char *dynamic_args);
void property_changed(const char *name, const char *value);

+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ int lookup_keyword(const char *s)
        if (!strcmp(s, "lass")) return K_class;
        if (!strcmp(s, "lass_start")) return K_class_start;
        if (!strcmp(s, "lass_stop")) return K_class_stop;
        if (!strcmp(s, "lass_reset")) return K_class_reset;
        if (!strcmp(s, "onsole")) return K_console;
        if (!strcmp(s, "hown")) return K_chown;
        if (!strcmp(s, "hmod")) return K_chmod;
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ int do_chroot(int nargs, char **args);
int do_chdir(int nargs, char **args);
int do_class_start(int nargs, char **args);
int do_class_stop(int nargs, char **args);
int do_class_reset(int nargs, char **args);
int do_domainname(int nargs, char **args);
int do_exec(int nargs, char **args);
int do_export(int nargs, char **args);
@@ -39,6 +40,7 @@ enum {
    KEYWORD(class,       OPTION,  0, 0)
    KEYWORD(class_start, COMMAND, 1, do_class_start)
    KEYWORD(class_stop,  COMMAND, 1, do_class_stop)
    KEYWORD(class_reset, COMMAND, 1, do_class_reset)
    KEYWORD(console,     OPTION,  0, 0)
    KEYWORD(critical,    OPTION,  0, 0)
    KEYWORD(disabled,    OPTION,  0, 0)
Loading