update_engine: Expose the update_engine.conf in the FilesystemInterface.
The old image contains a /etc/update_engine.conf file that states the
payload version supported by that image. Currently we read this file
directly from the mounted filesystem and parse its contents. To stop
mounting the filesystem we need to retrieve the information on this file
somehow.
This patch extends the FilesystemInterface with a method to load the
update_engine.conf settings from the filesystem and implemets it using
ext2fs on ext2 filesystems.
CQ-DEPED=CL:282380
BUG=chromium:305832
TEST=Added new unittests with and without this file.
Change-Id: I41b41e8aac58c645fb40aabfe340cde8821e405a
Reviewed-on: https://chromium-review.googlesource.com/282381
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
diff --git a/payload_generator/ext2_filesystem.cc b/payload_generator/ext2_filesystem.cc
index 9670e39..b7276d5 100644
--- a/payload_generator/ext2_filesystem.cc
+++ b/payload_generator/ext2_filesystem.cc
@@ -111,6 +111,7 @@
if (filename.empty())
return nullptr;
unique_ptr<Ext2Filesystem> result(new Ext2Filesystem());
+ result->filename_ = filename;
errcode_t err = ext2fs_open(filename.c_str(),
0, // flags (read only)
@@ -304,4 +305,39 @@
return true;
}
+bool Ext2Filesystem::LoadSettings(chromeos::KeyValueStore* store) const {
+ // First search for the settings inode following symlinks if we find some.
+ ext2_ino_t ino_num = 0;
+ errcode_t err = ext2fs_namei_follow(
+ filsys_, EXT2_ROOT_INO /* root */, EXT2_ROOT_INO /* cwd */,
+ "/etc/update_engine.conf", &ino_num);
+ if (err != 0)
+ return false;
+
+ ext2_inode ino_data;
+ if (ext2fs_read_inode(filsys_, ino_num, &ino_data) != 0)
+ return false;
+
+ // Load the list of blocks and then the contents of the inodes.
+ vector<Extent> extents;
+ err = ext2fs_block_iterate2(filsys_, ino_num, BLOCK_FLAG_DATA_ONLY,
+ nullptr, // block_buf
+ ProcessInodeAllBlocks,
+ &extents);
+ if (err != 0)
+ return false;
+
+ chromeos::Blob blob;
+ uint64_t physical_size = BlocksInExtents(extents) * filsys_->blocksize;
+ // Sparse holes in the settings file are not supported.
+ if (EXT2_I_SIZE(&ino_data) > physical_size)
+ return false;
+ if (!utils::ReadExtents(filename_, extents, &blob, physical_size,
+ filsys_->blocksize))
+ return false;
+
+ string text(blob.begin(), blob.begin() + EXT2_I_SIZE(&ino_data));
+ return store->LoadFromString(text);
+}
+
} // namespace chromeos_update_engine