From: dgoulet@efficios.com (David Goulet)
Subject: [lttng-dev] [PATCH 1/2] Fix: read subbuffer mmap signedness issue
Date: Fri, 7 Feb 2014 15:42:39 -0500 [thread overview]
Message-ID: <1391805760-30421-1-git-send-email-dgoulet@efficios.com> (raw)
Signed and unsigned values were compared thus making the code path where
ret = -1 being interpreted as ret > len == true thus not cleaning up the
relayd.
This patch simplifies the read subbuffer mmap operation since
lttng_write() now provides a guarantee that the return data is either
equal to the count passed or less which the later means the endpoint has
stop working.
Signed-off-by: David Goulet <dgoulet at efficios.com>
---
src/common/consumer.c | 82 +++++++++++++++++++++++++++++----------------------
1 file changed, 47 insertions(+), 35 deletions(-)
diff --git a/src/common/consumer.c b/src/common/consumer.c
index 36ec024..59d4366 100644
--- a/src/common/consumer.c
+++ b/src/common/consumer.c
@@ -1451,7 +1451,7 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap(
{
unsigned long mmap_offset;
void *mmap_base;
- ssize_t ret = 0, written = 0;
+ ssize_t ret = 0, written = 0, signed_len;
off_t orig_offset = stream->out_fd_offset;
/* Default is on the disk */
int outfd = stream->out_fd;
@@ -1584,44 +1584,56 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap(
}
}
- while (len > 0) {
- ret = lttng_write(outfd, mmap_base + mmap_offset, len);
- DBG("Consumer mmap write() ret %zd (len %lu)", ret, len);
- if (ret < len) {
- /*
- * This is possible if the fd is closed on the other side (outfd)
- * or any write problem. It can be verbose a bit for a normal
- * execution if for instance the relayd is stopped abruptly. This
- * can happen so set this to a DBG statement.
- */
- DBG("Error in file write mmap");
- if (written == 0) {
- written = -errno;
- }
- /* Socket operation failed. We consider the relayd dead */
- if (errno == EPIPE || errno == EINVAL) {
- relayd_hang_up = 1;
- goto write_error;
- }
- goto end;
- } else if (ret > len) {
- PERROR("Error in file write (ret %zd > len %lu)", ret, len);
- written += ret;
- goto end;
+ /*
+ * Set the len value to a signed value so the if/else statement can
+ * evaluate it against the signed returned value from lttng_write since
+ * -1 can be returned indicating a communication failure.
+ */
+ signed_len = len;
+
+ /*
+ * This call guarantee that len or less is returned. It's impossible to
+ * receive a ret value that is bigger than len.
+ */
+ ret = lttng_write(outfd, mmap_base + mmap_offset, len);
+ DBG("Consumer mmap write() ret %zd (len %lu)", ret, len);
+ if (ret != signed_len) {
+ /*
+ * Report error to caller if nothing was written else at least send the
+ * amount written.
+ */
+ if (ret < 0) {
+ written = -errno;
} else {
- len -= ret;
- mmap_offset += ret;
+ written = ret;
}
- /* This call is useless on a socket so better save a syscall. */
- if (!relayd) {
- /* This won't block, but will start writeout asynchronously */
- lttng_sync_file_range(outfd, stream->out_fd_offset, ret,
- SYNC_FILE_RANGE_WRITE);
- stream->out_fd_offset += ret;
+ /* Socket operation failed. We consider the relayd dead */
+ if (errno == EPIPE || errno == EINVAL) {
+ /*
+ * This is possible if the fd is closed on the other side
+ * (outfd) or any write problem. It can be verbose a bit for a
+ * normal execution if for instance the relayd is stopped
+ * abruptly. This can happen so set this to a DBG statement.
+ */
+ DBG("Consumer mmap write detected relayd hang up");
+ relayd_hang_up = 1;
+ goto write_error;
}
- stream->output_written += ret;
- written += ret;
+
+ /* Unhandled error, print it and stop function right now. */
+ PERROR("Error in write mmap (ret %zd < len %lu)", ret, len);
+ goto end;
+ }
+ stream->output_written += ret;
+ written = ret;
+
+ /* This call is useless on a socket so better save a syscall. */
+ if (!relayd) {
+ /* This won't block, but will start writeout asynchronously */
+ lttng_sync_file_range(outfd, stream->out_fd_offset, len,
+ SYNC_FILE_RANGE_WRITE);
+ stream->out_fd_offset += len;
}
lttng_consumer_sync_trace_file(stream, orig_offset);
--
1.8.5.3
next reply other threads:[~2014-02-07 20:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-07 20:42 David Goulet [this message]
2014-02-07 20:42 ` [lttng-dev] [PATCH 2/2] Fix: read subbuffer splice " David Goulet
2014-02-08 15:51 ` Mathieu Desnoyers
2014-02-08 15:50 ` [lttng-dev] [PATCH 1/2] Fix: read subbuffer mmap " Mathieu Desnoyers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1391805760-30421-1-git-send-email-dgoulet@efficios.com \
--to=dgoulet@efficios.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox