Merge "ueventd: require opt-in for modalias handling"
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c830321..321e6ba 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -127,6 +127,7 @@
                                                       "product-services",
                                                                   true,  false },
     { "recovery", "recovery.img",     "recovery.sig", "recovery", true,  false },
+    { "super",    "super.img",        "super.sig",    "super",    true,  false },
     { "system",   "system.img",       "system.sig",   "system",   false, false },
     { nullptr,    "system_other.img", "system.sig",   "system",   true,  true  },
     { "vbmeta",   "vbmeta.img",       "vbmeta.sig",   "vbmeta",   true,  false },
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index b3df811..5f57182 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1052,6 +1052,9 @@
         return FS_MGR_DOMNT_FAILED;
     }
 
+    // Run fsck if needed
+    prepare_fs_for_mount(rec->blk_device, rec);
+
     int ret = __mount(rec->blk_device, rec->mount_point, rec);
     if (ret) {
       ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED;
@@ -1177,8 +1180,8 @@
 {
     int ret;
 
-    ret = mount("tmpfs", n_name, "tmpfs",
-                MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
+    ret = mount("tmpfs", n_name, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV | MS_NOEXEC,
+                CRYPTO_TMPFS_OPTIONS);
     if (ret < 0) {
         LERROR << "Cannot mount tmpfs filesystem at " << n_name;
         return -1;
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 9d710f9..eb429b9 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -48,10 +48,20 @@
         PERROR << __PRETTY_FUNCTION__ << "BLKIOMIN failed";
         return false;
     }
-    if (ioctl(fd, BLKALIGNOFF, &device_info->alignment_offset) < 0) {
+
+    int alignment_offset;
+    if (ioctl(fd, BLKALIGNOFF, &alignment_offset) < 0) {
         PERROR << __PRETTY_FUNCTION__ << "BLKIOMIN failed";
         return false;
     }
+    int logical_block_size;
+    if (ioctl(fd, BLKSSZGET, &logical_block_size) < 0) {
+        PERROR << __PRETTY_FUNCTION__ << "BLKSSZGET failed";
+        return false;
+    }
+
+    device_info->alignment_offset = static_cast<uint32_t>(alignment_offset);
+    device_info->logical_block_size = static_cast<uint32_t>(logical_block_size);
     return true;
 #else
     (void)block_device;
@@ -82,11 +92,7 @@
     extents_.clear();
 }
 
-void Partition::ShrinkTo(uint64_t requested_size) {
-    uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
-    if (size_ <= aligned_size) {
-        return;
-    }
+void Partition::ShrinkTo(uint64_t aligned_size) {
     if (aligned_size == 0) {
         RemoveExtents();
         return;
@@ -106,7 +112,7 @@
         sectors_to_remove -= extent->num_sectors();
         extents_.pop_back();
     }
-    DCHECK(size_ == requested_size);
+    DCHECK(size_ == aligned_size);
 }
 
 std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device,
@@ -182,6 +188,7 @@
 
     device_info_.alignment = geometry_.alignment;
     device_info_.alignment_offset = geometry_.alignment_offset;
+    device_info_.logical_block_size = geometry_.logical_block_size;
     return true;
 }
 
@@ -205,6 +212,10 @@
         LERROR << "Block device size must be a multiple of 512.";
         return false;
     }
+    if (device_info_.logical_block_size % LP_SECTOR_SIZE != 0) {
+        LERROR << "Logical block size must be a multiple of 512.";
+        return false;
+    }
     if (device_info_.alignment_offset % LP_SECTOR_SIZE != 0) {
         LERROR << "Alignment offset is not sector-aligned.";
         return false;
@@ -248,6 +259,18 @@
         return false;
     }
 
+    // Finally, the size of the allocatable space must be a multiple of the
+    // logical block size. If we have no more free space after this
+    // computation, then we abort. Note that the last sector is inclusive,
+    // so we have to account for that.
+    uint64_t num_free_sectors = last_sector - first_sector + 1;
+    uint64_t sectors_per_block = device_info_.logical_block_size / LP_SECTOR_SIZE;
+    if (num_free_sectors < sectors_per_block) {
+        LERROR << "Not enough space to allocate any partition tables.";
+        return false;
+    }
+    last_sector = first_sector + (num_free_sectors / sectors_per_block) * sectors_per_block - 1;
+
     geometry_.first_logical_sector = first_sector;
     geometry_.last_logical_sector = last_sector;
     geometry_.metadata_max_size = metadata_max_size;
@@ -255,6 +278,7 @@
     geometry_.alignment = device_info_.alignment;
     geometry_.alignment_offset = device_info_.alignment_offset;
     geometry_.block_device_size = device_info_.size;
+    geometry_.logical_block_size = device_info.logical_block_size;
     return true;
 }
 
@@ -290,13 +314,7 @@
     }
 }
 
-bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t requested_size) {
-    // Align the space needed up to the nearest sector.
-    uint64_t aligned_size = AlignTo(requested_size, LP_SECTOR_SIZE);
-    if (partition->size() >= aligned_size) {
-        return true;
-    }
-
+bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
     // Figure out how much we need to allocate.
     uint64_t space_needed = aligned_size - partition->size();
     uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
@@ -307,95 +325,101 @@
         uint64_t end;
 
         Interval(uint64_t start, uint64_t end) : start(start), end(end) {}
+        uint64_t length() const { return end - start; }
         bool operator<(const Interval& other) const { return start < other.start; }
     };
-    std::vector<Interval> intervals;
 
-    // Collect all extents in the partition table.
+    // Collect all extents in the partition table, then sort them by starting
+    // sector.
+    std::vector<Interval> extents;
     for (const auto& partition : partitions_) {
         for (const auto& extent : partition->extents()) {
             LinearExtent* linear = extent->AsLinearExtent();
             if (!linear) {
                 continue;
             }
-            intervals.emplace_back(linear->physical_sector(),
-                                   linear->physical_sector() + extent->num_sectors());
+            extents.emplace_back(linear->physical_sector(),
+                                 linear->physical_sector() + extent->num_sectors());
         }
     }
+    std::sort(extents.begin(), extents.end());
 
-    // Sort extents by starting sector.
-    std::sort(intervals.begin(), intervals.end());
+    // Convert the extent list into a list of gaps between the extents; i.e.,
+    // the list of ranges that are free on the disk.
+    std::vector<Interval> free_regions;
+    for (size_t i = 1; i < extents.size(); i++) {
+        const Interval& previous = extents[i - 1];
+        const Interval& current = extents[i];
+
+        uint64_t aligned = AlignSector(previous.end);
+        if (aligned >= current.start) {
+            // There is no gap between these two extents, try the next one.
+            // Note that we check with >= instead of >, since alignment may
+            // bump the ending sector past the beginning of the next extent.
+            continue;
+        }
+
+        // The new interval represents the free space starting at the end of
+        // the previous interval, and ending at the start of the next interval.
+        free_regions.emplace_back(aligned, current.start);
+    }
+
+    // Add a final interval representing the remainder of the free space.
+    uint64_t last_free_extent_start =
+            extents.empty() ? geometry_.first_logical_sector : extents.back().end;
+    last_free_extent_start = AlignSector(last_free_extent_start);
+    if (last_free_extent_start <= geometry_.last_logical_sector) {
+        free_regions.emplace_back(last_free_extent_start, geometry_.last_logical_sector + 1);
+    }
+
+    const uint64_t sectors_per_block = device_info_.logical_block_size / LP_SECTOR_SIZE;
+    CHECK(sectors_needed % sectors_per_block == 0);
 
     // Find gaps that we can use for new extents. Note we store new extents in a
     // temporary vector, and only commit them if we are guaranteed enough free
     // space.
     std::vector<std::unique_ptr<LinearExtent>> new_extents;
