Diagnose/eliminate FilesystemCopierAction unit test failure.

* Added a retry count for failed write operations: for the particular
  failure at hand (an EIO return value on the last write call), we would
  attempt to "rewrite" the buffer up to a given number of times. This
  will tell us whether the error we're getting is transient or
  persistent. This mechanism will try to reposition the output stream to
  where it last succeeded, and re-mark buffer as full. The retry count
  is zero for all instances of FilesystemCopierAction with the exception
  of the instance used in RunAsRootSimpleTest (where it's set to 3).

  Note, however, that we will keep failing to operation to ensure that
  the unit tests are failing (and logs can be inspected). If this proves
  to be a transient error that can be worked around via retry, we'll
  probably leave this mechanism in place (but will stop failing the
  action).

* Added a debug message that prints the number of bytes we're trying to
  write when we attempt to write the residual (i.e. last piece of) data.
  This is just to be sure that we're passing the correct number.

* Removed the random selection of data to be copied during
  RunAsRootSimpleTest. It is obvious by now that only the sizes that are
  not divisible by the (unknown but likely a reasonably large exponent
  of two) fragment size are failing.

BUG=chromium-os:31082
TEST=Builds and runs unit tests

Change-Id: I3367eee638333686ab24997297d868cee416ff96
Reviewed-on: https://gerrit.chromium.org/gerrit/27094
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Commit-Ready: Gilad Arnold <garnold@chromium.org>
diff --git a/filesystem_copier_action.h b/filesystem_copier_action.h
index 0658597..d2f33cf 100644
--- a/filesystem_copier_action.h
+++ b/filesystem_copier_action.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -37,8 +37,8 @@
 
 class FilesystemCopierAction : public Action<FilesystemCopierAction> {
  public:
-  FilesystemCopierAction(bool copying_kernel_install_path,
-                         bool verify_hash);
+  FilesystemCopierAction(bool copying_kernel_install_path, bool verify_hash,
+                         unsigned max_rewrite_attempts);
 
   typedef ActionTraits<FilesystemCopierAction>::InputObjectType
   InputObjectType;
@@ -139,6 +139,19 @@
   // bytes get copied.
   int64_t filesystem_size_;
 
+  // The total number of bytes successfully written to the destination stream.
+  // This is used for repositioning the stream on rewrite attempts.
+  size_t total_bytes_written_;
+
+  // Number of successive rewrite attempts for a buffer, total rewrite attempts
+  // during a copy, and the maximum number of allowed attempts.
+  unsigned num_curr_rewrite_attempts_;
+  unsigned num_total_rewrite_attempts_;
+  unsigned max_rewrite_attempts_;
+
+  // TODO(garnold) used for debugging, to be removed.
+  bool is_debug_last_read_;
+
   DISALLOW_COPY_AND_ASSIGN(FilesystemCopierAction);
 };