Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89eb0177 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "liblp: Add an abstraction layer for opening partitions."

parents 13e160e0 7a6c511a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ cc_library {
    srcs: [
        "builder.cpp",
        "images.cpp",
        "partition_opener.cpp",
        "reader.cpp",
        "utility.cpp",
        "writer.cpp",
@@ -59,6 +60,7 @@ cc_test {
    srcs: [
        "builder_test.cpp",
        "io_test.cpp",
        "test_partition_opener.cpp",
        "utility_test.cpp",
    ],
}
+9 −44
Original line number Diff line number Diff line
@@ -16,11 +16,7 @@

#include "liblp/builder.h"

#if defined(__linux__)
#include <linux/fs.h>
#endif
#include <string.h>
#include <sys/ioctl.h>

#include <algorithm>

@@ -33,43 +29,6 @@
namespace android {
namespace fs_mgr {

bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) {
#if defined(__linux__)
    android::base::unique_fd fd(open(block_device.c_str(), O_RDONLY));
    if (fd < 0) {
        PERROR << __PRETTY_FUNCTION__ << "open '" << block_device << "' failed";
        return false;
    }
    if (!GetDescriptorSize(fd, &device_info->size)) {
        return false;
    }
    if (ioctl(fd, BLKIOMIN, &device_info->alignment) < 0) {
        PERROR << __PRETTY_FUNCTION__ << "BLKIOMIN failed";
        return false;
    }

    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;
    (void)device_info;
    LERROR << __PRETTY_FUNCTION__ << ": Not supported on this operating system.";
    return false;
#endif
}

void LinearExtent::AddTo(LpMetadata* out) const {
    out->extents.push_back(LpMetadataExtent{num_sectors_, LP_TARGET_TYPE_LINEAR, physical_sector_});
}
@@ -138,9 +97,10 @@ uint64_t Partition::BytesOnDisk() const {
    return sectors * LP_SECTOR_SIZE;
}

std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_device,
std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const IPartitionOpener& opener,
                                                      const std::string& super_partition,
                                                      uint32_t slot_number) {
    std::unique_ptr<LpMetadata> metadata = ReadMetadata(block_device.c_str(), slot_number);
    std::unique_ptr<LpMetadata> metadata = ReadMetadata(opener, super_partition, slot_number);
    if (!metadata) {
        return nullptr;
    }
@@ -149,12 +109,17 @@ std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& block_d
        return nullptr;
    }
    BlockDeviceInfo device_info;
    if (fs_mgr::GetBlockDeviceInfo(block_device, &device_info)) {
    if (opener.GetInfo(super_partition, &device_info)) {
        builder->UpdateBlockDeviceInfo(device_info);
    }
    return builder;
}

std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const std::string& super_partition,
                                                      uint32_t slot_number) {
    return New(PartitionOpener(), super_partition, slot_number);
}

std::unique_ptr<MetadataBuilder> MetadataBuilder::New(const BlockDeviceInfo& device_info,
                                                      uint32_t metadata_max_size,
                                                      uint32_t metadata_slot_count) {
+2 −5
Original line number Diff line number Diff line
@@ -424,13 +424,10 @@ TEST(liblp, block_device_info) {
                                                               fs_mgr_free_fstab);
    ASSERT_NE(fstab, nullptr);

    // This should read from the "super" partition once we have a well-defined
    // way to access it.
    struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab.get(), "/data");
    ASSERT_NE(rec, nullptr);
    PartitionOpener opener;

    BlockDeviceInfo device_info;
    ASSERT_TRUE(GetBlockDeviceInfo(rec->blk_device, &device_info));
    ASSERT_TRUE(opener.GetInfo(fs_mgr_get_super_partition_name(), &device_info));

    // Sanity check that the device doesn't give us some weird inefficient
    // alignment.
+7 −22
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <memory>

#include "liblp.h"
#include "partition_opener.h"

namespace android {
namespace fs_mgr {
@@ -34,27 +35,6 @@ class LinearExtent;
static const uint32_t kDefaultPartitionAlignment = 1024 * 1024;
static const uint32_t kDefaultBlockSize = 4096;

struct BlockDeviceInfo {
    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
    // this value by default. This value must be 0 or a multiple of 512.
    uint32_t alignment;
    // Alignment offset to parent device (if any), in bytes. The sector at
    // |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.
class Extent {
  public:
@@ -157,7 +137,12 @@ class MetadataBuilder {
    // Import an existing table for modification. This reads metadata off the
    // given block device and imports it. It also adjusts alignment information
    // based on run-time values in the operating system.
    static std::unique_ptr<MetadataBuilder> New(const std::string& block_device,
    static std::unique_ptr<MetadataBuilder> New(const IPartitionOpener& opener,
                                                const std::string& super_partition,
                                                uint32_t slot_number);

    // Same as above, but use the default PartitionOpener.
    static std::unique_ptr<MetadataBuilder> New(const std::string& super_partition,
                                                uint32_t slot_number);

    // Import an existing table for modification. If the table is not valid, for
+15 −4
Original line number Diff line number Diff line
@@ -24,7 +24,10 @@
#include <memory>
#include <string>

#include <android-base/unique_fd.h>

#include "metadata_format.h"
#include "partition_opener.h"

namespace android {
namespace fs_mgr {
@@ -44,7 +47,8 @@ struct LpMetadata {
// existing geometry, and should not be used for normal partition table
// updates. False can be returned if the geometry is incompatible with the
// block device or an I/O error occurs.
bool FlashPartitionTable(const std::string& block_device, const LpMetadata& metadata);
bool FlashPartitionTable(const IPartitionOpener& opener, const std::string& super_partition,
                         const LpMetadata& metadata);

// Update the partition table for a given metadata slot number. False is
// returned if an error occurs, which can include:
@@ -52,12 +56,19 @@ bool FlashPartitionTable(const std::string& block_device, const LpMetadata& meta
//  - I/O error.
//  - Corrupt or missing metadata geometry on disk.
//  - Incompatible geometry.
bool UpdatePartitionTable(const std::string& block_device, const LpMetadata& metadata,
                          uint32_t slot_number);
bool UpdatePartitionTable(const IPartitionOpener& opener, const std::string& super_partition,
                          const LpMetadata& metadata, uint32_t slot_number);

// Read logical partition metadata from its predetermined location on a block
// device. If readback fails, we also attempt to load from a backup copy.
std::unique_ptr<LpMetadata> ReadMetadata(const char* block_device, uint32_t slot_number);
std::unique_ptr<LpMetadata> ReadMetadata(const IPartitionOpener& opener,
                                         const std::string& super_partition, uint32_t slot_number);

// Helper functions that use the default PartitionOpener.
bool FlashPartitionTable(const std::string& super_partition, const LpMetadata& metadata);
bool UpdatePartitionTable(const std::string& super_partition, const LpMetadata& metadata,
                          uint32_t slot_number);
std::unique_ptr<LpMetadata> ReadMetadata(const std::string& super_partition, uint32_t slot_number);

// Read/Write logical partition metadata to an image file, for diagnostics or
// flashing.
Loading