summaryrefslogtreecommitdiffstats
path: root/src/kernel/blk.c
diff options
context:
space:
mode:
authorManuel Bentele2020-11-06 12:44:43 +0100
committerManuel Bentele2020-11-06 12:44:43 +0100
commitef92307fd49e75482c7599caf68685afc1807512 (patch)
tree14dfcdd43d0a1c12d9e84d5b7c98807a2e56bece /src/kernel/blk.c
parent[BUILD] add CMake support to build docker images based on Archlinux (diff)
downloaddnbd3-ef92307fd49e75482c7599caf68685afc1807512.tar.gz
dnbd3-ef92307fd49e75482c7599caf68685afc1807512.tar.xz
dnbd3-ef92307fd49e75482c7599caf68685afc1807512.zip
[KERNEL, CLIENT]: submit and probe multiple dnbd3-server with ioctl OPEN
The ioctl OPEN call for DNBD3 devices exposed by the dnbd3 Linux kernel module, is extended with a fixed array of dnbd3 hosts. The fixed array allows the dnbd3-client to submit host information (IP address and port) of multiple dnbd3-servers. This information is used to probe all submitted dnbd3-servers and add them to the alternative dnbd3-server list. If at least one dnbd3-server is not reachable, the OPEN ioctl call will abort with an error code.
Diffstat (limited to 'src/kernel/blk.c')
-rw-r--r--src/kernel/blk.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 00c3f8f..2ff322a 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -39,6 +39,7 @@ static int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
struct request_queue *blk_queue = dev->disk->queue;
char *imgname = NULL;
dnbd3_ioctl_t *msg = NULL;
+ int i = 0;
while (dev->disconnecting) { /* do nothing */ }
@@ -91,30 +92,58 @@ static int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
}
else
{
- if (sizeof(msg->host) != sizeof(dev->cur_server.host))
- dev_info(dnbd3_device_to_dev(dev), "odd size bug triggered in IOCTL\n");
- memcpy(&dev->cur_server.host, &msg->host, sizeof(msg->host));
- dev->cur_server.failures = 0;
- memcpy(&dev->initial_server, &dev->cur_server, sizeof(dev->initial_server));
+ if (sizeof(msg->hosts[0]) != sizeof(dev->cur_server.host))
+ dev_warn(dnbd3_device_to_dev(dev), "odd size bug triggered in IOCTL\n");
+
+ /* assert that at least one and not to many hosts are given */
+ if (msg->hosts_num < 1 || msg->hosts_num > NUMBER_SERVERS) {
+ result = -EINVAL;
+ break;
+ }
+
dev->imgname = imgname;
dev->rid = msg->rid;
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]));
+
if (blk_queue->backing_dev_info != NULL) {
blk_queue->backing_dev_info->ra_pages = (msg->read_ahead_kb * 1024) / PAGE_SIZE;
}
- if (dnbd3_net_connect(dev) == 0)
- {
+ /* probe and add specified servers */
+ /* copy and probe servers in reverse order, so that the first specified server will be remain as inital/current server */
+ for (i = msg->hosts_num - 1; i >= 0; i--) {
+ /* copy provided host into corresponding alt server slot */
+ memset(&dev->alt_servers[i], 0, sizeof(dev->alt_servers[i]));
+ memcpy(&dev->alt_servers[i].host, &msg->hosts[i], sizeof(msg->hosts[i]));
+ dev->alt_servers[i].failures = 0;
+ /* probe added alt server */
+ memcpy(&dev->cur_server, &dev->alt_servers[i], sizeof(dev->cur_server));
+ memcpy(&dev->initial_server, &dev->cur_server, sizeof(dev->initial_server));
+ if (dnbd3_net_connect(dev) != 0) {
+ /* probing server failed, abort IOCTL with error */
+ result = -ENOENT;
+ break;
+ }
+
+ /* probing server was successful, go on with other servers */
result = 0;
+ /* do not disconnect last server since this is the current/initial server that should be connected */
+ if (i > 0) {
+ dnbd3_blk_fail_all_requests(dev);
+ result = dnbd3_net_disconnect(dev);
+ dnbd3_blk_fail_all_requests(dev);
+ }
+ }
+
+ if (result == 0)
+ {
+ /* probing was successful */
imgname = NULL; // Prevent kfree at the end
}
else
{
- result = -ENOENT;
+ /* probing failed */
dev->imgname = NULL;
}
}
@@ -154,7 +183,7 @@ static int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
}
else
{
- memcpy(&dev->new_servers[dev->new_servers_num].host, &msg->host, sizeof(msg->host));
+ memcpy(&dev->new_servers[dev->new_servers_num].host, &msg->hosts[0], sizeof(msg->hosts[0]));
dev->new_servers[dev->new_servers_num].failures = (cmd == IOCTL_ADD_SRV ? 0 : 1); // 0 = ADD, 1 = REM
++dev->new_servers_num;
result = 0;
@@ -231,7 +260,6 @@ int dnbd3_blk_add_device(dnbd3_device_t *dev, int minor)
int ret;
init_waitqueue_head(&dev->process_queue_send);
- init_waitqueue_head(&dev->process_queue_receive);
init_waitqueue_head(&dev->process_queue_discover);
INIT_LIST_HEAD(&dev->request_queue_send);
INIT_LIST_HEAD(&dev->request_queue_receive);