From 9be57e249a31b51a471b4d0aaa43c917cec5e97a Mon Sep 17 00:00:00 2001 From: Pierre-Marc Fournier Date: Sat, 27 Feb 2010 12:21:36 -0500 Subject: [PATCH] ustd: unwrite the subbuffer if the put() was unsuccessful and we are going to crash-recover it This prevents the subbuffer to be written twice and fixes a FIXME. --- ustd/ustd.c | 36 +++++++++++++++++++++++++++++++++--- ustd/ustd.h | 3 +++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/ustd/ustd.c b/ustd/ustd.c index d2a9712..f3285f5 100644 --- a/ustd/ustd.c +++ b/ustd/ustd.c @@ -400,6 +400,25 @@ error: return NULL; } +int unwrite_last_subbuffer(struct buffer_info *buf) +{ + int result; + + result = ftruncate(buf->file_fd, buf->previous_offset); + if(result == -1) { + PERROR("ftruncate"); + return -1; + } + + result = lseek(buf->file_fd, buf->previous_offset, SEEK_SET); + if(result == (int)(off_t)-1) { + PERROR("lseek"); + return -1; + } + + return 0; +} + int write_current_subbuffer(struct buffer_info *buf) { int result; @@ -408,11 +427,20 @@ int write_current_subbuffer(struct buffer_info *buf) size_t cur_sb_size = subbuffer_data_size(subbuf_mem); + off_t cur_offset = lseek(buf->file_fd, 0, SEEK_CUR); + if(cur_offset == (off_t)-1) { + PERROR("lseek"); + return -1; + } + + buf->previous_offset = cur_offset; + DBG("previous_offset: %ld", cur_offset); + result = patient_write(buf->file_fd, subbuf_mem, cur_sb_size); if(result == -1) { PERROR("write"); /* FIXME: maybe drop this trace */ - return 0; + return -1; } return 0; @@ -445,7 +473,6 @@ int consumer_loop(struct buffer_info *buf) /* FIXME: handle return value? */ /* put the subbuffer */ - /* FIXME: we actually should unput the buffer before consuming... */ result = put_subbuffer(buf); if(result == -1) { ERR("unknown error putting subbuffer (channel=%s)", buf->name); @@ -457,7 +484,10 @@ int consumer_loop(struct buffer_info *buf) } else if(result == PUT_SUBBUF_DIED) { WARN("application died while putting subbuffer"); - /* FIXME: probably need to skip the first subbuffer in finish_consuming_dead_subbuffer */ + /* Skip the first subbuffer. We are not sure it is trustable + * because the put_subbuffer() did not complete. + */ + unwrite_last_subbuffer(buf); finish_consuming_dead_subbuffer(buf); break; } diff --git a/ustd/ustd.h b/ustd/ustd.h index 5be186a..d8c4c50 100644 --- a/ustd/ustd.h +++ b/ustd/ustd.h @@ -30,6 +30,9 @@ struct buffer_info { long consumed_old; s64 pidunique; + + /* the offset we must truncate to, to unput the last subbuffer */ + off_t previous_offset; }; void finish_consuming_dead_subbuffer(struct buffer_info *buf); -- 2.34.1