summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobbie Harwood <rharwood@redhat.com>2015-09-08 17:27:30 -0400
committerSimo Sorce <simo@redhat.com>2015-09-15 18:23:36 -0400
commit883a5a050e98014671eadd47a9c2a221403796a5 (patch)
treeb979fe98742efff1f1d6d86e86b3164fa624c68a
parentd9ebdccbc0a01acaf773ea9f3976c6ff9b51a5b4 (diff)
downloadgss-proxy-883a5a050e98014671eadd47a9c2a221403796a5.tar.gz
gss-proxy-883a5a050e98014671eadd47a9c2a221403796a5.tar.xz
gss-proxy-883a5a050e98014671eadd47a9c2a221403796a5.zip
Reload config on SIGHUP
For sockets, we will only reinitialize those that have changed. Additionally, the old text about SIGHUP behavior was incorrect. Signed-off-by: Robbie Harwood <rharwood@redhat.com> Ticket: https://fedorahosted.org/gss-proxy/ticket/125
-rw-r--r--proxy/man/gssproxy.8.xml9
-rw-r--r--proxy/src/gp_init.c12
-rw-r--r--proxy/src/gp_proxy.h4
-rw-r--r--proxy/src/gp_socket.c9
-rw-r--r--proxy/src/gssproxy.c177
5 files changed, 162 insertions, 49 deletions
diff --git a/proxy/man/gssproxy.8.xml b/proxy/man/gssproxy.8.xml
index 809ec20..1df4b0d 100644
--- a/proxy/man/gssproxy.8.xml
+++ b/proxy/man/gssproxy.8.xml
@@ -158,10 +158,11 @@
<term>SIGHUP</term>
<listitem>
<para>
- Tells the GssProxy to stop writing to its current debug
- file descriptors and to close and reopen them. This is
- meant to facilitate log rolling with programs like
- logrotate.
+ Request a reload of all configuration for gssproxy.
+ If there is an error in the configuration files, the
+ existing configuration will not be replaced; if there
+ is a problem applying the new configuration, gssproxy
+ will exit.
</para>
</listitem>
</varlistentry>
diff --git a/proxy/src/gp_init.c b/proxy/src/gp_init.c
index 376b97e..3430c90 100644
--- a/proxy/src/gp_init.c
+++ b/proxy/src/gp_init.c
@@ -102,12 +102,6 @@ static void break_loop(verto_ctx *vctx, verto_ev *ev)
verto_break(vctx);
}
-static void reload_conf(verto_ctx *vctx, verto_ev *ev)
-{
- GPDEBUG("Reloading configuration after receiving a signal\n");
- /* TODO */
-}
-
verto_ctx *init_event_loop(void)
{
verto_ctx *vctx;
@@ -136,16 +130,12 @@ verto_ctx *init_event_loop(void)
verto_free(vctx);
return NULL;
}
- ev = verto_add_signal(vctx, VERTO_EV_FLAG_PERSIST, reload_conf, SIGHUP);
- if (!ev) {
- verto_free(vctx);
- return NULL;
- }
ev = verto_add_signal(vctx, VERTO_EV_FLAG_PERSIST, VERTO_SIG_IGN, SIGPIPE);
if (!ev) {
verto_free(vctx);
return NULL;
}
+ /* SIGHUP handler added in main */
return vctx;
}
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index d5f6fb1..e6753a1 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -41,6 +41,8 @@ struct gp_service {
struct gp_cred_krb5 krb5;
struct gp_creds_handle *creds_handle;
+
+ verto_ev *ev;
};
struct gp_config {
@@ -62,6 +64,7 @@ struct gssproxy_ctx {
struct gp_config *config;
struct gp_workers *workers;
verto_ctx *vctx;
+ verto_ev *sock_ev; /* default socket event */
};
struct gp_sock_ctx {
@@ -94,6 +97,7 @@ void write_pid(void);
int drop_privs(struct gp_config *cfg);
/* from gp_socket.c */
+void free_unix_socket(verto_ctx *ctx, verto_ev *ev);
struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
const char *file_name);
void accept_sock_conn(verto_ctx *vctx, verto_ev *ev);
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c
index c25854f..62d7dbc 100644
--- a/proxy/src/gp_socket.c
+++ b/proxy/src/gp_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
+/* Copyright (C) 2011,2015 the GSS-PROXY contributors, see COPYING for license */
#include "config.h"
#include <stdlib.h>
@@ -146,6 +146,13 @@ static int set_fd_flags(int fd, int flags)
return 0;
}
+void free_unix_socket(verto_ctx *ctx, verto_ev *ev)
+{
+ struct gp_sock_ctx *sock_ctx = NULL;
+ sock_ctx = verto_get_private(ev);
+ free(sock_ctx);
+}
+
struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
const char *file_name)
{
diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c
index f025aa2..3067fb4 100644
--- a/proxy/src/gssproxy.c
+++ b/proxy/src/gssproxy.c
@@ -1,29 +1,158 @@
-/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
+/* Copyright (C) 2011,2015 the GSS-PROXY contributors, see COPYING for license */
#include "config.h"
#include <stdlib.h>
#include "popt.h"
#include "gp_proxy.h"
+#include <signal.h>
+#include <string.h>
+
+const int vflags =
+ VERTO_EV_FLAG_PERSIST |
+ VERTO_EV_FLAG_IO_READ |
+ VERTO_EV_FLAG_IO_CLOSE_FD;
+
+char *opt_config_file = NULL;
+char *opt_config_dir = NULL;
+char *opt_config_socket = NULL;
+int opt_daemon = 0;
+
+struct gssproxy_ctx *gpctx;
+
+static struct gp_service *
+find_service_by_name(struct gp_config *cfg, const char *name)
+{
+ int i;
+ struct gp_service *ret = NULL;
+
+ for (i = 0; i < cfg->num_svcs; i++) {
+ if (strcmp(cfg->svcs[i]->name, name) == 0) {
+ ret = cfg->svcs[i];
+ break;
+ }
+ }
+ return ret;
+}
+
+static verto_ev *setup_socket(char *sock_name, verto_ctx *vctx)
+{
+ struct gp_sock_ctx *sock_ctx;
+ verto_ev *ev;
+
+ sock_ctx = init_unix_socket(gpctx, sock_name);
+ if (!sock_ctx) {
+ return NULL;
+ }
+
+ ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd);
+ if (!ev) {
+ return NULL;
+ }
+
+ verto_set_private(ev, sock_ctx, free_unix_socket);
+ return ev;
+}
+
+static int init_sockets(verto_ctx *vctx, struct gp_config *old_config)
+{
+ int i;
+ struct gp_sock_ctx *sock_ctx;
+ verto_ev *ev;
+ struct gp_service *svc;
+
+ /* init main socket */
+ if (!old_config) {
+ ev = setup_socket(gpctx->config->socket_name, vctx);
+ if (!ev) {
+ return 1;
+ }
+
+ gpctx->sock_ev = ev;
+ } else if (strcmp(old_config->socket_name,
+ gpctx->config->socket_name) != 0) {
+ ev = setup_socket(gpctx->config->socket_name, vctx);
+ if (!ev) {
+ return 1;
+ }
+
+ gpctx->sock_ev = ev;
+ verto_del(gpctx->sock_ev);
+ } else {
+ /* free_config will erase the socket name; update it accordingly */
+ sock_ctx = verto_get_private(gpctx->sock_ev);
+ sock_ctx->socket = gpctx->config->socket_name;
+ }
+
+ /* propagate any sockets that shouldn't change */
+ if (old_config) {
+ for (i = 0; i < old_config->num_svcs; i++) {
+ if (old_config->svcs[i]->ev) {
+ svc = find_service_by_name(gpctx->config,
+ old_config->svcs[i]->name);
+ if (svc && strcmp(svc->socket,
+ old_config->svcs[i]->socket) == 0) {
+ svc->ev = old_config->svcs[i]->ev;
+ sock_ctx = verto_get_private(svc->ev);
+ sock_ctx->socket = svc->socket;
+ } else {
+ verto_del(old_config->svcs[i]->ev);
+ }
+ }
+ }
+ }
+
+ /* init all other sockets */
+ for (i = 0; i < gpctx->config->num_svcs; i++) {
+ svc = gpctx->config->svcs[i];
+ if (svc->socket != NULL && svc->ev == NULL) {
+ ev = setup_socket(svc->socket, vctx);
+ if (!ev) {
+ return 1;
+ }
+ svc->ev = ev;
+ }
+ }
+ return 0;
+}
+
+static void hup_handler(verto_ctx *vctx, verto_ev *ev)
+{
+ int ret;
+ struct gp_config *new_config, *old_config;
+
+ GPDEBUG("Received SIGHUP; re-reading config.\n");
+ new_config = read_config(opt_config_file, opt_config_dir,
+ opt_config_socket, opt_daemon);
+ if (!new_config) {
+ GPERROR("Error reading new configuration on SIGHUP; keeping old "
+ "configuration instead!\n");
+ return;
+ }
+ old_config = gpctx->config;
+ gpctx->config = new_config;
+
+ ret = init_sockets(vctx, old_config);
+ if (ret != 0) {
+ exit(ret);
+ }
+
+ free_config(&old_config);
+
+ GPDEBUG("New config loaded successfully.\n");
+ return;
+}
int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
- int opt_daemon = 0;
int opt_interactive = 0;
int opt_version = 0;
- char *opt_config_file = NULL;
- char *opt_config_dir = NULL;
- char *opt_config_socket = NULL;
int opt_debug = 0;
verto_ctx *vctx;
verto_ev *ev;
- int vflags;
- struct gssproxy_ctx *gpctx;
- struct gp_sock_ctx *sock_ctx;
int wait_fd;
int ret;
- int i;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -96,34 +225,16 @@ int main(int argc, const char *argv[])
}
gpctx->vctx = vctx;
- /* init main socket */
- sock_ctx = init_unix_socket(gpctx, gpctx->config->socket_name);
- if (!sock_ctx) {
- return 1;
- }
-
- vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ;
- ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd);
+ /* Add SIGHUP here so that gpctx is in scope for the handler */
+ ev = verto_add_signal(vctx, VERTO_EV_FLAG_PERSIST, hup_handler, SIGHUP);
if (!ev) {
+ fprintf(stderr, "Failed to register SIGHUP handler with verto!\n");
return 1;
}
- verto_set_private(ev, sock_ctx, NULL);
-
- /* init secondary sockets */
- for (i = 0; i < gpctx->config->num_svcs; i++) {
- if (gpctx->config->svcs[i]->socket != NULL) {
- sock_ctx = init_unix_socket(gpctx, gpctx->config->svcs[i]->socket);
- if (!sock_ctx) {
- return 1;
- }
- vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ;
- ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd);
- if (!ev) {
- return 1;
- }
- verto_set_private(ev, sock_ctx, NULL);
- }
+ ret = init_sockets(vctx, NULL);
+ if (ret != 0) {
+ return ret;
}
/* We need to tell nfsd that GSS-Proxy is available before it starts,