summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/kernel/dnbd3.h73
-rw-r--r--src/kernel/net.c31
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;