Browse Source

[LibOS] Allow zero size read/write on pipes/sockets/eventfds

Previously, zero size read/write on PAL streams of pipes/sockets/eventfds was
avoided due to PAL_ERROR_ZEROSIZE. But now PAL allows this, so allow LibOS to
issue zero size reads/writes.
Isaku Yamahata 4 years ago
parent
commit
93eb9bc595

+ 5 - 5
LibOS/shim/src/fs/chroot/fs.c

@@ -741,7 +741,7 @@ static ssize_t map_write (struct shim_handle * hdl, const void * buf, size_t cou
 
         PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void *) buf, NULL);
 
-        if (!pal_ret) {
+        if (pal_ret == PAL_STREAM_ERROR) {
             ret = -PAL_ERRNO;
             goto out;
         }
@@ -819,7 +819,7 @@ static ssize_t chroot_read (struct shim_handle * hdl, void * buf, size_t count)
     }
 
     PAL_NUM pal_ret = DkStreamRead(hdl->pal_handle, file->marker, count, buf, NULL, 0);
-    if (pal_ret > 0) {
+    if (pal_ret != PAL_STREAM_ERROR) {
         if (__builtin_add_overflow(pal_ret, 0, &ret))
             BUG();
         if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker))
@@ -869,7 +869,7 @@ static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t
     }
 
     PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void *) buf, NULL);
-    if (pal_ret > 0) {
+    if (pal_ret != PAL_STREAM_ERROR) {
         if (__builtin_add_overflow(pal_ret, 0, &ret))
             BUG();
         if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker))
@@ -1032,8 +1032,8 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent)
 
     while (1) {
         /* DkStreamRead for directory will return as many entries as fits into the buffer. */
-        size_t bytes = DkStreamRead(pal_hdl, 0, buf_size, buf, NULL, 0);
-        if (!bytes) {
+        PAL_NUM bytes = DkStreamRead(pal_hdl, 0, buf_size, buf, NULL, 0);
+        if (bytes == PAL_STREAM_ERROR) {
             if (PAL_NATIVE_ERRNO == PAL_ERROR_ENDOFSTREAM) {
                 /* End of directory listing */
                 ret = 0;

+ 2 - 12
LibOS/shim/src/fs/eventfd/fs.c

@@ -31,36 +31,26 @@
 #include <shim_fs.h>
 
 static ssize_t eventfd_read(struct shim_handle* hdl, void* buf, size_t count) {
-    if (!count)
-        return 0;
-
     if (count < sizeof(uint64_t))
         return -EINVAL;
 
     PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
 
-    if (bytes <= 0)
+    if (bytes == PAL_STREAM_ERROR)
         return -PAL_ERRNO;
 
-    assert((ssize_t ) bytes == sizeof(uint64_t));
-
     return (ssize_t) bytes;
 }
 
 static ssize_t eventfd_write(struct shim_handle* hdl, const void* buf, size_t count) {
-    if (!count)
-        return 0;
-
     if (count < sizeof(uint64_t))
         return -EINVAL;
 
     PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void *) buf, NULL);
 
-    if (bytes <= 0)
+    if (bytes == PAL_STREAM_ERROR)
         return -PAL_ERRNO;
 
-    assert((ssize_t ) bytes == sizeof(uint64_t));
-
     return (ssize_t) bytes;
 }
 

+ 2 - 10
LibOS/shim/src/fs/pipe/fs.c

@@ -40,28 +40,20 @@
 #include <linux/stat.h>
 
 static ssize_t pipe_read(struct shim_handle* hdl, void* buf, size_t count) {
-    if (!count)
-        return 0;
-
     PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
 
-    if (!bytes)
+    if (bytes == PAL_STREAM_ERROR)
         return -PAL_ERRNO;
 
-    assert((ssize_t)bytes > 0);
     return (ssize_t)bytes;
 }
 
 static ssize_t pipe_write(struct shim_handle* hdl, const void* buf, size_t count) {
-    if (!count)
-        return 0;
-
     PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL);
 
-    if (!bytes)
+    if (bytes == PAL_STREAM_ERROR)
         return -PAL_ERRNO;
 
-    assert((ssize_t)bytes > 0);
     return (ssize_t)bytes;
 }
 

+ 2 - 10
LibOS/shim/src/fs/socket/fs.c

@@ -45,9 +45,6 @@ static int socket_close(struct shim_handle* hdl) {
 static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
     struct shim_sock_handle* sock = &hdl->info.sock;
 
-    if (!count)
-        return 0;
-
     lock(&hdl->lock);
 
     if (sock->sock_type == SOCK_STREAM && sock->sock_state != SOCK_ACCEPTED &&
@@ -68,7 +65,7 @@ static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
 
     PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
 
-    if (!bytes)
+    if (bytes == PAL_STREAM_ERROR)
         switch (PAL_NATIVE_ERRNO) {
             case PAL_ERROR_ENDOFSTREAM:
                 return 0;
@@ -81,7 +78,6 @@ static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
             }
         }
 
-    assert((ssize_t)bytes > 0);
     return (ssize_t)bytes;
 }
 
@@ -106,12 +102,9 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou
 
     unlock(&hdl->lock);
 
-    if (!count)
-        return 0;
-
     PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL);
 
