summaryrefslogtreecommitdiff
path: root/bootctl
diff options
context:
space:
mode:
authorHåkan Kvist <hakan.kvist@sony.com>2020-07-02 17:27:06 +0200
committerAlessio Balsini <balsini@google.com>2020-07-15 09:54:50 +0100
commit079aaac6c5e07ef8cfd4264591bcf062ed0661d4 (patch)
tree9a96ef1087904fdd4c37859c4686024e6af0f271 /bootctl
parent3c5ea31c4dcd8b8f5d34cb97caa91692e4ca680b (diff)
downloadextras-079aaac6c5e07ef8cfd4264591bcf062ed0661d4.tar.gz
Make bootctl work on devices that does not have v1.1 API
Execute the commands with the API version where the command was introduced. This makes it possible to run the v1.0 HAL commands on a device where v1.1 HAL implementation is not available. Without this patch, on devices that only support bootcontrol v1.0 API, bootctl would just fail with error message. Bug: 160405575 Test: Execute command on device that only implements v1.0 API adb shell bootctl hal-info Change-Id: I56e9a81bcae49b6859b04394d571b5151a235675 Merged-In: I56e9a81bcae49b6859b04394d571b5151a235675 Signed-off-by: Håkan Kvist <hakan.kvist@sony.com> Signed-off-by: Alessio Balsini <balsini@google.com>
Diffstat (limited to 'bootctl')
-rw-r--r--bootctl/bootctl.cpp129
1 files changed, 78 insertions, 51 deletions
diff --git a/bootctl/bootctl.cpp b/bootctl/bootctl.cpp
index b9aae9cd..c8f8b0bc 100644
--- a/bootctl/bootctl.cpp
+++ b/bootctl/bootctl.cpp
@@ -31,7 +31,12 @@ using android::hardware::boot::V1_0::Slot;
using android::hardware::boot::V1_1::IBootControl;
using android::hardware::boot::V1_1::MergeStatus;
-static void usage(FILE* where, int /* argc */, char* argv[])
+namespace V1_0 = android::hardware::boot::V1_0;
+namespace V1_1 = android::hardware::boot::V1_1;
+
+enum BootCtlVersion { BOOTCTL_V1_0, BOOTCTL_V1_1 };
+
+static void usage(FILE* where, BootCtlVersion bootVersion, int /* argc */, char* argv[])
{
fprintf(where,
"%s - command-line wrapper for the boot HAL.\n"
@@ -48,18 +53,22 @@ static void usage(FILE* where, int /* argc */, char* argv[])
" set-slot-as-unbootable SLOT - Mark SLOT as invalid.\n"
" is-slot-bootable SLOT - Returns 0 only if SLOT is bootable.\n"
" is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n"
- " get-suffix SLOT - Prints suffix for SLOT.\n"
- " set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic\n"
- " partition is in progress. Valid STAT values\n"
- " are: none, unknown, snapshotted, merging,\n"
- " or cancelled.\n"
- " get-snapshot-merge-status - Prints the current snapshot-merge status.\n"
- "\n"
- "SLOT parameter is the zero-based slot-number.\n",
+ " get-suffix SLOT - Prints suffix for SLOT.\n",
argv[0], argv[0]);
+ if (bootVersion >= BOOTCTL_V1_1) {
+ fprintf(where,
+ " set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic\n"
+ " partition is in progress. Valid STAT values\n"
+ " are: none, unknown, snapshotted, merging,\n"
+ " or cancelled.\n"
+ " get-snapshot-merge-status - Prints the current snapshot-merge status.\n");
+ }
+ fprintf(where,
+ "\n"
+ "SLOT parameter is the zero-based slot-number.\n");
}
-static int do_hal_info(const sp<IBootControl> module) {
+static int do_hal_info(const sp<V1_0::IBootControl> module) {
module->interfaceDescriptor([&](const auto& descriptor) {
fprintf(stdout,
"HAL Version: %s\n",
@@ -68,14 +77,14 @@ static int do_hal_info(const sp<IBootControl> module) {
return EX_OK;
}
-static int do_get_number_slots(sp<IBootControl> module)
+static int do_get_number_slots(sp<V1_0::IBootControl> module)
{
uint32_t numSlots = module->getNumberSlots();
fprintf(stdout, "%u\n", numSlots);
return EX_OK;
}
-static int do_get_current_slot(sp<IBootControl> module)
+static int do_get_current_slot(sp<V1_0::IBootControl> module)
{
Slot curSlot = module->getCurrentSlot();
fprintf(stdout, "%u\n", curSlot);
@@ -99,14 +108,14 @@ static int handle_return(const Return<void> &ret, CommandResult cr, const char*
return EX_OK;
}
-static int do_mark_boot_successful(sp<IBootControl> module)
+static int do_mark_boot_successful(sp<V1_0::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,
+static int do_set_active_boot_slot(sp<V1_0::IBootControl> module,
Slot slot_number)
{
CommandResult cr;
@@ -114,7 +123,7 @@ static int do_set_active_boot_slot(sp<IBootControl> module,
return handle_return(ret, cr, "Error setting active boot slot: %s\n");
}
-static int do_set_slot_as_unbootable(sp<IBootControl> module,
+static int do_set_slot_as_unbootable(sp<V1_0::IBootControl> module,
Slot slot_number)
{
CommandResult cr;
@@ -135,13 +144,13 @@ static int handle_return(const Return<BoolResult> &ret, const char* errStr) {
return EX_SOFTWARE;
}
-static int do_is_slot_bootable(sp<IBootControl> module, Slot slot_number)
+static int do_is_slot_bootable(sp<V1_0::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,
+static int do_is_slot_marked_successful(sp<V1_0::IBootControl> module,
Slot slot_number)
{
Return<BoolResult> ret = module->isSlotMarkedSuccessful(slot_number);
@@ -157,16 +166,17 @@ std::optional<MergeStatus> stringToMergeStatus(const std::string &status) {
return {};
}
-static int do_set_snapshot_merge_status(sp<IBootControl> module, int argc, char *argv[]) {
+static int do_set_snapshot_merge_status(sp<V1_1::IBootControl> module, BootCtlVersion bootVersion,
+ int argc, char *argv[]) {
if (argc != 3) {
- usage(stderr, argc, argv);
+ usage(stderr, bootVersion, argc, argv);
exit(EX_USAGE);
return -1;
}
auto status = stringToMergeStatus(argv[2]);
if (!status.has_value()) {
- usage(stderr, argc, argv);
+ usage(stderr, bootVersion, argc, argv);
exit(EX_USAGE);
return -1;
}
@@ -194,7 +204,7 @@ std::ostream& operator<<(std::ostream& os, MergeStatus state) {
}
}
-static int do_get_snapshot_merge_status(sp<IBootControl> module) {
+static int do_get_snapshot_merge_status(sp<V1_1::IBootControl> module) {
MergeStatus ret = module->getSnapshotMergeStatus();
std::stringstream ss;
ss << ret;
@@ -202,7 +212,7 @@ static int do_get_snapshot_merge_status(sp<IBootControl> module) {
return EX_OK;
}
-static int do_get_suffix(sp<IBootControl> module, Slot slot_number) {
+static int do_get_suffix(sp<V1_0::IBootControl> module, Slot slot_number) {
std::function<void(hidl_string)> cb = [](hidl_string suffix){
fprintf(stdout, "%s\n", suffix.c_str());
};
@@ -215,17 +225,17 @@ static int do_get_suffix(sp<IBootControl> module, Slot slot_number) {
return EX_OK;
}
-static uint32_t parse_slot(int pos, int argc, char *argv[])
+static uint32_t parse_slot(BootCtlVersion bootVersion, int pos, int argc, char *argv[])
{
if (pos > argc - 1) {
- usage(stderr, argc, argv);
+ usage(stderr, bootVersion, 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);
+ usage(stderr, bootVersion, argc, argv);
exit(EX_USAGE);
return -1;
}
@@ -234,45 +244,62 @@ static uint32_t parse_slot(int pos, int argc, char *argv[])
int main(int argc, char *argv[])
{
- sp<IBootControl> module;
+ sp<V1_0::IBootControl> v1_0_module;
+ sp<V1_1::IBootControl> v1_1_module;
+ BootCtlVersion bootVersion = BOOTCTL_V1_0;
- if (argc < 2) {
- usage(stderr, argc, argv);
- return EX_USAGE;
+ v1_0_module = V1_0::IBootControl::getService();
+ if (v1_0_module == nullptr) {
+ fprintf(stderr, "Error getting bootctrl v1.0 module.\n");
+ return EX_SOFTWARE;
+ }
+ v1_1_module = V1_1::IBootControl::castFrom(v1_0_module);
+ if (v1_1_module != nullptr) {
+ bootVersion = BOOTCTL_V1_1;
}
- module = IBootControl::getService();
- if (module == NULL) {
- fprintf(stderr, "Error getting bootctrl module.\n");
- return EX_SOFTWARE;
+ if (argc < 2) {
+ usage(stderr, bootVersion, argc, argv);
+ return EX_USAGE;
}
+ // Functions present from version 1.0
if (strcmp(argv[1], "hal-info") == 0) {
- return do_hal_info(module);
+ return do_hal_info(v1_0_module);
} else if (strcmp(argv[1], "get-number-slots") == 0) {
- return do_get_number_slots(module);
+ return do_get_number_slots(v1_0_module);
} else if (strcmp(argv[1], "get-current-slot") == 0) {
- return do_get_current_slot(module);
+ return do_get_current_slot(v1_0_module);
} else if (strcmp(argv[1], "mark-boot-successful") == 0) {
- return do_mark_boot_successful(module);
+ return do_mark_boot_successful(v1_0_module);
} else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
- return do_set_active_boot_slot(module, parse_slot(2, argc, argv));
+ return do_set_active_boot_slot(v1_0_module, parse_slot(bootVersion, 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));
+ return do_set_slot_as_unbootable(v1_0_module, parse_slot(bootVersion, 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));
+ return do_is_slot_bootable(v1_0_module, parse_slot(bootVersion, 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 if (strcmp(argv[1], "set-snapshot-merge-status") == 0) {
- return do_set_snapshot_merge_status(module, argc, argv);
- } else if (strcmp(argv[1], "get-snapshot-merge-status") == 0) {
- return do_get_snapshot_merge_status(module);
- } else {
- usage(stderr, argc, argv);
- return EX_USAGE;
+ return do_is_slot_marked_successful(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+ } else if (strcmp(argv[1], "get-suffix") == 0) {
+ return do_get_suffix(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+ }
+
+ // Functions present from version 1.1
+ if (strcmp(argv[1], "set-snapshot-merge-status") == 0 ||
+ strcmp(argv[1], "get-snapshot-merge-status") == 0 ) {
+
+ if (v1_1_module == nullptr) {
+ fprintf(stderr, "Error getting bootctrl v1.1 module.\n");
+ return EX_SOFTWARE;
+ }
+ if (strcmp(argv[1], "set-snapshot-merge-status") == 0) {
+ return do_set_snapshot_merge_status(v1_1_module, bootVersion, argc, argv);
+ } else if (strcmp(argv[1], "get-snapshot-merge-status") == 0) {
+ return do_get_snapshot_merge_status(v1_1_module);
+ }
}
- return 0;
+ // Parameter not matched, print usage
+ usage(stderr, bootVersion, argc, argv);
+ return EX_USAGE;
}