From ecd41fa1ea2b5b267e6f04170bad30b150433fc6 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Thu, 26 Jan 2012 18:53:43 +0100 Subject: [SERVER] Reload configuration at runtime --- src/server/server.c | 96 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 31 deletions(-) (limited to 'src/server/server.c') diff --git a/src/server/server.c b/src/server/server.c index c266f19..90ec77b 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -39,14 +39,22 @@ #include "../types.h" #include "../version.h" +#include "utils.h" #include "hashtable.h" +int _sock; +pthread_spinlock_t spinlock; +char *config_file_name = DEFAULT_CONFIG_FILE; + 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 Configuration file\n \t\t\t (default /etc/dnbd3-server.conf)\n"); + printf("-f or --file \t\t Configuration file (default /etc/dnbd3-server.conf)\n"); + printf("-n or --nodaemon \t\t Start server in foreground\n"); + printf("-r or --reload \t\t Reload configuration file\n"); + printf("-s or --stop \t\t Stop running dnbd3-server\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); @@ -64,6 +72,24 @@ void handle_sigpipe(int signum) return; } +void handle_sighup(int signum) +{ + printf("INFO: SIGHUP received!\n"); + printf("INFO: Reloading configuration...\n"); + pthread_spin_lock(&spinlock); + reload_config(config_file_name); + pthread_spin_unlock(&spinlock); + // TODO: stop handle_query or use mutex before image_file = open(ht_search(request.image_id), O_RDONLY); +} + +void handle_sigterm(int signum) +{ + printf("INFO: SIGTERM or SIGINT received!\n"); + close(_sock); + delete_pid_file(); + exit(EXIT_SUCCESS); +} + void *handle_query(void *client_socket) { int image_file = -1; @@ -79,7 +105,9 @@ void *handle_query(void *client_socket) switch (cmd) { case CMD_GET_SIZE: + pthread_spin_lock(&spinlock); // because of reloading config image_file = open(ht_search(request.image_id), O_RDONLY); + pthread_spin_unlock(&spinlock); if (image_file < 0) { printf("ERROR: Client requested an unknown image id.\n"); @@ -124,14 +152,16 @@ void *handle_query(void *client_socket) int main(int argc, char* argv[]) { - char *config_file_name = DEFAULT_CONFIG_FILE; - + int demonize = 1; int opt = 0; int longIndex = 0; - static const char *optString = "f:hv?"; + static const char *optString = "f:nrshv?"; static const struct option longOpts[] = { { "file", required_argument, NULL, 'f' }, + { "nodaemon", no_argument, NULL, 'n' }, + { "reload", no_argument, NULL, 'r' }, + { "stop", no_argument, NULL, 's' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' } }; @@ -144,6 +174,17 @@ int main(int argc, char* argv[]) case 'f': config_file_name = optarg; break; + case 'n': + demonize = 0; + break; + case 'r': + printf("INFO: Reloading configuration file...\n"); + send_signal(SIGHUP); + return EXIT_SUCCESS; + case 's': + printf("INFO: Stopping running server...\n"); + send_signal(SIGTERM); + return EXIT_SUCCESS; case 'h': print_help(argv[0]); break; @@ -156,38 +197,27 @@ 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); - } - } + if (demonize) + daemon(1,0); - // setup network + pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE); + load_config(config_file_name); + + // setup signal handler signal(SIGPIPE, handle_sigpipe); + signal(SIGHUP, handle_sighup); + signal(SIGTERM, handle_sigterm); + signal(SIGINT, handle_sigterm); + // setup network struct sockaddr_in server; struct sockaddr_in client; - int sock, fd; + int fd; unsigned int len; // Create socket - sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sock < 0) + _sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (_sock < 0) { printf("ERROR: Socket failure\n"); exit(EXIT_FAILURE); @@ -199,25 +229,26 @@ int main(int argc, char* argv[]) server.sin_port = htons(PORT); // set port number // Bind to socket - if (bind(sock, (struct sockaddr*) &server, sizeof(server)) < 0) + if (bind(_sock, (struct sockaddr*) &server, sizeof(server)) < 0) { printf("ERROR: Bind failure\n"); exit(EXIT_FAILURE); } // Listen on socket - if (listen(sock, 50) == -1) + if (listen(_sock, 50) == -1) { printf("ERROR: Listen failure\n"); exit(EXIT_FAILURE); } + write_pid_file(getpid()); printf("INFO: Server is ready...\n"); while (1) { len = sizeof(client); - fd = accept(sock, (struct sockaddr*) &client, &len); + fd = accept(_sock, (struct sockaddr*) &client, &len); if (fd < 0) { printf("ERROR: Accept failure\n"); @@ -230,5 +261,8 @@ int main(int argc, char* argv[]) pthread_create(&(thread), NULL, handle_query, (void *) fd); pthread_detach(thread); } + + close(_sock); + delete_pid_file(); return EXIT_SUCCESS; } -- cgit v1.2.3-55-g7522