-    if (!bytes) {
+    if (bytes == PAL_STREAM_ERROR) {
         int err;
         switch (PAL_NATIVE_ERRNO) {
             case PAL_ERROR_CONNFAILED:
@@ -127,7 +120,6 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou
         return -err;
     }
 
-    assert((ssize_t)bytes > 0);
     return (ssize_t)bytes;
 }
 

+ 2 - 2
LibOS/shim/src/ipc/shim_ipc.c

@@ -311,10 +311,10 @@ int send_ipc_message(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
     size_t bytes       = 0;
 
     do {
-        size_t ret =
+        PAL_NUM ret =
             DkStreamWrite(port->pal_handle, 0, total_bytes - bytes, (void*)msg + bytes, NULL);
 
-        if (!ret) {
+        if (ret == PAL_STREAM_ERROR) {
             if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
                 continue;
 

+ 2 - 2
LibOS/shim/src/ipc/shim_ipc_helper.c

@@ -557,10 +557,10 @@ static int receive_ipc_message(struct shim_ipc_port* port) {
                 msg = tmp_buf;
             }
 
-            size_t read = DkStreamRead(port->pal_handle, /*offset=*/0, expected_size - bytes + readahead,
+            PAL_NUM read = DkStreamRead(port->pal_handle, /*offset=*/0, expected_size - bytes + readahead,
                                        (void *) msg + bytes, NULL, 0);
 
-            if (!read) {
+            if (read == PAL_STREAM_ERROR) {
                 if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
                     continue;
 

+ 11 - 11
LibOS/shim/src/shim_checkpoint.c

@@ -500,10 +500,10 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
     size_t bytes = 0;
 
     do {
-        size_t ret = DkStreamWrite(stream, 0, total_bytes - bytes,
+        PAL_NUM ret = DkStreamWrite(stream, 0, total_bytes - bytes,
                                    (void *) store->base + bytes, NULL);
 
-        if (!ret) {
+        if (ret == PAL_STREAM_ERROR) {
             if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
                 PAL_ERRNO == EWOULDBLOCK)
                 continue;
@@ -520,9 +520,9 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
         void * mem_addr = mem_entries[i]->addr;
         bytes = 0;
         do {
-            size_t ret = DkStreamWrite(stream, 0, mem_size - bytes,
+            PAL_NUM ret = DkStreamWrite(stream, 0, mem_size - bytes,
                                        mem_addr + bytes, NULL);
-            if (!ret) {
+            if (ret == PAL_STREAM_ERROR) {
                 if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
                     PAL_ERRNO == EWOULDBLOCK)
                     continue;
@@ -929,7 +929,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     int ret = 0;
     struct shim_process * new_process = NULL;
     struct newproc_header hdr;
-    size_t bytes;
+    PAL_NUM bytes;
     PAL_HANDLE gipc_hdl = NULL;
     memset(&hdr, 0, sizeof(hdr));
 
@@ -1073,7 +1073,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
      * notify the process to start receiving the checkpoint.
      */
     bytes = DkStreamWrite(proc, 0, sizeof(struct newproc_header), &hdr, NULL);
-    if (!bytes) {
+    if (bytes == PAL_STREAM_ERROR) {
         ret = -PAL_ERRNO;
         debug("failed writing to process stream (ret = %d)\n", ret);
         goto out;
@@ -1120,7 +1120,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
     struct newproc_response res;
     bytes = DkStreamRead(proc, 0, sizeof(struct newproc_response), &res,
                          NULL, 0);
-    if (bytes == 0) {
+    if (bytes == PAL_STREAM_ERROR) {
         ret = -PAL_ERRNO;
         goto out;
     }
@@ -1257,11 +1257,11 @@ int do_migration (struct newproc_cp_header * hdr, void ** cpptr)
     } else {
         size_t total_bytes = 0;
         while (total_bytes < size) {
-            int bytes = DkStreamRead(PAL_CB(parent_process), 0,
-                                     size - total_bytes,
-                                     (void *) base + total_bytes, NULL, 0);
+            PAL_NUM bytes = DkStreamRead(PAL_CB(parent_process), 0,
+                                         size - total_bytes,
+                                         (void *) base + total_bytes, NULL, 0);
 
-            if (!bytes) {
+            if (bytes == PAL_STREAM_ERROR) {
                 if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
                     PAL_ERRNO == EWOULDBLOCK)
                     continue;

+ 21 - 19
LibOS/shim/src/shim_init.c

@@ -101,7 +101,6 @@ static int pal_errno_to_unix_errno [PAL_ERROR_NATIVE_COUNT + 1] = {
         /* PAL_ERROR_ENDOFSTREAM    */  0,
         /* PAL_ERROR_NOTSERVER      */  EINVAL,
         /* PAL_ERROR_NOTCONNECTION  */  ENOTCONN,
-        /* PAL_ERROR_ZEROSIZE       */  0,
         /* PAL_ERROR_CONNFAILED     */  ECONNRESET,
         /* PAL_ERROR_ADDRNOTEXIST   */  EADDRNOTAVAIL,
         /* PAL_ERROR_AFNOSUPPORT    */  EAFNOSUPPORT,
@@ -617,10 +616,10 @@ static int init_newproc (struct newproc_header * hdr)
 {
     BEGIN_PROFILE_INTERVAL();
 
-    int bytes = DkStreamRead(PAL_CB(parent_process), 0,
-                             sizeof(struct newproc_header), hdr,
-                             NULL, 0);
-    if (!bytes)
+    PAL_NUM bytes = DkStreamRead(PAL_CB(parent_process), 0,
+                                 sizeof(struct newproc_header), hdr,
+                                 NULL, 0);
+    if (bytes == PAL_STREAM_ERROR)
         return -PAL_ERRNO;
 
     SAVE_PROFILE_INTERVAL(child_wait_header);
@@ -788,9 +787,10 @@ noreturn void* shim_init (int argc, void * args)
         struct newproc_response res;
         res.child_vmid = cur_process.vmid;
         res.failure = 0;
-        if (!DkStreamWrite(PAL_CB(parent_process), 0,
-                           sizeof(struct newproc_response),
-                           &res, NULL))
+        PAL_NUM ret = DkStreamWrite(PAL_CB(parent_process), 0,
+                                    sizeof(struct newproc_response),
+                                    &res, NULL);
+        if (ret == PAL_STREAM_ERROR)
             shim_do_exit(-PAL_ERRNO);
     }
 
@@ -1231,20 +1231,22 @@ int message_confirm (const char * message, const char * options)
         return -EACCES;
     }
 
-#define WRITE(buf, len)                                             \
-    ({  int _ret = DkStreamWrite(hdl, 0, len, (void*)(buf), NULL);  \
-        _ret ? : -PAL_ERRNO; })
-
-#define READ(buf, len)                                              \
-    ({  int _ret = DkStreamRead(hdl, 0, len, buf, NULL, 0);         \
-        _ret ? : -PAL_ERRNO; })
-
-    if ((ret = WRITE(message, strlen(message))) < 0)
+    PAL_NUM pal_ret;
+    pal_ret = DkStreamWrite(hdl, 0, strlen(message), (void*)message, NULL);
+    if (pal_ret == PAL_STREAM_ERROR) {
+        ret = -PAL_ERRNO;
         goto out;
-    if ((ret = WRITE(option_str, noptions * 2 + 3)) < 0)
+    }
+    pal_ret = DkStreamWrite(hdl, 0, noptions * 2 + 3, option_str, NULL);
+    if (pal_ret == PAL_STREAM_ERROR) {
+        ret = -PAL_ERRNO;
         goto out;
-    if ((ret = READ(&answer, 1)) < 0)
+    }
+    pal_ret = DkStreamRead(hdl, 0, 1, &answer, NULL, 0);
+    if (pal_ret == PAL_STREAM_ERROR) {
+        ret = -PAL_ERRNO;
         goto out;
+    }
 
 out:
     DkObjectClose(hdl);

+ 5 - 1
LibOS/shim/src/sys/shim_msgget.c

@@ -832,8 +832,12 @@ static int __load_msg_persist(struct shim_msg_handle* msgq, bool readmsg) {
 
     size_t bytes = DkStreamRead(file, 0, sizeof(struct msg_handle_backup), &mback, NULL, 0);
 
+    if (bytes == PAL_STREAM_ERROR) {
+        ret = -PAL_ERRNO;
+        goto out;
+    }
     if (bytes < sizeof(struct msg_handle_backup)) {
-        ret = bytes ? -EFAULT : -PAL_ERRNO;
+        ret = -EFAULT;
         goto out;
     }
 

+ 6 - 7
LibOS/shim/src/sys/shim_socket.c

@@ -1057,14 +1057,14 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags,
     ret       = 0;
 
     for (int i = 0; i < nbufs; i++) {
-        ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri);
+        PAL_NUM pal_ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri);
 
-        if (!ret) {
+        if (pal_ret == PAL_STREAM_ERROR) {
             ret = (PAL_NATIVE_ERRNO == PAL_ERROR_STREAMEXIST) ? -ECONNABORTED : -PAL_ERRNO;
             break;
         }
 
-        bytes += ret;
+        bytes += pal_ret;
     }
 
     if (bytes)
@@ -1189,15 +1189,14 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, int nbufs, int flags, stru
     ret                   = 0;
 
     for (int i = 0; i < nbufs; i++) {
-        ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri,
-                           uri ? SOCK_URI_SIZE : 0);
+        PAL_NUM pal_ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri, uri ? SOCK_URI_SIZE : 0);
 
-        if (!ret) {
+        if (pal_ret == PAL_STREAM_ERROR) {
             ret = (PAL_NATIVE_ERRNO == PAL_ERROR_STREAMNOTEXIST) ? -ECONNABORTED : -PAL_ERRNO;
             break;
         }
 
-        bytes += ret;
+        bytes += pal_ret;
 
         if (!addr || !bytes || address_received)
             continue;

+ 1 - 1
Pal/lib/graphene/path.c

@@ -74,7 +74,7 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) {
 
     size_t size = *size_ptr;
     if (!size) {
-        return -PAL_ERROR_ZEROSIZE;
+        return -PAL_ERROR_INVAL;
     }
     /* reserve 1 byte for ending '\0' */
     size--;