update_engine: Remove rootfs_mountpt from ImageConfig.

The mounted rootfs is not used anymore during opeartions generation so
this patch removes the setting from the ImageConfig. The --new_dir flag
is now deprecated because of this.

The --old_dir is still being used when no --minor_version is passed, to
autodetect the minor version of the old image.

With this patch, the rootfs and kernel partitions have a more generic
description in the config.

BUG=None
TEST=Unittest still pass.

Change-Id: I0398493a44f8c09159a93a716f2168f45e8f8df9
Reviewed-on: https://chromium-review.googlesource.com/275805
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/delta_performer_unittest.cc b/delta_performer_unittest.cc
index 381f777..3a175c4 100644
--- a/delta_performer_unittest.cc
+++ b/delta_performer_unittest.cc
@@ -519,9 +519,6 @@
                                   nullptr));
   LOG(INFO) << "delta path: " << state->delta_path;
   {
-    string a_mnt, b_mnt;
-    ScopedLoopMounter a_mounter(state->a_img, &a_mnt, MS_RDONLY);
-    ScopedLoopMounter b_mounter(state->b_img, &b_mnt, MS_RDONLY);
     const string private_key =
         signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
 
@@ -531,10 +528,9 @@
     payload_config.rootfs_partition_size = kRootFSPartitionSize;
     payload_config.minor_version = minor_version;
     if (!full_rootfs) {
-      payload_config.source.rootfs_part = state->a_img;
-      payload_config.source.rootfs_mountpt = a_mnt;
+      payload_config.source.rootfs.path = state->a_img;
       if (!full_kernel)
-        payload_config.source.kernel_part = state->old_kernel;
+        payload_config.source.kernel.path = state->old_kernel;
       payload_config.source.image_info = old_image_info;
       EXPECT_TRUE(payload_config.source.LoadImageSize());
 
@@ -542,9 +538,8 @@
       if (payload_config.chunk_size == -1)
         payload_config.chunk_size = kDefaultChunkSize;
     }
-    payload_config.target.rootfs_part = state->b_img;
-    payload_config.target.rootfs_mountpt = b_mnt;
-    payload_config.target.kernel_part = state->new_kernel;
+    payload_config.target.rootfs.path = state->b_img;
+    payload_config.target.kernel.path = state->new_kernel;
     payload_config.target.image_info = new_image_info;
     EXPECT_TRUE(payload_config.target.LoadImageSize());
 
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index 9ff78a9..34b9737 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -636,51 +636,36 @@
   return true;
 }
 
-bool DeltaDiffGenerator::InitializePartitionInfo(bool is_kernel,
-                                                 const string& partition,
+bool DeltaDiffGenerator::InitializePartitionInfo(const PartitionConfig& part,
                                                  PartitionInfo* info) {
-  int64_t size = 0;
-  if (is_kernel) {
-    size = utils::FileSize(partition);
-  } else {
-    int block_count = 0, block_size = 0;
-    TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(partition,
-                                                   &block_count,
-                                                   &block_size));
-    size = static_cast<int64_t>(block_count) * block_size;
-  }
-  TEST_AND_RETURN_FALSE(size > 0);
-  info->set_size(size);
+  info->set_size(part.size);
   OmahaHashCalculator hasher;
-  TEST_AND_RETURN_FALSE(hasher.UpdateFile(partition, size) == size);
+  TEST_AND_RETURN_FALSE(hasher.UpdateFile(part.path, part.size) ==
+                        static_cast<off_t>(part.size));
   TEST_AND_RETURN_FALSE(hasher.Finalize());
   const chromeos::Blob& hash = hasher.raw_hash();
   info->set_hash(hash.data(), hash.size());
-  LOG(INFO) << partition << ": size=" << size << " hash=" << hasher.hash();
+  LOG(INFO) << part.path << ": size=" << part.size << " hash=" << hasher.hash();
   return true;
 }
 
 bool InitializePartitionInfos(const PayloadGenerationConfig& config,
                               DeltaArchiveManifest* manifest) {
-  if (!config.source.kernel_part.empty()) {
+  if (!config.source.kernel.path.empty()) {
     TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
-        true,
-        config.source.kernel_part,
+        config.source.kernel,
         manifest->mutable_old_kernel_info()));
   }
   TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
-      true,
-      config.target.kernel_part,
+      config.target.kernel,
       manifest->mutable_new_kernel_info()));
