fastboot shouldn't erase non-existent cache partitions.
Check that the cache partition exists before trying to erase it.
Also clean up some of the C string handling and int booleans.
Bug: http://b/25375777
Change-Id: I1880e542b729f2026ab3a2943d4bee9d659b1eeb
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index e2971f2..7bf4b31 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -43,6 +43,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <base/parseint.h>
#include <sparse/sparse.h>
#include <ziparchive/zip_archive.h>
@@ -567,25 +568,23 @@
return out_s;
}
-static int64_t get_target_sparse_limit(struct usb_handle *usb)
-{
- int64_t limit = 0;
- char response[FB_RESPONSE_SZ + 1];
- int status = fb_getvar(usb, response, "max-download-size");
-
- if (!status) {
- limit = strtoul(response, nullptr, 0);
- if (limit > 0) {
- fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n",
- limit);
- }
+static int64_t get_target_sparse_limit(usb_handle* usb) {
+ std::string max_download_size;
+ if (!fb_getvar(usb, "max-download-size", &max_download_size)) {
+ return 0;
}
+ uint64_t limit;
+ if (!android::base::ParseUint(max_download_size.c_str(), &limit)) {
+ return 0;
+ }
+ if (limit > 0) {
+ fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n", limit);
+ }
return limit;
}
-static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size)
-{
+static int64_t get_sparse_limit(usb_handle* usb, int64_t size) {
int64_t limit;
if (sparse_limit == 0) {
@@ -610,16 +609,11 @@
return 0;
}
-/* Until we get lazy inode table init working in make_ext4fs, we need to
- * erase partitions of type ext4 before flashing a filesystem so no stale
- * inodes are left lying around. Otherwise, e2fsck gets very upset.
- */
-static int needs_erase(usb_handle* usb, const char *part)
-{
- /* The function fb_format_supported() currently returns the value
- * we want, so just call it.
- */
- return fb_format_supported(usb, part, nullptr);
+// Until we get lazy inode table init working in make_ext4fs, we need to
+// erase partitions of type ext4 before flashing a filesystem so no stale
+// inodes are left lying around. Otherwise, e2fsck gets very upset.
+static bool needs_erase(usb_handle* usb, const char* part) {
+ return !fb_format_supported(usb, part, nullptr);
}
static int load_buf_fd(usb_handle* usb, int fd, struct fastboot_buffer* buf) {
@@ -852,87 +846,84 @@
}
static void fb_perform_format(usb_handle* usb,
- const char *partition, int skip_if_not_supported,
- const char *type_override, const char *size_override) {
- char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1];
- char *pType = pTypeBuff;
- char *pSize = pSizeBuff;
- unsigned int limit = INT_MAX;
+ const char* partition, int skip_if_not_supported,
+ const char* type_override, const char* size_override) {
+ std::string partition_type, partition_size;
+
struct fastboot_buffer buf;
- const char *errMsg = nullptr;
- const struct fs_generator *gen;
- uint64_t pSz;
- int status;
+ const char* errMsg = nullptr;
+ const struct fs_generator* gen = nullptr;
int fd;
- if (target_sparse_limit > 0 && target_sparse_limit < limit)
+ unsigned int limit = INT_MAX;
+ if (target_sparse_limit > 0 && target_sparse_limit < limit) {
limit = target_sparse_limit;
- if (sparse_limit > 0 && sparse_limit < limit)
+ }
+ if (sparse_limit > 0 && sparse_limit < limit) {
limit = sparse_limit;
+ }
- status = fb_getvar(usb, pType, "partition-type:%s", partition);
- if (status) {
+ if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) {
errMsg = "Can't determine partition type.\n";
goto failed;
}
if (type_override) {
- if (strcmp(type_override, pType)) {
- fprintf(stderr,
- "Warning: %s type is %s, but %s was requested for formating.\n",
- partition, pType, type_override);
+ if (partition_type != type_override) {
+ fprintf(stderr, "Warning: %s type is %s, but %s was requested for formatting.\n",
+ partition, partition_type.c_str(), type_override);
}
- pType = (char *)type_override;
+ partition_type = type_override;
}
- status = fb_getvar(usb, pSize, "partition-size:%s", partition);
- if (status) {
+ if (!fb_getvar(usb, std::string("partition-size:") + partition, &partition_size)) {
errMsg = "Unable to get partition size\n";
goto failed;
}
if (size_override) {
- if (strcmp(size_override, pSize)) {
- fprintf(stderr,
- "Warning: %s size is %s, but %s was requested for formating.\n",
- partition, pSize, size_override);
+ if (partition_size != size_override) {
+ fprintf(stderr, "Warning: %s size is %s, but %s was requested for formatting.\n",
+ partition, partition_size.c_str(), size_override);
}
- pSize = (char *)size_override;
+ partition_size = size_override;
}
- gen = fs_get_generator(pType);
+ gen = fs_get_generator(partition_type.c_str());
if (!gen) {
if (skip_if_not_supported) {
fprintf(stderr, "Erase successful, but not automatically formatting.\n");
- fprintf(stderr, "File system type %s not supported.\n", pType);
+ fprintf(stderr, "File system type %s not supported.\n", partition_type.c_str());
return;
}
- fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType);
+ fprintf(stderr, "Formatting is not supported for file system with type '%s'.\n",
+ partition_type.c_str());
return;
}
- pSz = strtoll(pSize, (char **)nullptr, 16);
+ int64_t size;
+ if (!android::base::ParseInt(partition_size.c_str(), &size)) {
+ fprintf(stderr, "Couldn't parse partition size '%s'.\n", partition_size.c_str());
+ return;
+ }
fd = fileno(tmpfile());
- if (fs_generator_generate(gen, fd, pSz)) {
+ if (fs_generator_generate(gen, fd, size)) {
+ fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
close(fd);
- fprintf(stderr, "Cannot generate image.\n");
return;
}
if (load_buf_fd(usb, fd, &buf)) {
- fprintf(stderr, "Cannot read image.\n");
+ fprintf(stderr, "Cannot read image: %s\n", strerror(errno));
close(fd);
return;
}
flash_buf(partition, &buf);
-
return;
-
failed:
if (skip_if_not_supported) {
fprintf(stderr, "Erase successful, but not automatically formatting.\n");
- if (errMsg)
- fprintf(stderr, "%s", errMsg);
+ if (errMsg) fprintf(stderr, "%s", errMsg);
}
fprintf(stderr,"FAILED (%s)\n", fb_get_error());
}
@@ -945,8 +936,6 @@
bool erase_first = true;
void *data;
int64_t sz;
- int status;
- int c;
int longindex;
const struct option longopts[] = {
@@ -964,7 +953,7 @@
serial = getenv("ANDROID_SERIAL");
while (1) {
- c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex);
+ int c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, &longindex);
if (c < 0) {
break;
}
@@ -1061,14 +1050,14 @@
usb_handle* usb = open_device();
while (argc > 0) {
- if(!strcmp(*argv, "getvar")) {
+ if (!strcmp(*argv, "getvar")) {
require(2);
fb_queue_display(argv[1], argv[1]);
skip(2);
} else if(!strcmp(*argv, "erase")) {
require(2);
- if (fb_format_supported(usb, argv[1], nullptr)) {
+ if (!fb_format_supported(usb, argv[1], nullptr)) {
fprintf(stderr, "******** Did you mean to fastboot format this partition?\n");
}
@@ -1217,10 +1206,16 @@
}
if (wants_wipe) {
+ fprintf(stderr, "wiping userdata...\n");
fb_queue_erase("userdata");
fb_perform_format(usb, "userdata", 1, nullptr, nullptr);
- fb_queue_erase("cache");
- fb_perform_format(usb, "cache", 1, nullptr, nullptr);
+
+ std::string cache_type;
+ if (fb_getvar(usb, "partition-type:cache", &cache_type) && !cache_type.empty()) {
+ fprintf(stderr, "wiping cache...\n");
+ fb_queue_erase("cache");
+ fb_perform_format(usb, "cache", 1, nullptr, nullptr);
+ }
}
if (wants_reboot) {
fb_queue_reboot();
@@ -1230,9 +1225,5 @@
fb_queue_wait_for_disconnect();
}
- if (fb_queue_is_empty())
- return 0;
-
- status = fb_execute_queue(usb);
- return (status) ? 1 : 0;
+ return fb_execute_queue(usb) ? EXIT_FAILURE : EXIT_SUCCESS;
}