Merge "Implement support for linker rosegment option."
diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp
index c00d955..4cbc45a 100644
--- a/adb/client/adb_install.cpp
+++ b/adb/client/adb_install.cpp
@@ -408,7 +408,8 @@
     for (int i = argc - 1; i >= 0; i--) {
         const char* file = argv[i];
 
-        if (android::base::EndsWithIgnoreCase(file, ".apk")) {
+        if (android::base::EndsWithIgnoreCase(file, ".apk") ||
+            android::base::EndsWithIgnoreCase(file, ".dm")) {
             struct stat sb;
             if (stat(file, &sb) != -1) total_size += sb.st_size;
             first_apk = i;
@@ -470,9 +471,9 @@
         }
 
         std::string cmd =
-                android::base::StringPrintf("%s install-write -S %" PRIu64 " %d %d_%s -",
+                android::base::StringPrintf("%s install-write -S %" PRIu64 " %d %s -",
                                             install_cmd.c_str(), static_cast<uint64_t>(sb.st_size),
-                                            session_id, i, android::base::Basename(file).c_str());
+                                            session_id, android::base::Basename(file).c_str());
 
         int localFd = adb_open(file, O_RDONLY);
         if (localFd < 0) {
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index b02d968..6c0aba1 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -27,6 +27,7 @@
 #include <android-base/unique_fd.h>
 #include <cutils/android_reboot.h>
 #include <ext4_utils/wipe.h>
+#include <fs_mgr.h>
 #include <liblp/builder.h>
 #include <liblp/liblp.h>
 #include <uuid/uuid.h>
@@ -310,7 +311,7 @@
 };
 
 PartitionBuilder::PartitionBuilder(FastbootDevice* device) {
-    auto super_device = FindPhysicalPartition(LP_METADATA_PARTITION_NAME);
+    auto super_device = FindPhysicalPartition(fs_mgr_get_super_partition_name());
     if (!super_device) {
         return;
     }
@@ -353,13 +354,7 @@
         return device->WriteFail("Partition already exists");
     }
 
-    // Make a random UUID, since they're not currently used.
-    uuid_t uuid;
-    char uuid_str[37];
-    uuid_generate_random(uuid);
-    uuid_unparse(uuid, uuid_str);
-
-    Partition* partition = builder->AddPartition(partition_name, uuid_str, 0);
+    Partition* partition = builder->AddPartition(partition_name, 0);
     if (!partition) {
         return device->WriteFail("Failed to add partition");
     }
diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp
index a383c54..4fc3d1d 100644
--- a/fastboot/device/flashing.cpp
+++ b/fastboot/device/flashing.cpp
@@ -146,8 +146,7 @@
         if (builder->FindPartition(name)) {
             continue;
         }
-        std::string guid = GetPartitionGuid(partition);
-        if (!builder->AddPartition(name, guid, partition.attributes)) {
+        if (!builder->AddPartition(name, partition.attributes)) {
             return device->WriteFail("Unable to add partition: " + name);
         }
     }
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
index 02f6f2c..528abec 100644
--- a/fastboot/device/utility.cpp
+++ b/fastboot/device/utility.cpp
@@ -23,6 +23,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <fs_mgr.h>
 #include <fs_mgr_dm_linear.h>
 #include <liblp/liblp.h>
 
@@ -44,7 +45,7 @@
 
 static bool OpenLogicalPartition(const std::string& name, const std::string& slot,
                                  PartitionHandle* handle) {
-    std::optional<std::string> path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME);
+    std::optional<std::string> path = FindPhysicalPartition(fs_mgr_get_super_partition_name());
     if (!path) {
         return false;
     }
@@ -100,7 +101,7 @@
 
 bool LogicalPartitionExists(const std::string& name, const std::string& slot_suffix,
                             bool* is_zero_length) {
-    auto path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME);
+    auto path = FindPhysicalPartition(fs_mgr_get_super_partition_name());
     if (!path) {
         return false;
     }
@@ -149,7 +150,7 @@
     }
 
     // Next get logical partitions.
-    if (auto path = FindPhysicalPartition(LP_METADATA_PARTITION_NAME)) {
+    if (auto path = FindPhysicalPartition(fs_mgr_get_super_partition_name())) {
         uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
         if (auto metadata = ReadMetadata(path->c_str(), slot_number)) {
             for (const auto& partition : metadata->partitions) {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 1598a5c..3ab9732 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -55,6 +55,7 @@
 #include <ext4_utils/wipe.h>
 #include <fs_mgr_overlayfs.h>
 #include <libdm/dm.h>
+#include <liblp/metadata_format.h>
 #include <linux/fs.h>
 #include <linux/loop.h>
 #include <linux/magic.h>
@@ -1343,29 +1344,25 @@
              * on a system (all the memory comes from the same pool) so
              * we can assume the device number is 0.
              */
-            FILE *zram_fp;
-            FILE *zram_mcs_fp;
-
             if (fstab->recs[i].max_comp_streams >= 0) {
-               zram_mcs_fp = fopen(ZRAM_CONF_MCS, "r+");
-              if (zram_mcs_fp == NULL) {
-                LERROR << "Unable to open zram conf comp device "
-                       << ZRAM_CONF_MCS;
-                ret = -1;
-                continue;
-              }
-              fprintf(zram_mcs_fp, "%d\n", fstab->recs[i].max_comp_streams);
-              fclose(zram_mcs_fp);
+                auto zram_mcs_fp = std::unique_ptr<FILE, decltype(&fclose)>{
+                        fopen(ZRAM_CONF_MCS, "re"), fclose};
+                if (zram_mcs_fp == NULL) {
+                    LERROR << "Unable to open zram conf comp device " << ZRAM_CONF_MCS;
+                    ret = -1;
+                    continue;
+                }
+                fprintf(zram_mcs_fp.get(), "%d\n", fstab->recs[i].max_comp_streams);
             }
 
-            zram_fp = fopen(ZRAM_CONF_DEV, "r+");
+            auto zram_fp =
+                    std::unique_ptr<FILE, decltype(&fclose)>{fopen(ZRAM_CONF_DEV, "re+"), fclose};
             if (zram_fp == NULL) {
                 LERROR << "Unable to open zram conf device " << ZRAM_CONF_DEV;
                 ret = -1;
                 continue;
             }
-            fprintf(zram_fp, "%u\n", fstab->recs[i].zram_size);
-            fclose(zram_fp);
+            fprintf(zram_fp.get(), "%u\n", fstab->recs[i].zram_size);
         }
 
         if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
@@ -1544,3 +1541,7 @@
 
     return true;
 }
+
+std::string fs_mgr_get_super_partition_name(int /* slot */) {
+    return LP_METADATA_DEFAULT_PARTITION_NAME;
+}
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 250793a..fc3a05c 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -732,21 +732,19 @@
 
 struct fstab *fs_mgr_read_fstab(const char *fstab_path)
 {
-    FILE *fstab_file;
     struct fstab *fstab;
 
-    fstab_file = fopen(fstab_path, "r");
+    auto fstab_file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(fstab_path, "re"), fclose};
     if (!fstab_file) {
         PERROR << __FUNCTION__<< "(): cannot open file: '" << fstab_path << "'";
         return nullptr;
     }
 
-    fstab = fs_mgr_read_fstab_file(fstab_file, !strcmp("/proc/mounts", fstab_path));
+    fstab = fs_mgr_read_fstab_file(fstab_file.get(), !strcmp("/proc/mounts", fstab_path));
     if (!fstab) {
         LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << fstab_path << "'";
     }
 
-    fclose(fstab_file);
     return fstab;
 }
 
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 07b2a7a..ee63d60 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -344,6 +344,50 @@
     return ret;
 }
 
+bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
+                                   bool* change) {
+    const auto top = overlay + kOverlayTopDir;
+    auto save_errno = errno;
+    auto missing = access(top.c_str(), F_OK);
+    errno = save_errno;
+    if (missing) return false;
+
+    const auto oldpath = top + (mount_point.empty() ? "" : ("/"s + mount_point));
+    const auto newpath = oldpath + ".teardown";
+    auto ret = fs_mgr_rm_all(newpath);
+    save_errno = errno;
+    if (!rename(oldpath.c_str(), newpath.c_str())) {
+        if (change) *change = true;
+    } else if (errno != ENOENT) {
+        ret = false;
+        PERROR << "mv " << oldpath << " " << newpath;
+    } else {
+        errno = save_errno;
+    }
+    ret &= fs_mgr_rm_all(newpath, change);
+    save_errno = errno;
+    if (!rmdir(newpath.c_str())) {
+        if (change) *change = true;
+    } else if (errno != ENOENT) {
+        ret = false;
+        PERROR << "rmdir " << newpath;
+    } else {
+        errno = save_errno;
+    }
+    if (!mount_point.empty()) {
+        save_errno = errno;
+        if (!rmdir(top.c_str())) {
+            if (change) *change = true;
+        } else if ((errno != ENOENT) && (errno != ENOTEMPTY)) {
+            ret = false;
+            PERROR << "rmdir " << top;
+        } else {
+            errno = save_errno;
+        }
+    }
+    return ret;
+}
+
 bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
     auto options = fs_mgr_get_overlayfs_options(mount_point);
     if (options.empty()) return false;
