summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payload_generator/ext2_filesystem.cc36
-rw-r--r--payload_generator/ext2_filesystem.h5
-rw-r--r--payload_generator/ext2_filesystem_unittest.cc22
-rw-r--r--payload_generator/fake_filesystem.cc7
-rw-r--r--payload_generator/fake_filesystem.h8
-rw-r--r--payload_generator/filesystem_interface.h5
-rw-r--r--payload_generator/raw_filesystem.h4
-rw-r--r--sample_images/disk_ext2_1k.txt2
-rw-r--r--sample_images/disk_ext2_4k.txt2
-rw-r--r--sample_images/disk_ext2_ue_settings.txt1
-rwxr-xr-xsample_images/generate_image.sh93
-rw-r--r--update_engine.gyp1
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'],
},