Merge "Fix "adb sync" (and "adb push") error reporting." am: d0d87f78e5

am: 59021ad415

* commit '59021ad415f10004eb7f936bc55062efc027b9b4':
  Fix "adb sync" (and "adb push") error reporting.
This commit is contained in:
Elliott Hughes 2015-12-02 19:03:12 +00:00 committed by android-build-merger
commit fa454c1faa
4 changed files with 65 additions and 62 deletions

View file

@ -33,21 +33,17 @@ static alistener listener_list = {
};
static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
asocket *s;
if(ev & FDE_READ) {
if (ev & FDE_READ) {
struct sockaddr addr;
socklen_t alen;
int fd;
socklen_t alen = sizeof(addr);
int fd = adb_socket_accept(_fd, &addr, &alen);
if (fd < 0) return;
alen = sizeof(addr);
fd = adb_socket_accept(_fd, &addr, &alen);
if(fd < 0) return;
int rcv_buf_size = CHUNK_SIZE;
adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
adb_socket_setbufsize(fd, CHUNK_SIZE);
s = create_local_socket(fd);
if(s) {
asocket* s = create_local_socket(fd);
if (s) {
connect_to_smartsocket(s);
return;
}

View file

@ -103,7 +103,7 @@ class SyncConnection {
// Sending header, payload, and footer in a single write makes a huge
// difference to "adb sync" performance.
bool SendSmallFile(const char* path_and_mode,
const char* rpath,
const char* lpath, const char* rpath,
unsigned mtime,
const char* data, size_t data_length) {
Print(rpath);
@ -139,8 +139,7 @@ class SyncConnection {
req_done->path_length = mtime;
p += sizeof(SyncRequest);
if (!WriteFdExactly(fd, &buf[0], (p - &buf[0]))) return false;
WriteOrDie(lpath, rpath, &buf[0], (p - &buf[0]));
total_bytes += data_length;
return true;
}
@ -164,31 +163,27 @@ class SyncConnection {
int lfd = adb_open(lpath, O_RDONLY);
if (lfd < 0) {
Error("cannot open '%s': %s", lpath, strerror(errno));
Error("opening '%s' locally failed: %s", lpath, strerror(errno));
return false;
}
syncsendbuf sbuf;
sbuf.id = ID_DATA;
while (true) {
int ret = adb_read(lfd, sbuf.data, max);
if (ret <= 0) {
if (ret < 0) {
Error("cannot read '%s': %s", lpath, strerror(errno));
adb_close(lfd);
return false;
}
int bytes_read = adb_read(lfd, sbuf.data, max);
if (bytes_read == -1) {
Error("reading '%s' locally failed: %s", lpath, strerror(errno));
adb_close(lfd);
return false;
} else if (bytes_read == 0) {
break;
}
sbuf.size = ret;
if (!WriteFdExactly(fd, &sbuf, sizeof(unsigned) * 2 + ret)) {
adb_close(lfd);
return false;
}
total_bytes += ret;
sbuf.size = bytes_read;
WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + bytes_read);
bytes_copied += ret;
total_bytes += bytes_read;
bytes_copied += bytes_read;
int percentage = static_cast<int>(bytes_copied * 100 / total_size);
Printf("%s: %d%%", rpath, percentage);
@ -199,12 +194,7 @@ class SyncConnection {
syncmsg msg;
msg.data.id = ID_DONE;
msg.data.size = mtime;
if (!WriteFdExactly(fd, &msg.data, sizeof(msg.data))) {
Error("failed to send ID_DONE message for '%s': %s", rpath, strerror(errno));
return false;
}
return true;
return WriteOrDie(lpath, rpath, &msg.data, sizeof(msg.data));
}
bool CopyDone(const char* from, const char* to) {
@ -297,6 +287,27 @@ class SyncConnection {
return SendRequest(ID_QUIT, ""); // TODO: add a SendResponse?
}
bool WriteOrDie(const char* from, const char* to, const void* data, size_t data_length) {
if (!WriteFdExactly(fd, data, data_length)) {
if (errno == ECONNRESET) {
// Assume adbd told us why it was closing the connection, and
// try to read failure reason from adbd.
syncmsg msg;
if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) {
Error("failed to copy '%s' to '%s': no response: %s", from, to, strerror(errno));
} else if (msg.status.id != ID_FAIL) {
Error("failed to copy '%s' to '%s': not ID_FAIL: %d", from, to, msg.status.id);
} else {
ReportCopyFailure(from, to, msg);
}
} else {
Error("%zu-byte write failed: %s", data_length, strerror(errno));
}
_exit(1);
}
return true;
}
static uint64_t CurrentTimeMs() {
struct timeval tv;
gettimeofday(&tv, 0); // (Not clock_gettime because of Mac/Windows.)
@ -362,7 +373,9 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath,
}
buf[data_length++] = '\0';
if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, mtime, buf, data_length)) return false;
if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime, buf, data_length)) {
return false;
}
return sc.CopyDone(lpath, rpath);
#endif
}
@ -383,7 +396,8 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath,
sc.Error("failed to read all of '%s': %s", lpath, strerror(errno));
return false;
}
if (!sc.SendSmallFile(path_and_mode.c_str(), rpath, mtime, data.data(), data.size())) {
if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime,
data.data(), data.size())) {
return false;
}
} else {

View file

@ -394,6 +394,18 @@ static bool handle_sync_command(int fd, std::vector<char>& buffer) {
void file_sync_service(int fd, void* cookie) {
std::vector<char> buffer(SYNC_DATA_MAX);
// If there's a problem on the device, we'll send an ID_FAIL message and
// close the socket. Unfortunately the kernel will sometimes throw that
// data away if the other end keeps writing without reading (which is
// the normal case with our protocol --- they won't read until the end).
// So set SO_LINGER to give the client 20s to get around to reading our
// failure response. Without this, the other side's ability to report
// useful errors is reduced.
struct linger l;
l.l_onoff = 1;
l.l_linger = 20;
adb_setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
while (handle_sync_command(fd, buffer)) {
}

View file

@ -242,18 +242,6 @@ extern int adb_setsockopt(int fd, int level, int optname, const void* optva
#undef setsockopt
#define setsockopt ___xxx_setsockopt
static __inline__ int adb_socket_setbufsize( int fd, int bufsize )
{
int opt = bufsize;
return adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void*)&opt, sizeof(opt));
}
static __inline__ void disable_tcp_nagle( int fd )
{
int on = 1;
adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on, sizeof(on));
}
extern int adb_socketpair( int sv[2] );
static __inline__ int adb_is_absolute_host_path(const char* path) {
@ -670,18 +658,6 @@ static __inline__ int adb_thread_setname(const std::string& name) {
#endif
}
static __inline__ int adb_socket_setbufsize(int fd, int bufsize )
{
int opt = bufsize;
return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
}
static __inline__ void disable_tcp_nagle(int fd)
{
int on = 1;
setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) );
}
static __inline__ int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen )
{
return setsockopt( fd, level, optname, optval, optlen );
@ -739,4 +715,9 @@ static __inline__ unsigned long adb_thread_id()
#endif /* !_WIN32 */
static inline void disable_tcp_nagle(int fd) {
int off = 1;
adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
}
#endif /* _ADB_SYSDEPS_H */