@@ -475,41 +519,7 @@
                                              fs_mgr_read_fstab_default(), fs_mgr_free_fstab)
                                              .get(),
                                      mount_point);
-    auto ret = true;
-    const auto overlay = kOverlayMountPoint + kOverlayTopDir;
-    const auto oldpath = overlay + (mount_point ? "/"s + mount_point : ""s);
-    const auto newpath = oldpath + ".teardown";
-    ret &= fs_mgr_rm_all(newpath);
-    auto save_errno = errno;
-    if (!rename(oldpath.c_str(), newpath.c_str())) {
-        if (change) *change = true;
-    } else if (errno != ENOENT) {
-        ret = false;
-        PERROR << "mv " << oldpath << " " << newpath;
-    } else {
-        errno = save_errno;
-    }
-    ret &= fs_mgr_rm_all(newpath, change);
-    save_errno = errno;
-    if (!rmdir(newpath.c_str())) {
-        if (change) *change = true;
-    } else if (errno != ENOENT) {
-        ret = false;
-        PERROR << "rmdir " << newpath;
-    } else {
-        errno = save_errno;
-    }
-    if (mount_point) {
-        save_errno = errno;
-        if (!rmdir(overlay.c_str())) {
-            if (change) *change = true;
-        } else if ((errno != ENOENT) && (errno != ENOTEMPTY)) {
-            ret = false;
-            PERROR << "rmdir " << overlay;
-        } else {
-            errno = save_errno;
-        }
-    }
+    auto ret = fs_mgr_overlayfs_teardown_one(kOverlayMountPoint, mount_point ?: "", change);
     if (!fs_mgr_wants_overlayfs()) {
         // After obligatory teardown to make sure everything is clean, but if
         // we didn't want overlayfs in the the first place, we do not want to
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 5fb4ebb..2727a6d 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -89,24 +89,21 @@
 {
     uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
 
-    FILE* f = fopen(path, "r");
+    auto f = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path, "re"), fclose};
     if (!f) {
         LERROR << "Can't open " << path;
-        return NULL;
+        return nullptr;
     }
 
