Merge changes I939b1e01,I8b723dda,I4acab4b5,Ibc16e93c into nyc-mr1-dev

* changes:
  Handle invalid suffix lists
  Call set_active after flashall and update
  Revert "Make fastboot flash 'B' partitions automatically."
  Revert "Fix issue where non-AB-ota devices will cause flashall to fail."
This commit is contained in:
TreeHugger Robot 2016-06-29 01:34:09 +00:00 committed by Android (Google) Code Review
commit 3fdcf8c3ab

View file

@ -99,20 +99,15 @@ struct fastboot_buffer {
}; };
static struct { static struct {
char img_name[17]; char img_name[13];
char sig_name[17]; char sig_name[13];
char item_name[17];
char part_name[9]; char part_name[9];
bool active_slot;
bool is_optional; bool is_optional;
} images[] = { } images[] = {
{"boot.img", "boot.sig", "boot", "boot", true, false}, {"boot.img", "boot.sig", "boot", false},
{"boot_other.img", "boot_other.sig", "boot_other", "boot", false, true}, {"recovery.img", "recovery.sig", "recovery", true},
{"recovery.img", "recovery.sig", "recovery", "recovery", true, true}, {"system.img", "system.sig", "system", false},
{"system.img", "system.sig", "system", "system", true, false}, {"vendor.img", "vendor.sig", "vendor", true},
{"system_other.img", "system_other.sig", "system_other", "system", false, true},
{"vendor.img", "vendor.sig", "vendor", "vendor", true, true},
{"vendor_other.img", "vendor_other.sig", "vendor_other", "vendor", false, true},
}; };
static char* find_item(const char* item, const char* product) { static char* find_item(const char* item, const char* product) {
@ -134,12 +129,6 @@ static char* find_item(const char* item, const char* product) {
fn = "cache.img"; fn = "cache.img";
} else if(!strcmp(item,"info")) { } else if(!strcmp(item,"info")) {
fn = "android-info.txt"; fn = "android-info.txt";
} else if(!strcmp(item,"system_other")) {
fn = "system_other.img";
} else if(!strcmp(item,"boot_other")) {
fn = "boot_other.img";
} else if(!strcmp(item,"vendor_other")) {
fn = "vendor_other.img";
} else { } else {
fprintf(stderr,"unknown partition '%s'\n", item); fprintf(stderr,"unknown partition '%s'\n", item);
return 0; return 0;
@ -325,8 +314,11 @@ static void usage() {
"\n" "\n"
"commands:\n" "commands:\n"
" update <filename> Reflash device from update.zip.\n" " update <filename> Reflash device from update.zip.\n"
" Sets the flashed slot as active.\n"
" flashall Flash boot, system, vendor, and --\n" " flashall Flash boot, system, vendor, and --\n"
" if found -- recovery.\n" " if found -- recovery. If the device\n"
" supports slots, the slot that has\n"
" been flashed to is set as active.\n"
" flash <partition> [ <filename> ] Write a file to a flash partition.\n" " flash <partition> [ <filename> ] Write a file to a flash partition.\n"
" flashing lock Locks the device. Prevents flashing.\n" " flashing lock Locks the device. Prevents flashing.\n"
" flashing unlock Unlocks the device. Allows flashing\n" " flashing unlock Unlocks the device. Allows flashing\n"
@ -391,10 +383,9 @@ static void usage() {
" added to all partition names that use\n" " added to all partition names that use\n"
" slots. 'all' can be given to refer\n" " slots. 'all' can be given to refer\n"
" to all slots. 'other' can be given to\n" " to all slots. 'other' can be given to\n"
" refer to a non-current slot. 'active' can\n" " refer to a non-current slot. If this\n"
" be given to refer to a current slot only.\n" " flag is not used, slotted partitions\n"
" If this flag is not given slots will be\n" " will default to the current active slot.\n"
" written to based on the filename.\n"
" -a, --set-active[=<suffix>] Sets the active slot. If no suffix is\n" " -a, --set-active[=<suffix>] Sets the active slot. If no suffix is\n"
" provided, this will default to the value\n" " provided, this will default to the value\n"
" given by --slot. If slots are not\n" " given by --slot. If slots are not\n"
@ -860,39 +851,33 @@ static void flash_buf(const char *pname, struct fastboot_buffer *buf)
} }
} }
static bool has_slots(Transport* transport) {
std::string suffix_list_unused;
return fb_getvar(transport, "slot-suffixes", &suffix_list_unused);
}
static std::vector<std::string> get_suffixes(Transport* transport) { static std::vector<std::string> get_suffixes(Transport* transport) {
std::vector<std::string> suffixes; std::vector<std::string> suffixes;
std::string suffix_list; std::string suffix_list;
if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) { if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
die("Could not get suffixes.\n"); return suffixes;
} }
return android::base::Split(suffix_list, ","); suffixes = android::base::Split(suffix_list, ",");
// Unfortunately some devices will return an error message in the
// guise of a valid value. If we only see only one suffix, it's probably
// not real.
if (suffixes.size() == 1) {
suffixes.clear();
}
return suffixes;
} }
// Returns a std::string of the slot name 'active_offset' after the active slot // Given a current slot, this returns what the 'other' slot is.
static std::string get_slot_name(Transport* transport, size_t active_offset) { static std::string get_other_slot(Transport* transport, std::string& current_slot) {
std::vector<std::string> suffixes = get_suffixes(transport); std::vector<std::string> suffixes = get_suffixes(transport);
std::string current_slot;
if (!fb_getvar(transport, "current-slot", &current_slot)) {
die("Failed to identify current slot.");
}
if (active_offset >= suffixes.size()) {
die("active slot offset larger than total number of slots!");
}
if (!suffixes.empty()) { if (!suffixes.empty()) {
for (size_t i = 0; i < suffixes.size(); i++) { for (size_t i = 0; i < suffixes.size(); i++) {
if (current_slot == suffixes[i]) if (current_slot == suffixes[i]) {
return suffixes[(i + active_offset) % suffixes.size()]; return suffixes[(i+1)%suffixes.size()];
}
} }
} else {
die("No known slots.");
} }
die("Unable to find current slot");
return ""; return "";
} }
@ -913,18 +898,28 @@ static std::string verify_slot(Transport* transport, const char *slot, bool allo
std::vector<std::string> suffixes = get_suffixes(transport); std::vector<std::string> suffixes = get_suffixes(transport);
if (strcmp(slot, "other") == 0) { if (strcmp(slot, "other") == 0) {
return get_slot_name(transport, 1); std::string current_slot;
} else if (strcmp(slot, "active") == 0) { if (!fb_getvar(transport, "current-slot", &current_slot)) {
return get_slot_name(transport, 0); die("Failed to identify current slot.");
}
std::string other = get_other_slot(transport, current_slot);
if (other == "") {
die("No known slots.");
}
return other;
} }
for (const std::string &suffix : suffixes) { for (const std::string &suffix : suffixes) {
if (suffix == slot) if (suffix == slot)
return slot; return slot;
} }
fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot); if (suffixes.empty()) {
for (const std::string &suffix : suffixes) { fprintf(stderr, "Device does not support slots.\n");
fprintf(stderr, "%s\n", suffix.c_str()); } else {
fprintf(stderr, "Slot %s does not exist. supported slots are:\n", slot);
for (const std::string &suffix : suffixes) {
fprintf(stderr, "%s\n", suffix.c_str());
}
} }
exit(1); exit(1);
} }
@ -975,6 +970,9 @@ static void do_for_partitions(Transport* transport, const char *part, const char
} }
if (has_slot == "yes") { if (has_slot == "yes") {
std::vector<std::string> suffixes = get_suffixes(transport); std::vector<std::string> suffixes = get_suffixes(transport);
if (suffixes.empty()) {
die("Error reading suffixes.\n");
}
for (std::string &suffix : suffixes) { for (std::string &suffix : suffixes) {
do_for_partition(transport, part, suffix.c_str(), func, force_slot); do_for_partition(transport, part, suffix.c_str(), func, force_slot);
} }
@ -1003,6 +1001,20 @@ static void do_update_signature(ZipArchiveHandle zip, char* fn) {
fb_queue_command("signature", "installing signature"); fb_queue_command("signature", "installing signature");
} }
// Sets slot_override as the active slot. If slot_override is blank,
// set current slot as active instead. This clears slot-unbootable.
static void set_active(Transport* transport, const char* slot_override) {
if (slot_override && slot_override[0]) {
fb_set_active(slot_override);
} else {
std::string current_slot;
if (fb_getvar(transport, "current-slot", &current_slot)) {
current_slot = verify_slot(transport, current_slot.c_str(), false);
fb_set_active(current_slot.c_str());
}
}
}
static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) { static void do_update(Transport* transport, const char* filename, const char* slot_override, bool erase_first) {
queue_info_dump(); queue_info_dump();
@ -1052,6 +1064,7 @@ static void do_update(Transport* transport, const char* filename, const char* sl
} }
CloseArchive(zip); CloseArchive(zip);
set_active(transport, slot_override);
} }
static void do_send_signature(char* fn) { static void do_send_signature(char* fn) {
@ -1072,9 +1085,6 @@ static void do_send_signature(char* fn) {
static void do_flashall(Transport* transport, const char* slot_override, int erase_first) { static void do_flashall(Transport* transport, const char* slot_override, int erase_first) {
queue_info_dump(); queue_info_dump();
const bool device_has_slots = has_slots(transport);
const bool has_slot_override = slot_override != nullptr && strcmp(slot_override, "") != 0;
const bool should_ignore_slots = !device_has_slots || has_slot_override;
fb_queue_query_save("product", cur_product, sizeof(cur_product)); fb_queue_query_save("product", cur_product, sizeof(cur_product));
@ -1088,26 +1098,13 @@ static void do_flashall(Transport* transport, const char* slot_override, int era
setup_requirements(reinterpret_cast<char*>(data), sz); setup_requirements(reinterpret_cast<char*>(data), sz);
for (size_t i = 0; i < ARRAY_SIZE(images); i++) { for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
if (should_ignore_slots && !images[i].active_slot) { fname = find_item(images[i].part_name, product);
// We will not do anything with _other files if we are given an explicit slot to use.
continue;
}
fname = find_item(images[i].item_name, product);
fastboot_buffer buf; fastboot_buffer buf;
if (load_buf(transport, fname, &buf)) { if (load_buf(transport, fname, &buf)) {
if (images[i].is_optional) if (images[i].is_optional)
continue; continue;
die("could not load %s\n", images[i].img_name); die("could not load %s\n", images[i].img_name);
} }
// Get the actual slot we are writing to based on the filename. This is because we need to
// sometimes write the 'active + 1'th slot for first boot optimization reasons. This is
// defined by the images array unless one is explicitly provided.
std::string real_slot_override;
if (should_ignore_slots) {
real_slot_override = slot_override;
} else {
real_slot_override = get_slot_name(transport, images[i].active_slot ? 0 : 1);
}
auto flashall = [&](const std::string &partition) { auto flashall = [&](const std::string &partition) {
do_send_signature(fname); do_send_signature(fname);
@ -1116,12 +1113,10 @@ static void do_flashall(Transport* transport, const char* slot_override, int era
} }
flash_buf(partition.c_str(), &buf); flash_buf(partition.c_str(), &buf);
}; };
do_for_partitions(transport, do_for_partitions(transport, images[i].part_name, slot_override, flashall, false);
images[i].part_name,
real_slot_override.c_str(),
flashall,
false);
} }
set_active(transport, slot_override);
} }
#define skip(n) do { argc -= (n); argv += (n); } while (0) #define skip(n) do { argc -= (n); argv += (n); } while (0)
@ -1456,7 +1451,12 @@ int main(int argc, char **argv)
if (wants_set_active) { if (wants_set_active) {
if (next_active == "") { if (next_active == "") {
if (slot_override == "") { if (slot_override == "") {
wants_set_active = false; std::string current_slot;
if (fb_getvar(transport, "current-slot", &current_slot)) {
next_active = verify_slot(transport, current_slot.c_str(), false);
} else {
wants_set_active = false;
}
} else { } else {
next_active = verify_slot(transport, slot_override.c_str(), false); next_active = verify_slot(transport, slot_override.c_str(), false);
} }