update_verifier: Support verifying product partition.

We have added the support for building /product partition in build
system (the CL in [1]), where /product is an optional partition that
contains system files. This CL adds the matching support if /product
needs to be verified during A/B OTA (i.e. listed in care_map file).

[1]: commit b7735d81054002961b681f4bdf296d4de2701135,
https://android-review.googlesource.com/c/platform/build/+/598454

Bug: 63974895
Test: Run update_verifier test on walleye.
Change-Id: Ia1c35e9583b8e66c98a4495b1f81a5ea7e65036f
(cherry picked from commit ec2e8c6c1ef3cbafa129ade95abca3203e062b5f)
diff --git a/tests/component/update_verifier_test.cpp b/tests/component/update_verifier_test.cpp
index b04e118..1544bb2 100644
--- a/tests/component/update_verifier_test.cpp
+++ b/tests/component/update_verifier_test.cpp
@@ -46,7 +46,6 @@
     return;
   }
 
-  // The care map file can have only two or four lines.
   TemporaryFile temp_file;
   std::string content = "system\n2,0,1";
   ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file.path));
@@ -58,7 +57,7 @@
 }
 
 TEST_F(UpdateVerifierTest, verify_image_wrong_lines) {
-  // The care map file can have only two or four lines.
+  // The care map file can have only 2 / 4 / 6 lines.
   TemporaryFile temp_file;
   ASSERT_FALSE(verify_image(temp_file.path));
 
diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp
index c5e154f..92d9313 100644
--- a/update_verifier/update_verifier.cpp
+++ b/update_verifier/update_verifier.cpp
@@ -74,14 +74,13 @@
 }
 
 static bool read_blocks(const std::string& partition, const std::string& range_str) {
-  if (partition != "system" && partition != "vendor") {
-    LOG(ERROR) << "partition name must be system or vendor: " << partition;
+  if (partition != "system" && partition != "vendor" && partition != "product") {
+    LOG(ERROR) << "Invalid partition name \"" << partition << "\"";
     return false;
   }
-  // Iterate the content of "/sys/block/dm-X/dm/name". If it matches "system"
-  // (or "vendor"), then dm-X is a dm-wrapped system/vendor partition.
-  // Afterwards, update_verifier will read every block on the care_map_file of
-  // "/dev/block/dm-X" to ensure the partition's integrity.
+  // Iterate the content of "/sys/block/dm-X/dm/name". If it matches one of "system", "vendor" or
+  // "product", then dm-X is a dm-wrapped device for that target. We will later read all the
+  // ("cared") blocks from "/dev/block/dm-X" to ensure the target partition's integrity.
   static constexpr auto DM_PATH_PREFIX = "/sys/block/";
   dirent** namelist;
   int n = scandir(DM_PATH_PREFIX, &namelist, dm_name_filter, alphasort);
@@ -206,10 +205,9 @@
     PLOG(WARNING) << "Failed to open " << care_map_name;
     return true;
   }
-  // Care map file has four lines (two lines if vendor partition is not present):
-  // First line has the block partition name (system/vendor).
-  // Second line holds all ranges of blocks to verify.
-  // The next two lines have the same format but for vendor partition.
+  // care_map file has up to six lines, where every two lines make a pair. Within each pair, the
+  // first line has the partition name (e.g. "system"), while the second line holds the ranges of
+  // all the blocks to verify.
   std::string file_content;
   if (!android::base::ReadFdToString(care_map_fd.get(), &file_content)) {
     LOG(ERROR) << "Error reading care map contents to string.";
@@ -218,9 +216,9 @@
 
   std::vector<std::string> lines;
   lines = android::base::Split(android::base::Trim(file_content), "\n");
-  if (lines.size() != 2 && lines.size() != 4) {
+  if (lines.size() != 2 && lines.size() != 4 && lines.size() != 6) {
     LOG(ERROR) << "Invalid lines in care_map: found " << lines.size()
-               << " lines, expecting 2 or 4 lines.";
+               << " lines, expecting 2 or 4 or 6 lines.";
     return false;
   }