-    if (!fread(key_data, sizeof(key_data), 1, f)) {
+    if (!fread(key_data, sizeof(key_data), 1, f.get())) {
         LERROR << "Could not read key!";
-        fclose(f);
-        return NULL;
+        return nullptr;
     }
 
-    fclose(f);
-
-    RSA* key = NULL;
+    RSA* key = nullptr;
     if (!android_pubkey_decode(key_data, sizeof(key_data), &key)) {
         LERROR << "Could not parse key!";
-        return NULL;
+        return nullptr;
     }
 
     return key;
@@ -368,7 +365,6 @@
 static int metadata_find(const char *fname, const char *stag,
         unsigned int slength, off64_t *offset)
 {
-    FILE *fp = NULL;
     char tag[METADATA_TAG_MAX_LENGTH + 1];
     int rc = -1;
     int n;
@@ -380,75 +376,64 @@
         return -1;
     }
 
-    fp = fopen(fname, "r+");
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(fname, "re+"), fclose};
 
     if (!fp) {
         PERROR << "Failed to open " << fname;
-        goto out;
+        return -1;
     }
 
     /* check magic */
-    if (fseek(fp, start, SEEK_SET) < 0 ||
-        fread(&magic, sizeof(magic), 1, fp) != 1) {
+    if (fseek(fp.get(), start, SEEK_SET) < 0 || fread(&magic, sizeof(magic), 1, fp.get()) != 1) {
         PERROR << "Failed to read magic from " << fname;
-        goto out;
+        return -1;
     }
 
     if (magic != METADATA_MAGIC) {
         magic = METADATA_MAGIC;
 
-        if (fseek(fp, start, SEEK_SET) < 0 ||
-            fwrite(&magic, sizeof(magic), 1, fp) != 1) {
+        if (fseek(fp.get(), start, SEEK_SET) < 0 ||
+            fwrite(&magic, sizeof(magic), 1, fp.get()) != 1) {
             PERROR << "Failed to write magic to " << fname;
-            goto out;
+            return -1;
         }
 
-        rc = metadata_add(fp, start + sizeof(magic), stag, slength, offset);
+        rc = metadata_add(fp.get(), start + sizeof(magic), stag, slength, offset);
         if (rc < 0) {
             PERROR << "Failed to add metadata to " << fname;
         }
 
-        goto out;
+        return rc;
     }
 
     start += sizeof(magic);
 
     while (1) {
-        n = fscanf(fp, "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n",
-                tag, &length);
+        n = fscanf(fp.get(), "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n", tag, &length);
 
         if (n == 2 && strcmp(tag, METADATA_EOD)) {
             /* found a tag */
-            start = ftell(fp);
+            start = ftell(fp.get());
 
             if (!strcmp(tag, stag) && length == slength) {
                 *offset = start;
-                rc = 0;
-                goto out;
+                return 0;
             }
 
             start += length;
 
-            if (fseek(fp, length, SEEK_CUR) < 0) {
+            if (fseek(fp.get(), length, SEEK_CUR) < 0) {
                 PERROR << "Failed to seek " << fname;
-                goto out;
+                return -1;
             }
         } else {
-            rc = metadata_add(fp, start, stag, slength, offset);
+            rc = metadata_add(fp.get(), start, stag, slength, offset);
             if (rc < 0) {
                 PERROR << "Failed to write metadata to " << fname;
             }
-            goto out;
+            return rc;
         }
-   }
-
-out:
-    if (fp) {
-        fflush(fp);
-        fclose(fp);
     }
-
-    return rc;
 }
 
 static int write_verity_state(const char *fname, off64_t offset, int32_t mode)
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index cee069b..a4544b2 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -23,6 +23,7 @@
 #include <linux/dm-ioctl.h>
 
 #include <functional>
+#include <string>
 
 #include <fstab/fstab.h>
 
@@ -89,4 +90,9 @@
 #define FS_MGR_SETUP_VERITY_SUCCESS 0
 int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev);
 
+// Return the name of the super partition if it exists. If a slot number is
+// specified, the super partition for the corresponding metadata slot will be
+// returned. Otherwise, it will use the current slot.
+std::string fs_mgr_get_super_partition_name(int slot = -1);
+
 #endif /* __CORE_FS_MGR_H */
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 89282db..69dc065 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -35,7 +35,6 @@
         "libcrypto",
         "libcrypto_utils",
         "libsparse",
-        "libext2_uuid",
         "libext4_utils",
         "libz",
     ],
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index d9a0e9c..97b15bd 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -25,7 +25,6 @@
 #include <algorithm>
 
 #include <android-base/unique_fd.h>