-    for (size_t i = 1; i < intervals.size(); i++) {
-        const Interval& previous = intervals[i - 1];
-        const Interval& current = intervals[i];
+    for (auto& region : free_regions) {
+        if (region.length() % sectors_per_block != 0) {
+            // This should never happen, because it would imply that we
+            // once allocated an extent that was not a multiple of the
+            // block size. That extent would be rejected by DM_TABLE_LOAD.
+            LERROR << "Region " << region.start << ".." << region.end
+                   << " is not a multiple of the block size, " << sectors_per_block;
 
-        if (previous.end >= current.start) {
-            // There is no gap between these two extents, try the next one. Note that
-            // extents may never overlap, but just for safety, we ignore them if they
-            // do.
-            DCHECK(previous.end == current.start);
-            continue;
+            // If for some reason the final region is mis-sized we still want
+            // to be able to grow partitions. So just to be safe, round the
+            // region down to the nearest block.
+            region.end = region.start + (region.length() / sectors_per_block) * sectors_per_block;
+            if (!region.length()) {
+                continue;
+            }
         }
 
-        uint64_t aligned = AlignSector(previous.end);
-        if (aligned >= current.start) {
-            // After alignment, this extent is not usable.
-            continue;
-        }
+        uint64_t sectors = std::min(sectors_needed, region.length());
+        CHECK(sectors % sectors_per_block == 0);
 
-        // This gap is enough to hold the remainder of the space requested, so we
-        // can allocate what we need and return.
-        if (current.start - aligned >= sectors_needed) {
-            auto extent = std::make_unique<LinearExtent>(sectors_needed, aligned);
-            sectors_needed -= extent->num_sectors();
-            new_extents.push_back(std::move(extent));
+        auto extent = std::make_unique<LinearExtent>(sectors, region.start);
+        new_extents.push_back(std::move(extent));
+        sectors_needed -= sectors;
+        if (!sectors_needed) {
             break;
         }
-
-        // This gap is not big enough to fit the remainder of the space requested,
-        // so consume the whole thing and keep looking for more.
-        auto extent = std::make_unique<LinearExtent>(current.start - aligned, aligned);
-        sectors_needed -= extent->num_sectors();
-        new_extents.push_back(std::move(extent));
     }
-
-    // If we still have more to allocate, take it from the remaining free space
-    // in the allocatable region.
     if (sectors_needed) {
-        uint64_t first_sector;
-        if (intervals.empty()) {
-            first_sector = geometry_.first_logical_sector;
-        } else {
-            first_sector = intervals.back().end;
-        }
-        DCHECK(first_sector <= geometry_.last_logical_sector);
-
-        // Note: After alignment, |first_sector| may be > the last usable sector.
-        first_sector = AlignSector(first_sector);
-
-        // Note: the last usable sector is inclusive.
-        if (first_sector > geometry_.last_logical_sector ||
-            geometry_.last_logical_sector + 1 - first_sector < sectors_needed) {
-            LERROR << "Not enough free space to expand partition: " << partition->name();
-            return false;
-        }
-        auto extent = std::make_unique<LinearExtent>(sectors_needed, first_sector);
-        new_extents.push_back(std::move(extent));
+        LERROR << "Not enough free space to expand partition: " << partition->name();
+        return false;
     }
 
+    // Everything succeeded, so commit the new extents.
     for (auto& extent : new_extents) {
         partition->AddExtent(std::move(extent));
     }
     return true;
 }
 
-void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t requested_size) {
-    partition->ShrinkTo(requested_size);
+void MetadataBuilder::ShrinkPartition(Partition* partition, uint64_t aligned_size) {
+    partition->ShrinkTo(aligned_size);
 }
 
 std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
@@ -455,6 +479,12 @@
 void MetadataBuilder::set_block_device_info(const BlockDeviceInfo& device_info) {
     device_info_.size = device_info.size;
 
+    // Note that if the logical block size changes, we're probably in trouble:
+    // we could have already built extents that will only work on the previous
+    // size.
+    DCHECK(partitions_.empty() ||
+           device_info_.logical_block_size == device_info.logical_block_size);
+
     // The kernel does not guarantee these values are present, so we only
     // replace existing values if the new values are non-zero.
     if (device_info.alignment) {
@@ -465,5 +495,18 @@
     }
 }
 
+bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
+    // Align the space needed up to the nearest sector.
+    uint64_t aligned_size = AlignTo(requested_size, device_info_.logical_block_size);
+
+    if (aligned_size > partition->size()) {
+        return GrowPartition(partition, aligned_size);
+    }
+    if (aligned_size < partition->size()) {
+        ShrinkPartition(partition, aligned_size);
+    }
+    return true;
+}
+
 }  // namespace fs_mgr
 }  // namespace android
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index b610fd4..f1a91c4 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -45,7 +45,7 @@
 
     Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 65536), true);
+    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
     EXPECT_EQ(system->size(), 65536);
     ASSERT_EQ(system->extents().size(), 1);
 
@@ -55,24 +55,23 @@
     // The first logical sector will be (4096+1024*2)/512 = 12.
     EXPECT_EQ(extent->physical_sector(), 12);
 
-    // Test growing to the same size.
-    EXPECT_EQ(builder->GrowPartition(system, 65536), true);
+    // Test resizing to the same size.
+    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
     EXPECT_EQ(system->size(), 65536);
     EXPECT_EQ(system->extents().size(), 1);
     EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
-    // Test growing to a smaller size.
-    EXPECT_EQ(builder->GrowPartition(system, 0), true);
-    EXPECT_EQ(system->size(), 65536);
+    // Test resizing to a smaller size.
+    EXPECT_EQ(builder->ResizePartition(system, 0), true);
+    EXPECT_EQ(system->size(), 0);
+    EXPECT_EQ(system->extents().size(), 0);
+    // Test resizing to a greater size.
+    builder->ResizePartition(system, 131072);
+    EXPECT_EQ(system->size(), 131072);
     EXPECT_EQ(system->extents().size(), 1);
