diff --git a/init/builtins.c b/init/builtins.c index 4326ebcc8..8b2e4aacc 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -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 */ 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) { - return -1; + /* 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; } } diff --git a/init/init.c b/init/init.c index 7aef38721..e13d4b186 100755 --- a/init/init.c +++ b/init/init.c @@ -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"); diff --git a/init/init.h b/init/init.h index 869133510..05cdfaa96 100644 --- a/init/init.h +++ b/init/init.h @@ -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); diff --git a/init/init_parser.c b/init/init_parser.c index d136c28a0..7ac1a1ec8 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -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; diff --git a/init/keywords.h b/init/keywords.h index 25315d835..d15ad49ef 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -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) diff --git a/init/signal_handler.c b/init/signal_handler.c index 3e5d1368d..833e59df0 100644 --- a/init/signal_handler.c +++ b/init/signal_handler.c @@ -83,8 +83,8 @@ static int wait_for_one_process(int block) svc->flags |= SVC_DISABLED; } - /* disabled processes do not get restarted automatically */ - if (svc->flags & SVC_DISABLED) { + /* disabled and reset processes do not get restarted automatically */ + if (svc->flags & (SVC_DISABLED | SVC_RESET) ) { notify_service_state(svc->name, "stopped"); return 0; } diff --git a/rootdir/init.rc b/rootdir/init.rc index d252d7163..9f3020f7d 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -96,6 +96,32 @@ on post-fs # once everything is setup, no need to modify / mount rootfs rootfs / ro remount + # We chown/chmod /cache again so because mount is run as root + defaults + chown system cache /cache + chmod 0770 /cache + + # This may have been created by the recovery system with odd permissions + chown system cache /cache/recovery + chmod 0770 /cache/recovery + + #change permissions on vmallocinfo so we can grab it from bugreports + chown root log /proc/vmallocinfo + chmod 0440 /proc/vmallocinfo + + #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks + chown root system /proc/kmsg + chmod 0440 /proc/kmsg + chown root system /proc/sysrq-trigger + chmod 0220 /proc/sysrq-trigger + + # create the lost+found directories, so as to enforce our permissions + mkdir /cache/lost+found 0770 + + # double check the perms, in case lost+found already exists, and set owner + chown root root /cache/lost+found + chmod 0770 /cache/lost+found + +on post-fs-data # We chown/chmod /data again so because mount is run as root + defaults chown system system /data chmod 0771 /data @@ -119,25 +145,7 @@ on post-fs write /proc/apanic_console 1 - # Same reason as /data above - chown system cache /cache - chmod 0770 /cache - - # This may have been created by the recovery system with odd permissions - chown system cache /cache/recovery - chmod 0770 /cache/recovery - - #change permissions on vmallocinfo so we can grab it from bugreports - chown root log /proc/vmallocinfo - chmod 0440 /proc/vmallocinfo - - #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks - chown root system /proc/kmsg - chmod 0440 /proc/kmsg - chown root system /proc/sysrq-trigger - chmod 0220 /proc/sysrq-trigger - -# create basic filesystem structure + # create basic filesystem structure mkdir /data/misc 01771 system misc mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth mkdir /data/misc/bluetooth 0770 system system @@ -163,19 +171,22 @@ on post-fs # create the lost+found directories, so as to enforce our permissions mkdir /data/lost+found 0770 - mkdir /cache/lost+found 0770 # double check the perms, in case lost+found already exists, and set owner chown root root /data/lost+found chmod 0770 /data/lost+found - chown root root /cache/lost+found - chmod 0770 /cache/lost+found # create directory for DRM plug-ins mkdir /data/drm 0774 drm drm mkdir /data/drm/plugins 0774 drm drm mkdir /data/drm/plugins/native 0774 drm drm + # If there is no fs-post-data action in the init..rc file, you + # must uncomment this line, otherwise encrypted filesystems + # won't work. + # Set indication (checked by vold) that we have finished this action + #setprop vold.post_fs_data_done 1 + on boot # basic network init ifup lo @@ -273,14 +284,34 @@ on boot setprop net.tcp.buffersize.edge 4093,26280,35040,4096,16384,35040 setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680 - class_start default + class_start core + class_start main + +on nonencrypted + class_start late_start + +on property:vold.decrypt=trigger_reset_main + class_reset main + +on property:vold.decrypt=trigger_post_fs_data + trigger post-fs-data + +on property:vold.decrypt=trigger_restart_framework + class_start main + class_start late_start + +on property:vold.decrypt=trigger_shutdown_framework + class_reset late_start + class_reset main ## Daemon processes to be run by init. ## service ueventd /sbin/ueventd + class core critical service console /system/bin/sh + class core console disabled user shell @@ -291,6 +322,7 @@ on property:ro.debuggable=1 # adbd is controlled by the persist.service.adb.enable system property service adbd /sbin/adbd + class core disabled # adbd on at boot in emulator @@ -304,6 +336,7 @@ on property:persist.service.adb.enable=0 stop adbd service servicemanager /system/bin/servicemanager + class core user system group system critical @@ -311,22 +344,27 @@ service servicemanager /system/bin/servicemanager onrestart restart media service vold /system/bin/vold + class core socket vold stream 0660 root mount ioprio be 2 service netd /system/bin/netd + class main socket netd stream 0660 root system socket dnsproxyd stream 0660 root inet service debuggerd /system/bin/debuggerd + class main service ril-daemon /system/bin/rild + class main socket rild stream 660 root radio socket rild-debug stream 660 radio system user root group radio cache inet misc audio sdcard_rw service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server + class main socket zygote stream 666 onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on @@ -334,30 +372,36 @@ service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-sys onrestart restart netd service drm /system/bin/drmserver + class main user drm group system root inet service drmio /system/bin/drmioserver + class main user drmio group drmio service media /system/bin/mediaserver + class main user media group system audio camera graphics inet net_bt net_bt_admin net_raw ioprio rt 4 service bootanim /system/bin/bootanimation + class main user graphics group graphics disabled oneshot service dbus /system/bin/dbus-daemon --system --nofork + class main socket dbus stream 660 bluetooth bluetooth user bluetooth group bluetooth net_bt_admin service bluetoothd /system/bin/bluetoothd -n + class main socket bluetooth stream 660 bluetooth bluetooth socket dbus_bluetooth stream 660 bluetooth bluetooth # init.rc does not yet support applying capabilities, so run as root and @@ -366,12 +410,15 @@ service bluetoothd /system/bin/bluetoothd -n disabled service installd /system/bin/installd + class main socket installd stream 600 system system service flash_recovery /system/etc/install-recovery.sh + class main oneshot service racoon /system/bin/racoon + class main socket racoon stream 600 system system # racoon will setuid to vpn after getting necessary resources. group net_admin @@ -379,6 +426,7 @@ service racoon /system/bin/racoon oneshot service mtpd /system/bin/mtpd + class main socket mtpd stream 600 system system user vpn group vpn net_admin net_raw @@ -386,11 +434,13 @@ service mtpd /system/bin/mtpd oneshot service keystore /system/bin/keystore /data/misc/keystore + class main user keystore group keystore socket keystore stream 666 service dumpstate /system/bin/dumpstate -s + class main socket dumpstate stream 0660 shell log disabled oneshot