-#include <uuid/uuid.h>
 
 #include "liblp/liblp.h"
 #include "reader.h"
@@ -79,9 +78,8 @@
     out->extents.push_back(LpMetadataExtent{num_sectors_, LP_TARGET_TYPE_ZERO, 0});
 }
 
-Partition::Partition(const std::string& name, const std::string& group_name,
-                     const std::string& guid, uint32_t attributes)
-    : name_(name), group_name_(group_name), guid_(guid), attributes_(attributes), size_(0) {}
+Partition::Partition(const std::string& name, const std::string& group_name, uint32_t attributes)
+    : name_(name), group_name_(group_name), attributes_(attributes), size_(0) {}
 
 void Partition::AddExtent(std::unique_ptr<Extent>&& extent) {
     size_ += extent->num_sectors() * LP_SECTOR_SIZE;
@@ -202,8 +200,8 @@
 
     for (const auto& partition : metadata.partitions) {
         std::string group_name = GetPartitionGroupName(metadata.groups[partition.group_index]);
-        Partition* builder = AddPartition(GetPartitionName(partition), group_name,
-                                          GetPartitionGuid(partition), partition.attributes);
+        Partition* builder =
+                AddPartition(GetPartitionName(partition), group_name, partition.attributes);
         if (!builder) {
             return false;
         }
@@ -329,13 +327,12 @@
     return true;
 }
 
-Partition* MetadataBuilder::AddPartition(const std::string& name, const std::string& guid,
-                                         uint32_t attributes) {
-    return AddPartition(name, "default", guid, attributes);
+Partition* MetadataBuilder::AddPartition(const std::string& name, uint32_t attributes) {
+    return AddPartition(name, "default", attributes);
 }
 
 Partition* MetadataBuilder::AddPartition(const std::string& name, const std::string& group_name,
-                                         const std::string& guid, uint32_t attributes) {
+                                         uint32_t attributes) {
     if (name.empty()) {
         LERROR << "Partition must have a non-empty name.";
         return nullptr;
@@ -348,7 +345,7 @@
         LERROR << "Could not find partition group: " << group_name;
         return nullptr;
     }
-    partitions_.push_back(std::make_unique<Partition>(name, group_name, guid, attributes));
+    partitions_.push_back(std::make_unique<Partition>(name, group_name, attributes));
     return partitions_.back().get();
 }
 
@@ -549,12 +546,6 @@
         }
 
         strncpy(part.name, partition->name().c_str(), sizeof(part.name));
-        if (uuid_parse(partition->guid().c_str(), part.guid) != 0) {
-            LERROR << "Could not parse guid " << partition->guid() << " for partition "
-                   << partition->name();
-            return nullptr;
-        }
-
         part.first_extent_index = static_cast<uint32_t>(metadata->extents.size());
         part.num_extents = static_cast<uint32_t>(partition->extents().size());
         part.attributes = partition->attributes();
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index 711cc64..c916b44 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -22,16 +22,12 @@
 using namespace std;
 using namespace android::fs_mgr;
 
-static const char* TEST_GUID = "A799D1D6-669F-41D8-A3F0-EBB7572D8302";
-static const char* TEST_GUID2 = "A799D1D6-669F-41D8-A3F0-EBB7572D8303";
-
 TEST(liblp, BuildBasic) {
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
-    Partition* partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(partition, nullptr);
     EXPECT_EQ(partition->name(), "system");
-    EXPECT_EQ(partition->guid(), TEST_GUID);
     EXPECT_EQ(partition->attributes(), LP_PARTITION_ATTR_READONLY);
     EXPECT_EQ(partition->size(), 0);
     EXPECT_EQ(builder->FindPartition("system"), partition);
@@ -43,7 +39,7 @@
 TEST(liblp, ResizePartition) {
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
     EXPECT_EQ(system->size(), 65536);
@@ -94,7 +90,7 @@
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
     // Test that we align up to one sector.
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, 10000), true);
     EXPECT_EQ(system->size(), 12288);
@@ -171,9 +167,9 @@
     BlockDeviceInfo device_info(512 * 1024 * 1024, 768 * 1024, 753664, 4096);
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 32 * 1024, 2);
 
-    Partition* a = builder->AddPartition("a", TEST_GUID, 0);
+    Partition* a = builder->AddPartition("a", 0);
     ASSERT_NE(a, nullptr);
