Handle resume of VABC updates by emitting labels

To support resuming an update with Virtual AB Compression, we emit
labels in between operations. After writing all SOURCE_COPY, we
emit label 0. Each time we finished writing an InstallOp, we emit
a label incremented by 1. When resuming, we pass the label to CowWriter.

Test: treehugger
     1. update_device.py ota.zip
     --extra-headers="SWITCH_SLOT_ON_REBOOT=0"
     2. update_device.py ota.zip
     3. Verify that 2 did not re-start the entire update,
        only fs verification and postinstall may re-run.
Change-Id: I785cd04a35457181621ed7b8c0be9a46b6004b7b
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index ada1372..c3a321e 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -48,6 +48,7 @@
 #include "update_engine/common/prefs_interface.h"
 #include "update_engine/common/subprocess.h"
 #include "update_engine/common/terminator.h"
+#include "update_engine/common/utils.h"
 #include "update_engine/payload_consumer/bzip_extent_writer.h"
 #include "update_engine/payload_consumer/cached_file_descriptor.h"
 #include "update_engine/payload_consumer/certificate_parser_interface.h"
@@ -197,12 +198,9 @@
   if (op_result)
     return true;
 
-  size_t partition_first_op_num =
-      current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0;
   LOG(ERROR) << "Failed to perform " << op_type_name << " operation "
              << next_operation_num_ << ", which is the operation "
-             << next_operation_num_ - partition_first_op_num
-             << " in partition \""
+             << GetPartitionOperationNum() << " in partition \""
              << partitions_[current_partition_].partition_name() << "\"";
   if (*error == ErrorCode::kSuccess)
     *error = ErrorCode::kDownloadOperationExecutionError;
@@ -253,7 +251,17 @@
   // partial update.
   bool source_may_exist = manifest_.partial_update() ||
                           payload_->type == InstallPayloadType::kDelta;
-  return partition_writer_->Init(install_plan_, source_may_exist);
+  const size_t partition_operation_num = GetPartitionOperationNum();
+
+  TEST_AND_RETURN_FALSE(partition_writer_->Init(
+      install_plan_, source_may_exist, partition_operation_num));
+  CheckpointUpdateProgress(true);
+  return true;
+}
+
+size_t DeltaPerformer::GetPartitionOperationNum() {
+  return next_operation_num_ -
+         (current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0);
 }
 
 namespace {
@@ -502,12 +510,9 @@
         return false;
       }
     }
-    const size_t partition_operation_num =
-        next_operation_num_ -
-        (current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0);
 
     const InstallOperation& op =
-        partitions_[current_partition_].operations(partition_operation_num);
+        partitions_[current_partition_].operations(GetPartitionOperationNum());
 
     CopyDataToBuffer(&c_bytes, &count, op.data_length());
 
@@ -1438,6 +1443,7 @@
       TEST_AND_RETURN_FALSE(
           prefs_->SetInt64(kPrefsUpdateStateNextDataLength, 0));
     }
+    partition_writer_->CheckpointUpdateProgress(GetPartitionOperationNum());
   }
   TEST_AND_RETURN_FALSE(
       prefs_->SetInt64(kPrefsUpdateStateNextOperation, next_operation_num_));