[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.
This commit is contained in:
Isaku Yamahata
2019-10-31 14:44:46 -07:00
committed by Dmitrii Kuvaiskii
parent 7495dffda7
commit 93eb9bc595
11 changed files with 59 additions and 80 deletions
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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--;