-    Partition* b = builder->AddPartition("b", TEST_GUID2, 0);
+    Partition* b = builder->AddPartition("b", 0);
     ASSERT_NE(b, nullptr);
 
     // Add a bunch of small extents to each, interleaving.
@@ -214,7 +210,7 @@
     EXPECT_EQ(builder->AllocatableSpace(), allocatable);
     EXPECT_EQ(builder->UsedSpace(), 0);
 
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, allocatable), true);
     EXPECT_EQ(system->size(), allocatable);
@@ -229,8 +225,8 @@
 TEST(liblp, BuildComplex) {
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
-    Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
+    Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
@@ -263,15 +259,15 @@
 TEST(liblp, AddInvalidPartition) {
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
-    Partition* partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    Partition* partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(partition, nullptr);
 
     // Duplicate name.
-    partition = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    partition = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
     EXPECT_EQ(partition, nullptr);
 
     // Empty name.
-    partition = builder->AddPartition("", TEST_GUID, LP_PARTITION_ATTR_READONLY);
+    partition = builder->AddPartition("", LP_PARTITION_ATTR_READONLY);
     EXPECT_EQ(partition, nullptr);
 }
 
@@ -282,8 +278,8 @@
     unique_ptr<MetadataBuilder> builder =
             MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
 
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
-    Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
+    Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
@@ -322,7 +318,6 @@
     for (const auto& partition : exported->partitions) {
         Partition* original = builder->FindPartition(GetPartitionName(partition));
         ASSERT_NE(original, nullptr);
-        EXPECT_EQ(original->guid(), GetPartitionGuid(partition));
         for (size_t i = 0; i < partition.num_extents; i++) {
             const auto& extent = exported->extents[partition.first_extent_index + i];
             LinearExtent* original_extent = original->extents()[i]->AsLinearExtent();
@@ -337,8 +332,8 @@
 TEST(liblp, BuilderImport) {
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
-    Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_READONLY);
+    Partition* vendor = builder->AddPartition("vendor", LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
     EXPECT_EQ(builder->ResizePartition(system, 65536), true);
@@ -357,11 +352,9 @@
 
     EXPECT_EQ(system->size(), 98304);
     ASSERT_EQ(system->extents().size(), 2);
-    EXPECT_EQ(system->guid(), TEST_GUID);
     EXPECT_EQ(system->attributes(), LP_PARTITION_ATTR_READONLY);
     EXPECT_EQ(vendor->size(), 32768);
     ASSERT_EQ(vendor->extents().size(), 1);
-    EXPECT_EQ(vendor->guid(), TEST_GUID2);
     EXPECT_EQ(vendor->attributes(), LP_PARTITION_ATTR_READONLY);
 
     LinearExtent* system1 = system->extents()[0]->AsLinearExtent();
@@ -378,17 +371,7 @@
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
 
     std::string name = "abcdefghijklmnopqrstuvwxyz0123456789";
-    Partition* system = builder->AddPartition(name + name, TEST_GUID, LP_PARTITION_ATTR_READONLY);
-    EXPECT_NE(system, nullptr);
-
-    unique_ptr<LpMetadata> exported = builder->Export();
-    EXPECT_EQ(exported, nullptr);
-}
-
-TEST(liblp, ExportInvalidGuid) {
-    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2);
-
-    Partition* system = builder->AddPartition("system", "bad", LP_PARTITION_ATTR_READONLY);
+    Partition* system = builder->AddPartition(name + name, LP_PARTITION_ATTR_READONLY);
     EXPECT_NE(system, nullptr);
 
     unique_ptr<LpMetadata> exported = builder->Export();
@@ -483,7 +466,7 @@
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
     ASSERT_NE(builder, nullptr);
 
-    Partition* partition = builder->AddPartition("system", TEST_GUID, 0);
+    Partition* partition = builder->AddPartition("system", 0);
     ASSERT_NE(partition, nullptr);
     ASSERT_TRUE(builder->ResizePartition(partition, 512));
     EXPECT_EQ(partition->size(), 4096);
@@ -511,7 +494,7 @@
 
     ASSERT_TRUE(builder->AddGroup("google", 16384));
 
-    Partition* partition = builder->AddPartition("system", "google", TEST_GUID, 0);
+    Partition* partition = builder->AddPartition("system", "google", 0);
     ASSERT_NE(partition, nullptr);
     EXPECT_TRUE(builder->ResizePartition(partition, 8192));
     EXPECT_EQ(partition->size(), 8192);
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index f1edee7..a6044d0 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -112,8 +112,7 @@
     friend class MetadataBuilder;
 
   public:
-    Partition(const std::string& name, const std::string& group_name, const std::string& guid,
-              uint32_t attributes);
+    Partition(const std::string& name, const std::string& group_name, uint32_t attributes);
 
     // Add a raw extent.
     void AddExtent(std::unique_ptr<Extent>&& extent);
@@ -128,7 +127,6 @@
     const std::string& name() const { return name_; }
     const std::string& group_name() const { return group_name_; }
     uint32_t attributes() const { return attributes_; }
-    const std::string& guid() const { return guid_; }
     const std::vector<std::unique_ptr<Extent>>& extents() const { return extents_; }
     uint64_t size() const { return size_; }
 
@@ -137,7 +135,6 @@
 
     std::string name_;
     std::string group_name_;
-    std::string guid_;
     std::vector<std::unique_ptr<Extent>> extents_;
     uint32_t attributes_;
     uint64_t size_;
@@ -190,11 +187,11 @@
     // Add a partition, returning a handle so it can be sized as needed. If a
     // partition with the given name already exists, nullptr is returned.
     Partition* AddPartition(const std::string& name, const std::string& group_name,
-                            const std::string& guid, uint32_t attributes);
+                            uint32_t attributes);
 
     // Same as AddPartition above, but uses the default partition group which
     // has no size restrictions.
-    Partition* AddPartition(const std::string& name, const std::string& guid, uint32_t attributes);
+    Partition* AddPartition(const std::string& name, uint32_t attributes);
 
     // Delete a partition by name if it exists.
     void RemovePartition(const std::string& name);
diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h
index 51d262b..5f95dca 100644
--- a/fs_mgr/liblp/include/liblp/liblp.h
+++ b/fs_mgr/liblp/include/liblp/liblp.h
@@ -68,7 +68,6 @@
 
 // Helper to extract safe C++ strings from partition info.
 std::string GetPartitionName(const LpMetadataPartition& partition);
-std::string GetPartitionGuid(const LpMetadataPartition& partition);
 std::string GetPartitionGroupName(const LpMetadataPartitionGroup& group);
 
 // Helper to return a slot number for a slot suffix.
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index 79ef2ab..7d1a2a9 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -38,7 +38,7 @@
 #define LP_METADATA_HEADER_MAGIC 0x414C5030
 
 /* Current metadata version. */
-#define LP_METADATA_MAJOR_VERSION 2
+#define LP_METADATA_MAJOR_VERSION 3
 #define LP_METADATA_MINOR_VERSION 0
 
 /* Attributes for the LpMetadataPartition::attributes field.
@@ -67,7 +67,7 @@
  *     | Geometry Backup    |
  *     +--------------------+
  */
-#define LP_METADATA_PARTITION_NAME "super"
+#define LP_METADATA_DEFAULT_PARTITION_NAME "super"
 
 /* Size of a sector is always 512 bytes for compatibility with the Linux kernel. */
 #define LP_SECTOR_SIZE 512
@@ -232,23 +232,20 @@
      */
     char name[36];
 
-    /* 36: Globally unique identifier (GUID) of this partition. */
-    uint8_t guid[16];
-
-    /* 52: Attributes for the partition (see LP_PARTITION_ATTR_* flags above). */
+    /* 36: Attributes for the partition (see LP_PARTITION_ATTR_* flags above). */
     uint32_t attributes;
 
-    /* 56: Index of the first extent owned by this partition. The extent will
+    /* 40: Index of the first extent owned by this partition. The extent will
      * start at logical sector 0. Gaps between extents are not allowed.
      */
     uint32_t first_extent_index;
 
-    /* 60: Number of extents in the partition. Every partition must have at
+    /* 44: Number of extents in the partition. Every partition must have at
      * least one extent.
      */
     uint32_t num_extents;
 
-    /* 64: Group this partition belongs to. */
+    /* 48: Group this partition belongs to. */
     uint32_t group_index;
 } __attribute__((packed)) LpMetadataPartition;
 
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index f93852b..01de3ac 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -37,8 +37,6 @@
 static const size_t kDiskSize = 131072;
 static const size_t kMetadataSize = 512;
 static const size_t kMetadataSlots = 2;
-static const char* TEST_GUID_BASE = "A799D1D6-669F-41D8-A3F0-EBB7572D830";
-static const char* TEST_GUID = "A799D1D6-669F-41D8-A3F0-EBB7572D8302";
 
 // Helper function for creating an in-memory file descriptor. This lets us
 // simulate read/writing logical partition metadata as if we had a block device
@@ -81,7 +79,7 @@
 }
 
 static bool AddDefaultPartitions(MetadataBuilder* builder) {
-    Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_NONE);
+    Partition* system = builder->AddPartition("system", LP_PARTITION_ATTR_NONE);
     if (!system) {
         return false;
     }