-    EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
-    // Test shrinking to a greater size.
-    builder->ShrinkPartition(system, 131072);
-    EXPECT_EQ(system->size(), 65536);
-    EXPECT_EQ(system->extents().size(), 1);
-    EXPECT_EQ(system->extents()[0]->num_sectors(), 65536 / LP_SECTOR_SIZE);
+    EXPECT_EQ(system->extents()[0]->num_sectors(), 131072 / LP_SECTOR_SIZE);
 
     // Test shrinking within the same extent.
-    builder->ShrinkPartition(system, 32768);
+    builder->ResizePartition(system, 32768);
     EXPECT_EQ(system->size(), 32768);
     EXPECT_EQ(system->extents().size(), 1);
     extent = system->extents()[0]->AsLinearExtent();
@@ -81,7 +80,7 @@
     EXPECT_EQ(extent->physical_sector(), 12);
 
     // Test shrinking to 0.
-    builder->ShrinkPartition(system, 0);
+    builder->ResizePartition(system, 0);
     EXPECT_EQ(system->size(), 0);
     EXPECT_EQ(system->extents().size(), 0);
 }
@@ -92,12 +91,12 @@
     // Test that we align up to one sector.
     Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 10000), true);
-    EXPECT_EQ(system->size(), 10240);
+    EXPECT_EQ(builder->ResizePartition(system, 10000), true);
+    EXPECT_EQ(system->size(), 12288);
     EXPECT_EQ(system->extents().size(), 1);
 
-    builder->ShrinkPartition(system, 9000);
-    EXPECT_EQ(system->size(), 9216);
+    builder->ResizePartition(system, 7000);
+    EXPECT_EQ(system->size(), 8192);
     EXPECT_EQ(system->extents().size(), 1);
 }
 
@@ -121,13 +120,13 @@
 
 TEST(liblp, InternalAlignment) {
     // Test the metadata fitting within alignment.
-    BlockDeviceInfo device_info(1024 * 1024, 768 * 1024, 0);
+    BlockDeviceInfo device_info(1024 * 1024, 768 * 1024, 0, 4096);
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 2);
     ASSERT_NE(builder, nullptr);
     unique_ptr<LpMetadata> exported = builder->Export();
     ASSERT_NE(exported, nullptr);
     EXPECT_EQ(exported->geometry.first_logical_sector, 1536);
-    EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
+    EXPECT_EQ(exported->geometry.last_logical_sector, 2031);
 
     // Test a large alignment offset thrown in.
     device_info.alignment_offset = 753664;
@@ -136,7 +135,7 @@
     exported = builder->Export();
     ASSERT_NE(exported, nullptr);
     EXPECT_EQ(exported->geometry.first_logical_sector, 1472);
-    EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
+    EXPECT_EQ(exported->geometry.last_logical_sector, 2031);
 
     // Alignment offset without alignment doesn't mean anything.
     device_info.alignment = 0;
@@ -151,7 +150,7 @@
     exported = builder->Export();
     ASSERT_NE(exported, nullptr);
     EXPECT_EQ(exported->geometry.first_logical_sector, 78);
-    EXPECT_EQ(exported->geometry.last_logical_sector, 1975);
+    EXPECT_EQ(exported->geometry.last_logical_sector, 1973);
 
     // Test a small alignment with no alignment offset.
     device_info.alignment = 11 * 1024;
@@ -164,7 +163,7 @@
 }
 
 TEST(liblp, InternalPartitionAlignment) {
-    BlockDeviceInfo device_info(512 * 1024 * 1024, 768 * 1024, 753664);
+    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);
@@ -174,8 +173,8 @@
 
     // Add a bunch of small extents to each, interleaving.
     for (size_t i = 0; i < 10; i++) {
-        ASSERT_TRUE(builder->GrowPartition(a, a->size() + 4096));
-        ASSERT_TRUE(builder->GrowPartition(b, b->size() + 4096));
+        ASSERT_TRUE(builder->ResizePartition(a, a->size() + 4096));
+        ASSERT_TRUE(builder->ResizePartition(b, b->size() + 4096));
     }
     EXPECT_EQ(a->size(), 40960);
     EXPECT_EQ(b->size(), 40960);
@@ -203,9 +202,9 @@
 
     Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 1036288), true);
+    EXPECT_EQ(builder->ResizePartition(system, 1036288), true);
     EXPECT_EQ(system->size(), 1036288);
-    EXPECT_EQ(builder->GrowPartition(system, 1036289), false);
+    EXPECT_EQ(builder->ResizePartition(system, 1036289), false);
 }
 
 TEST(liblp, BuildComplex) {
@@ -215,9 +214,9 @@
     Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 65536), true);
