From aedf8c534195772f60e7c6409ae045fa20415aef Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 11 Jan 2016 11:59:03 +0100 Subject: [KERNEL/CLIENT] Several minor tweaks and changes - Disable panic timeout that reports errors to block layer by default - Get rid of "is_server" used by old proxy mode, introduce "honor_server_alts" that just controls whether we use alts provided by the server - Allow switching servers when we only have 3 RTT measurements - If using alts provided by server, don't ignore those that come from other servers than the initial one --- src/client/client.c | 4 ++-- src/config.h | 3 ++- src/kernel/blk.c | 4 ++-- src/kernel/dnbd3.h | 3 ++- src/kernel/net.c | 19 +++++++++---------- src/types.h | 4 +++- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/client/client.c b/src/client/client.c index a692897..b3069fe 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -205,7 +205,7 @@ int main(int argc, char *argv[]) msg.host.port = htons( PORT ); msg.host.type = 0; msg.imgname = NULL; - msg.is_server = false; + msg.use_server_provided_alts = true; int opt = 0; int longIndex = 0; @@ -567,7 +567,7 @@ static char* dnbd3_daemon_open(int uid, char *host, char *image, int rid, int re msg.imgname = image; msg.imgnamelen = strlen( image ); msg.rid = rid; - msg.is_server = false; + msg.use_server_provided_alts = true; msg.read_ahead_kb = readAhead; if ( dnbd3_ioctl( dev, IOCTL_OPEN, &msg ) ) { openDevices[i] = uid; diff --git a/src/config.h b/src/config.h index f5b550c..c6405b5 100644 --- a/src/config.h +++ b/src/config.h @@ -86,7 +86,8 @@ // Number of unsuccessful alt_server probes before read errors are reported to the block layer // (ALL servers will be probed this many times) -#define PROBE_COUNT_TIMEOUT 20 +// Set to 0 to disable +#define PROBE_COUNT_TIMEOUT 0 // +++++ Block Device +++++ #define KERNEL_SECTOR_SIZE 512 diff --git a/src/kernel/blk.c b/src/kernel/blk.c index e55de25..3e3cdd7 100644 --- a/src/kernel/blk.c +++ b/src/kernel/blk.c @@ -169,7 +169,7 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u memcpy(&dev->initial_server, &dev->cur_server, sizeof(dev->initial_server)); dev->imgname = imgname; dev->rid = msg->rid; - dev->is_server = msg->is_server; + dev->use_server_provided_alts = msg->use_server_provided_alts; // Forget all alt servers on explicit connect, set first al server to initial server memset(dev->alt_servers, 0, sizeof(dev->alt_servers[0])*NUMBER_SERVERS); memcpy(dev->alt_servers, &dev->initial_server, sizeof(dev->alt_servers[0])); @@ -266,7 +266,7 @@ void dnbd3_blk_request(struct request_queue *q) continue; } - if (dev->panic_count >= PROBE_COUNT_TIMEOUT) + if (PROBE_COUNT_TIMEOUT > 0 && dev->panic_count >= PROBE_COUNT_TIMEOUT) { __blk_end_request_all(req, -EIO); continue; diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h index c0c7f4d..f8af69f 100644 --- a/src/kernel/dnbd3.h +++ b/src/kernel/dnbd3.h @@ -60,7 +60,8 @@ typedef struct dnbd3_server_t alt_servers[NUMBER_SERVERS]; // array of alt servers int new_servers_num; // number of new alt servers that are waiting to be copied to above array dnbd3_server_entry_t new_servers[NUMBER_SERVERS]; // pending new alt servers - uint8_t discover, panic, disconnecting, is_server, update_available, panic_count; + uint8_t discover, panic, disconnecting, update_available, panic_count; + uint8_t use_server_provided_alts; uint16_t rid; uint32_t heartbeat_count; uint64_t reported_size; diff --git a/src/kernel/net.c b/src/kernel/net.c index 3392feb..58b4664 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -210,7 +210,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev) serializer_put_uint16(&dev->payload_buffer, PROTOCOL_VERSION); serializer_put_string(&dev->payload_buffer, dev->imgname); serializer_put_uint16(&dev->payload_buffer, dev->rid); - serializer_put_uint8(&dev->payload_buffer, dev->is_server); + serializer_put_uint8(&dev->payload_buffer, 0); // is_server = false iov[1].iov_base = &dev->payload_buffer; dnbd3_request.size = iov[1].iov_len = serializer_get_written_length(&dev->payload_buffer); fixup_request(dnbd3_request); @@ -731,7 +731,7 @@ int dnbd3_net_discover(void *data) if (dev->panic) { // After 21 retries, bail out by reporting errors to block layer - if (dev->panic_count < 255 && ++dev->panic_count == PROBE_COUNT_TIMEOUT + 1) + if (PROBE_COUNT_TIMEOUT > 0 && dev->panic_count < 255 && ++dev->panic_count == PROBE_COUNT_TIMEOUT + 1) dnbd3_blk_fail_all_requests(dev); } @@ -745,7 +745,7 @@ int dnbd3_net_discover(void *data) continue; } - do_change = !dev->is_server && ready && best_server != current_server && (start.tv_usec & 3) != 0 + do_change = ready && best_server != current_server && (start.tv_usec & 3) != 0 && RTT_THRESHOLD_FACTOR(dev->cur_rtt) > best_rtt + 1500; if (ready && !do_change) { @@ -765,7 +765,7 @@ int dnbd3_net_discover(void *data) spin_unlock_irqrestore(&dev->blk_lock, irqflags); } - // take server with lowest rtt (only if in client mode) + // take server with lowest rtt if (do_change) { printk("INFO: Server %d on %s is faster (%lluµs vs. %lluµs)\n", best_server, dev->disk->disk_name, @@ -787,9 +787,9 @@ int dnbd3_net_discover(void *data) best_sock = NULL; } - if (!ready || (start.tv_usec & 7) != 0) + if (!ready || (start.tv_usec & 15) != 0) turn = (turn + 1) % 4; - if (turn == 3) + if (turn == 2) // Set ready when we only have 2 of 4 measurements for quicker load balancing ready = 1; } @@ -1002,11 +1002,10 @@ int dnbd3_net_receive(void *data) continue; case CMD_GET_SERVERS: - if (dev->is_server || !is_same_server(&dev->cur_server, &dev->initial_server)) + if (!dev->use_server_provided_alts) { - // If not connected to initial server, or device is in proxy mode, ignore this message remaining = dnbd3_reply.size; - goto clear_remaining_payload; + goto consume_payload; } spin_lock_irqsave(&dev->blk_lock, irqflags); dev->new_servers_num = 0; @@ -1026,7 +1025,7 @@ int dnbd3_net_receive(void *data) } // If there were more servers than accepted, remove the remaining data from the socket buffer remaining = dnbd3_reply.size - (count * sizeof(dnbd3_server_entry_t)); - clear_remaining_payload: while (remaining > 0) + consume_payload: while (remaining > 0) { count = MIN(sizeof(dnbd3_reply), remaining); // Abuse the reply struct as the receive buffer iov.iov_base = &dnbd3_reply; diff --git a/src/types.h b/src/types.h index 7303baa..6652a0d 100644 --- a/src/types.h +++ b/src/types.h @@ -86,6 +86,7 @@ typedef struct } dnbd3_host_t; #pragma pack(0) +#pragma pack(1) typedef struct { uint16_t len; @@ -94,8 +95,9 @@ typedef struct char *imgname; int rid; int read_ahead_kb; - uint8_t is_server; // FALSE = automatic (real client), TRUE = manual control (proxy) + uint8_t use_server_provided_alts; } dnbd3_ioctl_t; +#pragma pack(0) // network #define CMD_GET_BLOCK 1 -- cgit v1.2.3-55-g7522