@@ -171,7 +169,6 @@
     // Check partition tables.
     ASSERT_EQ(exported->partitions.size(), imported->partitions.size());
     EXPECT_EQ(GetPartitionName(exported->partitions[0]), GetPartitionName(imported->partitions[0]));
-    EXPECT_EQ(GetPartitionGuid(exported->partitions[0]), GetPartitionGuid(imported->partitions[0]));
     EXPECT_EQ(exported->partitions[0].attributes, imported->partitions[0].attributes);
     EXPECT_EQ(exported->partitions[0].first_extent_index,
               imported->partitions[0].first_extent_index);
@@ -331,18 +328,18 @@
     unique_ptr<MetadataBuilder> builder = CreateDefaultBuilder();
     ASSERT_NE(builder, nullptr);
 
-    // Compute the maximum number of partitions we can fit in 1024 bytes of metadata.
-    size_t max_partitions = (kMetadataSize - sizeof(LpMetadataHeader)) / sizeof(LpMetadataPartition);
-    EXPECT_LT(max_partitions, 10);
+    // Compute the maximum number of partitions we can fit in 512 bytes of
+    // metadata. By default there is the header, and one partition group.
+    static const size_t kMaxPartitionTableSize =
+            kMetadataSize - sizeof(LpMetadataHeader) - sizeof(LpMetadataPartitionGroup);
+    size_t max_partitions = kMaxPartitionTableSize / sizeof(LpMetadataPartition);
 
     // Add this number of partitions.
     Partition* partition = nullptr;
     for (size_t i = 0; i < max_partitions; i++) {
-        std::string guid = std::string(TEST_GUID) + to_string(i);
-        partition = builder->AddPartition(to_string(i), TEST_GUID, LP_PARTITION_ATTR_NONE);
+        partition = builder->AddPartition(to_string(i), LP_PARTITION_ATTR_NONE);
         ASSERT_NE(partition, nullptr);
     }
