init: early_mount: add support to mount non-verity partitions early

This is done by parsing 'androidboot.fstab=<fstab>' kernel cmdline
option to get the fstab file that *only* specifies partitions to be
mounted early (i.e. in init's first stage).

Note that, the same fstab file may not be used as an argument to
mount_all later in the boot as that will cause fs_mgr to fail with
EBUSY.

TODO:
- Possibly add a new mount_mode so the same fstab can be used for
early_mount, 'mount_all --early/--late' etc.
- Add support for dm-verity enabled partitions to mount early.
- Add support for getting fstab arguments through DT instead of kernel
cmdline.

Bug: 27805372

Test:
Boot angler by passing a seperate fstab file using the kernel
cmdline option to mount vendor partition early, remove the vendor
partition entry from the main fstab file for the test.

Boot sailfish by passing a seperate fstab entry via device tree
to mount vendor partition early. Remove vendor partition entry from
the main fstab file for the test

Change-Id: I18785b893c54c8cee960ab44d5e8f83e5d624aa8
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/init/devices.cpp b/init/devices.cpp
index 2224c13..b3b808b 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -62,7 +62,7 @@
 
 extern struct selabel_handle *sehandle;
 
-static int device_fd = -1;
+static android::base::unique_fd device_fd;
 
 struct perms_ {
     char *name;
@@ -341,6 +341,19 @@
     }
 }
 
+static void destroy_platform_devices() {
+    struct listnode* node;
+    struct listnode* n;
+    struct platform_node* bus;
+
+    list_for_each_safe(node, n, &platform_names) {
+        list_remove(node);
+        bus = node_to_item(node, struct platform_node, list);
+        free(bus->path);
+        free(bus);
+    }
+}
+
 /* Given a path that may start with a PCI device, populate the supplied buffer
  * with the PCI domain/bus number and the peripheral ID and return 0.
  * If it doesn't start with a PCI device, or there is some error, return -1 */
@@ -507,7 +520,7 @@
         return NULL;
     memset(links, 0, sizeof(char *) * 4);
 
-    LOG(INFO) << "found " << type << " device " << device;
+    LOG(VERBOSE) << "found " << type << " device " << device;
 
     snprintf(link_path, sizeof(link_path), "/dev/block/%s/%s", type, device);
 
@@ -990,7 +1003,7 @@
     selinux_status_open(true);
 
     /* is 256K enough? udev uses 16MB! */
-    device_fd = uevent_open_socket(256*1024, true);
+    device_fd.reset(uevent_open_socket(256*1024, true));
     if (device_fd == -1) {
         return;
     }
@@ -1024,6 +1037,11 @@
     LOG(INFO) << "Coldboot took " << t;
 }
 
+void device_close() {
+    destroy_platform_devices();
+    device_fd.reset();
+}
+
 int get_device_fd() {
     return device_fd;
 }