-    EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
-    EXPECT_EQ(builder->GrowPartition(system, 98304), true);
+    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
+    EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
+    EXPECT_EQ(builder->ResizePartition(system, 98304), true);
     EXPECT_EQ(system->size(), 98304);
     EXPECT_EQ(vendor->size(), 32768);
 
@@ -268,9 +267,9 @@
     Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 65536), true);
-    EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
-    EXPECT_EQ(builder->GrowPartition(system, 98304), true);
+    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
+    EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
+    EXPECT_EQ(builder->ResizePartition(system, 98304), true);
 
     unique_ptr<LpMetadata> exported = builder->Export();
     EXPECT_NE(exported, nullptr);
@@ -323,9 +322,9 @@
     Partition* vendor = builder->AddPartition("vendor", TEST_GUID2, LP_PARTITION_ATTR_READONLY);
     ASSERT_NE(system, nullptr);
     ASSERT_NE(vendor, nullptr);
-    EXPECT_EQ(builder->GrowPartition(system, 65536), true);
-    EXPECT_EQ(builder->GrowPartition(vendor, 32768), true);
-    EXPECT_EQ(builder->GrowPartition(system, 98304), true);
+    EXPECT_EQ(builder->ResizePartition(system, 65536), true);
+    EXPECT_EQ(builder->ResizePartition(vendor, 32768), true);
+    EXPECT_EQ(builder->ResizePartition(system, 98304), true);
 
     unique_ptr<LpMetadata> exported = builder->Export();
     ASSERT_NE(exported, nullptr);
@@ -382,7 +381,7 @@
     static const size_t kMetadataSize = 64 * 1024;
 
     // No space to store metadata + geometry.
-    BlockDeviceInfo device_info(kDiskSize, 0, 0);
+    BlockDeviceInfo device_info(kDiskSize, 0, 0, 4096);
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
     EXPECT_EQ(builder, nullptr);
 
@@ -391,8 +390,8 @@
     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
     EXPECT_EQ(builder, nullptr);
 
-    // Space for metadata + geometry + one free sector.
-    device_info.size += LP_SECTOR_SIZE;
+    // Space for metadata + geometry + one free block.
+    device_info.size += device_info.logical_block_size;
     builder = MetadataBuilder::New(device_info, kMetadataSize, 1);
     EXPECT_NE(builder, nullptr);
 
@@ -425,19 +424,21 @@
     ASSERT_EQ(device_info.alignment % LP_SECTOR_SIZE, 0);
     ASSERT_EQ(device_info.alignment_offset % LP_SECTOR_SIZE, 0);
     ASSERT_LE(device_info.alignment_offset, INT_MAX);
+    ASSERT_EQ(device_info.logical_block_size % LP_SECTOR_SIZE, 0);
 
     // Having an alignment offset > alignment doesn't really make sense.
     ASSERT_LT(device_info.alignment_offset, device_info.alignment);
 }
 
 TEST(liblp, UpdateBlockDeviceInfo) {
-    BlockDeviceInfo device_info(1024 * 1024, 4096, 1024);
+    BlockDeviceInfo device_info(1024 * 1024, 4096, 1024, 4096);
     unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
     ASSERT_NE(builder, nullptr);
 
     EXPECT_EQ(builder->block_device_info().size, device_info.size);
     EXPECT_EQ(builder->block_device_info().alignment, device_info.alignment);
     EXPECT_EQ(builder->block_device_info().alignment_offset, device_info.alignment_offset);
+    EXPECT_EQ(builder->block_device_info().logical_block_size, device_info.logical_block_size);
 
     device_info.alignment = 0;
     device_info.alignment_offset = 2048;
@@ -451,3 +452,27 @@
     EXPECT_EQ(builder->block_device_info().alignment, 8192);
     EXPECT_EQ(builder->block_device_info().alignment_offset, 2048);
 }
+
+TEST(liblp, InvalidBlockSize) {
+    BlockDeviceInfo device_info(1024 * 1024, 0, 0, 513);
+    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
+    EXPECT_EQ(builder, nullptr);
+}
+
+TEST(liblp, AlignedExtentSize) {
+    BlockDeviceInfo device_info(1024 * 1024, 0, 0, 4096);
+    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 1024, 1);
+    ASSERT_NE(builder, nullptr);
+
+    Partition* partition = builder->AddPartition("system", TEST_GUID, 0);
+    ASSERT_NE(partition, nullptr);
+    ASSERT_TRUE(builder->ResizePartition(partition, 512));
+    EXPECT_EQ(partition->size(), 4096);
+}
+
+TEST(liblp, AlignedFreeSpace) {
+    // Only one sector free - at least one block is required.
+    BlockDeviceInfo device_info(10240, 0, 0, 4096);
+    unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(device_info, 512, 1);
+    ASSERT_EQ(builder, nullptr);
+}
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 8bde313..e83b922 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -32,11 +32,16 @@
 
 // By default, partitions are aligned on a 1MiB boundary.
 static const uint32_t kDefaultPartitionAlignment = 1024 * 1024;
