From 6f94560a050962daad560dac2823bd97b0b1bf98 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 23 Jul 2012 11:13:40 -0400 Subject: [PATCH] fix: write EINTR handling Ensure that we always test for ret < 0 && errno == EINTR for each write() call. Signed-off-by: Mathieu Desnoyers --- src/bin/lttng-relayd/main.c | 20 ++++++--- src/bin/lttng-sessiond/utils.c | 4 +- src/common/consumer.c | 6 ++- src/common/kernel-consumer/kernel-consumer.c | 45 +++++++++----------- src/common/runas.c | 6 ++- src/common/ust-consumer/ust-consumer.c | 31 ++++++-------- 6 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 5a12ba888..0428d33ce 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -246,7 +246,9 @@ int notify_thread_pipe(int wpipe) { int ret; - ret = write(wpipe, "!", 1); + do { + ret = write(wpipe, "!", 1); + } while (ret < 0 && errno == EINTR); if (ret < 0) { PERROR("write poll pipe"); } @@ -627,8 +629,10 @@ void *relay_thread_dispatcher(void *data) * call is blocking so we can be assured that the data will be read * at some point in time or wait to the end of the world :) */ - ret = write(relay_cmd_pipe[1], relay_cmd, - sizeof(struct relay_command)); + do { + ret = write(relay_cmd_pipe[1], relay_cmd, + sizeof(struct relay_command)); + } while (ret < 0 && errno == EINTR); free(relay_cmd); if (ret < 0) { PERROR("write cmd pipe"); @@ -1054,8 +1058,10 @@ int relay_recv_metadata(struct lttcomm_relayd_hdr *recv_hdr, goto end; } - ret = write(metadata_stream->fd, metadata_struct->payload, - payload_size); + do { + ret = write(metadata_stream->fd, metadata_struct->payload, + payload_size); + } while (ret < 0 && errno == EINTR); if (ret < (payload_size)) { ERR("Relay error writing metadata on file"); ret = -1; @@ -1189,7 +1195,9 @@ int relay_process_data(struct relay_command *cmd, struct lttng_ht *streams_ht) goto end; } - ret = write(stream->fd, data_buffer, data_size); + do { + ret = write(stream->fd, data_buffer, data_size); + } while (ret < 0 && errno == EINTR); if (ret < data_size) { ERR("Relay error writing data to file"); ret = -1; diff --git a/src/bin/lttng-sessiond/utils.c b/src/bin/lttng-sessiond/utils.c index 07f29aded..d503665a4 100644 --- a/src/bin/lttng-sessiond/utils.c +++ b/src/bin/lttng-sessiond/utils.c @@ -31,7 +31,9 @@ int notify_thread_pipe(int wpipe) { int ret; - ret = write(wpipe, "!", 1); + do { + ret = write(wpipe, "!", 1); + } while (ret < 0 && errno == EINTR); if (ret < 0) { PERROR("write poll pipe"); } diff --git a/src/common/consumer.c b/src/common/consumer.c index 88e8d9d28..974c65f55 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -875,7 +875,9 @@ void lttng_consumer_should_exit(struct lttng_consumer_local_data *ctx) { int ret; consumer_quit = 1; - ret = write(ctx->consumer_should_quit[1], "4", 1); + do { + ret = write(ctx->consumer_should_quit[1], "4", 1); + } while (ret < 0 && errno == EINTR); if (ret < 0) { perror("write consumer quit"); } @@ -1522,7 +1524,7 @@ end: */ do { ret = write(ctx->consumer_poll_pipe[1], "", 1); - } while (ret == -1UL && errno == EINTR); + } while (ret < 0 && errno == EINTR); rcu_unregister_thread(); return NULL; } diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 8ed279f44..00bb7f721 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -101,12 +101,12 @@ ssize_t lttng_kconsumer_on_read_subbuffer_mmap( do { ret = write(outfd, (void *) &metadata_id, sizeof(stream->relayd_stream_id)); - if (ret < 0) { - PERROR("write metadata stream id"); - written = ret; - goto end; - } - } while (errno == EINTR); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + PERROR("write metadata stream id"); + written = ret; + goto end; + } DBG("Metadata stream id %zu written before data", stream->relayd_stream_id); /* @@ -120,18 +120,15 @@ ssize_t lttng_kconsumer_on_read_subbuffer_mmap( } while (len > 0) { - ret = write(outfd, stream->mmap_base + mmap_offset, len); + do { + ret = write(outfd, stream->mmap_base + mmap_offset, len); + } while (ret < 0 && errno == EINTR); if (ret < 0) { - if (errno == EINTR) { - /* restart the interrupted system call */ - continue; - } else { - perror("Error in file write"); - if (written == 0) { - written = ret; - } - goto end; + perror("Error in file write"); + if (written == 0) { + written = ret; } + goto end; } else if (ret > len) { perror("Error in file write"); written += ret; @@ -200,17 +197,17 @@ ssize_t lttng_kconsumer_on_read_subbuffer_splice( */ pthread_mutex_lock(&relayd->ctrl_sock_mutex); + metadata_id = htobe64(stream->relayd_stream_id); do { - metadata_id = htobe64(stream->relayd_stream_id); ret = write(ctx->consumer_thread_pipe[1], (void *) &metadata_id, sizeof(stream->relayd_stream_id)); - if (ret < 0) { - PERROR("write metadata stream id"); - written = ret; - goto end; - } - } while (errno == EINTR); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + PERROR("write metadata stream id"); + written = ret; + goto end; + } DBG("Metadata stream id %zu written before data", stream->relayd_stream_id); } @@ -581,7 +578,7 @@ end: */ do { ret = write(ctx->consumer_poll_pipe[1], "", 1); - } while (ret == -1UL && errno == EINTR); + } while (ret < 0 && errno == EINTR); end_nosignal: return 0; } diff --git a/src/common/runas.c b/src/common/runas.c index 3a89cc9ab..43b154f10 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -192,8 +192,10 @@ int child_run_as(void *_data) writeleft = sizeof(sendret); index = 0; do { - writelen = write(data->retval_pipe, &sendret.c[index], - writeleft); + do { + writelen = write(data->retval_pipe, &sendret.c[index], + writeleft); + } while (writelen < 0 && errno == EINTR); if (writelen < 0) { PERROR("write"); return EXIT_FAILURE; diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index f6add2c2c..1cd39ef34 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -91,12 +91,12 @@ ssize_t lttng_ustconsumer_on_read_subbuffer_mmap( do { ret = write(outfd, (void *) &metadata_id, sizeof(stream->relayd_stream_id)); - if (ret < 0) { - PERROR("write metadata stream id"); - written = ret; - goto end; - } - } while (errno == EINTR); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + PERROR("write metadata stream id"); + written = ret; + goto end; + } DBG("Metadata stream id %zu written before data", stream->relayd_stream_id); } @@ -105,18 +105,15 @@ ssize_t lttng_ustconsumer_on_read_subbuffer_mmap( } while (len > 0) { - ret = write(outfd, stream->mmap_base + mmap_offset, len); + do { + ret = write(outfd, stream->mmap_base + mmap_offset, len); + } while (ret < 0 && errno == EINTR); if (ret < 0) { - if (errno == EINTR) { - /* restart the interrupted system call */ - continue; - } else { - PERROR("Error in file write"); - if (written == 0) { - written = ret; - } - goto end; + PERROR("Error in file write"); + if (written == 0) { + written = ret; } + goto end; } else if (ret > len) { PERROR("ret %ld > len %lu", ret, len); written += ret; @@ -434,7 +431,7 @@ end: */ do { ret = write(ctx->consumer_poll_pipe[1], "", 1); - } while (ret == -1UL && errno == EINTR); + } while (ret < 0 && errno == EINTR); end_nosignal: return 0; } -- 2.34.1