summaryrefslogtreecommitdiffstats
path: root/fs_mgr
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr')
-rw-r--r--fs_mgr/liblp/Android.bp2
-rw-r--r--fs_mgr/liblp/builder.cpp7
-rw-r--r--fs_mgr/liblp/builder_test.cpp21
-rw-r--r--fs_mgr/liblp/images.cpp192
-rw-r--r--fs_mgr/liblp/images.h29
-rw-r--r--fs_mgr/liblp/include/liblp/liblp.h1
-rw-r--r--fs_mgr/liblp/include/liblp/metadata_format.h9
-rw-r--r--fs_mgr/liblp/io_test.cpp1
-rw-r--r--fs_mgr/liblp/reader.cpp32
-rw-r--r--fs_mgr/liblp/reader.h3
-rw-r--r--fs_mgr/liblp/utility_test.cpp12
-rw-r--r--fs_mgr/liblp/writer.cpp32
-rw-r--r--fs_mgr/liblp/writer.h8
13 files changed, 268 insertions, 81 deletions
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 1050cf560..1434b212e 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -24,6 +24,7 @@ cc_library_static {
],
srcs: [
"builder.cpp",
+ "images.cpp",
"reader.cpp",
"utility.cpp",
"writer.cpp",
@@ -33,6 +34,7 @@ cc_library_static {
"liblog",
"libcrypto",
"libcrypto_utils",
+ "libsparse",
],
whole_static_libs: [
"libext2_uuid",
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index d15fa8c17..9d710f90b 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -200,6 +200,11 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
metadata_max_size = AlignTo(metadata_max_size, LP_SECTOR_SIZE);
// Check that device properties are sane.
+ device_info_ = device_info;
+ if (device_info_.size % LP_SECTOR_SIZE != 0) {
+ LERROR << "Block device 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;
@@ -212,7 +217,6 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
LERROR << "Partition alignment offset is greater than its alignment.";
return false;
}
- device_info_ = device_info;
// We reserve a geometry block (4KB) plus space for each copy of the
// maximum size of a metadata blob. Then, we double that space since
@@ -250,6 +254,7 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
geometry_.metadata_slot_count = metadata_slot_count;
geometry_.alignment = device_info_.alignment;
geometry_.alignment_offset = device_info_.alignment_offset;
+ geometry_.block_device_size = device_info_.size;
return true;
}
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index 08440a3d0..b610fd4c4 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -106,19 +106,9 @@ TEST(liblp, DiskAlignment) {
static const uint32_t kMetadataSize = 1024;
static const uint32_t kMetadataSlots = 2;
- // If the disk size is not aligned to 512 bytes, make sure it still leaves
- // space at the end for backup metadata, and that it doesn't overlap with
- // the space for logical partitions.
unique_ptr<MetadataBuilder> builder =
MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
- unique_ptr<LpMetadata> exported = builder->Export();
- ASSERT_NE(exported, nullptr);
-
- static const size_t kMetadataSpace =
- (kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
- uint64_t space_at_end =
- kDiskSize - (exported->geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
- EXPECT_GE(space_at_end, kMetadataSpace);
+ ASSERT_EQ(builder, nullptr);
}
TEST(liblp, MetadataAlignment) {
@@ -148,15 +138,10 @@ TEST(liblp, InternalAlignment) {
EXPECT_EQ(exported->geometry.first_logical_sector, 1472);
EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
- // Test only an alignment offset (which should simply bump up the first
- // logical sector).
+ // Alignment offset without alignment doesn't mean anything.
device_info.alignment = 0;
builder = MetadataBuilder::New(device_info, 1024, 2);
- ASSERT_NE(builder, nullptr);
- exported = builder->Export();
- ASSERT_NE(exported, nullptr);
- EXPECT_EQ(exported->geometry.first_logical_sector, 1484);
- EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
+ ASSERT_EQ(builder, nullptr);
// Test a small alignment with an alignment offset.
device_info.alignment = 12 * 1024;
diff --git a/fs_mgr/liblp/images.cpp b/fs_mgr/liblp/images.cpp
new file mode 100644
index 000000000..93c56180f
--- /dev/null
+++ b/fs_mgr/liblp/images.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "images.h"
+
+#include <limits.h>
+
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+#include <sparse/sparse.h>
+
+#include "reader.h"
+#include "utility.h"
+#include "writer.h"
+
+namespace android {
+namespace fs_mgr {
+
+std::unique_ptr<LpMetadata> ReadFromImageFile(int fd) {
+ LpMetadataGeometry geometry;
+ if (!ReadLogicalPartitionGeometry(fd, &geometry)) {
+ return nullptr;
+ }
+ if (SeekFile64(fd, LP_METADATA_GEOMETRY_SIZE, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << LP_METADATA_GEOMETRY_SIZE;
+ return nullptr;
+ }
+ std::unique_ptr<LpMetadata> metadata = ParseMetadata(fd);
+ if (!metadata) {
+ return nullptr;
+ }
+ metadata->geometry = geometry;
+ return metadata;
+}
+
+std::unique_ptr<LpMetadata> ReadFromImageFile(const char* file) {
+ android::base::unique_fd fd(open(file, O_RDONLY));
+ if (fd < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "open failed: " << file;
+ return nullptr;
+ }
+ return ReadFromImageFile(fd);
+}
+
+bool WriteToImageFile(int fd, const LpMetadata& input) {
+ std::string geometry = SerializeGeometry(input.geometry);
+ std::string padding(LP_METADATA_GEOMETRY_SIZE - geometry.size(), '\0');
+ std::string metadata = SerializeMetadata(input);
+
+ std::string everything = geometry + padding + metadata;
+
+ if (!android::base::WriteFully(fd, everything.data(), everything.size())) {
+ PERROR << __PRETTY_FUNCTION__ << "write " << everything.size() << " bytes failed";
+ return false;
+ }
+ return true;
+}
+
+bool WriteToImageFile(const char* file, const LpMetadata& input) {
+ android::base::unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC, 0644));
+ if (fd < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "open failed: " << file;
+ return false;
+ }
+ return WriteToImageFile(fd, input);
+}
+
+// We use an object to build the sparse file since it requires that data
+// pointers be held alive until the sparse file is destroyed. It's easier
+// to do this when the data pointers are all in one place.
+class SparseBuilder {
+ public:
+ explicit SparseBuilder(const LpMetadata& metadata);
+
+ bool Build();
+ bool Export(const char* file);
+ bool IsValid() const { return file_ != nullptr; }
+
+ private:
+ bool AddData(const std::string& blob, uint32_t block);
+
+ const LpMetadata& metadata_;
+ const LpMetadataGeometry& geometry_;
+ std::unique_ptr<sparse_file, decltype(&sparse_file_destroy)> file_;
+ std::string geometry_blob_;
+ std::string metadata_blob_;
+};
+
+SparseBuilder::SparseBuilder(const LpMetadata& metadata)
+ : metadata_(metadata),
+ geometry_(metadata.geometry),
+ file_(sparse_file_new(LP_SECTOR_SIZE, geometry_.block_device_size), sparse_file_destroy) {}
+
+bool SparseBuilder::Export(const char* file) {
+ android::base::unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC, 0644));
+ if (fd < 0) {
+ PERROR << "open failed: " << file;
+ return false;
+ }
+ // No gzip compression; sparseify; no checksum.
+ int ret = sparse_file_write(file_.get(), fd, false, true, false);
+ if (ret != 0) {
+ LERROR << "sparse_file_write failed (error code " << ret << ")";
+ return false;
+ }
+ return true;
+}
+
+bool SparseBuilder::AddData(const std::string& blob, uint32_t block) {
+ void* data = const_cast<char*>(blob.data());
+ int ret = sparse_file_add_data(file_.get(), data, blob.size(), block);
+ if (ret != 0) {
+ LERROR << "sparse_file_add_data failed (error code " << ret << ")";
+ return false;
+ }
+ return true;
+}
+
+bool SparseBuilder::Build() {
+ geometry_blob_ = SerializeGeometry(geometry_);
+ geometry_blob_.resize(LP_METADATA_GEOMETRY_SIZE);
+ if (!AddData(geometry_blob_, 0)) {
+ return false;
+ }
+
+ // Metadata immediately follows geometry, and we write the same metadata
+ // to all slots.
+ uint32_t metadata_block = LP_METADATA_GEOMETRY_SIZE / LP_SECTOR_SIZE;
+ metadata_blob_ = SerializeMetadata(metadata_);
+ for (size_t i = 0; i < geometry_.metadata_slot_count; i++) {
+ if (!AddData(metadata_blob_, metadata_block)) {
+ return false;
+ }
+ metadata_block += geometry_.metadata_max_size / LP_SECTOR_SIZE;
+ }
+
+ // The backup area contains all metadata slots, and then geometry. Similar
+ // to before we write the metadata to every slot.
+ int64_t backup_offset = GetBackupMetadataOffset(geometry_, 0);
+ uint64_t backups_start = geometry_.block_device_size + backup_offset;
+ uint64_t backup_sector = backups_start / LP_SECTOR_SIZE;
+ for (size_t i = 0; i < geometry_.metadata_slot_count; i++) {
+ if (!AddData(metadata_blob_, backup_sector)) {
+ return false;
+ }
+ backup_sector += geometry_.metadata_max_size / LP_SECTOR_SIZE;
+ }
+ if (!AddData(geometry_blob_, backup_sector)) {
+ return false;
+ }
+ return true;
+}
+
+bool WriteToSparseFile(const char* file, const LpMetadata& metadata) {
+ uint64_t num_blocks =
+ AlignTo(metadata.geometry.block_device_size, LP_SECTOR_SIZE) / LP_SECTOR_SIZE;
+ if (num_blocks >= UINT_MAX) {
+ // libsparse counts blocks in unsigned 32-bit integers, but our block
+ // size is rather low (512 bytes), since we operate in sectors.
+ // Therefore the maximum block device size we can represent with a
+ // sparse file is 2TB for now.
+ LERROR << "Block device is too large to encode with libsparse.";
+ return false;
+ }
+
+ SparseBuilder builder(metadata);
+ if (!builder.IsValid()) {
+ LERROR << "Could not allocate sparse file of size " << metadata.geometry.block_device_size;
+ return false;
+ }
+ if (!builder.Build()) {
+ return false;
+ }
+
+ return builder.Export(file);
+}
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/liblp/images.h b/fs_mgr/liblp/images.h
new file mode 100644
index 000000000..3a999b89c
--- /dev/null
+++ b/fs_mgr/liblp/images.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <liblp/liblp.h>
+
+namespace android {
+namespace fs_mgr {
+
+// Helper function to serialize geometry and metadata to a normal file, for
+// flashing or debugging.
+std::unique_ptr<LpMetadata> ReadFromImageFile(int fd);
+bool WriteToImageFile(const char* file, const LpMetadata& metadata);
+bool WriteToImageFile(int fd, const LpMetadata& metadata);
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h
index 469ef9e59..c8d34d969 100644
--- a/fs_mgr/liblp/include/liblp/liblp.h
+++ b/fs_mgr/liblp/include/liblp/liblp.h
@@ -59,6 +59,7 @@ std::unique_ptr<LpMetadata> ReadMetadata(const char* block_device, uint32_t slot
// Read/Write logical partition metadata to an image file, for diagnostics or
// flashing.
+bool WriteToSparseFile(const char* file, const LpMetadata& metadata);
bool WriteToImageFile(const char* file, const LpMetadata& metadata);
std::unique_ptr<LpMetadata> ReadFromImageFile(const char* file);
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index b5202f030..e1323e11e 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -86,7 +86,9 @@ typedef struct LpMetadataGeometry {
/* 8: SHA256 checksum of this struct, with this field set to 0. */
uint8_t checksum[32];
- /* 40: Maximum amount of space a single copy of the metadata can use. */
+ /* 40: Maximum amount of space a single copy of the metadata can use. This
+ * must be a multiple of LP_SECTOR_SIZE.
+ */
uint32_t metadata_max_size;
/* 44: Number of copies of the metadata to keep. For A/B devices, this
@@ -129,6 +131,11 @@ typedef struct LpMetadataGeometry {
* If it cannot be determined, it is assumed to be 0.
*/
uint32_t alignment_offset;
+
+ /* 72: Block device size, as specified when the metadata was created. This
+ * can be used to verify the geometry against a target device.
+ */
+ uint64_t block_device_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 e91cc3e0a..bbbedc761 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -24,6 +24,7 @@
#include <gtest/gtest.h>
#include <liblp/builder.h>
+#include "images.h"
#include "reader.h"
#include "utility.h"
#include "writer.h"
diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp
index 985cf0991..117da5991 100644
--- a/fs_mgr/liblp/reader.cpp
+++ b/fs_mgr/liblp/reader.cpp
@@ -68,6 +68,10 @@ static bool ParseGeometry(const void* buffer, LpMetadataGeometry* geometry) {
LERROR << "Logical partition metadata has invalid slot count.";
return false;
}
+ if (geometry->metadata_max_size % LP_SECTOR_SIZE != 0) {
+ LERROR << "Metadata max size is not sector-aligned.";
+ return false;
+ }
// Check that the metadata area and logical partition areas don't overlap.
int64_t end_of_metadata =
@@ -167,7 +171,7 @@ static bool ValidateMetadataHeader(const LpMetadataHeader& header) {
// Parse and validate all metadata at the current position in the given file
// descriptor.
-static std::unique_ptr<LpMetadata> ParseMetadata(int fd) {
+std::unique_ptr<LpMetadata> ParseMetadata(int fd) {
// First read and validate the header.
std::unique_ptr<LpMetadata> metadata = std::make_unique<LpMetadata>();
if (!android::base::ReadFully(fd, &metadata->header, sizeof(metadata->header))) {
@@ -282,32 +286,6 @@ std::unique_ptr<LpMetadata> ReadMetadata(const char* block_device, uint32_t slot
return ReadMetadata(fd, slot_number);
}
-std::unique_ptr<LpMetadata> ReadFromImageFile(int fd) {
- LpMetadataGeometry geometry;
- if (!ReadLogicalPartitionGeometry(fd, &geometry)) {
- return nullptr;
- }
- if (SeekFile64(fd, LP_METADATA_GEOMETRY_SIZE, SEEK_SET) < 0) {
- PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << LP_METADATA_GEOMETRY_SIZE;
- return nullptr;
- }
- std::unique_ptr<LpMetadata> metadata = ParseMetadata(fd);
- if (!metadata) {
- return nullptr;
- }
- metadata->geometry = geometry;
- return metadata;
-}
-
-std::unique_ptr<LpMetadata> ReadFromImageFile(const char* file) {
- android::base::unique_fd fd(open(file, O_RDONLY));
- if (fd < 0) {
- PERROR << __PRETTY_FUNCTION__ << "open failed: " << file;
- return nullptr;
- }
- return ReadFromImageFile(fd);
-}
-
static std::string NameFromFixedArray(const char* name, size_t buffer_size) {
// If the end of the buffer has a null character, it's safe to assume the
// buffer is null terminated. Otherwise, we cap the string to the input
diff --git a/fs_mgr/liblp/reader.h b/fs_mgr/liblp/reader.h
index c4cac8fcb..843b2f25b 100644
--- a/fs_mgr/liblp/reader.h
+++ b/fs_mgr/liblp/reader.h
@@ -30,6 +30,7 @@ std::unique_ptr<LpMetadata> ReadMetadata(int fd, uint32_t slot_number);
// Helper functions for manually reading geometry and metadata.
bool ReadLogicalPartitionGeometry(int fd, LpMetadataGeometry* geometry);
+std::unique_ptr<LpMetadata> ParseMetadata(int fd);
// These functions assume a valid geometry and slot number.
std::unique_ptr<LpMetadata> ReadPrimaryMetadata(int fd, const LpMetadataGeometry& geometry,
@@ -37,8 +38,6 @@ std::unique_ptr<LpMetadata> ReadPrimaryMetadata(int fd, const LpMetadataGeometry
std::unique_ptr<LpMetadata> ReadBackupMetadata(int fd, const LpMetadataGeometry& geometry,
uint32_t slot_number);
-std::unique_ptr<LpMetadata> ReadFromImageFile(int fd);
-
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/utility_test.cpp b/fs_mgr/liblp/utility_test.cpp
index 2143e13de..092dbf11c 100644
--- a/fs_mgr/liblp/utility_test.cpp
+++ b/fs_mgr/liblp/utility_test.cpp
@@ -31,8 +31,16 @@ TEST(liblp, SlotNumberForSlotSuffix) {
}
TEST(liblp, GetMetadataOffset) {
- LpMetadataGeometry geometry = {
- LP_METADATA_GEOMETRY_MAGIC, sizeof(geometry), {0}, 16384, 4, 10000, 80000, 0, 0};
+ LpMetadataGeometry geometry = {LP_METADATA_GEOMETRY_MAGIC,
+ sizeof(geometry),
+ {0},
+ 16384,
+ 4,
+ 10000,
+ 80000,
+ 0,
+ 0,
+ 1024 * 1024};
EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 0), 4096);
EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 1), 4096 + 16384);
EXPECT_EQ(GetPrimaryMetadataOffset(geometry, 2), 4096 + 16384 * 2);
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index b85e4ad6c..74c03bf2f 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -30,7 +30,7 @@
namespace android {
namespace fs_mgr {
-static std::string SerializeGeometry(const LpMetadataGeometry& input) {
+std::string SerializeGeometry(const LpMetadataGeometry& input) {
LpMetadataGeometry geometry = input;
memset(geometry.checksum, 0, sizeof(geometry.checksum));
SHA256(&geometry, sizeof(geometry), geometry.checksum);
@@ -44,7 +44,7 @@ static bool CompareGeometry(const LpMetadataGeometry& g1, const LpMetadataGeomet
g1.last_logical_sector == g2.last_logical_sector;
}
-static std::string SerializeMetadata(const LpMetadata& input) {
+std::string SerializeMetadata(const LpMetadata& input) {
LpMetadata metadata = input;
LpMetadataHeader& header = metadata.header;
@@ -108,6 +108,11 @@ static bool ValidateAndSerializeMetadata(int fd, const LpMetadata& metadata, std
LERROR << "Not enough space to backup all logical partition metadata slots.";
return false;
}
+ if (blockdevice_size != metadata.geometry.block_device_size) {
+ LERROR << "Block device size " << blockdevice_size
+ << " does not match metadata requested size " << metadata.geometry.block_device_size;
+ return false;
+ }
// Make sure all partition entries reference valid extents.
for (const auto& partition : metadata.partitions) {
@@ -313,28 +318,5 @@ bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_numb
return UpdatePartitionTable(fd, metadata, slot_number, DefaultWriter);
}
-bool WriteToImageFile(int fd, const LpMetadata& input) {
- std::string geometry = SerializeGeometry(input.geometry);
- std::string padding(LP_METADATA_GEOMETRY_SIZE - geometry.size(), '\0');
- std::string metadata = SerializeMetadata(input);
-
- std::string everything = geometry + padding + metadata;
-
- if (!android::base::WriteFully(fd, everything.data(), everything.size())) {
- PERROR << __PRETTY_FUNCTION__ << "write " << everything.size() << " bytes failed";
- return false;
- }
- return true;
-}
-
-bool WriteToImageFile(const char* file, const LpMetadata& input) {
- android::base::unique_fd fd(open(file, O_CREAT | O_RDWR | O_TRUNC, 0644));
- if (fd < 0) {
- PERROR << __PRETTY_FUNCTION__ << "open failed: " << file;
- return false;
- }
- return WriteToImageFile(fd, input);
-}
-
} // namespace fs_mgr
} // namespace android
diff --git a/fs_mgr/liblp/writer.h b/fs_mgr/liblp/writer.h
index 94c1d3195..adbbebf66 100644
--- a/fs_mgr/liblp/writer.h
+++ b/fs_mgr/liblp/writer.h
@@ -25,6 +25,9 @@
namespace android {
namespace fs_mgr {
+std::string SerializeGeometry(const LpMetadataGeometry& input);
+std::string SerializeMetadata(const LpMetadata& input);
+
// These variants are for testing only. The path-based functions should be used
// for actual operation, so that open() is called with the correct flags.
bool FlashPartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number);
@@ -33,11 +36,6 @@ bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_numb
bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number,
const std::function<bool(int, const std::string&)>& writer);
-// Helper function to serialize geometry and metadata to a normal file, for
-// flashing or debugging.
-bool WriteToImageFile(const char* file, const LpMetadata& metadata);
-bool WriteToImageFile(int fd, const LpMetadata& metadata);
-
} // namespace fs_mgr
} // namespace android