From b4df59e1711abb0e9a0a21dd92b8f966d9334b4a Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Thu, 2 Feb 2012 23:32:03 +0100 Subject: [SERVER] IPC over unix socket [SERVER] Print connected clients and used images --- src/config.h | 2 +- src/server/ipc.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/server/ipc.h | 32 ++++++++++ src/server/net.c | 1 + src/server/server.c | 25 +++++--- src/server/server.h | 16 ++--- src/server/signal.c | 45 ------------- src/server/signal.h | 30 --------- src/server/utils.c | 80 +++++------------------ src/server/utils.h | 10 ++- 10 files changed, 258 insertions(+), 162 deletions(-) create mode 100644 src/server/ipc.c create mode 100644 src/server/ipc.h delete mode 100644 src/server/signal.c delete mode 100644 src/server/signal.h (limited to 'src') diff --git a/src/config.h b/src/config.h index c839f6e..e9d564a 100644 --- a/src/config.h +++ b/src/config.h @@ -33,6 +33,6 @@ // misc #define DEFAULT_CONFIG_FILE "/etc/dnbd3-server.conf" -#define SERVER_PID_FILE "/tmp/dnbd3-server.pid" +#define UNIX_SOCKET "/tmp/dnbd3-server.sock" #endif /* CONFIG_H_ */ diff --git a/src/server/ipc.c b/src/server/ipc.c new file mode 100644 index 0000000..b5651ac --- /dev/null +++ b/src/server/ipc.c @@ -0,0 +1,179 @@ +/* + * This file is part of the Distributed Network Block Device 3 + * + * Copyright(c) 2011-2012 Johann Latocha + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include "ipc.h" +#include "config.h" +#include "server.h" +#include "utils.h" + +void* dnbd3_ipc_receive() +{ + int server_sock, client_sock; + struct sockaddr_un server, client; + unsigned int len = sizeof(client); + + GSList *iterator = NULL; + + // Create socket + if ((server_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + perror("ERROR: IPC socket"); + exit(EXIT_FAILURE); + } + + server.sun_family = AF_UNIX; + strcpy(server.sun_path, UNIX_SOCKET); + unlink(UNIX_SOCKET); + + // Bind to socket + if (bind(server_sock, &server, sizeof(server.sun_family) + strlen(server.sun_path)) < 0) + { + perror("ERROR: IPC bind"); + exit(EXIT_FAILURE); + } + + // Listen on socket + if (listen(server_sock, 5) < 0) + { + perror("ERROR: IPC listen"); + exit(EXIT_FAILURE); + } + + while (1) + { + int cmd; + int num = 0; + char buf[4096]; + + // Accept connection + if ((client_sock = accept(server_sock, &client, &len)) < 0) + { + perror("ERROR: IPC accept"); + exit(EXIT_FAILURE); + } + + recv(client_sock, &cmd, sizeof(int), MSG_WAITALL); + + switch (cmd) + { + case IPC_EXIT: + close(server_sock); + dnbd3_cleanup(); + break; + + case IPC_RELOAD: + printf("INFO: Reloading configuration...\n"); + pthread_spin_lock(&_spinlock); + dnbd3_reload_config(_config_file_name); + pthread_spin_unlock(&_spinlock); + break; + + case IPC_INFO: + num = g_slist_length(_dnbd3_clients); + send(client_sock, &num, sizeof(int), MSG_WAITALL); // send number of clients + for (iterator = _dnbd3_clients; iterator; iterator = iterator->next) + { + dnbd3_client_t *client = iterator->data; + if (client->image) + { + sprintf(buf, "%s\t%s\n", client->ip, client->image->file); + send(client_sock, buf, sizeof(buf), MSG_WAITALL); + } + } + close(client_sock); + break; + + default: + printf("ERROR: Unknown command: %i", cmd); + break; + + } + + } + + close(server_sock); +} + +void dnbd3_ipc_send(int cmd) +{ + int client_sock; + struct sockaddr_un server; + + // Create socket + if ((client_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + perror("ERROR: IPC socket"); + exit(EXIT_FAILURE); + } + + server.sun_family = AF_UNIX; + strcpy(server.sun_path, UNIX_SOCKET); + + // Connect to server + if (connect(client_sock, &server, sizeof(server.sun_family) + strlen(server.sun_path)) < 0) + { + perror("ERROR: IPC connect"); + exit(EXIT_FAILURE); + } + + int i, num = 0; + char buf[4096]; + + switch (cmd) + { + case IPC_EXIT: + send(client_sock, &cmd, sizeof(int), MSG_WAITALL); + break; + + case IPC_RELOAD: + send(client_sock, &cmd, sizeof(int), MSG_WAITALL); + break; + + case IPC_INFO: + send(client_sock, &cmd, sizeof(int), MSG_WAITALL); + recv(client_sock, &num, sizeof(int), MSG_WAITALL); + + printf("INFO: Number clients connected: %i\n", num); + + for (i = 0; i < num; i++) + { + if (recv(client_sock, &buf, sizeof(buf), MSG_WAITALL) > 0) + printf("INFO: %s", buf); + } + + break; + + default: + printf("ERROR: Unknown command: %i", cmd); + break; + + } + + close(client_sock); +} diff --git a/src/server/ipc.h b/src/server/ipc.h new file mode 100644 index 0000000..b08ce3c --- /dev/null +++ b/src/server/ipc.h @@ -0,0 +1,32 @@ +/* + * This file is part of the Distributed Network Block Device 3 + * + * Copyright(c) 2011-2012 Johann Latocha + * + * 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 IPC_H_ +#define IPC_H_ + +#define IPC_EXIT 0 +#define IPC_RELOAD 1 +#define IPC_INFO 2 + +void* dnbd3_ipc_receive(); + +void dnbd3_ipc_send(int cmd); + +#endif /* IPC_H_ */ diff --git a/src/server/net.c b/src/server/net.c index 4f0e5a4..f49305b 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -60,6 +60,7 @@ void *dnbd3_handle_query(void *dnbd3_client) { image_file = open(image->file, O_RDONLY); reply.filesize = image->filesize; + client->image = image; } else { diff --git a/src/server/server.c b/src/server/server.c index a324682..4309989 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -31,8 +31,8 @@ #include "server.h" #include "utils.h" -#include "signal.h" #include "net.h" +#include "ipc.h" int _sock; @@ -47,9 +47,10 @@ void dnbd3_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 (default /etc/dnbd3-server.conf)\n"); - printf("-n or --nodaemon \t\t Start server in foreground\n"); + printf("-n or --nodaemon \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("-i or --info \t\t Print connected clients and used images\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); @@ -76,7 +77,7 @@ void dnbd3_cleanup() close(_sock); free(_images); - dnbd3_delete_pid_file(); + unlink(UNIX_SOCKET); exit(EXIT_SUCCESS); } @@ -85,13 +86,14 @@ int main(int argc, char* argv[]) int demonize = 1; int opt = 0; int longIndex = 0; - static const char *optString = "f:nrshv?"; + static const char *optString = "f:nrsihv?"; 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' }, + { "info", no_argument, NULL, 'i' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' } }; @@ -109,11 +111,15 @@ int main(int argc, char* argv[]) break; case 'r': printf("INFO: Reloading configuration file...\n"); - dnbd3_send_signal(SIGHUP); + dnbd3_ipc_send(IPC_RELOAD); return EXIT_SUCCESS; case 's': printf("INFO: Stopping running server...\n"); - dnbd3_send_signal(SIGTERM); + dnbd3_ipc_send(IPC_EXIT); + return EXIT_SUCCESS; + case 'i': + printf("INFO: Requesting information...\n"); + dnbd3_ipc_send(IPC_INFO); return EXIT_SUCCESS; case 'h': dnbd3_print_help(argv[0]); @@ -136,7 +142,6 @@ int main(int argc, char* argv[]) // setup signal handler signal(SIGPIPE, dnbd3_handle_sigpipe); - signal(SIGHUP, dnbd3_handle_sighup); signal(SIGTERM, dnbd3_handle_sigterm); signal(SIGINT, dnbd3_handle_sigterm); @@ -151,7 +156,10 @@ int main(int argc, char* argv[]) timeout.tv_sec = SERVER_SOCKET_TIMEOUT; timeout.tv_usec = 0; - dnbd3_write_pid_file(getpid()); + // setup icp + pthread_t thread_ipc; + pthread_create(&(thread_ipc), NULL, dnbd3_ipc_receive, NULL); + printf("INFO: Server is ready...\n"); // main loop @@ -173,6 +181,7 @@ int main(int argc, char* argv[]) strcpy(dnbd3_client->ip, inet_ntoa(client.sin_addr)); dnbd3_client->sock = fd; dnbd3_client->thread = &thread; + dnbd3_client->image = NULL; _dnbd3_clients = g_slist_append(_dnbd3_clients, dnbd3_client); diff --git a/src/server/server.h b/src/server/server.h index 303d6ee..dd8584c 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -28,13 +28,6 @@ #include "config.h" #include "../types.h" -typedef struct -{ - int sock; - char ip[16]; - pthread_t *thread; -} dnbd3_client_t; - typedef struct { char *file; @@ -45,13 +38,20 @@ typedef struct int rid; } dnbd3_image_t; +typedef struct +{ + int sock; + char ip[16]; + pthread_t *thread; + dnbd3_image_t *image; +} dnbd3_client_t; + extern GSList *_dnbd3_clients; extern pthread_spinlock_t _spinlock; extern char *_config_file_name; extern dnbd3_image_t *_images; extern size_t _num_images; - void dnbd3_cleanup(); #endif /* SERVER_H_ */ diff --git a/src/server/signal.c b/src/server/signal.c deleted file mode 100644 index 443742f..0000000 --- a/src/server/signal.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the Distributed Network Block Device 3 - * - * Copyright(c) 2011-2012 Johann Latocha - * - * 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 -#include - -#include "server.h" -#include "utils.h" - -void dnbd3_handle_sigpipe(int signum) -{ - printf("ERROR: SIGPIPE received!\n"); -} - -void dnbd3_handle_sighup(int signum) -{ - printf("INFO: SIGHUP received!\n"); - printf("INFO: Reloading configuration...\n"); - pthread_spin_lock(&_spinlock); - dnbd3_reload_config(_config_file_name); - pthread_spin_unlock(&_spinlock); -} - -void dnbd3_handle_sigterm(int signum) -{ - printf("INFO: SIGTERM or SIGINT received!\n"); - dnbd3_cleanup(); -} diff --git a/src/server/signal.h b/src/server/signal.h deleted file mode 100644 index d91babf..0000000 --- a/src/server/signal.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the Distributed Network Block Device 3 - * - * Copyright(c) 2011-2012 Johann Latocha - * - * 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 SIGNAL_H_ -#define SIGNAL_H_ - -void dnbd3_handle_sigpipe(int signum); - -void dnbd3_handle_sighup(int signum); - -void dnbd3_handle_sigterm(int signum); - -#endif /* SIGNAL_H_ */ diff --git a/src/server/utils.c b/src/server/utils.c index f3a4c5e..67d91c9 100644 --- a/src/server/utils.c +++ b/src/server/utils.c @@ -18,72 +18,12 @@ * */ -#include "server.h" -#include "utils.h" - -#include #include -#include #include #include - -void dnbd3_write_pid_file(pid_t pid) -{ - FILE *f = fopen(SERVER_PID_FILE, "w"); - if (f != NULL) - { - fprintf(f, "%i", pid); - fclose(f); - } - else - { - printf("ERROR: Couldn't write pid file (%s).\n", SERVER_PID_FILE); - } -} - -pid_t dnbd3_read_pid_file() -{ - pid_t pid = 0; - - FILE *f = fopen(SERVER_PID_FILE, "r"); - if (f != NULL) - { - fscanf(f, "%i", &pid); - fclose(f); - } - else - { - printf("ERROR: Couldn't read pid file (%s).\n", SERVER_PID_FILE); - } - - return pid; -} - -void dnbd3_delete_pid_file() -{ - if (unlink(SERVER_PID_FILE) != 0) - { - printf("ERROR: Couldn't delete pid file (%s).\n", SERVER_PID_FILE); - } -} - -void dnbd3_send_signal(int signum) -{ - pid_t pid = dnbd3_read_pid_file(); - if (pid != 0) - { - if (kill(pid, signum) != 0) - { - printf("ERROR: dnbd3-server is not running\n"); - dnbd3_delete_pid_file(); - } - } - else - { - printf("ERROR: dnbd3-server is not running\n"); - } -} +#include "server.h" +#include "utils.h" void dnbd3_load_config(char *file) { @@ -124,7 +64,7 @@ void dnbd3_load_config(char *file) } g_strfreev(groups); - g_key_file_free (gkf); + g_key_file_free(gkf); } void dnbd3_reload_config(char* config_file_name) @@ -139,10 +79,22 @@ dnbd3_image_t* dnbd3_get_image(int vid, int rid) // TODO: find better data structure dnbd3_image_t *result = NULL; int i; - for (i = 0; i < _num_images; ++i) { + for (i = 0; i < _num_images; ++i) + { if (_images[i].vid == vid && _images[i].rid == rid) result = &_images[i]; } return result; } + +void dnbd3_handle_sigpipe(int signum) +{ + printf("ERROR: SIGPIPE received!\n"); +} + +void dnbd3_handle_sigterm(int signum) +{ + printf("INFO: SIGTERM or SIGINT received!\n"); + dnbd3_cleanup(); +} diff --git a/src/server/utils.h b/src/server/utils.h index 6ac51ff..e6bd6a9 100644 --- a/src/server/utils.h +++ b/src/server/utils.h @@ -26,14 +26,12 @@ #ifndef UTILS_H_ #define UTILS_H_ -pid_t dnbd3_read_pid_file(); -void dnbd3_write_pid_file(pid_t pid); -void dnbd3_delete_pid_file(); - -void dnbd3_send_signal(int signum); - void dnbd3_load_config(char *file); void dnbd3_reload_config(char* config_file_name); + dnbd3_image_t* dnbd3_get_image(int vid, int rid); +void dnbd3_handle_sigpipe(int signum); +void dnbd3_handle_sigterm(int signum); + #endif /* UTILS_H_ */ -- cgit v1.2.3-55-g7522