update_engine: Added more logging and debugging for rollback checking

To help troubleshoot issues similar to http://crbug.com/356975 I added
more logging in DBus methods of update_engine to trace various stages
of determining available boot partitions, etc.

Also added two more DBus methods - to get the suggested rollback
partition name (and switched CanRollback to use this method) and
the list of availavle kernel partitions along with the 'bootable'
flag for each.

Changed update_engine_client to show the name of avaiable rollback
partition with --can_rollback and also added --show_kernels to
output list of available kernel partitions and whether each partition
is bootable or not.

BUG=None
TEST=Unit tests pass

Change-Id: Ib7f92a6460c578953ea1ba9b23bd0669acb0e22f
Reviewed-on: https://chromium-review.googlesource.com/191949
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/update_attempter.cc b/update_attempter.cc
index d5c2d98..e71d104 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -785,19 +785,28 @@
 }
 
 bool UpdateAttempter::CanRollback() const {
+  return !GetRollbackPartition().empty();
+}
+
+std::string UpdateAttempter::GetRollbackPartition() const {
   std::vector<std::string> kernel_devices =
       system_state_->hardware()->GetKernelDevices();
 
   std::string boot_kernel_device =
       system_state_->hardware()->BootKernelDevice();
 
+  LOG(INFO) << "UpdateAttempter::GetRollbackPartition";
+  for (auto&& name : kernel_devices)
+    LOG(INFO) << "  Available kernel device = " << name;
+  LOG(INFO) << "  Boot kernel device =      " << boot_kernel_device;
+
   auto current = std::find(kernel_devices.begin(), kernel_devices.end(),
                            boot_kernel_device);
 
   if(current == kernel_devices.end()) {
     LOG(ERROR) << "Unable to find the boot kernel device in the list of "
                << "available devices";
-    return false;
+    return std::string();
   }
 
   for (std::string const& device_name : kernel_devices) {
@@ -805,12 +814,35 @@
       bool bootable = false;
       if (system_state_->hardware()->IsKernelBootable(device_name, &bootable) &&
           bootable) {
-        return true;
+        return device_name;
       }
     }
   }
 
-  return false;
+  return std::string();
+}
+
+std::vector<std::pair<std::string, bool>>
+    UpdateAttempter::GetKernelDevices() const {
+  std::vector<std::string> kernel_devices =
+    system_state_->hardware()->GetKernelDevices();
+
+  std::string boot_kernel_device =
+    system_state_->hardware()->BootKernelDevice();
+
+  std::vector<std::pair<std::string, bool>> info_list;
+  info_list.reserve(kernel_devices.size());
+
+  for (std::string device_name : kernel_devices) {
+    bool bootable = false;
+    system_state_->hardware()->IsKernelBootable(device_name, &bootable);
+    // Add '*' to the name of the partition we booted from.
+    if (device_name == boot_kernel_device)
+      device_name += '*';
+    info_list.emplace_back(device_name, bootable);
+  }
+
+  return info_list;
 }
 
 void UpdateAttempter::CheckForUpdate(const string& app_version,