Merge "fastboot shouldn't erase non-existent cache partitions."
This commit is contained in:
commit
9ebdf72a54
|
@ -75,41 +75,35 @@ static Action *action_last = 0;
|
|||
|
||||
|
||||
|
||||
int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...)
|
||||
{
|
||||
char cmd[CMD_SIZE] = "getvar:";
|
||||
int getvar_len = strlen(cmd);
|
||||
va_list args;
|
||||
bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) {
|
||||
std::string cmd = "getvar:";
|
||||
cmd += key;
|
||||
|
||||
response[FB_RESPONSE_SZ] = '\0';
|
||||
va_start(args, fmt);
|
||||
vsnprintf(cmd + getvar_len, sizeof(cmd) - getvar_len, fmt, args);
|
||||
va_end(args);
|
||||
cmd[CMD_SIZE - 1] = '\0';
|
||||
return fb_command_response(usb, cmd, response);
|
||||
char buf[FB_RESPONSE_SZ + 1];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (fb_command_response(usb, cmd.c_str(), buf)) {
|
||||
return false;
|
||||
}
|
||||
*value = buf;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if this partition is supported by the fastboot format command.
|
||||
* It is also used to determine if we should first erase a partition before
|
||||
* flashing it with an ext4 filesystem. See needs_erase()
|
||||
*
|
||||
* Not all devices report the filesystem type, so don't report any errors,
|
||||
* just return false.
|
||||
*/
|
||||
int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override)
|
||||
{
|
||||
char fs_type[FB_RESPONSE_SZ + 1] = {0,};
|
||||
int status;
|
||||
|
||||
// Return true if this partition is supported by the fastboot format command.
|
||||
// It is also used to determine if we should first erase a partition before
|
||||
// flashing it with an ext4 filesystem. See needs_erase()
|
||||
//
|
||||
// Not all devices report the filesystem type, so don't report any errors,
|
||||
// just return false.
|
||||
bool fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) {
|
||||
if (type_override) {
|
||||
return !!fs_get_generator(type_override);
|
||||
return fs_get_generator(type_override) != nullptr;
|
||||
}
|
||||
status = fb_getvar(usb, fs_type, "partition-type:%s", partition);
|
||||
if (status) {
|
||||
return 0;
|
||||
std::string partition_type;
|
||||
if (!fb_getvar(usb, std::string("partition-type:") + partition, &partition_type)) {
|
||||
return false;
|
||||
}
|
||||
return !!fs_get_generator(fs_type);
|
||||
return fs_get_generator(partition_type.c_str()) != nullptr;
|
||||
}
|
||||
|
||||
static int cb_default(Action* a, int status, const char* resp) {
|
||||
|
@ -394,8 +388,3 @@ int fb_execute_queue(usb_handle *usb)
|
|||
fprintf(stderr,"finished. total time: %.3fs\n", (now() - start));
|
||||
return status;
|
||||
}
|
||||
|
||||
int fb_queue_is_empty(void)
|
||||
{
|
||||
return (action_list == nullptr);
|
||||
}
|
||||
|
|
|
@ -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 @@ static struct sparse_file **load_sparse_files(int fd, int max_size)
|
|||
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 @@ static int64_t get_sparse_limit(struct usb_handle *usb, int64_t size)
|
|||
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 int64_t parse_num(const char *arg)
|
|||
}
|
||||
|
||||
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 @@ int main(int argc, char **argv)
|
|||
bool erase_first = true;
|
||||
void *data;
|
||||
int64_t sz;
|
||||
int status;
|
||||
int c;
|
||||
int longindex;
|
||||
|
||||
const struct option longopts[] = {
|
||||
|
@ -964,7 +953,7 @@ int main(int argc, char **argv)
|
|||
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 @@ int main(int argc, char **argv)
|
|||
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 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
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 @@ int main(int argc, char **argv)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
struct sparse_file;
|
||||
|
@ -47,8 +49,8 @@ char *fb_get_error(void);
|
|||
#define FB_RESPONSE_SZ 64
|
||||
|
||||
/* engine.c - high level command queue engine */
|
||||
int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...);
|
||||
int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override);
|
||||
bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value);
|
||||
bool fb_format_supported(usb_handle* usb, const char* partition, const char* type_override);
|
||||
void fb_queue_flash(const char *ptn, void *data, uint32_t sz);
|
||||
void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, uint32_t sz);
|
||||
void fb_queue_erase(const char *ptn);
|
||||
|
@ -63,7 +65,6 @@ void fb_queue_download(const char *name, void *data, uint32_t size);
|
|||
void fb_queue_notice(const char *notice);
|
||||
void fb_queue_wait_for_disconnect(void);
|
||||
int fb_execute_queue(usb_handle *usb);
|
||||
int fb_queue_is_empty(void);
|
||||
|
||||
/* util stuff */
|
||||
double now();
|
||||
|
|
Loading…
Reference in New Issue