From ecc6e5dd28821bf1c207e074f1b5903426a7e4c4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 1 Dec 2015 13:38:10 +0100 Subject: [FUSE] Stability improvements, runs for longer than a couple secs now :) --- src/shared/protocol.h | 40 +++++++++++++++++----------------------- src/shared/sockhelper.c | 23 ++++++++++++++++++++--- src/shared/sockhelper.h | 7 ++++++- 3 files changed, 43 insertions(+), 27 deletions(-) (limited to 'src/shared') diff --git a/src/shared/protocol.h b/src/shared/protocol.h index a5c7bbd..3539c21 100644 --- a/src/shared/protocol.h +++ b/src/shared/protocol.h @@ -4,6 +4,7 @@ #include #include #include +#include "sockhelper.h" #include "../types.h" #include "../serialize.h" @@ -35,9 +36,11 @@ static inline int dnbd3_read_reply(int sock, dnbd3_reply_t *reply, bool wait) static inline bool dnbd3_get_reply(int sock, dnbd3_reply_t *reply) { - int ret = dnbd3_read_reply( sock, reply, true ); - if ( ret != REPLY_INTR ) return ret == REPLY_OK; - return dnbd3_read_reply( sock, reply, true ) == REPLY_OK; + int ret; + do { + ret = dnbd3_read_reply( sock, reply, true ); + } while ( ret == REPLY_INTR ); + return ret == REPLY_OK; } static inline bool dnbd3_select_image(int sock, const char *lower_name, uint16_t rid, uint8_t flags8) @@ -63,10 +66,10 @@ static inline bool dnbd3_select_image(int sock, const char *lower_name, uint16_t iov[0].iov_len = sizeof(request); iov[1].iov_base = &serialized; iov[1].iov_len = len; - ssize_t ret = writev( sock, iov, 2 ); - if ( ret == -1 && errno == EINTR ) { + ssize_t ret; + do { ret = writev( sock, iov, 2 ); - } + } while ( ret == -1 && errno == EINTR ); return ret == len + (ssize_t)sizeof(request); } @@ -79,7 +82,7 @@ static inline bool dnbd3_get_block(int sock, uint64_t offset, uint32_t size, uin request.offset = offset; request.size = size; fixup_request( request ); - return send( sock, &request, sizeof(request), MSG_NOSIGNAL ) == sizeof(request); + return sock_sendAll( sock, &request, sizeof(request), 2 ) == (ssize_t)sizeof(request); } static inline bool dnbd3_get_crc32(int sock, uint32_t *master, void *buffer, size_t *bufferLen) @@ -92,7 +95,7 @@ static inline bool dnbd3_get_crc32(int sock, uint32_t *master, void *buffer, siz request.offset = 0; request.size = 0; fixup_request( request ); - if ( send( sock, &request, sizeof(request), 0 ) != sizeof(request) ) return false; + if ( sock_sendAll( sock, &request, sizeof(request), 2 ) != (ssize_t)sizeof(request) ) return false; if ( !dnbd3_get_reply( sock, &reply ) ) return false; if ( reply.size == 0 ) { *bufferLen = 0; @@ -102,14 +105,8 @@ static inline bool dnbd3_get_crc32(int sock, uint32_t *master, void *buffer, siz reply.size -= 4; if ( reply.cmd != CMD_GET_CRC32 || reply.size > *bufferLen ) return false; *bufferLen = reply.size; - if ( recv( sock, master, sizeof(uint32_t), MSG_WAITALL | MSG_NOSIGNAL ) != sizeof(uint32_t) ) return false; - uint32_t done = 0; - while ( done < reply.size ) { - const ssize_t ret = recv( sock, (char*)buffer + done, reply.size - done, 0 ); - if ( ret <= 0 ) return false; - done += ret; - } - return true; + if ( sock_recv( sock, master, sizeof(uint32_t) ) != (ssize_t)sizeof(uint32_t) ) return false; + return sock_recv( sock, buffer, reply.size ) == (ssize_t)reply.size; } /** @@ -128,15 +125,12 @@ static inline bool dnbd3_select_image_reply(serialized_buffer_t *buffer, int soc if ( reply.cmd != CMD_SELECT_IMAGE || reply.size < 3 || reply.size > MAX_PAYLOAD ) { return false; } -// receive reply payload - ssize_t ret = recv( sock, buffer, reply.size, MSG_WAITALL | MSG_NOSIGNAL ); - if ( ret == -1 && errno == EINTR ) { - ret = recv( sock, buffer, reply.size, MSG_WAITALL | MSG_NOSIGNAL ); - } - if ( ret != reply.size ) { + // receive reply payload + ssize_t ret = sock_recv( sock, buffer, reply.size ); + if ( ret != (ssize_t)reply.size ) { return false; } -// handle/check reply payload + // handle/check reply payload serializer_reset_read( buffer, reply.size ); *protocol_version = serializer_get_uint16( buffer ); *name = serializer_get_string( buffer ); diff --git a/src/shared/sockhelper.c b/src/shared/sockhelper.c index 0e732c1..f2f8b97 100644 --- a/src/shared/sockhelper.c +++ b/src/shared/sockhelper.c @@ -264,17 +264,16 @@ bool sock_append(poll_list_t *list, const int sock, bool wantRead, bool wantWrit return true; } -ssize_t sock_sendAll(int sock, void *buffer, size_t len, int maxtries) +ssize_t sock_sendAll(const int sock, void *buffer, const size_t len, int maxtries) { size_t done = 0; ssize_t ret = 0; while ( done < len ) { if ( maxtries >= 0 && --maxtries == -1 ) break; ret = write( sock, (char*)buffer + done, len - done ); - if ( ret < 0 ) { + if ( ret == -1 ) { if ( errno == EINTR ) continue; if ( errno == EAGAIN || errno == EWOULDBLOCK ) { - usleep( 1000 ); continue; } break; @@ -286,3 +285,21 @@ ssize_t sock_sendAll(int sock, void *buffer, size_t len, int maxtries) return done; } +ssize_t sock_recv(const int sock, void *buffer, const size_t len) +{ + size_t done = 0; + ssize_t ret = 0; + int intrs = 0; + while ( done < len ) { + ret = recv( sock, (char*)buffer + done, len - done, MSG_NOSIGNAL ); + if ( ret == -1 ) { + if ( errno == EINTR && ++intrs < 10 ) continue; + break; + } + if ( ret == 0 ) break; + done += ret; + } + if ( done == 0 ) return ret; + return done; +} + diff --git a/src/shared/sockhelper.h b/src/shared/sockhelper.h index dc22e2b..6ffc31a 100644 --- a/src/shared/sockhelper.h +++ b/src/shared/sockhelper.h @@ -90,6 +90,11 @@ bool sock_append(poll_list_t *list, const int sock, bool wantRead, bool wantWrit * Give up after calling write() maxtries times. * Set maxtries < 0 to try infinitely. */ -ssize_t sock_sendAll(int sock, void *buffer, size_t len, int maxtries); +ssize_t sock_sendAll(const int sock, void *buffer, const size_t len, int maxtries); + +/** + * Send given buffer, repeatedly calling recv on partial send or EINTR. + */ +ssize_t sock_recv(const int sock, void *buffer, const size_t len); #endif /* SOCKHELPER_H_ */ -- cgit v1.2.3-55-g7522