summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorJohann Latocha2012-01-24 20:42:30 +0100
committerJohann Latocha2012-01-24 20:42:30 +0100
commit90123ef4fbe457642325362ca07fe5b75df3f0c9 (patch)
tree12654b30e62d0819c54abbceae483800d1d608d1 /src/server
parentSupport files > 4GB (diff)
downloaddnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.tar.gz
dnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.tar.xz
dnbd3-90123ef4fbe457642325362ca07fe5b75df3f0c9.zip
Serving more than one image.
Diffstat (limited to 'src/server')
-rw-r--r--src/server/hashtable.c70
-rw-r--r--src/server/hashtable.h30
-rw-r--r--src/server/server.c84
3 files changed, 170 insertions, 14 deletions
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)