summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohann Latocha2012-01-24 20:42:30 +0100
committerJohann Latocha2012-01-24 20:42:30 +0100
commit90123ef4fbe457642325362ca07fe5b75df3f0c9 (patch)
tree12654b30e62d0819c54abbceae483800d1d608d1
parentSupport files > 4GB (diff)
downloaddnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.tar.gz
dnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.tar.xz
dnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.zip
Serving more than one image.
-rw-r--r--.gitignore1
-rw-r--r--src/client/client.c15
-rw-r--r--src/config.h29
-rw-r--r--src/kernel/blk.c4
-rw-r--r--src/kernel/core.c5
-rw-r--r--src/kernel/dnbd3.h1
-rw-r--r--src/kernel/net.c9
-rw-r--r--src/server/hashtable.c70
-rw-r--r--src/server/hashtable.h30
-rw-r--r--src/server/server.c84
-rw-r--r--src/types.h24
-rw-r--r--src/version.h20
12 files changed, 270 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore
index 567609b..7dd2803 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
build/
+dnbd3-server.conf
diff --git a/src/client/client.c b/src/client/client.c
index 68b7f5c..d60614b 100644
--- a/src/client/client.c
+++ b/src/client/client.c
@@ -31,10 +31,11 @@
void print_help(char* argv_0)
{
- printf("Usage: %s -H <host> -p <port> -d <device>\n", argv_0);
+ printf("Usage: %s -H <host> -p <port> -i <image-id> -d <device>\n", argv_0);
printf("Start the DNBD3 client.\n");
printf("-H or --host \t\t Host running dnbd3-server.\n");
printf("-p or --port \t\t Port used by server.\n");
+ printf("-i or --image \t\t Exported image ID.\n");
printf("-d or --device \t\t DNBD3 device name.\n");
printf("-h or --help \t\t Show this help text and quit.\n");
printf("-v or --version \t Show version and quit.\n");
@@ -51,15 +52,17 @@ int main(int argc, char *argv[])
{
char *host = NULL;
char *port = NULL;
+ char *image_id = NULL;
char *dev = NULL;
int opt = 0;
int longIndex = 0;
- static const char *optString = "H:p:d:hv?";
+ static const char *optString = "H:p:i:d:hv?";
static const struct option longOpts[] =
{
{ "host", required_argument, NULL, 'H' },
{ "port", required_argument, NULL, 'p' },
+ { "image", required_argument, NULL, 'i' },
{ "device", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' }, };
@@ -76,6 +79,9 @@ int main(int argc, char *argv[])
case 'p':
port = optarg;
break;
+ case 'i':
+ image_id = optarg;
+ break;
case 'd':
dev = optarg;
break;
@@ -91,7 +97,7 @@ int main(int argc, char *argv[])
opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
}
- if (!host || !port || !dev)
+ if (!host || !port || !dev || !image_id)
{
printf("FATAL: Not enough information specified\n");
exit(EXIT_FAILURE);
@@ -106,6 +112,9 @@ int main(int argc, char *argv[])
if (ioctl(fd, IOCTL_SET_PORT, port) < 0)
printf("ERROR: ioctl not successful\n");
+ if (ioctl(fd, IOCTL_SET_IMAGE, image_id) < 0)
+ printf("ERROR: ioctl not successful\n");
+
if (ioctl(fd, IOCTL_CONNECT) < 0)
printf("ERROR: ioctl not successful\n");
diff --git a/src/config.h b/src/config.h
index 1d31f60..2df4dab 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,9 +1,38 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
#ifndef CONFIG_H_
#define CONFIG_H_
+// network
#define PORT 5003
+// block device
#define KERNEL_SECTOR_SIZE 512
#define DNBD3_BLOCK_SIZE 4096
+// configuration file
+#define DEFAULT_CONFIG_FILE "/etc/dnbd3-server.conf"
+#define MAX_NUMBER_IMAGES 1024
+#define MAX_FILE_NAME 4096
+#define MAX_FILE_ID 8
+
+
#endif /* CONFIG_H_ */
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index bf7f4e8..8a31841 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -36,7 +36,9 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
case IOCTL_SET_PORT:
_port = (char *) arg;
break;
-
+ case IOCTL_SET_IMAGE:
+ _image_id = (char *) arg;
+ break;
case IOCTL_CONNECT:
dnbd3_net_connect();
break;
diff --git a/src/kernel/core.c b/src/kernel/core.c
index 3b6ce54..3fe88f3 100644
--- a/src/kernel/core.c
+++ b/src/kernel/core.c
@@ -28,8 +28,9 @@ struct request_queue *dnbd3_queue;
spinlock_t dnbd3_lock;
// network
-char* _host;
-char* _port;
+char* _host = NULL;
+char* _port = NULL;
+char* _image_id = NULL;
struct socket *_sock;
// process
diff --git a/src/kernel/dnbd3.h b/src/kernel/dnbd3.h
index 11eee48..71be4e8 100644
--- a/src/kernel/dnbd3.h
+++ b/src/kernel/dnbd3.h
@@ -36,6 +36,7 @@ extern spinlock_t dnbd3_lock;
// network
extern char* _host;
extern char* _port;
+extern char* _image_id;
extern struct socket *_sock;
// process
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 1ec92ca..ac8e81d 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -31,7 +31,7 @@ void dnbd3_net_connect(void)
struct task_struct *thread_send;
struct task_struct *thread_receive;
- if (!_host || !_port)
+ if (!_host || !_port || !_image_id)
{
printk("ERROR: Host or port not set.");
return;
@@ -55,6 +55,7 @@ void dnbd3_net_connect(void)
// prepare message and send request
dnbd3_request.cmd = CMD_GET_SIZE;
+ strcpy(dnbd3_request.image_id, _image_id);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
@@ -71,6 +72,12 @@ void dnbd3_net_connect(void)
kernel_recvmsg(_sock, &msg, &iov, 1, sizeof(dnbd3_reply), msg.msg_flags);
// set filesize
+ if (dnbd3_reply.filesize <= 0)
+ {
+ printk("ERROR: File size returned by server is < 0.\n");
+ return;
+ }
+
printk("INFO: dnbd3 filesize: %llu\n", dnbd3_reply.filesize);
set_capacity(disk, dnbd3_reply.filesize >> 9); /* 512 Byte blocks */
diff --git a/src/server/hashtable.c b/src/server/hashtable.c
new file mode 100644
index 0000000..518454f
--- /dev/null
+++ b/src/server/hashtable.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <search.h>
+#include <string.h>
+
+#include "../config.h"
+
+char key_buf[MAX_NUMBER_IMAGES * MAX_FILE_ID];
+char value_buf[MAX_NUMBER_IMAGES * MAX_FILE_NAME];
+
+char *key_ptr = key_buf;
+char *val_ptr = value_buf;
+
+void ht_create()
+{
+ (void) hcreate(MAX_NUMBER_IMAGES);
+}
+
+int ht_insert(char* key, char* value)
+{
+ if (strlen(key) > MAX_FILE_ID) return -1;
+ if (strlen(value) > MAX_FILE_NAME) return -2;
+
+ strcpy(key_ptr, key);
+ strcpy(val_ptr, value);
+
+ ENTRY item;
+ item.key = key_ptr;
+ item.data = val_ptr;
+
+ (void) hsearch(item, ENTER);
+
+ key_ptr += strlen(key) + 1;
+ val_ptr += strlen(value) + 1;
+
+ return 0;
+}
+
+char* ht_search(char* key)
+{
+ ENTRY *result;
+
+ ENTRY item;
+ item.key = key;
+
+ if ((result = hsearch(item, FIND)) != NULL)
+ return result->data;
+ else
+ return NULL;
+}
+
diff --git a/src/server/hashtable.h b/src/server/hashtable.h
new file mode 100644
index 0000000..c05d459
--- /dev/null
+++ b/src/server/hashtable.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef HASHTABLE_H_
+#define HASHTABLE_H_
+
+void ht_create ();
+
+int ht_insert(char* key, char* value);
+
+char* ht_search(char* key);
+
+#endif /* HASHTABLE_H_ */
diff --git a/src/server/server.c b/src/server/server.c
index 7f62a53..7185e2f 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -1,3 +1,23 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -19,17 +39,16 @@
#include "../types.h"
#include "../version.h"
-int file;
-off_t filesize;
+#include "hashtable.h"
void print_help(char* argv_0)
{
printf("Usage: %s [OPTIONS]...\n", argv_0);
- printf("Start the DNBD3 server.\n");
- printf("-f or --file \t\t File to export.\n");
- printf("-h or --help \t\t Show this help text and quit.\n");
- printf("-v or --version \t Show version and quit.\n");
+ printf("Start the DNBD3 server\n");
+ printf("-f or --file \t\t Configuration file\n \t\t\t (default /etc/dnbd3-server.conf)\n");
+ printf("-h or --help \t\t Show this help text and quit\n");
+ printf("-v or --version \t Show version and quit\n");
exit(0);
}
@@ -47,6 +66,8 @@ void handle_sigpipe(int signum)
void *handle_query(void *client_socket)
{
+ int image_file = -1;
+ off_t filesize = 0;
int sock = (int) client_socket;
struct dnbd3_request request;
struct dnbd3_reply reply;
@@ -58,23 +79,40 @@ void *handle_query(void *client_socket)
switch (cmd)
{
case CMD_GET_SIZE:
+ image_file = open(ht_search(request.image_id), O_RDONLY);
+ if (image_file < 0)
+ {
+ printf("ERROR: Client requested an unknown image id.\n");
+ filesize = 0;
+ }
+ else
+ {
+ struct stat st;
+ fstat(image_file, &st);
+ filesize = st.st_size;
+ }
+
reply.cmd = request.cmd;
reply.filesize = filesize;
send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0);
break;
case CMD_GET_BLOCK:
+ if (image_file < 0)
+ break;
+
reply.cmd = request.cmd;
memcpy(reply.handle, request.handle, sizeof(request.handle));
send(sock, (char *) &reply, sizeof(struct dnbd3_reply), 0);
- if (sendfile(sock, file, (off_t *) &request.offset, request.size) <0)
+ if (sendfile(sock, image_file, (off_t *) &request.offset, request.size) <0)
printf("ERROR: sendfile returned -1\n");
break;
default:
printf("ERROR: Unknown command\n");
+ break;
}
}
@@ -85,6 +123,8 @@ void *handle_query(void *client_socket)
int main(int argc, char* argv[])
{
+ char *config_file_name = DEFAULT_CONFIG_FILE;
+
int opt = 0;
int longIndex = 0;
static const char *optString = "f:hv?";
@@ -95,18 +135,13 @@ int main(int argc, char* argv[])
{ "version", no_argument, NULL, 'v' } };
opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
- if (opt == -1)
- print_help(argv[0]);
while (opt != -1)
{
switch (opt)
{
case 'f':
- file = open(optarg, O_RDONLY);
- struct stat st;
- fstat(file, &st);
- filesize = st.st_size;
+ config_file_name = optarg;
break;
case 'h':
print_help(argv[0]);
@@ -120,6 +155,28 @@ int main(int argc, char* argv[])
opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
}
+ // parse config file
+ ht_create();
+ FILE *config_file = fopen(config_file_name , "r");
+ if (config_file == NULL)
+ {
+ printf("ERROR: Config file not found: %s\n", config_file_name);
+ exit(EXIT_FAILURE);
+ }
+ char line[MAX_FILE_NAME + 1 + MAX_FILE_ID];
+ char* image_name = NULL;
+ char* image_id = NULL;
+ while (fgets (line , sizeof(line) , config_file) != NULL )
+ {
+ sscanf (line, "%as %as", &image_name, &image_id);
+ if (ht_insert(image_id, image_name) < 0)
+ {
+ printf("ERROR: Image name or ID is too big\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ // setup network
signal(SIGPIPE, handle_sigpipe);
struct sockaddr_in server;
@@ -154,7 +211,6 @@ int main(int argc, char* argv[])
exit(EXIT_FAILURE);
}
- printf("INFO: Filesize: %llu bytes\n", filesize);
printf("INFO: Server is ready...\n");
while (1)
diff --git a/src/types.h b/src/types.h
index 3005f62..f3b2b97 100644
--- a/src/types.h
+++ b/src/types.h
@@ -1,3 +1,23 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
#ifndef TYPES_H_
#define TYPES_H_
@@ -7,7 +27,8 @@
#define DNBD3_MAGIC 'd'
#define IOCTL_SET_HOST _IO(0xab, 1)
#define IOCTL_SET_PORT _IO(0xab, 2)
-#define IOCTL_CONNECT _IO(0xab, 3)
+#define IOCTL_SET_IMAGE _IO(0xab, 3)
+#define IOCTL_CONNECT _IO(0xab, 4)
// network
#define CMD_GET_BLOCK 1
@@ -18,6 +39,7 @@ typedef struct dnbd3_request {
uint16_t cmd;
uint64_t offset;
uint64_t size;
+ char image_id[MAX_FILE_ID];
char handle[8];
} dnbd3_request_t;
#pragma pack(0)
diff --git a/src/version.h b/src/version.h
index 86e034a..bbaaf41 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,3 +1,23 @@
+/*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2011-2012 Johann Latocha <johann@latocha.de>
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
#ifndef VERSION_H_
#define VERSION_H_