AU: Handle firmware update failure when booted from FW slot B.

The firmware updater will fail if we are booted into FW slot B and we
try to update firmware. We shouldn't treat this like a usual update
failure because trying again won't help until we reboot. Thus, with
this CL, we detect this case and request a reboot from the
user. Technically this request is a lie, b/c we are reusing the reboot
request mechanism which tells the user an update has been applied and
thus must be rebooted. We accept this fib since this situation is very
rare: use would have to have 2 FW update updates in a row w/o any
extra boots between.

Also, fix error code in subprocess.

Also, remove execute permissions on a bunch of source files.

BUG=chromium-os:14343
TEST=unittests, tested updates on machine that success, fail, have FW B failure

Review URL: http://codereview.chromium.org/6880077

Change-Id: I2509c6e1c9c9da3ff1ea27da4861c4850bd4d000
diff --git a/update_attempter.cc b/update_attempter.cc
index 61c9947..1314086 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -103,6 +103,7 @@
       prefs_(prefs),
       metrics_lib_(metrics_lib),
       update_check_scheduler_(NULL),
+      fake_update_success_(false),
       http_response_code_(0),
       priority_(utils::kProcessPriorityNormal),
       manage_priority_source_(NULL),
@@ -129,6 +130,7 @@
                              const std::string& omaha_url,
                              bool obey_proxies) {
   chrome_proxy_resolver_.Init();
+  fake_update_success_ = false;
   UpdateBootFlags();  // Just in case we didn't do this yet.
   if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) {
     // Although we have applied an update, we still want to ping Omaha
@@ -314,7 +316,11 @@
   if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) {
     LOG(INFO) << "Error event sent.";
     SetStatusAndNotify(UPDATE_STATUS_IDLE);
-    return;
+    if (!fake_update_success_) {
+      return;
+    }
+    LOG(INFO) << "Booted from FW B and tried to install new firmware, "
+        "so requesting reboot from user.";
   }
 
   if (code == kActionCodeSuccess) {
@@ -326,11 +332,12 @@
 
     // Report the time it took to update the system.
     int64_t update_time = time(NULL) - last_checked_time_;
-    metrics_lib_->SendToUMA("Installer.UpdateTime",
-                            static_cast<int>(update_time),  // sample
-                            1,  // min = 1 second
-                            20 * 60,  // max = 20 minutes
-                            50);  // buckets
+    if (!fake_update_success_)
+      metrics_lib_->SendToUMA("Installer.UpdateTime",
+                              static_cast<int>(update_time),  // sample
+                              1,  // min = 1 second
+                              20 * 60,  // max = 20 minutes
+                              50);  // buckets
     return;
   }
 
@@ -511,6 +518,7 @@
   }
 
   code = GetErrorCodeForAction(action, code);
+  fake_update_success_ = code == kActionCodePostinstallBootedFromFirmwareB;
   error_event_.reset(new OmahaEvent(OmahaEvent::kTypeUpdateComplete,
                                     OmahaEvent::kResultError,
                                     code));