-    ASSERT_NE(partition, nullptr);
 
     unique_ptr<LpMetadata> exported = builder->Export();
     ASSERT_NE(exported, nullptr);
@@ -354,7 +351,7 @@
     ASSERT_TRUE(FlashPartitionTable(fd, *exported.get()));
 
     // Check that adding one more partition overflows the metadata allotment.
-    partition = builder->AddPartition("final", TEST_GUID, LP_PARTITION_ATTR_NONE);
+    partition = builder->AddPartition("final", LP_PARTITION_ATTR_NONE);
     EXPECT_NE(partition, nullptr);
 
     exported = builder->Export();
diff --git a/fs_mgr/liblp/utility.cpp b/fs_mgr/liblp/utility.cpp
index a590037..b08f96c 100644
--- a/fs_mgr/liblp/utility.cpp
+++ b/fs_mgr/liblp/utility.cpp
@@ -23,7 +23,6 @@
 #include <android-base/file.h>
 #include <ext4_utils/ext4_utils.h>
 #include <openssl/sha.h>
-#include <uuid/uuid.h>
 
 #include "utility.h"
 
@@ -80,15 +79,6 @@
     SHA256_Final(out, &c);
 }
 
-std::string GetPartitionGuid(const LpMetadataPartition& partition) {
-    // 32 hex characters, four hyphens. Unfortunately libext2_uuid provides no
-    // macro to assist with buffer sizing.
-    static const size_t kGuidLen = 36;
-    char buffer[kGuidLen + 1];
-    uuid_unparse_upper(partition.guid, buffer);
-    return buffer;
-}
-
 uint32_t SlotNumberForSlotSuffix(const std::string& suffix) {
     if (suffix.empty()) {
         return 0;
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 8b1c55a..db01c1e 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -139,7 +139,7 @@
     auto fstab = fs_mgr_read_fstab("/proc/mounts");
     ASSERT_NE(fstab, nullptr);
 
-    std::unique_ptr<std::FILE, int (*)(std::FILE*)> mounts(setmntent("/proc/mounts", "r"),
+    std::unique_ptr<std::FILE, int (*)(std::FILE*)> mounts(setmntent("/proc/mounts", "re"),
                                                            endmntent);
     ASSERT_NE(mounts, nullptr);
 
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 6f97d19..684bf1f 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -83,6 +83,7 @@
     std::string lp_metadata_partition_;
     std::vector<fstab_rec*> mount_fstab_recs_;
     std::set<std::string> required_devices_partition_names_;
+    std::string super_partition_name_;
     std::unique_ptr<DeviceHandler> device_handler_;
     UeventListener uevent_listener_;
 };
@@ -153,6 +154,8 @@
     device_handler_ = std::make_unique<DeviceHandler>(
             std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
             std::move(boot_devices), false);
+
+    super_partition_name_ = fs_mgr_get_super_partition_name();
 }
 
 std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
@@ -196,7 +199,7 @@
         return true;
     }
 
-    required_devices_partition_names_.emplace(LP_METADATA_PARTITION_NAME);
+    required_devices_partition_names_.emplace(super_partition_name_);
     return true;
 }
 
@@ -262,7 +265,7 @@
 
     if (lp_metadata_partition_.empty()) {
         LOG(ERROR) << "Could not locate logical partition tables in partition "
-                   << LP_METADATA_PARTITION_NAME;
+                   << super_partition_name_;
         return false;
     }
     return android::fs_mgr::CreateLogicalPartitions(lp_metadata_partition_);
