Don't rollback if the other partition isn't valid.

Before we start a rollback to the other OS slot, validate the GPT flags show
it as bootable. This should prevent us from attempting a rollback if an
update has been attempted and failed, or is currently in progress. Such
a rollback would always fail, since the other partition would be left in
a partially modified state.

Piggyback:
Move sanity test in hardware that was added to the wrong method.
Undid some unittest changes that were decided against after the fact.

BUG=chromium:267054
TEST=Unittests
     Manual Update Rollbacks (with/without flags on other partition)

Change-Id: Ide6b0673855ba2e4b05a0db93413a1a9f2ece2a9
Reviewed-on: https://chromium-review.googlesource.com/176755
Reviewed-by: David Zeuthen <zeuthen@chromium.org>
Commit-Queue: Don Garrett <dgarrett@chromium.org>
Tested-by: Don Garrett <dgarrett@chromium.org>
diff --git a/update_attempter.cc b/update_attempter.cc
index ea307f5..292d816 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -729,6 +729,23 @@
 
   install_plan.kernel_install_path =
       utils::KernelDeviceOfBootDevice(install_plan.install_path);
+
+  // Check to see if the kernel we want to rollback too is bootable.
+  LOG(INFO) << "Validating there is something to rollback too at: "
+            << install_plan.kernel_install_path;
+  bool rollback_bootable;
+  if (!system_state_->hardware()->IsKernelBootable(
+          install_plan.kernel_install_path,
+          &rollback_bootable)) {
+    LOG(ERROR) << "Unable to read GPT kernel flags.";
+    return false;
+  }
+
+  if (!rollback_bootable) {
+    LOG(ERROR) << "There is no valid OS to rollback too.";
+    return false;
+  }
+
   install_plan.powerwash_required = powerwash;
   if (powerwash) {
     // Enterprise-enrolled devices have an empty owner in their device policy.