diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/dnbd3.h | 73 | ||||
-rw-r--r-- | src/kernel/net.c | 31 |
2 files changed, 89 insertions, 15 deletions
diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h index c9f9fab..72294b0 100644 --- a/src/kernel/dnbd3.h +++ b/src/kernel/dnbd3.h @@ -30,8 +30,16 @@ #include "types.h" #include "serialize.h" +/** + * the number of parallel connections + */ +#define NUMBER_CONNECTIONS 4 // power of 2 + +/** + * limit to which the other connected servers are only allowed to be that worser then the best rtt + */ +#define RTT_THRESOULD_LIMIT(best_rtt) ((best_rtt) * 10) -#define NUMBER_CONNECTIONS 2 // power of 2 #define DEBUG @@ -56,7 +64,14 @@ struct dnbd3_server { * @sock_nr: nr of this socket * @device: the dnbd3_device this socket belongs to * @server: the server this socket is connected to, 'NULL' if not connected - * + * @tx_lock: mutex to lock when sending + * @sock: the socket, 'NULL' if not connected + * @panic: 'true' if it is not possible to send or receive + * @cookie: is incremented for every send, used to find the mq request in the receiver + * @keepalive_worker: worker to send a keepalive package + * @receive_worker: worker to handle the incoming packages + * @pending: the pending request which is going to be send + * @receive_command: the last command the receiver got */ struct dnbd3_sock { uint8_t sock_nr; @@ -66,7 +81,7 @@ struct dnbd3_sock { struct mutex tx_lock; struct socket *sock; - bool panic;//, discover, panic_count; + bool panic; uint32_t cookie; struct work_struct keepalive_worker; @@ -76,6 +91,30 @@ struct dnbd3_sock { uint16_t receive_command; }; +/** + * struct dnbd3_device - defining a dnbd3 device + * @minor: minor number of this device + * @tag_set: the blk mq tag set + * @list: list of previous and next dnbd3_device + * @disk: the gendisk + * @kobj: the kobject + * @device_lock: mutex to lock when device changes + * @socks: array of dnbd3_sock to connect to + * @imgname: the connected image name + * @initial_server: the server which was configured with ioctl, will not be overriden + * @alt_servers: array of alternative servers + * @new_servers_num: number of new alternative servers that are waiting to be copied to above array + * @new_servers: pending new alternative servers + * @update_available: 'true' if the rid has changes + * @use_server_provided_alts: 'true' if the alt_servers array is upated by the alternatives provided by the server + * @rid: the revision ID? TODO + * @reported_size: the size of the image + * @panic_worker: worker to handle panics and to connect if all connections are down + * @discovery_worker: worker to update the alt_servers, make rtt meassurement and reconnect to better servers + * @discovery_count: counter for the discovery worker + * @timer: timer to start the appropriate workers + * @timer_count: counter for the timer + */ struct dnbd3_device { int minor; struct blk_mq_tag_set tag_set; @@ -109,6 +148,14 @@ struct dnbd3_device { }; +/** + * struct dnbd3_cmd - defines a mq cmd for dnbd3 + * @dnbd3: the dnbd3 device this command belongs to + * @lock: mutex to lock the cmd + * @cookie: the cookie of the command, this is set by the socket when sending + * @status: the status of the command + * @requed: 'true' if the command is requed + */ struct dnbd3_cmd { struct dnbd3_device *dnbd3; struct mutex lock; @@ -118,7 +165,7 @@ struct dnbd3_cmd { }; -#define _print_sock(level, sock, fmt, ...) \ +#define __print_sock(level, sock, fmt, ...) \ do { \ if ((sock)->server->host.type == HOST_IP4) { \ printk(level "dnbd%d/%d %pI4:%d: " fmt "\n", (sock)->device->minor, (sock)->sock_nr, (sock)->server->host.addr, (sock)->server->host.port, ## __VA_ARGS__); \ @@ -127,7 +174,7 @@ struct dnbd3_cmd { } \ } while (0) -#define _print_server(level, dev, server, fmt, ...) \ +#define __print_server(level, dev, server, fmt, ...) \ do { \ if ((server)->host.type == HOST_IP4) { \ printk(level "dnbd%d: " fmt " %pI4:%d\n", (dev)->minor, ## __VA_ARGS__, (server)->host.addr, (server)->host.port); \ @@ -146,10 +193,10 @@ struct dnbd3_cmd { printk(KERN_DEBUG "dnbd%d: " fmt "\n", (dev)->minor, ## __VA_ARGS__) #define debug_sock(sock, fmt, ...) \ - _print_sock(KERN_DEBUG, sock, fmt, ## __VA_ARGS__) + __print_sock(KERN_DEBUG, sock, fmt, ## __VA_ARGS__) #define debug_server(dev, server, fmt, ...) \ - _print_server(KERN_DEBUG, dev, server, fmt, ## __VA_ARGS__) + __print_server(KERN_DEBUG, dev, server, fmt, ## __VA_ARGS__) #else @@ -170,10 +217,10 @@ struct dnbd3_cmd { printk(KERN_INFO "dnbd%d: " fmt "\n", (dev)->minor, ## __VA_ARGS__) #define info_sock(sock, fmt, ...) \ - _print_sock(KERN_INFO, sock, fmt, ## __VA_ARGS__) + __print_sock(KERN_INFO, sock, fmt, ## __VA_ARGS__) #define info_server(dev, server, fmt, ...) \ - _print_server(KERN_INFO, dev, server, fmt, ## __VA_ARGS__) + __print_server(KERN_INFO, dev, server, fmt, ## __VA_ARGS__) #define warn(fmt, ...) \ @@ -183,10 +230,10 @@ struct dnbd3_cmd { printk(KERN_WARNING "dnbd%d: " fmt "\n", (dev)->minor, ## __VA_ARGS__) #define warn_sock(sock, fmt, ...) \ - _print_sock(KERN_WARNING, sock, fmt, ## __VA_ARGS__) + __print_sock(KERN_WARNING, sock, fmt, ## __VA_ARGS__) #define warn_server(dev, server, fmt, ...) \ - _print_server(KERN_WARNING, dev, server, fmt, ## __VA_ARGS__) + __print_server(KERN_WARNING, dev, server, fmt, ## __VA_ARGS__) #define error(fmt, ...) \ @@ -196,9 +243,9 @@ struct dnbd3_cmd { printk(KERN_ERR "dnbd%d: " fmt "\n", (dev)->minor, ## __VA_ARGS__) #define error_sock(sock, fmt, ...) \ - _print_sock(KERN_ERR, sock, fmt, ## __VA_ARGS__) + __print_sock(KERN_ERR, sock, fmt, ## __VA_ARGS__) #define error_server(dev, server, fmt, ...) \ - _print_server(KERN_ERR, dev, server, fmt, ## __VA_ARGS__) + __print_server(KERN_ERR, dev, server, fmt, ## __VA_ARGS__) #endif /* DNBD_H_ */ diff --git a/src/kernel/net.c b/src/kernel/net.c index d493994..2edb422 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -548,7 +548,7 @@ static struct dnbd3_server *dnbd3_find_best_alt_server(struct dnbd3_device *dev) } } - best_rtt = current_best_rtt * 10; // TODO add DEFINE to control this + best_rtt = RTT_THRESOULD_LIMIT(current_best_rtt); debug_dev(dev, "best connected rtt is %llu, searching for rtt better than %llu", current_best_rtt, best_rtt); for (i = 0; i < NUMBER_SERVERS; i++) { @@ -581,7 +581,7 @@ static bool dnbd3_better_rtt(struct dnbd3_server *new_server, struct dnbd3_serve uint64_t new_rtt = (new_server->rtts[0] + new_server->rtts[1] + new_server->rtts[2] + new_server->rtts[3]) / 4; uint64_t existing_rtt = (existing_server->rtts[0] + existing_server->rtts[1] + existing_server->rtts[2] + existing_server->rtts[3]) / 4; - if (new_rtt < ((existing_rtt * 2)/3)) { //TODO add macro to control this + if (new_rtt < RTT_THRESHOLD_FACTOR(existing_rtt)) { return true; } return false; @@ -590,6 +590,8 @@ static bool dnbd3_better_rtt(struct dnbd3_server *new_server, struct dnbd3_serve static void dnbd3_adjust_connections(struct dnbd3_device *dev) { int i; int sock_alive = 0; + uint64_t rtt; + uint64_t best_rtt = RTT_UNREACHABLE; struct dnbd3_server *server, *existing_server; // connect empty sockets @@ -627,6 +629,28 @@ static void dnbd3_adjust_connections(struct dnbd3_device *dev) { } } + // remove a socket if it is much slower than the others + if (sock_alive > 1) { + for (i = 0; i < NUMBER_CONNECTIONS; i++) { + if (dnbd3_is_sock_alive(dev->socks[i])) { + rtt = (dev->socks[i].server->rtts[0] + dev->socks[i].server->rtts[1] + dev->socks[i].server->rtts[2] + dev->socks[i].server->rtts[3]) / 4; + if (rtt <= best_rtt) { + best_rtt = rtt; + } + } + } + for (i = 0; i < NUMBER_CONNECTIONS; i++) { + if (dnbd3_is_sock_alive(dev->socks[i])) { + rtt = (dev->socks[i].server->rtts[0] + dev->socks[i].server->rtts[1] + dev->socks[i].server->rtts[2] + dev->socks[i].server->rtts[3]) / 4; + if (rtt > RTT_THRESOULD_LIMIT(best_rtt)) { + info_sock(&dev->socks[i], "removing connection with rtt %llu", rtt); + dnbd3_socket_disconnect(dev, NULL, &dev->socks[i]); + sock_alive--; + } + } + } + } + debug_dev(dev, "connected to %d/%d sockets", sock_alive, NUMBER_CONNECTIONS); } @@ -972,6 +996,9 @@ error: return result; } +/** + * connect a dnbd3 device to a server + */ static int dnbd3_socket_connect(struct dnbd3_device *dev, struct dnbd3_server *server) { int i; |