-  if (!config.source.rootfs_part.empty()) {
+  if (!config.source.rootfs.path.empty()) {
     TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
-        false,
-        config.source.rootfs_part,
+        config.source.rootfs,
         manifest->mutable_old_rootfs_info()));
   }
   TEST_AND_RETURN_FALSE(DeltaDiffGenerator::InitializePartitionInfo(
-      false,
-      config.target.rootfs_part,
+      config.target.rootfs,
       manifest->mutable_new_rootfs_info()));
   return true;
 }
@@ -781,17 +766,17 @@
     vector<AnnotatedOperation>* rootfs_ops,
     vector<AnnotatedOperation>* kernel_ops) {
   unique_ptr<Ext2Filesystem> old_fs = Ext2Filesystem::CreateFromFile(
-      config.source.rootfs_part);
+      config.source.rootfs.path);
   unique_ptr<Ext2Filesystem> new_fs = Ext2Filesystem::CreateFromFile(
-      config.target.rootfs_part);
+      config.target.rootfs.path);
 
   off_t chunk_blocks = config.chunk_size == -1 ? -1 : (
       config.chunk_size / config.block_size);
 
   rootfs_ops->clear();
   TEST_AND_RETURN_FALSE(DeltaReadFilesystem(rootfs_ops,
-                                            config.source.rootfs_part,
-                                            config.target.rootfs_part,
+                                            config.source.rootfs.path,
+                                            config.target.rootfs.path,
                                             old_fs.get(),
                                             new_fs.get(),
                                             chunk_blocks,
@@ -802,10 +787,10 @@
 
   // Read kernel partition
   TEST_AND_RETURN_FALSE(
-      DeltaCompressKernelPartition(config.source.kernel_part,
-                                   config.target.kernel_part,
-                                   config.source.kernel_size,
-                                   config.target.kernel_size,
+      DeltaCompressKernelPartition(config.source.kernel.path,
+                                   config.target.kernel.path,
+                                   config.source.kernel.size,
+                                   config.target.kernel.size,
                                    config.block_size,
                                    kernel_ops,
                                    data_file_fd,
@@ -814,11 +799,11 @@
   LOG(INFO) << "done reading kernel";
 
   TEST_AND_RETURN_FALSE(FragmentOperations(rootfs_ops,
-                                           config.target.rootfs_part,
+                                           config.target.rootfs.path,
                                            data_file_fd,
                                            data_file_size));
   TEST_AND_RETURN_FALSE(FragmentOperations(kernel_ops,
-                                           config.target.kernel_part,
+                                           config.target.kernel.path,
                                            data_file_fd,
                                            data_file_size));
   SortOperationsByDestination(rootfs_ops);
@@ -827,12 +812,12 @@
   // specifying chunk_size on the command line works. crbug/485397.
   TEST_AND_RETURN_FALSE(MergeOperations(rootfs_ops,
                                         kDefaultChunkSize,
-                                        config.target.rootfs_part,
+                                        config.target.rootfs.path,
                                         data_file_fd,
                                         data_file_size));
   TEST_AND_RETURN_FALSE(MergeOperations(kernel_ops,
                                         kDefaultChunkSize,
-                                        config.target.kernel_part,
+                                        config.target.kernel.path,
                                         data_file_fd,
                                         data_file_size));
   return true;
@@ -844,20 +829,20 @@
     const string& private_key_path,
     uint64_t* metadata_size) {
   if (config.is_delta) {
-    LOG_IF(WARNING, config.source.rootfs_size != config.target.rootfs_size)
+    LOG_IF(WARNING, config.source.rootfs.size != config.target.rootfs.size)
         << "Old and new images have different block counts.";
     // TODO(deymo): Our tools only support growing the filesystem size during
     // an update. Remove this check when that's fixed. crbug.com/192136
-    LOG_IF(FATAL, config.source.rootfs_size > config.target.rootfs_size)
+    LOG_IF(FATAL, config.source.rootfs.size > config.target.rootfs.size)
         << "Shirking the rootfs size is not supported at the moment.";
   }
 
   // Sanity checks for the partition size.
   LOG(INFO) << "Rootfs partition size: " << config.rootfs_partition_size;
-  LOG(INFO) << "Actual filesystem size: " << config.target.rootfs_size;
+  LOG(INFO) << "Actual filesystem size: " << config.target.rootfs.size;
 
   LOG(INFO) << "Block count: "
-            << config.target.rootfs_size / config.block_size;
+            << config.target.rootfs.size / config.block_size;
 
   const string kTempFileTemplate("CrAU_temp_data.XXXXXX");
   string temp_file_path;
@@ -878,11 +863,11 @@
   if (config.is_delta) {
     // We don't efficiently support deltas on squashfs. For now, we will
     // produce full operations in that case.
-    if (utils::IsSquashfsFilesystem(config.target.rootfs_part)) {
+    if (utils::IsSquashfsFilesystem(config.target.rootfs.path)) {
       LOG(INFO) << "Using generator FullUpdateGenerator::Run for squashfs "
                    "deltas";
       strategy.reset(new FullUpdateGenerator());
-    } else if (utils::IsExtFilesystem(config.target.rootfs_part)) {
+    } else if (utils::IsExtFilesystem(config.target.rootfs.path)) {
       // Delta update (with possibly a full kernel update).
       if (config.minor_version == kInPlaceMinorPayloadVersion) {
         LOG(INFO) << "Using generator InplaceGenerator::GenerateInplaceDelta";
@@ -897,7 +882,7 @@
       }
     } else {
       LOG(ERROR) << "Unsupported filesystem for delta payload in "
-                 << config.target.rootfs_part;
+                 << config.target.rootfs.path;
       return false;
     }
   } else {
diff --git a/payload_generator/delta_diff_generator.h b/payload_generator/delta_diff_generator.h
index 1d37d5b..53a2968 100644
--- a/payload_generator/delta_diff_generator.h
+++ b/payload_generator/delta_diff_generator.h
@@ -165,8 +165,7 @@
   // of the rest of the operations.
   static void FilterNoopOperations(std::vector<AnnotatedOperation>* ops);
 
-  static bool InitializePartitionInfo(bool is_kernel,
-                                      const std::string& partition,
+  static bool InitializePartitionInfo(const PartitionConfig& partition,
                                       PartitionInfo* info);
 
   // Runs the bsdiff tool on two files and returns the resulting delta in
diff --git a/payload_generator/full_update_generator.cc b/payload_generator/full_update_generator.cc
index 3513746..b75e513 100644
--- a/payload_generator/full_update_generator.cc
+++ b/payload_generator/full_update_generator.cc
@@ -132,22 +132,20 @@
   TEST_AND_RETURN_FALSE(full_chunk_size > 0);
   TEST_AND_RETURN_FALSE(full_chunk_size % config.block_size == 0);
 
-  const ImageConfig& target = config.target;  // Shortcut.
   size_t max_threads = std::max(sysconf(_SC_NPROCESSORS_ONLN), 4L);
   LOG(INFO) << "Max threads: " << max_threads;
 
-  uint64_t part_sizes[] = { target.rootfs_size, target.kernel_size };
-  string paths[] = { target.rootfs_part, target.kernel_part };
+  PartitionConfig partitions[] = { config.target.rootfs, config.target.kernel };
 
-  for (int partition = 0; partition < 2; ++partition) {
-    const string& path = paths[partition];
-    LOG(INFO) << "compressing " << path;
-    int in_fd = open(path.c_str(), O_RDONLY, 0);
+  for (int part_id = 0; part_id < 2; ++part_id) {
+    const PartitionConfig& partition = partitions[part_id];
+    LOG(INFO) << "compressing " << partition.path;
+    int in_fd = open(partition.path.c_str(), O_RDONLY, 0);
     TEST_AND_RETURN_FALSE(in_fd >= 0);
     ScopedFdCloser in_fd_closer(&in_fd);
     deque<shared_ptr<ChunkProcessor>> threads;
     int last_progress_update = INT_MIN;
-    size_t bytes_left = part_sizes[partition], counter = 0, offset = 0;
+    size_t bytes_left = partition.size, counter = 0, offset = 0;
     while (bytes_left > 0 || !threads.empty()) {
       // Check and start new chunk processors if possible.
       while (threads.size() < max_threads && bytes_left > 0) {
@@ -167,7 +165,7 @@
       TEST_AND_RETURN_FALSE(processor->Wait());
 
       DeltaArchiveManifest_InstallOperation* op = nullptr;
-      if (partition == 0) {
+      if (part_id == 0) {
         rootfs_ops->emplace_back();
         rootfs_ops->back().name =
             base::StringPrintf("<rootfs-operation-%" PRIuS ">", counter++);
@@ -196,7 +194,7 @@
 
       int progress = static_cast<int>(
           (processor->offset() + processor->buffer_in().size()) * 100.0 /
-          part_sizes[partition]);
+          partition.size);
       if (last_progress_update < progress &&
           (last_progress_update + 10 <= progress || progress == 100)) {
         LOG(INFO) << progress << "% complete (output size: "
diff --git a/payload_generator/full_update_generator_unittest.cc b/payload_generator/full_update_generator_unittest.cc
index c69f2ee..cf8def1 100644
--- a/payload_generator/full_update_generator_unittest.cc
+++ b/payload_generator/full_update_generator_unittest.cc
@@ -39,21 +39,21 @@
 
   // Assume hashes take 2 MiB beyond the rootfs.
   config_.rootfs_partition_size = new_root.size();
-  config_.target.rootfs_size = new_root.size() - 2 * 1024 * 1024;
-  config_.target.kernel_size = new_kern.size();
+  config_.target.rootfs.size = new_root.size() - 2 * 1024 * 1024;
+  config_.target.kernel.size = new_kern.size();
 
   EXPECT_TRUE(utils::MakeTempFile("NewFullUpdateTest_R.XXXXXX",
-                                  &config_.target.rootfs_part,
+                                  &config_.target.rootfs.path,
                                   nullptr));
-  ScopedPathUnlinker rootfs_part_unlinker(config_.target.rootfs_part);
-  EXPECT_TRUE(test_utils::WriteFileVector(config_.target.rootfs_part,
+  ScopedPathUnlinker rootfs_part_unlinker(config_.target.rootfs.path);
+  EXPECT_TRUE(test_utils::WriteFileVector(config_.target.rootfs.path,
                                           new_root));
 
   EXPECT_TRUE(utils::MakeTempFile("NewFullUpdateTest_K.XXXXXX",
-                                  &config_.target.kernel_part,
+                                  &config_.target.kernel.path,
                                   nullptr));
-  ScopedPathUnlinker kernel_path_unlinker(config_.target.kernel_part);
-  EXPECT_TRUE(test_utils::WriteFileVector(config_.target.kernel_part,
+  ScopedPathUnlinker kernel_path_unlinker(config_.target.kernel.path);
+  EXPECT_TRUE(test_utils::WriteFileVector(config_.target.kernel.path,
                                           new_kern));
 
   string out_blobs_path;
@@ -76,7 +76,7 @@
                                            &rootfs_ops,
                                            &kernel_ops));
   int64_t target_rootfs_chunks =
-      config_.target.rootfs_size / config_.chunk_size;
+      config_.target.rootfs.size / config_.chunk_size;
   EXPECT_EQ(target_rootfs_chunks, rootfs_ops.size());
   EXPECT_EQ(new_kern.size() / config_.chunk_size, kernel_ops.size());
   for (off_t i = 0; i < target_rootfs_chunks; ++i) {
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index 49d8f8b..7f7b2b8 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -173,10 +173,10 @@
 
 void ApplyDelta(const string& in_file,
                 const string& old_kernel,
-                const string& old_image,
+                const string& old_rootfs,
                 const string& prefs_dir) {
   LOG(INFO) << "Applying delta.";
-  LOG_IF(FATAL, old_image.empty())
+  LOG_IF(FATAL, old_rootfs.empty())
       << "Must pass --old_image to apply delta.";
   Prefs prefs;
   InstallPlan install_plan;
@@ -186,18 +186,20 @@
   // Get original checksums
   LOG(INFO) << "Calculating original checksums";
   PartitionInfo kern_info, root_info;
-  CHECK(DeltaDiffGenerator::InitializePartitionInfo(true,  // is_kernel
-                                                    old_kernel,
+  ImageConfig old_image;
+  old_image.kernel.path = old_kernel;
+  old_image.rootfs.path = old_rootfs;
+  CHECK(old_image.LoadImageSize());
+  CHECK(DeltaDiffGenerator::InitializePartitionInfo(old_image.kernel,
                                                     &kern_info));
-  CHECK(DeltaDiffGenerator::InitializePartitionInfo(false,  // is_kernel
-                                                    old_image,
+  CHECK(DeltaDiffGenerator::InitializePartitionInfo(old_image.rootfs,
                                                     &root_info));
   install_plan.kernel_hash.assign(kern_info.hash().begin(),
                                   kern_info.hash().end());
   install_plan.rootfs_hash.assign(root_info.hash().begin(),
                                   root_info.hash().end());
   DeltaPerformer performer(&prefs, nullptr, &install_plan);
-  CHECK_EQ(performer.Open(old_image.c_str(), 0, 0), 0);
+  CHECK_EQ(performer.Open(old_rootfs.c_str(), 0, 0), 0);
   CHECK(performer.OpenKernel(old_kernel.c_str()));
   chromeos::Blob buf(1024 * 1024);
   int fd = open(in_file.c_str(), O_RDONLY, 0);
@@ -219,7 +221,8 @@
   DEFINE_string(old_dir, "",
                 "Directory where the old rootfs is loop mounted read-only");
   DEFINE_string(new_dir, "",
-                "Directory where the new rootfs is loop mounted read-only");
+                "[DEPRECATED] Directory where the new rootfs is loop mounted "
+                "read-only. Not required anymore.");
   DEFINE_string(old_image, "", "Path to the old rootfs");
   DEFINE_string(new_image, "", "Path to the new rootfs");
   DEFINE_string(old_kernel, "", "Path to the old kernel partition image");
@@ -308,6 +311,11 @@
 
   logging::InitLogging(log_settings);
 
+  // Check flags.
+  if (!FLAGS_new_dir.empty()) {
+    LOG(INFO) << "--new_dir flag is deprecated and ignored.";
+  }
+
   vector<int> signature_sizes;
   ParseSignatureSizes(FLAGS_signature_size, &signature_sizes);
 
@@ -341,13 +349,11 @@
   // A payload generation was requested. Convert the flags to a
   // PayloadGenerationConfig.
   PayloadGenerationConfig payload_config;
-  payload_config.source.rootfs_part = FLAGS_old_image;
-  payload_config.source.rootfs_mountpt = FLAGS_old_dir;
-  payload_config.source.kernel_part = FLAGS_old_kernel;
+  payload_config.source.rootfs.path = FLAGS_old_image;
+  payload_config.source.kernel.path = FLAGS_old_kernel;
 
-  payload_config.target.rootfs_part = FLAGS_new_image;
-  payload_config.target.rootfs_mountpt = FLAGS_new_dir;
-  payload_config.target.kernel_part = FLAGS_new_kernel;
+  payload_config.target.rootfs.path = FLAGS_new_image;
+  payload_config.target.kernel.path = FLAGS_new_kernel;
 
   payload_config.chunk_size = FLAGS_chunk_size;
   payload_config.block_size = kBlockSize;
diff --git a/payload_generator/inplace_generator.cc b/payload_generator/inplace_generator.cc
index 827f63b..fd19d14 100644
--- a/payload_generator/inplace_generator.cc
+++ b/payload_generator/inplace_generator.cc
@@ -708,9 +708,9 @@
     vector<AnnotatedOperation>* rootfs_ops,
     vector<AnnotatedOperation>* kernel_ops) {
   unique_ptr<Ext2Filesystem> old_fs = Ext2Filesystem::CreateFromFile(
-      config.source.rootfs_part);
+      config.source.rootfs.path);
   unique_ptr<Ext2Filesystem> new_fs = Ext2Filesystem::CreateFromFile(
-      config.target.rootfs_part);
+      config.target.rootfs.path);
 
   off_t chunk_blocks = (config.chunk_size == -1 ? -1 :
                         config.chunk_size / config.block_size);
@@ -719,8 +719,8 @@
   vector<AnnotatedOperation> aops;
   TEST_AND_RETURN_FALSE(
       DeltaDiffGenerator::DeltaReadFilesystem(&aops,
-                                              config.source.rootfs_part,
-                                              config.target.rootfs_part,
+                                              config.source.rootfs.path,
+                                              config.target.rootfs.path,
                                               old_fs.get(),
                                               new_fs.get(),
                                               chunk_blocks,
@@ -730,7 +730,7 @@
   // Convert the rootfs operations to the graph.
   Graph graph;
   CheckGraph(graph);
-  vector<Block> blocks(config.target.rootfs_size / config.block_size);
+  vector<Block> blocks(config.target.rootfs.size / config.block_size);
   for (const auto& aop : aops) {
     AddInstallOpToGraph(
         &graph, Vertex::kInvalidIndex, &blocks, aop.op, aop.name);
@@ -752,10 +752,10 @@
   // Read kernel partition
   TEST_AND_RETURN_FALSE(
       DeltaDiffGenerator::DeltaCompressKernelPartition(
-          config.source.kernel_part,
-          config.target.kernel_part,
-          config.source.kernel_size,
-          config.target.kernel_size,
+          config.source.kernel.path,
+          config.target.kernel.path,
+          config.source.kernel.size,
+          config.target.kernel.size,
           config.block_size,
           kernel_ops,
           data_file_fd,
@@ -772,7 +772,7 @@
   vector<Vertex::Index> final_order;
   TEST_AND_RETURN_FALSE(ConvertGraphToDag(
       &graph,
-      config.target.rootfs_part,
+      config.target.rootfs.path,
       data_file_fd,
       data_file_size,
       &final_order,
diff --git a/payload_generator/payload_generation_config.cc b/payload_generator/payload_generation_config.cc
index 4249b9e..3af9b4f 100644
--- a/payload_generator/payload_generation_config.cc
+++ b/payload_generator/payload_generation_config.cc
@@ -13,50 +13,40 @@
 
 namespace chromeos_update_engine {
 
-bool ImageConfig::ValidateRootfsExists() const {
-  TEST_AND_RETURN_FALSE(!rootfs_part.empty());
-  TEST_AND_RETURN_FALSE(utils::FileExists(rootfs_part.c_str()));
-  TEST_AND_RETURN_FALSE(rootfs_size > 0);
+bool PartitionConfig::ValidateExists() const {
+  TEST_AND_RETURN_FALSE(!path.empty());
+  TEST_AND_RETURN_FALSE(utils::FileExists(path.c_str()));
+  TEST_AND_RETURN_FALSE(size > 0);
   // The requested size is within the limits of the file.
-  TEST_AND_RETURN_FALSE(static_cast<off_t>(rootfs_size) <=
-                        utils::FileSize(rootfs_part.c_str()));
-  return true;
-}
-
-bool ImageConfig::ValidateKernelExists() const {
-  TEST_AND_RETURN_FALSE(!kernel_part.empty());
-  TEST_AND_RETURN_FALSE(utils::FileExists(kernel_part.c_str()));
-  TEST_AND_RETURN_FALSE(kernel_size > 0);
-  TEST_AND_RETURN_FALSE(static_cast<off_t>(kernel_size) <=
-                        utils::FileSize(kernel_part.c_str()));
+  TEST_AND_RETURN_FALSE(static_cast<off_t>(size) <=
+                        utils::FileSize(path.c_str()));
   return true;
 }
 
 bool ImageConfig::ValidateIsEmpty() const {
   TEST_AND_RETURN_FALSE(ImageInfoIsEmpty());
 
-  TEST_AND_RETURN_FALSE(rootfs_part.empty());
-  TEST_AND_RETURN_FALSE(rootfs_size == 0);
-  TEST_AND_RETURN_FALSE(rootfs_mountpt.empty());
-  TEST_AND_RETURN_FALSE(kernel_part.empty());
-  TEST_AND_RETURN_FALSE(kernel_size == 0);
+  TEST_AND_RETURN_FALSE(rootfs.path.empty());
+  TEST_AND_RETURN_FALSE(rootfs.size == 0);
+  TEST_AND_RETURN_FALSE(kernel.path.empty());
+  TEST_AND_RETURN_FALSE(kernel.size == 0);
   return true;
 }
 
 bool ImageConfig::LoadImageSize() {
-  TEST_AND_RETURN_FALSE(!rootfs_part.empty());
+  TEST_AND_RETURN_FALSE(!rootfs.path.empty());
   int rootfs_block_count, rootfs_block_size;
-  TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(rootfs_part,
+  TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(rootfs.path,
                                                  &rootfs_block_count,
                                                  &rootfs_block_size));
-  rootfs_size = static_cast<uint64_t>(rootfs_block_count) * rootfs_block_size;
-  if (!kernel_part.empty())
-    kernel_size = utils::FileSize(kernel_part);
+  rootfs.size = static_cast<uint64_t>(rootfs_block_count) * rootfs_block_size;
+  if (!kernel.path.empty())
+    kernel.size = utils::FileSize(kernel.path);
 
   // TODO(deymo): The delta generator algorithm doesn't support a block size
   // different than 4 KiB. Remove this check once that's fixed. crbug.com/455045
   if (rootfs_block_size != 4096) {
-    LOG(ERROR) << "The filesystem provided in " << rootfs_part
+    LOG(ERROR) << "The filesystem provided in " << rootfs.path
                << " has a block size of " << rootfs_block_size
                << " but delta_generator only supports 4096.";
     return false;
@@ -65,19 +55,19 @@
 }
 
 bool ImageConfig::LoadVerityRootfsSize() {
-  if (kernel_part.empty())
+  if (kernel.path.empty())
     return false;
   uint64_t verity_rootfs_size = 0;
-  if (!GetVerityRootfsSize(kernel_part, &verity_rootfs_size)) {
+  if (!GetVerityRootfsSize(kernel.path, &verity_rootfs_size)) {
     LOG(INFO) << "Couldn't find verity options in source kernel config, will "
-              << "use the rootfs filesystem size instead: " << rootfs_size;
+              << "use the rootfs filesystem size instead: " << rootfs.size;
     return false;
   }
-  if (rootfs_size != verity_rootfs_size) {
+  if (rootfs.size != verity_rootfs_size) {
     LOG(WARNING) << "Using the rootfs size found in the kernel config ("
                  << verity_rootfs_size << ") instead of the rootfs filesystem "
-                 << " size (" << rootfs_size << ").";
-    rootfs_size = verity_rootfs_size;
+                 << " size (" << rootfs.size << ").";
+    rootfs.size = verity_rootfs_size;
   }
   return true;
 }
@@ -93,22 +83,14 @@
 
 bool PayloadGenerationConfig::Validate() const {
   if (is_delta) {
-    TEST_AND_RETURN_FALSE(source.ValidateRootfsExists());
-    TEST_AND_RETURN_FALSE(source.rootfs_size % block_size == 0);
+    TEST_AND_RETURN_FALSE(source.rootfs.ValidateExists());
+    TEST_AND_RETURN_FALSE(source.rootfs.size % block_size == 0);
 
-    if (!source.kernel_part.empty()) {
-      TEST_AND_RETURN_FALSE(source.ValidateKernelExists());
-      TEST_AND_RETURN_FALSE(source.kernel_size % block_size == 0);
+    if (!source.kernel.path.empty()) {
+      TEST_AND_RETURN_FALSE(source.kernel.ValidateExists());
+      TEST_AND_RETURN_FALSE(source.kernel.size % block_size == 0);
     }
 
-    // For deltas, we also need to check that the image is mounted in order to
-    // inspect the contents.
-    TEST_AND_RETURN_FALSE(!source.rootfs_mountpt.empty());
-    TEST_AND_RETURN_FALSE(utils::IsDir(source.rootfs_mountpt.c_str()));
-
-    TEST_AND_RETURN_FALSE(!target.rootfs_mountpt.empty());
-    TEST_AND_RETURN_FALSE(utils::IsDir(target.rootfs_mountpt.c_str()));
-
     // Check for the supported minor_version values.
     TEST_AND_RETURN_FALSE(minor_version == kInPlaceMinorPayloadVersion ||
                           minor_version == kSourceMinorPayloadVersion);
@@ -124,15 +106,15 @@
   }
 
   // In all cases, the target image must exists.
-  TEST_AND_RETURN_FALSE(target.ValidateRootfsExists());
-  TEST_AND_RETURN_FALSE(target.ValidateKernelExists());
-  TEST_AND_RETURN_FALSE(target.rootfs_size % block_size == 0);
-  TEST_AND_RETURN_FALSE(target.kernel_size % block_size == 0);
+  TEST_AND_RETURN_FALSE(target.rootfs.ValidateExists());
+  TEST_AND_RETURN_FALSE(target.kernel.ValidateExists());
+  TEST_AND_RETURN_FALSE(target.rootfs.size % block_size == 0);
+  TEST_AND_RETURN_FALSE(target.kernel.size % block_size == 0);
 
   TEST_AND_RETURN_FALSE(chunk_size == -1 || chunk_size % block_size == 0);
 
   TEST_AND_RETURN_FALSE(rootfs_partition_size % block_size == 0);
-  TEST_AND_RETURN_FALSE(rootfs_partition_size >= target.rootfs_size);
+  TEST_AND_RETURN_FALSE(rootfs_partition_size >= target.rootfs.size);
 
   return true;
 }
diff --git a/payload_generator/payload_generation_config.h b/payload_generator/payload_generation_config.h
index 02bd8d4..af9afb5 100644
--- a/payload_generator/payload_generation_config.h
+++ b/payload_generator/payload_generation_config.h
@@ -14,6 +14,24 @@
 
 namespace chromeos_update_engine {
 
+struct PartitionConfig {
+  // Returns whether the PartitionConfig is not an empty image and all the
+  // fields are set correctly to a valid image file.
+  bool ValidateExists() const;
+
+  // The path to the partition file. This can be a regular file or a block
+  // device such as a loop device.
+  std::string path;
+
+  // The size of the data in |path|. If rootfs verification is used (verity)
+  // this value should match the size of the verity device for the rootfs, and
+  // the size of the whole kernel. This value could be smaller than the
+  // partition and is the size of the data update_engine assumes verified for
+  // the source image, and the size of that data it should generate for the
+  // target image.
+  uint64_t size = 0;
+};
+
 // The ImageConfig struct describes a pair of binaries kernel and rootfs and the
 // metadata associated with the image they are part of, like build number, size,
 // etc.
@@ -21,22 +39,16 @@
   // Returns whether the ImageConfig is an empty image.
   bool ValidateIsEmpty() const;
 
-  // Returns whether the ImageConfig is not an empty image and all the rootfs
-  // or kernel fields are set correctly. Source images are allowed to have an
-  // empty kernel_part meaning that the delta update ships a full kernel.
-  bool ValidateRootfsExists() const;
-  bool ValidateKernelExists() const;
-
-  // Load |rootfs_size| and |kernel_size| from the respective image files. For
-  // the kernel, the whole |kernel_part| file is assumed. For the rootfs, the
+  // Load |rootfs_size| and |kernel.size| from the respective image files. For
+  // the kernel, the whole |kernel.path| file is assumed. For the rootfs, the
   // size is detected from the filesystem.
   // Returns whether the image size was properly detected.
   bool LoadImageSize();
 
   // Load the |rootfs_size| stored in the kernel command line in the
-  // |kernel_part| when the kernel is using rootfs verification (dm-verity).
+  // |kernel.path| when the kernel is using rootfs verification (dm-verity).
   // Returns whether it loaded the size from the kernel command line. For
-  // example, it would return false if no |kernel_part| was provided or the
+  // example, it would return false if no |kernel.path| was provided or the
   // kernel doesn't have verity enabled.
   bool LoadVerityRootfsSize();
 
@@ -47,28 +59,9 @@
   // the metadata of the image.
   ImageInfo image_info;
 
-  // The path to the rootfs partition. This can be a regular file or a block
-  // device such as a loop device.
-  std::string rootfs_part;
-
-  // The size of the filesystem in rootfs_part. If rootfs verification is used
-  // (verity) this value should match the size of the verity device. This can be
-  // smaller than the partition and is the size of the data update_engine
-  // assumes verified for the source image, and the size of that data it
-  // should generate for the target image.
-  uint64_t rootfs_size = 0;
-
-  // The mount point where the rootfs_part is mounted. This is required for
-  // delta payloads that iterate the filesystem using the kernel API.
-  std::string rootfs_mountpt;
-
-  // The path to the kernel partition. This can be a regular file or a block
-  // device such as a loop device.
-  std::string kernel_part;
-
-  // The size of the verified part of the kernel partition. This is normally the
-  // whole partition.
-  uint64_t kernel_size = 0;
+  // The updated partitions.
+  PartitionConfig rootfs;
+  PartitionConfig kernel;
 };
 
 // The PayloadGenerationConfig struct encapsulates all the configuration to
@@ -103,7 +96,7 @@
   off_t chunk_size = -1;
 
   // TODO(deymo): Remove the block_size member and maybe replace it with a
-  // minimum alignment size for blocks (if needed). Algorithms shold be able to
+  // minimum alignment size for blocks (if needed). Algorithms should be able to
   // pick the block_size they want, but for now only 4 KiB is supported.
 
   // The block size used for all the operations in the manifest.