+static const uint32_t kDefaultBlockSize = 4096;
 
 struct BlockDeviceInfo {
-    BlockDeviceInfo() : size(0), alignment(0), alignment_offset(0) {}
-    BlockDeviceInfo(uint64_t size, uint32_t alignment, uint32_t alignment_offset)
-        : size(size), alignment(alignment), alignment_offset(alignment_offset) {}
+    BlockDeviceInfo() : size(0), alignment(0), alignment_offset(0), logical_block_size(0) {}
+    BlockDeviceInfo(uint64_t size, uint32_t alignment, uint32_t alignment_offset,
+                    uint32_t logical_block_size)
+        : size(size),
+          alignment(alignment),
+          alignment_offset(alignment_offset),
+          logical_block_size(logical_block_size) {}
     // Size of the block device, in bytes.
     uint64_t size;
     // Optimal target alignment, in bytes. Partition extents will be aligned to
@@ -46,6 +51,8 @@
     // |alignment_offset| on the target device is correctly aligned on its
     // parent device. This value must be 0 or a multiple of 512.
     uint32_t alignment_offset;
+    // Block size, for aligning extent sizes and partition sizes.
+    uint32_t logical_block_size;
 };
 
 // Abstraction around dm-targets that can be encoded into logical partition tables.
@@ -88,6 +95,8 @@
 };
 
 class Partition final {
+    friend class MetadataBuilder;
+
   public:
     Partition(const std::string& name, const std::string& guid, uint32_t attributes);
 
@@ -97,10 +106,6 @@
     // Remove all extents from this partition.
     void RemoveExtents();
 
-    // Remove and/or shrink extents until the partition is the requested size.
-    // See MetadataBuilder::ShrinkPartition for more information.
-    void ShrinkTo(uint64_t requested_size);
-
     const std::string& name() const { return name_; }
     uint32_t attributes() const { return attributes_; }
     const std::string& guid() const { return guid_; }
@@ -108,6 +113,8 @@
     uint64_t size() const { return size_; }
 
   private:
+    void ShrinkTo(uint64_t aligned_size);
+
     std::string name_;
     std::string guid_;
     std::vector<std::unique_ptr<Extent>> extents_;
@@ -144,7 +151,7 @@
     // size. This is a convenience method for tests.
     static std::unique_ptr<MetadataBuilder> New(uint64_t blockdev_size, uint32_t metadata_max_size,
                                                 uint32_t metadata_slot_count) {
-        BlockDeviceInfo device_info(blockdev_size, 0, 0);
+        BlockDeviceInfo device_info(blockdev_size, 0, 0, kDefaultBlockSize);
         return New(device_info, metadata_max_size, metadata_slot_count);
     }
 
@@ -162,29 +169,17 @@
     // Find a partition by name. If no partition is found, nullptr is returned.
     Partition* FindPartition(const std::string& name);
 
-    // Grow a partition to the requested size. If the partition's size is already
-    // greater or equal to the requested size, this will return true and the
-    // partition table will not be changed. Otherwise, a greedy algorithm is
-    // used to find free gaps in the partition table and allocate them for this
-    // partition. If not enough space can be allocated, false is returned, and
-    // the parition table will not be modified.
+    // Grow or shrink a partition to the requested size. This size will be
+    // rounded UP to the nearest block (512 bytes).
     //
-    // The size will be rounded UP to the nearest sector.
+    // When growing a partition, a greedy algorithm is used to find free gaps
+    // in the partition table and allocate them. If not enough space can be
+    // allocated, false is returned, and the parition table will not be
+    // modified.
     //
     // Note, this is an in-memory operation, and it does not alter the
     // underlying filesystem or contents of the partition on disk.
-    bool GrowPartition(Partition* partition, uint64_t requested_size);
-
-    // Shrink a partition to the requested size. If the partition is already
-    // smaller than the given size, this will return and the partition table
-    // will not be changed. Otherwise, extents will be removed and/or shrunk
-    // from the end of the partition until it is the requested size.
-    //
-    // The size will be rounded UP to the nearest sector.
-    //
-    // Note, this is an in-memory operation, and it does not alter the
-    // underlying filesystem or contents of the partition on disk.
-    void ShrinkPartition(Partition* partition, uint64_t requested_size);
+    bool ResizePartition(Partition* partition, uint64_t requested_size);
 
     // Amount of space that can be allocated to logical partitions.
     uint64_t AllocatableSpace() const;
@@ -198,7 +193,8 @@
     MetadataBuilder();
     bool Init(const BlockDeviceInfo& info, uint32_t metadata_max_size, uint32_t metadata_slot_count);
     bool Init(const LpMetadata& metadata);
-
+    bool GrowPartition(Partition* partition, uint64_t aligned_size);
+    void ShrinkPartition(Partition* partition, uint64_t aligned_size);
     uint64_t AlignSector(uint64_t sector);
 
     LpMetadataGeometry geometry_;
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index e1323e1..52c80f7 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -136,6 +136,12 @@
      * can be used to verify the geometry against a target device.
      */
     uint64_t block_device_size;
+
+    /* 76: Logical block size of the super partition block device. This is the
+     * minimal alignment for partition and extent sizes, and it must be a
+     * multiple of LP_SECTOR_SIZE.
+     */
+    uint32_t logical_block_size;
 } __attribute__((packed)) LpMetadataGeometry;
 
 /* The logical partition metadata has a number of tables; they are described
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index bbbedc7..638f4b3 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -85,7 +85,7 @@
     if (!system) {
         return false;
     }
-    return builder->GrowPartition(system, 24 * 1024);
+    return builder->ResizePartition(system, 24 * 1024);
 }
 
 // Create a temporary disk and flash it with the default partition setup.
@@ -345,7 +345,7 @@
     ASSERT_NE(partition, nullptr);
     // Add one extent to any partition to fill up more space - we're at 508
     // bytes after this, out of 512.
-    ASSERT_TRUE(builder->GrowPartition(partition, 1024));
+    ASSERT_TRUE(builder->ResizePartition(partition, 1024));
 
     unique_ptr<LpMetadata> exported = builder->Export();
     ASSERT_NE(exported, nullptr);
diff --git a/fs_mgr/liblp/utility_test.cpp b/fs_mgr/liblp/utility_test.cpp
index 092dbf1..7bf42ae 100644
--- a/fs_mgr/liblp/utility_test.cpp
+++ b/fs_mgr/liblp/utility_test.cpp
@@ -40,7 +40,8 @@
                                    80000,
                                    0,
                                    0,
-                                   1024 * 1024};
+                                   1024 * 1024,
+                                   4096};
     EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 0), 4096);
     EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 1), 4096 + 16384);
     EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 2), 4096 + 16384 * 2);
diff --git a/init/init.cpp b/init/init.cpp
index 73194bd..7ad9ec3 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -670,6 +670,10 @@
         CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
         CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
 
+        // This is needed for log wrapper, which gets called before ueventd runs.
+        CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));
+        CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
+
         // Mount staging areas for devices managed by vold
         // See storage config details at http://source.android.com/devices/storage/
         CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 94f206e..b788be9 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -414,6 +414,8 @@
     if constexpr (WORLD_WRITABLE_KMSG) {
         selinux_android_restorecon("/dev/kmsg_debug", 0);
     }
+    selinux_android_restorecon("/dev/null", 0);
+    selinux_android_restorecon("/dev/ptmx", 0);
     selinux_android_restorecon("/dev/socket", 0);
     selinux_android_restorecon("/dev/random", 0);
     selinux_android_restorecon("/dev/urandom", 0);
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
index bb1ce34..1b7c377 100644
--- a/liblog/include/log/log_event_list.h
+++ b/liblog/include/log/log_event_list.h
@@ -108,6 +108,13 @@
 android_log_list_element android_log_read_next(android_log_context ctx);
 android_log_list_element android_log_peek_next(android_log_context ctx);
 
+/* Reset writer context */
+int android_log_reset(android_log_context ctx);
+
+/* Reset reader context */
+int android_log_parser_reset(android_log_context ctx,
+                             const char* msg, size_t len);
+
 /* Finished with reader or writer context */
 int android_log_destroy(android_log_context* ctx);
 
