Use O_TRUNC + fd->Truncate() instead of dd
Originally CreateBlankImage was used for simple/small partition images
which needed to be reliably zeroed, so performance didn't really matter.
Now we will be using this utility function for larger, multi-GB
partitions, so let's make this code more efficient.
By opening the file with O_CREAT | O_TRUNC we can be sure that even
existing files will be truncated to zero length, and then using
fd->Truncate() they will be implicitly zeroed to the desired size. This
is more efficient as most filesystems don't need to write data blocks
for freelists.
Bug: 156286088
Change-Id: Ief47f2a085222a2f6a9c95b97a06ec2521e6e6f4
Merged-In: Ief47f2a085222a2f6a9c95b97a06ec2521e6e6f4
diff --git a/host/commands/assemble_cvd/data_image.cc b/host/commands/assemble_cvd/data_image.cc
index 701eb67..a19d7dc 100644
--- a/host/commands/assemble_cvd/data_image.cc
+++ b/host/commands/assemble_cvd/data_image.cc
@@ -63,20 +63,24 @@
} // namespace
void CreateBlankImage(
- const std::string& image, int block_count, const std::string& image_fmt,
- const std::string& block_size) {
+ const std::string& image, int num_mb, const std::string& image_fmt) {
LOG(INFO) << "Creating " << image;
- std::string of = "of=";
- of += image;
- std::string count = "count=";
- count += std::to_string(block_count);
- std::string bs = "bs=" + block_size;
- cvd::execute({"/bin/dd", "if=/dev/zero", of, bs, count});
+ off_t image_size_bytes = static_cast<off_t>(num_mb) << 20;
+ auto fd = cvd::SharedFD::Open(image, O_CREAT | O_TRUNC | O_RDWR, 0666);
+ if (fd->Truncate(image_size_bytes) != 0) {
+ LOG(ERROR) << "`truncate --size=" << num_mb << "M " << image
+ << "` failed:" << fd->StrError();
+ return;
+ }
+ fd->Close();
if (image_fmt == "ext4") {
cvd::execute({"/sbin/mkfs.ext4", image});
- } else if (image_fmt != "none") {
+ } else if (image_fmt == "f2fs") {
auto make_f2fs_path = vsoc::DefaultHostArtifactsPath("bin/make_f2fs");
cvd::execute({make_f2fs_path, "-t", image_fmt, image, "-g", "android"});
+ } else if (image_fmt != "none") {
+ LOG(WARNING) << "Unknown image format '" << image_fmt
+ << "' for " << image << ", treating as 'none'.";
}
}
diff --git a/host/commands/assemble_cvd/data_image.h b/host/commands/assemble_cvd/data_image.h
index 9d29141..4c4022f 100644
--- a/host/commands/assemble_cvd/data_image.h
+++ b/host/commands/assemble_cvd/data_image.h
@@ -8,5 +8,4 @@
const std::string& path);
bool InitializeMiscImage(const std::string& misc_image);
void CreateBlankImage(
- const std::string& image, int block_count, const std::string& image_fmt,
- const std::string& block_size = "1M");
+ const std::string& image, int num_mb, const std::string& image_fmt);
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index b67c360..ee5543a 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -871,7 +871,7 @@
for (const auto& instance : config->Instances()) {
if (!cvd::FileExists(instance.access_kregistry_path())) {
- CreateBlankImage(instance.access_kregistry_path(), 2, "none", "1M");
+ CreateBlankImage(instance.access_kregistry_path(), 2 /* mb */, "none");
}
}
@@ -897,7 +897,7 @@
<< "newer than its underlying composite disk. Wiping the overlay.";
}
CreateQcowOverlay(config->crosvm_binary(), config->composite_disk_path(), overlay_path);
- CreateBlankImage(instance.access_kregistry_path(), 2, "none", "1M");
+ CreateBlankImage(instance.access_kregistry_path(), 2 /* mb */, "none");
}
}