summaryrefslogtreecommitdiffstats
path: root/fastboot/fastboot.cpp
diff options
context:
space:
mode:
authorChris Fries <cfries@google.com>2017-04-12 10:25:57 -0500
committerChris Fries <cfries@google.com>2017-04-17 09:22:49 -0500
commit0ea946c007cf76a96d867ba3e96505f72639960e (patch)
treea67c7252fdc8a3c16b588ee6fc1e1155b00fb69b /fastboot/fastboot.cpp
parent6a99971096a9c5a6752f494db1d9b57d4ab77af2 (diff)
downloadcore-0ea946c007cf76a96d867ba3e96505f72639960e.tar.gz
core-0ea946c007cf76a96d867ba3e96505f72639960e.tar.bz2
core-0ea946c007cf76a96d867ba3e96505f72639960e.zip
fastboot: Support larger transfers during flash
Adding methods to queue and download flashable images by fd instead of by pointer, so that we can deal with sending large (up to 4GB) files on windows and linux. This gets past limitations on linux to read more than 2GB from a file at a time, as well as memory limitations on win32, in order to download up to 4GB in a single transfer. Test: fastboot -w Test: "flash-all" from nexus factory images site (incl. fastboot -w update) Test: fastboot flash with large and small image, large and small max-download-size Test: Sanity check flashing on win32, darwin, linux. Test: Sanity check 3GB image download (with 3GB max-download-size) on win32, darwin, linux. Bug: 36810152 Change-Id: I528d739d344eb080d59d721dadf3b3b34d4b375e
Diffstat (limited to 'fastboot/fastboot.cpp')
-rw-r--r--fastboot/fastboot.cpp33
1 files changed, 23 insertions, 10 deletions
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index cb8e5c026..3b524ac3c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -55,6 +55,7 @@
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <sparse/sparse.h>
#include <ziparchive/zip_archive.h>
@@ -67,6 +68,8 @@
#include "udp.h"
#include "usb.h"
+using android::base::unique_fd;
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -95,7 +98,7 @@ static unsigned tags_offset = 0x00000100;
static const std::string convert_fbe_marker_filename("convert_fbe");
enum fb_buffer_type {
- FB_BUFFER,
+ FB_BUFFER_FD,
FB_BUFFER_SPARSE,
};
@@ -103,6 +106,7 @@ struct fastboot_buffer {
enum fb_buffer_type type;
void* data;
int64_t sz;
+ int fd;
};
static struct {
@@ -826,10 +830,9 @@ static bool load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* bu
buf->type = FB_BUFFER_SPARSE;
buf->data = s;
} else {
- void* data = load_fd(fd, &sz);
- if (data == nullptr) return -1;
- buf->type = FB_BUFFER;
- buf->data = data;
+ buf->type = FB_BUFFER_FD;
+ buf->data = nullptr;
+ buf->fd = fd;
buf->sz = sz;
}
@@ -837,11 +840,22 @@ static bool load_buf_fd(Transport* transport, int fd, struct fastboot_buffer* bu
}
static bool load_buf(Transport* transport, const char* fname, struct fastboot_buffer* buf) {
- int fd = open(fname, O_RDONLY | O_BINARY);
+ unique_fd fd(TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_BINARY)));
+
if (fd == -1) {
return false;
}
- return load_buf_fd(transport, fd, buf);
+
+ struct stat s;
+ if (fstat(fd, &s)) {
+ return false;
+ }
+ if (!S_ISREG(s.st_mode)) {
+ errno = S_ISDIR(s.st_mode) ? EISDIR : EINVAL;
+ return false;
+ }
+
+ return load_buf_fd(transport, fd.release(), buf);
}
static void flash_buf(const char *pname, struct fastboot_buffer *buf)
@@ -864,9 +878,8 @@ static void flash_buf(const char *pname, struct fastboot_buffer *buf)
}
break;
}
-
- case FB_BUFFER:
- fb_queue_flash(pname, buf->data, buf->sz);
+ case FB_BUFFER_FD:
+ fb_queue_flash_fd(pname, buf->fd, buf->sz);
break;
default:
die("unknown buffer type: %d", buf->type);