Load the persistent properties after decrypting the /data partition

Fix for bug 3415286.  The persistent properties are normally read early
in the boot process after /data is mounted.  However, for an encrypted
system, at that point /data is a tmpfs ramdisk.  This change adds a new
command to init (load_persist_props) to read the persistent properties,
and adds an action to init.rc to load the persistent properties.  This
action is triggered by setting a property in vold, but that's in a
different CL.

Change-Id: I74b3057974ee6029c29d956b76fef5566700d471
diff --git a/init/builtins.c b/init/builtins.c
index d9a9634..f2f76b7 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -286,7 +286,6 @@
     unsigned flags = 0;
     int n, i;
     int wait = 0;
-    char *prop;
 
     for (n = 4; n < nargs; n++) {
         for (i = 0; mount_flags[i].name; i++) {
@@ -416,6 +415,8 @@
      * 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";
@@ -631,6 +632,14 @@
     return -1;
 }
 
+int do_load_persist_props(int nargs, char **args) {
+    if (nargs == 1) {
+        load_persist_props();
+        return 0;
+    }
+    return -1;
+}
+
 int do_wait(int nargs, char **args)
 {
     if (nargs == 2) {
diff --git a/init/init_parser.c b/init/init_parser.c
index 0898ae8..e8e65ac 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -113,6 +113,7 @@
         break;
     case 'l':
         if (!strcmp(s, "oglevel")) return K_loglevel;
+        if (!strcmp(s, "oad_persist_props")) return K_load_persist_props;
         break;
     case 'm':
         if (!strcmp(s, "kdir")) return K_mkdir;
diff --git a/init/keywords.h b/init/keywords.h
index c977fd7..95acd01 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -30,6 +30,7 @@
 int do_chown(int nargs, char **args);
 int do_chmod(int nargs, char **args);
 int do_loglevel(int nargs, char **args);
+int do_load_persist_props(int nargs, char **args);
 int do_wait(int nargs, char **args);
 #define __MAKE_KEYWORD_ENUM__
 #define KEYWORD(symbol, flags, nargs, func) K_##symbol,
@@ -81,6 +82,7 @@
     KEYWORD(chown,       COMMAND, 2, do_chown)
     KEYWORD(chmod,       COMMAND, 2, do_chmod)
     KEYWORD(loglevel,    COMMAND, 1, do_loglevel)
+    KEYWORD(load_persist_props,    COMMAND, 0, do_load_persist_props)
     KEYWORD(ioprio,      OPTION,  0, 0)
 #ifdef __MAKE_KEYWORD_ENUM__
     KEYWORD_COUNT,
diff --git a/init/property_service.c b/init/property_service.c
index fdfec43..be56a19 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -515,6 +515,18 @@
     return property_area_inited;
 }
 
+/* When booting an encrypted system, /data is not mounted when the
+ * property service is started, so any properties stored there are
+ * not loaded.  Vold triggers init to load these properties once it
+ * has mounted /data.
+ */
+void load_persist_props(void)
+{
+    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
+    /* Read persistent properties after all default values have been loaded. */
+    load_persistent_properties();
+}
+
 void start_property_service(void)
 {
     int fd;
diff --git a/init/property_service.h b/init/property_service.h
index 045d20a..bc97cc4 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -19,6 +19,7 @@
 
 extern void handle_property_set_fd(void);
 extern void property_init(void);
+extern void load_persist_props(void);
 extern void start_property_service(void);
 void get_property_workspace(int *fd, int *sz);
 extern const char* property_get(const char *name);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 046ab3d..ce000d6 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -304,6 +304,9 @@
 on property:vold.decrypt=trigger_reset_main
     class_reset main
 
+on property:vold.decrypt=trigger_load_persist_props
+    load_persist_props
+
 on property:vold.decrypt=trigger_post_fs_data
     trigger post-fs-data