diff options
-rw-r--r-- | payload_generator/ext2_filesystem.cc | 36 | ||||
-rw-r--r-- | payload_generator/ext2_filesystem.h | 5 | ||||
-rw-r--r-- | payload_generator/ext2_filesystem_unittest.cc | 22 | ||||
-rw-r--r-- | payload_generator/fake_filesystem.cc | 7 | ||||
-rw-r--r-- | payload_generator/fake_filesystem.h | 8 | ||||
-rw-r--r-- | payload_generator/filesystem_interface.h | 5 | ||||
-rw-r--r-- | payload_generator/raw_filesystem.h | 4 | ||||
-rw-r--r-- | sample_images/disk_ext2_1k.txt | 2 | ||||
-rw-r--r-- | sample_images/disk_ext2_4k.txt | 2 | ||||
-rw-r--r-- | sample_images/disk_ext2_ue_settings.txt | 1 | ||||
-rwxr-xr-x | sample_images/generate_image.sh | 93 | ||||
-rw-r--r-- | update_engine.gyp | 1 |
12 files changed, 161 insertions, 25 deletions
diff --git a/payload_generator/ext2_filesystem.cc b/payload_generator/ext2_filesystem.cc index 9670e395..b7276d5f 100644 --- a/payload_generator/ext2_filesystem.cc +++ b/payload_generator/ext2_filesystem.cc @@ -111,6 +111,7 @@ unique_ptr<Ext2Filesystem> Ext2Filesystem::CreateFromFile( 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 @@ bool Ext2Filesystem::GetFiles(vector<File>* files) const { 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 diff --git a/payload_generator/ext2_filesystem.h b/payload_generator/ext2_filesystem.h index c87849ca..66cb65f5 100644 --- a/payload_generator/ext2_filesystem.h +++ b/payload_generator/ext2_filesystem.h @@ -40,12 +40,17 @@ class Ext2Filesystem : public FilesystemInterface { // and bitmap tables. bool GetFiles(std::vector<File>* files) const override; + bool LoadSettings(chromeos::KeyValueStore* store) const override; + private: Ext2Filesystem() = default; // The ext2 main data structure holding the filesystem. ext2_filsys filsys_ = nullptr; + // The file where the filesystem is stored. + std::string filename_; + DISALLOW_COPY_AND_ASSIGN(Ext2Filesystem); }; diff --git a/payload_generator/ext2_filesystem_unittest.cc b/payload_generator/ext2_filesystem_unittest.cc index 122ba02c..d2ea2b30 100644 --- a/payload_generator/ext2_filesystem_unittest.cc +++ b/payload_generator/ext2_filesystem_unittest.cc @@ -177,4 +177,26 @@ TEST_F(Ext2FilesystemTest, ParseGeneratedImages) { } } +TEST_F(Ext2FilesystemTest, LoadSettingsFailsTest) { + base::FilePath path = test_utils::GetBuildArtifactsPath().Append( + "gen/disk_ext2_1k.img"); + unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(path.value()); + + chromeos::KeyValueStore store; + // disk_ext2_1k.img doesn't have the /etc/update_engine.conf file. + EXPECT_FALSE(fs->LoadSettings(&store)); +} + +TEST_F(Ext2FilesystemTest, LoadSettingsWorksTest) { + base::FilePath path = test_utils::GetBuildArtifactsPath().Append( + "gen/disk_ext2_ue_settings.img"); + unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(path.value()); + + chromeos::KeyValueStore store; + EXPECT_TRUE(fs->LoadSettings(&store)); + string minor_version; + EXPECT_TRUE(store.GetString("PAYLOAD_MINOR_VERSION", &minor_version)); + EXPECT_EQ("1234", minor_version); +} + } // namespace chromeos_update_engine diff --git a/payload_generator/fake_filesystem.cc b/payload_generator/fake_filesystem.cc index b474b26f..00911e12 100644 --- a/payload_generator/fake_filesystem.cc +++ b/payload_generator/fake_filesystem.cc @@ -38,4 +38,11 @@ void FakeFilesystem::AddFile(const std::string& filename, files_.push_back(file); } +bool FakeFilesystem::LoadSettings(chromeos::KeyValueStore* store) const { + if (minor_version_ < 0) + return false; + store->SetString("PAYLOAD_MINOR_VERSION", std::to_string(minor_version_)); + return true; +} + } // namespace chromeos_update_engine diff --git a/payload_generator/fake_filesystem.h b/payload_generator/fake_filesystem.h index 10b66837..35b7756f 100644 --- a/payload_generator/fake_filesystem.h +++ b/payload_generator/fake_filesystem.h @@ -26,17 +26,25 @@ class FakeFilesystem : public FilesystemInterface { size_t GetBlockSize() const override; size_t GetBlockCount() const override; bool GetFiles(std::vector<File>* files) const override; + bool LoadSettings(chromeos::KeyValueStore* store) const override; // Fake methods. // Add a file to the list of fake files. void AddFile(const std::string& filename, const std::vector<Extent> extents); + // Sets the PAYLOAD_MINOR_VERSION key stored by LoadSettings(). Use a negative + // value to produce an error in LoadSettings(). + void SetMinorVersion(int minor_version) { + minor_version_ = minor_version; + } + private: FakeFilesystem() = default; uint64_t block_size_; uint64_t block_count_; + int minor_version_{-1}; std::vector<File> files_; diff --git a/payload_generator/filesystem_interface.h b/payload_generator/filesystem_interface.h index 501a6be9..186eac43 100644 --- a/payload_generator/filesystem_interface.h +++ b/payload_generator/filesystem_interface.h @@ -20,6 +20,7 @@ #include <vector> #include <base/macros.h> +#include <chromeos/key_value_store.h> #include "update_engine/update_metadata.pb.h" @@ -66,6 +67,10 @@ class FilesystemInterface { // Returns whether the function succeeded. virtual bool GetFiles(std::vector<File>* files) const = 0; + // Load the image settings stored in the filesystem in the + // /etc/update_engine.conf file. Returns whether the settings were found. + virtual bool LoadSettings(chromeos::KeyValueStore* store) const = 0; + protected: FilesystemInterface() = default; diff --git a/payload_generator/raw_filesystem.h b/payload_generator/raw_filesystem.h index d8e1fe5f..bd664871 100644 --- a/payload_generator/raw_filesystem.h +++ b/payload_generator/raw_filesystem.h @@ -29,6 +29,10 @@ class RawFilesystem : public FilesystemInterface { // with the name passed during construction. bool GetFiles(std::vector<File>* files) const override; + bool LoadSettings(chromeos::KeyValueStore* store) const override { + return false; + } + private: RawFilesystem() = default; diff --git a/sample_images/disk_ext2_1k.txt b/sample_images/disk_ext2_1k.txt index f13c080e..1494535c 100644 --- a/sample_images/disk_ext2_1k.txt +++ b/sample_images/disk_ext2_1k.txt @@ -1 +1 @@ -16777216 1024 +default 16777216 1024 diff --git a/sample_images/disk_ext2_4k.txt b/sample_images/disk_ext2_4k.txt index d01d1054..cac718f7 100644 --- a/sample_images/disk_ext2_4k.txt +++ b/sample_images/disk_ext2_4k.txt @@ -1 +1 @@ -16777216 4096 +default 16777216 4096 diff --git a/sample_images/disk_ext2_ue_settings.txt b/sample_images/disk_ext2_ue_settings.txt new file mode 100644 index 00000000..554f7dac --- /dev/null +++ b/sample_images/disk_ext2_ue_settings.txt @@ -0,0 +1 @@ +ue_settings 16777216 4096 diff --git a/sample_images/generate_image.sh b/sample_images/generate_image.sh index 0f0c3846..c4f132a0 100755 --- a/sample_images/generate_image.sh +++ b/sample_images/generate_image.sh @@ -17,29 +17,11 @@ cleanup() { rmdir "$1" } -# generate_fs <filename> <size> [block_size] [block_groups] -generate_fs() { - local filename="$1" - local size="$2" - local block_size="${3:-4096}" - local block_groups="${4:-}" - - local mkfs_opts=( -q -F -b "${block_size}" -L "ROOT-TEST" -t ext2 ) - if [[ -n "${block_groups}" ]]; then - mkfs_opts+=( -G "${block_groups}" ) - fi - - local mntdir=$(mktemp --tmpdir -d generate_ext2.XXXXXX) - trap 'cleanup "${mntdir}"; rm -f "${filename}"' INT TERM EXIT - - # Cleanup old image. - if [[ -e "${filename}" ]]; then - rm -f "${filename}" - fi - truncate --size="${size}" "${filename}" - - mkfs.ext2 "${mkfs_opts[@]}" "${filename}" - sudo mount "${filename}" "${mntdir}" -o loop +# add_files_default <mntdir> <block_size> +# Add several test files to the image mounted in <mntdir>. +add_files_default() { + local mntdir="$1" + local block_size="$2" ### Generate the files used in unittest with descriptive names. sudo touch "${mntdir}"/empty-file @@ -93,6 +75,71 @@ generate_fs() { "empty space data but it won't be all zeros." | sudo dd of="${mntdir}"/removed conv=fsync status=none sudo rm "${mntdir}"/removed +} + +# add_files_ue_settings <mntdir> <block_size> +# Add the update_engine.conf settings file. This file contains the +add_files_ue_settings() { + local mntdir="$1" + + sudo mkdir -p "${mntdir}"/etc >/dev/null + sudo tee "${mntdir}"/etc/update_engine.conf >/dev/null <<EOF +PAYLOAD_MINOR_VERSION=1234 +EOF + # Example of a real lsb-release file released on link stable. + sudo tee "${mntdir}"/etc/lsb-release >/dev/null <<EOF +CHROMEOS_AUSERVER=https://tools.google.com/service/update2 +CHROMEOS_BOARD_APPID={F26D159B-52A3-491A-AE25-B23670A66B32} +CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1} +CHROMEOS_DEVSERVER= +CHROMEOS_RELEASE_APPID={F26D159B-52A3-491A-AE25-B23670A66B32} +CHROMEOS_RELEASE_BOARD=link-signed-mp-v4keys +CHROMEOS_RELEASE_BRANCH_NUMBER=63 +CHROMEOS_RELEASE_BUILD_NUMBER=6946 +CHROMEOS_RELEASE_BUILD_TYPE=Official Build +CHROMEOS_RELEASE_CHROME_MILESTONE=43 +CHROMEOS_RELEASE_DESCRIPTION=6946.63.0 (Official Build) stable-channel link +CHROMEOS_RELEASE_NAME=Chrome OS +CHROMEOS_RELEASE_PATCH_NUMBER=0 +CHROMEOS_RELEASE_TRACK=stable-channel +CHROMEOS_RELEASE_VERSION=6946.63.0 +GOOGLE_RELEASE=6946.63.0 +EOF +} + +# generate_fs <filename> <kind> <size> [block_size] [block_groups] +generate_fs() { + local filename="$1" + local kind="$2" + local size="$3" + local block_size="${4:-4096}" + local block_groups="${5:-}" + + local mkfs_opts=( -q -F -b "${block_size}" -L "ROOT-TEST" -t ext2 ) + if [[ -n "${block_groups}" ]]; then + mkfs_opts+=( -G "${block_groups}" ) + fi + + local mntdir=$(mktemp --tmpdir -d generate_ext2.XXXXXX) + trap 'cleanup "${mntdir}"; rm -f "${filename}"' INT TERM EXIT + + # Cleanup old image. + if [[ -e "${filename}" ]]; then + rm -f "${filename}" + fi + truncate --size="${size}" "${filename}" + + mkfs.ext2 "${mkfs_opts[@]}" "${filename}" + sudo mount "${filename}" "${mntdir}" -o loop + + case "${kind}" in + ue_settings) + add_files_ue_settings "${mntdir}" "${block_size}" + ;; + default) + add_files_default "${mntdir}" "${block_size}" + ;; + esac cleanup "${mntdir}" trap - INT TERM EXIT diff --git a/update_engine.gyp b/update_engine.gyp index 9294f661..6df8e7e5 100644 --- a/update_engine.gyp +++ b/update_engine.gyp @@ -332,6 +332,7 @@ 'sources': [ 'sample_images/disk_ext2_1k.txt', 'sample_images/disk_ext2_4k.txt', + 'sample_images/disk_ext2_ue_settings.txt', ], 'includes': ['generate_image.gypi'], }, |