@@ -275,7 +278,7 @@
     auto iter = required_devices_partition_names_.find(name);
     if (iter != required_devices_partition_names_.end()) {
         LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
-        if (IsDmLinearEnabled() && name == LP_METADATA_PARTITION_NAME) {
+        if (IsDmLinearEnabled() && name == super_partition_name_) {
             std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
             lp_metadata_partition_ = links[0];
         }
diff --git a/init/reboot.cpp b/init/reboot.cpp
index b84bfd3..866f40e 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -162,7 +162,7 @@
  */
 static bool FindPartitionsToUmount(std::vector<MountEntry>* blockDevPartitions,
                                    std::vector<MountEntry>* emulatedPartitions, bool dump) {
-    std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "r"), endmntent);
+    std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
     if (fp == nullptr) {
         PLOG(ERROR) << "Failed to open /proc/mounts";
         return false;
diff --git a/libstats/include/stats_event_list.h b/libstats/include/stats_event_list.h
index 5d174ae..a9832db 100644
--- a/libstats/include/stats_event_list.h
+++ b/libstats/include/stats_event_list.h
@@ -24,6 +24,8 @@
 #endif
 void reset_log_context(android_log_context ctx);
 int write_to_logger(android_log_context context, log_id_t id);
+void note_log_drop();
+void stats_log_close();
 
 #ifdef __cplusplus
 }
diff --git a/libstats/stats_event_list.c b/libstats/stats_event_list.c
index 3d746db..735088a 100644
--- a/libstats/stats_event_list.c
+++ b/libstats/stats_event_list.c
@@ -119,6 +119,18 @@
     return retValue;
 }
 
+void note_log_drop() {
+    statsdLoggerWrite.noteDrop();
+}
+
+void stats_log_close() {
+    statsd_writer_init_lock();
+    if (statsdLoggerWrite.close) {
+        (*statsdLoggerWrite.close)();
+    }
+    statsd_writer_init_unlock();
+}
+
 /* log_init_lock assumed */
 static int __write_to_statsd_initialize_locked() {
     if (!statsdLoggerWrite.open || ((*statsdLoggerWrite.open)() < 0)) {
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
index 9953bba..afe401f 100644
--- a/libstats/statsd_writer.c
+++ b/libstats/statsd_writer.c
@@ -38,6 +38,7 @@
 #define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
 
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
+static atomic_int dropped = 0;
 
 void statsd_writer_init_lock() {
     /*
@@ -59,14 +60,16 @@
 static int statsdOpen();
 static void statsdClose();
 static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr);
+static void statsdNoteDrop();
 
 struct android_log_transport_write statsdLoggerWrite = {
-    .name = "statsd",
-    .sock = -EBADF,
-    .available = statsdAvailable,
-    .open = statsdOpen,
-    .close = statsdClose,
-    .write = statsdWrite,
+        .name = "statsd",
+        .sock = -EBADF,
+        .available = statsdAvailable,
+        .open = statsdOpen,
+        .close = statsdClose,
+        .write = statsdWrite,
+        .noteDrop = statsdNoteDrop,
 };
 
 /* log_init_lock assumed */
@@ -131,6 +134,10 @@
     return 1;
 }
 
+static void statsdNoteDrop() {
+    atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
+}
+
 static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr) {
     ssize_t ret;
     int sock;
@@ -138,7 +145,6 @@
     struct iovec newVec[nr + headerLength];
     android_log_header_t header;
     size_t i, payloadSize;
-    static atomic_int dropped;
 
     sock = atomic_load(&statsdLoggerWrite.sock);
     if (sock < 0) switch (sock) {
@@ -252,8 +258,6 @@
 
     if (ret > (ssize_t)sizeof(header)) {
         ret -= sizeof(header);
-    } else if (ret == -EAGAIN) {
-        atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
     }
 
     return ret;
diff --git a/libstats/statsd_writer.h b/libstats/statsd_writer.h
index 82e14e0..7289441 100644
--- a/libstats/statsd_writer.h
+++ b/libstats/statsd_writer.h
@@ -38,6 +38,8 @@
     void (*close)();    /* free up resources */
     /* write log to transport, returns number of bytes propagated, or -errno */
     int (*write)(struct timespec* ts, struct iovec* vec, size_t nr);
+    /* note one log drop */
+    void (*noteDrop)();
 };
 
 #endif  // ANDROID_STATS_LOG_STATS_WRITER_H
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index b68dc34..a4c3955 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -77,7 +77,7 @@
 #
 # create some directories (some are mount points) and symlinks
 LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
-    sbin dev proc sys system data odm oem acct config storage mnt $(BOARD_ROOT_EXTRA_FOLDERS)); \
+    sbin dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \
     ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
     ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
     ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2a70a4a..6a6a8f9 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -269,6 +269,12 @@
     # that they can be chown'd to system:system later on boot
     write /sys/class/leds/vibrator/trigger "transient"
 
+    # Setup APEX mount point and its security context
+    mount tmpfs tmpfs /apex nodev noexec nosuid
+    chmod 0755 /apex
+    chown root root /apex
+    restorecon /apex
+
 # Healthd can trigger a full boot from charger mode by signaling this
 # property when the power button is held.
 on property:sys.boot_from_charger_mode=1
@@ -524,6 +530,8 @@
 
     mkdir /data/anr 0775 system system
 
+    mkdir /data/apex 0770 root root
+
     # NFC: create data/nfc for nv storage
     mkdir /data/nfc 0770 nfc nfc
     mkdir /data/nfc/param 0770 nfc nfc