diff --git a/liblog/include_vndk/log/log_event_list.h b/liblog/include_vndk/log/log_event_list.h
index cbd3091..9f74534 100644
--- a/liblog/include_vndk/log/log_event_list.h
+++ b/liblog/include_vndk/log/log_event_list.h
@@ -63,6 +63,13 @@
 /* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
 int android_log_write_list(android_log_context ctx, log_id_t id);
 
+/* Reset writer context */
+int android_log_reset(android_log_context ctx);
+
+/* Reset reader context */
+int android_log_parser_reset(android_log_context ctx,
+                             const char* msg, size_t len);
+
 /* Finished with reader or writer context */
 int android_log_destroy(android_log_context* ctx);
 
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
index 66670fe..015c9cb 100644
--- a/liblog/liblog.map.txt
+++ b/liblog/liblog.map.txt
@@ -53,3 +53,9 @@
     __android_log_is_loggable_len;
     __android_log_is_debuggable; # vndk
 };
+
+LIBLOG_Q {
+  global:
+    android_log_reset; #vndk
+    android_log_parser_reset; #vndk
+};
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index a59cb87..14002ce 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -45,14 +45,9 @@
   uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
 } android_log_context_internal;
 
-LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
-  size_t needed, i;
-  android_log_context_internal* context;
+static void init_context(android_log_context_internal* context, uint32_t tag) {
+  size_t needed;
 
-  context = calloc(1, sizeof(android_log_context_internal));
-  if (!context) {
-    return NULL;
-  }
   context->tag = tag;
   context->read_write_flag = kAndroidLoggerWrite;
   needed = sizeof(uint8_t) + sizeof(uint8_t);
@@ -63,6 +58,24 @@
   context->storage[context->pos + 0] = EVENT_TYPE_LIST;
   context->list[0] = context->pos + 1;
   context->pos += needed;
+}
+
+static void init_parser_context(android_log_context_internal* context,
+                                const char* msg, size_t len) {
+  len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
+  context->len = len;
+  memcpy(context->storage, msg, len);
+  context->read_write_flag = kAndroidLoggerRead;
+}
+
+LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
+  android_log_context_internal* context;
+
+  context = calloc(1, sizeof(android_log_context_internal));
+  if (!context) {
+    return NULL;
+  }
+  init_context(context, tag);
 
   return (android_log_context)context;
 }
