summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorSimon Rettberg2015-12-01 13:38:10 +0100
committerSimon Rettberg2015-12-01 13:38:10 +0100
commitecc6e5dd28821bf1c207e074f1b5903426a7e4c4 (patch)
tree5f9d8f8ffbcad5ae6ac1b9a0b3075155995537d8 /src/shared
parent[FUSE] It works! Kinda... (diff)
downloaddnbd3-ecc6e5dd28821bf1c207e074f1b5903426a7e4c4.tar.gz
dnbd3-ecc6e5dd28821bf1c207e074f1b5903426a7e4c4.tar.xz
dnbd3-ecc6e5dd28821bf1c207e074f1b5903426a7e4c4.zip
[FUSE] Stability improvements, runs for longer than a couple secs now :)
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/protocol.h40
-rw-r--r--src/shared/sockhelper.c23
-rw-r--r--src/shared/sockhelper.h7
3 files changed, 43 insertions, 27 deletions
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 <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
+#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_ */