summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohann Latocha2012-02-02 23:32:03 +0100
committerJohann Latocha2012-02-02 23:32:03 +0100
commitb4df59e1711abb0e9a0a21dd92b8f966d9334b4a (patch)
treea6def33319fe06ef7ce62134ed3ea2573a37fca7
parent[MISC] .cproject and .project removed (diff)
downloaddnbd3-b4df59e1711abb0e9a0a21dd92b8f966d9334b4a.tar.gz
dnbd3-b4df59e1711abb0e9a0a21dd92b8f966d9334b4a.tar.xz
dnbd3-b4df59e1711abb0e9a0a21dd92b8f966d9334b4a.zip
[SERVER] IPC over unix socket
[SERVER] Print connected clients and used images
-rw-r--r--src/config.h2
-rw-r--r--src/server/ipc.c179
-rw-r--r--src/server/ipc.h (renamed from src/server/signal.h)14
-rw-r--r--src/server/net.c1
-rw-r--r--src/server/server.c25
-rw-r--r--src/server/server.h16
-rw-r--r--src/server/signal.c45
-rw-r--r--src/server/utils.c80
-rw-r--r--src/server/utils.h10
9 files changed, 234 insertions, 138 deletions
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 <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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#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/signal.h b/src/server/ipc.h
index d91babf..b08ce3c 100644
--- a/src/server/signal.h
+++ b/src/server/ipc.h
@@ -18,13 +18,15 @@
*
*/
-#ifndef SIGNAL_H_
-#define SIGNAL_H_
+#ifndef IPC_H_
+#define IPC_H_
-void dnbd3_handle_sigpipe(int signum);
+#define IPC_EXIT 0
+#define IPC_RELOAD 1
+#define IPC_INFO 2
-void dnbd3_handle_sighup(int signum);
+void* dnbd3_ipc_receive();
-void dnbd3_handle_sigterm(int signum);
+void dnbd3_ipc_send(int cmd);
-#endif /* SIGNAL_H_ */
+#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
@@ -30,13 +30,6 @@
typedef struct
{
- int sock;
- char ip[16];
- pthread_t *thread;
-} dnbd3_client_t;
-
-typedef struct
-{
char *file;
off_t filesize;
char **servers;
@@ -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 <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 <pthread.h>
-
-#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/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 <stdio.h>
#include <stdlib.h>
-#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
-
-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_ */