@@ -76,10 +89,7 @@
   if (!context) {
     return NULL;
   }
-  len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
-  context->len = len;
-  memcpy(context->storage, msg, len);
-  context->read_write_flag = kAndroidLoggerRead;
+  init_parser_context(context, msg, len);
 
   return (android_log_context)context;
 }
@@ -97,6 +107,38 @@
   return 0;
 }
 
+LIBLOG_ABI_PUBLIC int android_log_reset(android_log_context ctx) {
+  android_log_context_internal* context;
+  uint32_t tag;
+
+  context = (android_log_context_internal*)ctx;
+  if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
+    return -EBADF;
+  }
+
+  tag = context->tag;
+  memset(context, 0, sizeof(*context));
+  init_context(context, tag);
+
+  return 0;
+}
+
+LIBLOG_ABI_PUBLIC int android_log_parser_reset(android_log_context ctx,
+                                               const char* msg, size_t len) {
+  android_log_context_internal* context;
+
+  context = (android_log_context_internal*)ctx;
+  if (!context || (kAndroidLoggerRead != context->read_write_flag)) {
+    return -EBADF;
+  }
+
+  memset(context, 0, sizeof(*context));
+  init_parser_context(context, msg, len);
+
+  return 0;
+}
+
+
 LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
   size_t needed;
   android_log_context_internal* context;
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 0586381..3d7521c 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -27,6 +27,7 @@
 phony {
     name: "shell_and_utilities_recovery",
     required: [
+        "grep.recovery",
         "sh.recovery",
         "toolbox.recovery",
         "toybox.recovery",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index e75e4af..f08cf93 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -62,8 +62,8 @@
 }
 
 // We build BSD grep separately (but see http://b/111849261).
-cc_binary {
-    name: "grep",
+cc_defaults {
+    name: "grep_common",
     defaults: ["toolbox_defaults"],
     srcs: [
         "upstream-netbsd/usr.bin/grep/fastgrep.c",
@@ -72,8 +72,27 @@
         "upstream-netbsd/usr.bin/grep/queue.c",
         "upstream-netbsd/usr.bin/grep/util.c",
     ],
-
+    symlinks: [
+        "egrep",
+        "fgrep",
+    ],
     sanitize: {
         integer_overflow: false,
     },
 }
+
+cc_binary {
+    name: "grep",
+    defaults: ["grep_common"],
+    recovery_available: true,
+}
+
+// Build vendor grep.
+// TODO: Add vendor_available to "grep" module and remove "grep_vendor" module
+//       when vendor_available is fully supported.
+cc_binary {
+    name: "grep_vendor",
+    stem: "grep",
+    vendor: true,
+    defaults: ["grep_common"],
+}