summaryrefslogtreecommitdiffstats
path: root/server/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.c')
-rw-r--r--server/server.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/server/server.c b/server/server.c
new file mode 100644
index 0000000..b701e4c
--- /dev/null
+++ b/server/server.c
@@ -0,0 +1,216 @@
+/*
+ * main.c - central part of the DNBD server application
+ * Copyright (C) 2006 Thorsten Zitterell <thorsten@zitterell.de>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+/* network includes */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+
+#define DNBD_USERSPACE 1
+#include "../common/dnbd-cliserv.h"
+
+#include "server.h"
+#include "query.h"
+#include "net.h"
+#include "filer.h"
+
+
+static int verbose = 0;
+static int running = 1;
+
+/*
+ * function: handle_signal(): set global variable running to 0 if signal arrives
+ */
+void handle_signal(int signum)
+{
+ running = 0;
+}
+
+void server_help(void)
+{
+ fprintf(stderr, "dnbd-server, version %s\n", DNBD_VERSION);
+ fprintf(stderr,
+ "Usage: dnbd-server -m <address> -d <device/file> -i <number>\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "description:\n");
+ fprintf(stderr, " -m|--mcast <multicast-address>\n");
+ fprintf(stderr, " -d|--device <block device or file>\n");
+ fprintf(stderr, " -i|--id <unique identification number>\n");
+ fprintf(stderr, " -t|--threads <number of threads>\n");
+}
+
+/*
+ * function: server_init(): parse command lines
+ */
+server_info_t *server_init(int argc, char **argv)
+{
+ /* cmd
+ * -1: error
+ * 0: not defined
+ * 1: serve
+ */
+ int cmd = 0;
+ server_info_t *server_info = NULL;
+
+ server_info = (server_info_t *) malloc(sizeof(server_info_t));
+ if (!server_info)
+ return NULL;
+
+ memset(server_info, 0, sizeof(server_info_t));
+
+ server_info->threads = 1;
+
+ /* return value for getopt */
+ int c;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"verbose", no_argument, 0, 'v'},
+ {"mcast", required_argument, 0, 'm'},
+ {"device", required_argument, 0, 'd'},
+ {"threads", required_argument, 0, 't'},
+ {"id", required_argument, 0, 'i'},
+ {0, 0, 0, 0}
+ };
+ /* option index for getopt_long */
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "vm:d:i:t:",
+ long_options, &option_index);
+
+ /* at end of options? */
+ if (c == -1)
+ break;
+
+ /*
+ cmd = (cmd ? -1 : xx) is used to set cmd when it was
+ unset (0) before. Otherwise save error value
+ */
+ switch (c) {
+ case 'v':
+ verbose++;
+ break;
+ case 'm':
+ server_info->mnet = optarg; /* multicast address */
+ break;
+ case 'd':
+ cmd = (cmd ? -1 : 2); /* device/file */
+ server_info->filename = optarg;
+ break;
+ case 'i':
+ if (sscanf(optarg, "%u",&server_info->id) != 1) {
+ fprintf(stderr,"ERROR: Id not a 16bit-integer (>0)\n");
+ cmd = -1;
+ }
+ break;
+ case 't':
+ if (sscanf(optarg, "%u",&server_info->threads) != 1) {
+ fprintf(stderr,"ERROR: Number of threads is wrong (>0)\n");
+ cmd = -1;
+ }
+ break;
+
+ default:
+ cmd = -1;
+ }
+
+ if (cmd < 0) break;
+ }
+
+ /* no/wrong command given? */
+ if (cmd <= 0) {
+ server_help();
+ goto out_free;
+ }
+
+ if (!server_info->mnet) {
+ fprintf(stderr, "ERROR: multicast group was not set!\n");
+ goto out_free;
+ }
+
+ if (!(server_info->id > 0)) {
+ fprintf(stderr, "ERROR: unique id not set or not valid!\n");
+ goto out_free;
+ }
+
+ if (!(server_info->threads > 0)) {
+ fprintf(stderr, "ERROR: number of threads is not valid!\n");
+ goto out_free;
+ }
+
+
+ /* call function for command */
+ goto out;
+
+ out_free:
+ if (server_info)
+ free(server_info);
+ server_info = NULL;
+ out:
+ return server_info;
+}
+
+/*
+ * function: main(): server startup
+ */
+int main(int argc, char **argv)
+{
+
+ server_info_t *server_info;
+
+ signal(SIGINT, handle_signal);
+
+ /* parse and verify command line options */
+ if (!(server_info = server_init(argc, argv))) {
+ fprintf(stderr, "ERROR: Parsing arguments!\n");
+ goto out_server;
+ }
+
+ /* initialize network configuration and start listener thread */
+ if (!(server_info->net_info = net_init(server_info->mnet))) {
+ fprintf(stderr, "ERROR: Initializing net!\n");
+ goto out_net;
+ }
+
+ if (!(server_info->filer_info = filer_init(server_info->filename))) {
+ fprintf(stderr, "ERROR: Initializing filer!\n");
+ goto out_filer;
+ }
+
+ /* initialize threads to handle requests */
+ if (!
+ (server_info->query_info =
+ query_init(server_info->net_info, server_info->filer_info,
+ server_info->id, server_info->threads))) {
+ fprintf(stderr, "ERROR: Initializing query!\n");
+ goto out_query;
+ }
+
+ while (running)
+ pause();
+
+ fprintf(stdout, "cleaning up...\n");
+ out_query:
+ if (server_info->filer_info)
+ free(server_info->filer_info);
+
+ out_filer:
+ if (server_info->net_info)
+ free(server_info->net_info);
+
+ out_net:
+ if (server_info) {
+ free(server_info);
+ }
+ out_server:
+ return 0;
+}