Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

device-generic-goldfish: Commit

device/generic/goldfish


Commit MetaInfo

Revisione392ef7206d6d74b455b95f6f09d8589da69cb94 (tree)
Time2017-02-25 05:55:39
Authorbohu <bohu@goog...>
Commiterbohu

Log Message

Emulator: handle partial read and write in qemu pipe functions

When partial read or write happens, the services that depend on
qemu pipe will be flaky.

This CL checks for partial read or write, and retries the rest, unless
there is hard failure.

Change-Id: I3ebeee3f57672a8ae07236a7e53e9d0eee09f4fc

Change Summary

Incremental Difference

--- a/include/qemu_pipe.h
+++ b/include/qemu_pipe.h
@@ -30,6 +30,30 @@
3030 # define D(...) do{}while(0)
3131 #endif
3232
33+static bool ReadFully(int fd, void* data, size_t byte_count) {
34+ uint8_t* p = (uint8_t*)(data);
35+ size_t remaining = byte_count;
36+ while (remaining > 0) {
37+ ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining));
38+ if (n <= 0) return false;
39+ p += n;
40+ remaining -= n;
41+ }
42+ return true;
43+}
44+
45+static bool WriteFully(int fd, const void* data, size_t byte_count) {
46+ const uint8_t* p = (const uint8_t*)(data);
47+ size_t remaining = byte_count;
48+ while (remaining > 0) {
49+ ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining));
50+ if (n == -1) return false;
51+ p += n;
52+ remaining -= n;
53+ }
54+ return true;
55+}
56+
3357 /* Try to open a new Qemu fast-pipe. This function returns a file descriptor
3458 * that can be used to communicate with a named service managed by the
3559 * emulator.
@@ -66,9 +90,9 @@ qemu_pipe_open(const char* pipeName)
6690
6791 snprintf(buff, sizeof buff, "pipe:%s", pipeName);
6892
69- fd = open("/dev/qemu_pipe", O_RDWR);
93+ fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR));
7094 if (fd < 0 && errno == ENOENT)
71- fd = open("/dev/goldfish_pipe", O_RDWR);
95+ fd = TEMP_FAILURE_RETRY(open("/dev/goldfish_pipe", O_RDWR));
7296 if (fd < 0) {
7397 D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
7498 //errno = ENOSYS;
@@ -77,14 +101,8 @@ qemu_pipe_open(const char* pipeName)
77101
78102 buffLen = strlen(buff);
79103
80- ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1));
81- if (ret != buffLen+1) {
104+ if (!WriteFully(fd, buff, buffLen + 1)) {
82105 D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
83- if (ret == 0) {
84- errno = ECONNRESET;
85- } else if (ret > 0) {
86- errno = EINVAL;
87- }
88106 return -1;
89107 }
90108
--- a/include/qemud.h
+++ b/include/qemud.h
@@ -39,26 +39,6 @@
3939 # define D(...) ((void)0)
4040
4141 static __inline__ int
42-qemud_fd_write(int fd, const void* buff, int len)
43-{
44- int len2;
45- do {
46- len2 = write(fd, buff, len);
47- } while (len2 < 0 && errno == EINTR);
48- return len2;
49-}
50-
51-static __inline__ int
52-qemud_fd_read(int fd, void* buff, int len)
53-{
54- int len2;
55- do {
56- len2 = read(fd, buff, len);
57- } while (len2 < 0 && errno == EINTR);
58- return len2;
59-}
60-
61-static __inline__ int
6242 qemud_channel_open(const char* name)
6343 {
6444 int fd;
@@ -82,7 +62,7 @@ qemud_channel_open(const char* name)
8262 }
8363
8464 /* send service name to connect */
85- if (qemud_fd_write(fd, name, namelen) != namelen) {
65+ if (!WriteFully(fd, name, namelen)) {
8666 D("can't send service name to qemud: %s",
8767 strerror(errno));
8868 close(fd);
@@ -90,7 +70,7 @@ qemud_channel_open(const char* name)
9070 }
9171
9272 /* read answer from daemon */
93- if (qemud_fd_read(fd, answer, 2) != 2 ||
73+ if (!ReadFully(fd, answer, 2) ||
9474 answer[0] != 'O' || answer[1] != 'K') {
9575 D("cant' connect to %s service through qemud", name);
9676 close(fd);
@@ -112,12 +92,12 @@ qemud_channel_send(int fd, const void* msg, int msglen)
11292 return 0;
11393
11494 snprintf(header, sizeof header, "%04x", msglen);
115- if (qemud_fd_write(fd, header, 4) != 4) {
95+ if (!WriteFully(fd, header, 4)) {
11696 D("can't write qemud frame header: %s", strerror(errno));
11797 return -1;
11898 }
11999
120- if (qemud_fd_write(fd, msg, msglen) != msglen) {
100+ if (!WriteFully(fd, msg, msglen)) {
121101 D("can4t write qemud frame payload: %s", strerror(errno));
122102 return -1;
123103 }
@@ -130,7 +110,7 @@ qemud_channel_recv(int fd, void* msg, int msgsize)
130110 char header[5];
131111 int size, avail;
132112
133- if (qemud_fd_read(fd, header, 4) != 4) {
113+ if (!ReadFully(fd, header, 4)) {
134114 D("can't read qemud frame header: %s", strerror(errno));
135115 return -1;
136116 }
@@ -142,7 +122,7 @@ qemud_channel_recv(int fd, void* msg, int msgsize)
142122 if (size > msgsize)
143123 return -1;
144124
145- if (qemud_fd_read(fd, msg, size) != size) {
125+ if (!ReadFully(fd, msg, size)) {
146126 D("can't read qemud frame payload: %s", strerror(errno));
147127 return -1;
148128 }
Show on old repository browser