summaryrefslogtreecommitdiff
path: root/bootctl
diff options
context:
space:
mode:
authorConnor O'Brien <connoro@google.com>2016-10-14 15:03:12 -0700
committerConnor O'Brien <connoro@google.com>2016-11-29 18:16:06 -0800
commita4fbed759a1eecd978fe2f8d426e68cff49fec77 (patch)
tree13f4150bd5df59ec2917edd2e3379d04809d1180 /bootctl
parent89bf4d4276ebe302722d2f929d4be41b0e155e00 (diff)
downloadextras-a4fbed759a1eecd978fe2f8d426e68cff49fec77.tar.gz
Rewrite bootctl utility to use new HAL interface
Test: Ran and compared output to old version Change-Id: I8889794a5c7953b066a1a7fecd0154c912f4d60d Signed-off-by: Connor O'Brien <connoro@google.com>
Diffstat (limited to 'bootctl')
-rw-r--r--bootctl/Android.mk11
-rw-r--r--bootctl/bootctl.c212
-rw-r--r--bootctl/bootctl.cpp213
3 files changed, 220 insertions, 216 deletions
diff --git a/bootctl/Android.mk b/bootctl/Android.mk
index f0f5a067..04dbf8dd 100644
--- a/bootctl/Android.mk
+++ b/bootctl/Android.mk
@@ -3,10 +3,13 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := bootctl.c
-LOCAL_SHARED_LIBRARIES := libhardware
+LOCAL_SRC_FILES := bootctl.cpp
LOCAL_MODULE := bootctl
-LOCAL_C_INCLUDES = hardware/libhardware/include
-LOCAL_CFLAGS := -Wno-unused-parameter
+LOCAL_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libutils \
+ android.hardware.boot@1.0 \
include $(BUILD_EXECUTABLE)
diff --git a/bootctl/bootctl.c b/bootctl/bootctl.c
deleted file mode 100644
index ee8378be..00000000
--- a/bootctl/bootctl.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sysexits.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <hardware/hardware.h>
-#include <hardware/boot_control.h>
-
-static void usage(FILE* where, int argc, char* argv[])
-{
- fprintf(where,
- "%s - command-line wrapper for the boot_control HAL.\n"
- "\n"
- "Usage:\n"
- " %s COMMAND\n"
- "\n"
- "Commands:\n"
- " %s hal-info - Show info about boot_control HAL used.\n"
- " %s get-number-slots - Prints number of slots.\n"
- " %s get-current-slot - Prints currently running SLOT.\n"
- " %s mark-boot-successful - Mark current slot as GOOD.\n"
- " %s set-active-boot-slot SLOT - On next boot, load and execute SLOT.\n"
- " %s set-slot-as-unbootable SLOT - Mark SLOT as invalid.\n"
- " %s is-slot-bootable SLOT - Returns 0 only if SLOT is bootable.\n"
- " %s is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n"
- " %s get-suffix SLOT - Prints suffix for SLOT.\n"
- "\n"
- "SLOT parameter is the zero-based slot-number.\n",
- argv[0], argv[0], argv[0], argv[0], argv[0], argv[0],
- argv[0], argv[0], argv[0], argv[0], argv[0]);
-}
-
-static int do_hal_info(const hw_module_t *hw_module)
-{
- fprintf(stdout,
- "HAL name: %s\n"
- "HAL author: %s\n"
- "HAL module version: %d.%d\n",
- hw_module->name,
- hw_module->author,
- hw_module->module_api_version>>8,
- hw_module->module_api_version&0xff);
- return EX_OK;
-}
-
-static int do_get_number_slots(boot_control_module_t *module)
-{
- int num_slots = module->getNumberSlots(module);
- fprintf(stdout, "%d\n", num_slots);
- return EX_OK;
-}
-
-static int do_get_current_slot(boot_control_module_t *module)
-{
- int cur_slot = module->getCurrentSlot(module);
- fprintf(stdout, "%d\n", cur_slot);
- return EX_OK;
-}
-
-static int do_mark_boot_successful(boot_control_module_t *module)
-{
- int ret = module->markBootSuccessful(module);
- if (ret == 0)
- return EX_OK;
- fprintf(stderr, "Error marking as having booted successfully: %s\n",
- strerror(-ret));
- return EX_SOFTWARE;
-}
-
-static int do_set_active_boot_slot(boot_control_module_t *module,
- int slot_number)
-{
- int ret = module->setActiveBootSlot(module, slot_number);
- if (ret == 0)
- return EX_OK;
- fprintf(stderr, "Error setting active boot slot: %s\n", strerror(-ret));
- return EX_SOFTWARE;
-}
-
-static int do_set_slot_as_unbootable(boot_control_module_t *module,
- int slot_number)
-{
- int ret = module->setSlotAsUnbootable(module, slot_number);
- if (ret == 0)
- return EX_OK;
- fprintf(stderr, "Error setting slot as unbootable: %s\n", strerror(-ret));
- return EX_SOFTWARE;
-}
-
-
-static int do_is_slot_bootable(boot_control_module_t *module, int slot_number)
-{
- int ret = module->isSlotBootable(module, slot_number);
- if (ret == 0) {
- return EX_SOFTWARE;
- } else if (ret < 0) {
- fprintf(stderr, "Error calling isSlotBootable(): %s\n",
- strerror(-ret));
- return EX_SOFTWARE;
- }
- return EX_OK;
-}
-
-
-static int do_get_suffix(boot_control_module_t *module, int slot_number)
-{
- const char* suffix = module->getSuffix(module, slot_number);
- fprintf(stdout, "%s\n", suffix);
- return EX_OK;
-}
-
-static int do_is_slot_marked_successful(boot_control_module_t *module,
- int slot_number)
-{
- if (module->isSlotMarkedSuccessful == NULL) {
- fprintf(stderr, "isSlotMarkedSuccessful() is not implemented by HAL.\n");
- return EX_UNAVAILABLE;
- }
- int ret = module->isSlotMarkedSuccessful(module, slot_number);
- if (ret == 0) {
- return EX_SOFTWARE;
- } else if (ret < 0) {
- fprintf(stderr, "Error calling isSlotMarkedSuccessful(): %s\n",
- strerror(-ret));
- return EX_SOFTWARE;
- }
- return EX_OK;
-}
-
-static int parse_slot(int pos, int argc, char *argv[])
-{
- if (pos > argc - 1) {
- usage(stderr, argc, argv);
- exit(EX_USAGE);
- return -1;
- }
- errno = 0;
- long int ret = strtol(argv[pos], NULL, 10);
- if (errno != 0 || ret > INT_MAX || ret < 0) {
- usage(stderr, argc, argv);
- exit(EX_USAGE);
- return -1;
- }
- return (int)ret;
-}
-
-int main(int argc, char *argv[])
-{
- const hw_module_t *hw_module;
- boot_control_module_t *module;
- int ret;
-
- if (argc < 2) {
- usage(stderr, argc, argv);
- return EX_USAGE;
- }
-
- ret = hw_get_module("bootctrl", &hw_module);
- if (ret != 0) {
- fprintf(stderr, "Error getting bootctrl module.\n");
- return EX_SOFTWARE;
- }
- module = (boot_control_module_t*) hw_module;
- module->init(module);
-
- if (strcmp(argv[1], "hal-info") == 0) {
- return do_hal_info(hw_module);
- } else if (strcmp(argv[1], "get-number-slots") == 0) {
- return do_get_number_slots(module);
- } else if (strcmp(argv[1], "get-current-slot") == 0) {
- return do_get_current_slot(module);
- } else if (strcmp(argv[1], "mark-boot-successful") == 0) {
- return do_mark_boot_successful(module);
- } else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
- return do_set_active_boot_slot(module, parse_slot(2, argc, argv));
- } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) {
- return do_set_slot_as_unbootable(module, parse_slot(2, argc, argv));
- } else if (strcmp(argv[1], "is-slot-bootable") == 0) {
- return do_is_slot_bootable(module, parse_slot(2, argc, argv));
- } else if (strcmp(argv[1], "get-suffix") == 0) {
- return do_get_suffix(module, parse_slot(2, argc, argv));
- } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) {
- return do_is_slot_marked_successful(module, parse_slot(2, argc, argv));
- } else {
- usage(stderr, argc, argv);
- return EX_USAGE;
- }
-
- return 0;
-}
diff --git a/bootctl/bootctl.cpp b/bootctl/bootctl.cpp
new file mode 100644
index 00000000..12baf831
--- /dev/null
+++ b/bootctl/bootctl.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sysexits.h>
+#include <android/hardware/boot/1.0/IBootControl.h>
+
+using android::sp;
+
+using android::hardware::hidl_string;
+using android::hardware::Return;
+
+using android::hardware::boot::V1_0::BoolResult;
+using android::hardware::boot::V1_0::IBootControl;
+using android::hardware::boot::V1_0::CommandResult;
+using android::hardware::boot::V1_0::Slot;
+
+static void usage(FILE* where, int /* argc */, char* argv[])
+{
+ fprintf(where,
+ "%s - command-line wrapper for the boot HAL.\n"
+ "\n"
+ "Usage:\n"
+ " %s COMMAND\n"
+ "\n"
+ "Commands:\n"
+ " %s hal-info - Show info about boot_control HAL used.\n"
+ " %s get-number-slots - Prints number of slots.\n"
+ " %s get-current-slot - Prints currently running SLOT.\n"
+ " %s mark-boot-successful - Mark current slot as GOOD.\n"
+ " %s set-active-boot-slot SLOT - On next boot, load and execute SLOT.\n"
+ " %s set-slot-as-unbootable SLOT - Mark SLOT as invalid.\n"
+ " %s is-slot-bootable SLOT - Returns 0 only if SLOT is bootable.\n"
+ " %s is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n"
+ " %s get-suffix SLOT - Prints suffix for SLOT.\n"
+ "\n"
+ "SLOT parameter is the zero-based slot-number.\n",
+ argv[0], argv[0], argv[0], argv[0], argv[0], argv[0],
+ argv[0], argv[0], argv[0], argv[0], argv[0]);
+}
+
+static int do_hal_info(const sp<IBootControl> module) {
+ fprintf(stdout,
+ "HAL module version: %u.%u\n",
+ module->getInterfaceVersion().get_major(),
+ module->getInterfaceVersion().get_minor());
+ return EX_OK;
+}
+
+static int do_get_number_slots(sp<IBootControl> module)
+{
+ uint32_t numSlots = module->getNumberSlots();
+ fprintf(stdout, "%u\n", numSlots);
+ return EX_OK;
+}
+
+static int do_get_current_slot(sp<IBootControl> module)
+{
+ Slot curSlot = module->getCurrentSlot();
+ fprintf(stdout, "%u\n", curSlot);
+ return EX_OK;
+}
+
+static std::function<void(CommandResult)> generate_callback(CommandResult *crp) {
+ return [=](CommandResult cr){
+ *crp = cr;
+ };
+}
+
+static int handle_return(Return<void> ret, CommandResult cr, const char* errStr) {
+ if (!ret.getStatus().isOk()) {
+ fprintf(stderr, errStr, ret.getStatus().exceptionMessage().string());
+ return EX_SOFTWARE;
+ } else if (!cr.success) {
+ fprintf(stderr, errStr, cr.errMsg.c_str());
+ return EX_SOFTWARE;
+ }
+ return EX_OK;
+}
+
+static int do_mark_boot_successful(sp<IBootControl> module)
+{
+ CommandResult cr;
+ Return<void> ret = module->markBootSuccessful(generate_callback(&cr));
+ return handle_return(ret, cr, "Error marking as having booted successfully: %s\n");
+}
+
+static int do_set_active_boot_slot(sp<IBootControl> module,
+ Slot slot_number)
+{
+ CommandResult cr;
+ Return<void> ret = module->setActiveBootSlot(slot_number, generate_callback(&cr));
+ return handle_return(ret, cr, "Error setting active boot slot: %s\n");
+}
+
+static int do_set_slot_as_unbootable(sp<IBootControl> module,
+ Slot slot_number)
+{
+ CommandResult cr;
+ Return<void> ret = module->setSlotAsUnbootable(slot_number, generate_callback(&cr));
+ return handle_return(ret, cr, "Error setting slot as unbootable: %s\n");
+}
+
+static int handle_return(Return<BoolResult> ret, const char* errStr) {
+ if (!ret.getStatus().isOk()) {
+ fprintf(stderr, errStr, ret.getStatus().exceptionMessage().string());
+ return EX_SOFTWARE;
+ } else if (ret == BoolResult::INVALID_SLOT) {
+ fprintf(stderr, errStr, "Invalid slot");
+ return EX_SOFTWARE;
+ } else if (ret == BoolResult::TRUE) {
+ return EX_OK;
+ }
+ return EX_SOFTWARE;
+}
+
+static int do_is_slot_bootable(sp<IBootControl> module, Slot slot_number)
+{
+ Return<BoolResult> ret = module->isSlotBootable(slot_number);
+ return handle_return(ret, "Error calling isSlotBootable(): %s\n");
+}
+
+static int do_is_slot_marked_successful(sp<IBootControl> module,
+ Slot slot_number)
+{
+ Return<BoolResult> ret = module->isSlotMarkedSuccessful(slot_number);
+ return handle_return(ret, "Error calling isSlotMarkedSuccessful(): %s\n");
+}
+
+
+static int do_get_suffix(sp<IBootControl> module, Slot slot_number) {
+ std::function<void(hidl_string)> cb = [](hidl_string suffix){
+ fprintf(stdout, "%s\n", suffix.c_str());
+ };
+ Return<void> ret = module->getSuffix(slot_number, cb);
+ if (!ret.getStatus().isOk()) {
+ fprintf(stderr, "Error calling getSuffix(): %s\n",
+ ret.getStatus().exceptionMessage().string());
+ return EX_SOFTWARE;
+ }
+ return EX_OK;
+}
+
+static uint32_t parse_slot(int pos, int argc, char *argv[])
+{
+ if (pos > argc - 1) {
+ usage(stderr, argc, argv);
+ exit(EX_USAGE);
+ return -1;
+ }
+ errno = 0;
+ uint64_t ret = strtoul(argv[pos], NULL, 10);
+ if (errno != 0 || ret > UINT_MAX) {
+ usage(stderr, argc, argv);
+ exit(EX_USAGE);
+ return -1;
+ }
+ return (uint32_t)ret;
+}
+
+int main(int argc, char *argv[])
+{
+ sp<IBootControl> module;
+ int ret;
+
+ if (argc < 2) {
+ usage(stderr, argc, argv);
+ return EX_USAGE;
+ }
+
+ module = IBootControl::getService("bootctrl");
+ if (module == NULL) {
+ fprintf(stderr, "Error getting bootctrl module.\n");
+ return EX_SOFTWARE;
+ }
+
+ if (strcmp(argv[1], "hal-info") == 0) {
+ return do_hal_info(module);
+ } else if (strcmp(argv[1], "get-number-slots") == 0) {
+ return do_get_number_slots(module);
+ } else if (strcmp(argv[1], "get-current-slot") == 0) {
+ return do_get_current_slot(module);
+ } else if (strcmp(argv[1], "mark-boot-successful") == 0) {
+ return do_mark_boot_successful(module);
+ } else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
+ return do_set_active_boot_slot(module, parse_slot(2, argc, argv));
+ } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) {
+ return do_set_slot_as_unbootable(module, parse_slot(2, argc, argv));
+ } else if (strcmp(argv[1], "is-slot-bootable") == 0) {
+ return do_is_slot_bootable(module, parse_slot(2, argc, argv));
+ } else if (strcmp(argv[1], "get-suffix") == 0) {
+ return do_get_suffix(module, parse_slot(2, argc, argv));
+ } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) {
+ return do_is_slot_marked_successful(module, parse_slot(2, argc, argv));
+ } else {
+ usage(stderr, argc, argv);
+ return EX_USAGE;
+ }
+
+ return 0;
+}