195 lines
5.5 KiB
Diff
195 lines
5.5 KiB
Diff
From fb8737b2c48d67a63a66abfa090e92f21765a94f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?David=20H=C3=A4rdeman?= <david@hardeman.nu>
|
|
Date: Wed, 18 Oct 2023 16:25:06 +0200
|
|
Subject: [PATCH] [gssproxy] retry writing to /proc/net/rpc/use-gss-proxy
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This improves the handling of cases where the auth_rpcgss module has not yet
|
|
been loaded when gssproxy is started.
|
|
|
|
Signed-off-by: David Härdeman <david@hardeman.nu>
|
|
---
|
|
src/gp_init.c | 102 +++++++++++++++++++++++++++++++++++++------------
|
|
src/gp_proxy.h | 4 +-
|
|
src/gssproxy.c | 2 +-
|
|
3 files changed, 82 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/src/gp_init.c b/src/gp_init.c
|
|
index 1cc7e28..8d72c3e 100644
|
|
--- a/src/gp_init.c
|
|
+++ b/src/gp_init.c
|
|
@@ -277,7 +277,7 @@ static void hup_handler(verto_ctx *vctx UNUSED, verto_ev *ev)
|
|
}
|
|
|
|
/* conditionally reload kernel interface */
|
|
- init_proc_nfsd(gpctx->config);
|
|
+ init_proc_nfsd(gpctx);
|
|
|
|
free_config(&old_config);
|
|
|
|
@@ -376,31 +376,26 @@ int init_event_fini(struct gssproxy_ctx *gpctx)
|
|
return 0;
|
|
}
|
|
|
|
-void init_proc_nfsd(struct gp_config *cfg)
|
|
+static int try_init_proc_nfsd(void)
|
|
{
|
|
char buf[] = "1";
|
|
- bool enabled = false;
|
|
int fd, ret;
|
|
- static int poked = 0;
|
|
+ static bool poked = false;
|
|
+ static bool warned_once = false;
|
|
|
|
- /* check first if any service enabled kernel support */
|
|
- for (int i = 0; i < cfg->num_svcs; i++) {
|
|
- if (cfg->svcs[i]->kernel_nfsd) {
|
|
- enabled = true;
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (!enabled || poked) {
|
|
- return;
|
|
- }
|
|
+ if (poked)
|
|
+ return 0;
|
|
|
|
fd = open(LINUX_PROC_USE_GSS_PROXY_FILE, O_RDWR);
|
|
if (fd == -1) {
|
|
ret = errno;
|
|
- GPDEBUG("Kernel doesn't support GSS-Proxy (can't open %s: %d (%s))\n",
|
|
- LINUX_PROC_USE_GSS_PROXY_FILE, ret, gp_strerror(ret));
|
|
- goto fail;
|
|
+ if (!warned_once) {
|
|
+ GPDEBUG("Kernel doesn't support GSS-Proxy "
|
|
+ "(can't open %s: %d (%s))\n",
|
|
+ LINUX_PROC_USE_GSS_PROXY_FILE, ret, gp_strerror(ret));
|
|
+ warned_once = true;
|
|
+ }
|
|
+ goto out;
|
|
}
|
|
|
|
ret = write(fd, buf, 1);
|
|
@@ -408,15 +403,74 @@ void init_proc_nfsd(struct gp_config *cfg)
|
|
ret = errno;
|
|
GPDEBUG("Failed to write to %s: %d (%s)\n",
|
|
LINUX_PROC_USE_GSS_PROXY_FILE, ret, gp_strerror(ret));
|
|
- close(fd);
|
|
- goto fail;
|
|
+ goto out;
|
|
}
|
|
|
|
- poked = 1;
|
|
+ GPDEBUG("Kernel GSS-Proxy support enabled\n");
|
|
+ poked = true;
|
|
+ ret = 0;
|
|
+
|
|
+out:
|
|
close(fd);
|
|
- return;
|
|
-fail:
|
|
- GPDEBUG("Problem with kernel communication! NFS server will not work\n");
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void delayed_proc_nfsd(verto_ctx *vctx UNUSED, verto_ev *ev)
|
|
+{
|
|
+ struct gssproxy_ctx *gpctx;
|
|
+ int ret;
|
|
+
|
|
+ gpctx = verto_get_private(ev);
|
|
+
|
|
+ ret = try_init_proc_nfsd();
|
|
+ if (ret == 0) {
|
|
+ verto_del(gpctx->retry_proc_ev);
|
|
+ gpctx->retry_proc_ev = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+int init_proc_nfsd(struct gssproxy_ctx *gpctx)
|
|
+{
|
|
+ bool enabled = false;
|
|
+ int ret;
|
|
+
|
|
+ /* check first if any service enabled kernel support */
|
|
+ for (int i = 0; i < gpctx->config->num_svcs; i++) {
|
|
+ if (gpctx->config->svcs[i]->kernel_nfsd) {
|
|
+ enabled = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!enabled) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ret = try_init_proc_nfsd();
|
|
+ if (ret == 0) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ /* failure, but the auth_rpcgss module might not be loaded yet */
|
|
+ if (!gpctx->retry_proc_ev) {
|
|
+ gpctx->retry_proc_ev = verto_add_timeout(gpctx->vctx,
|
|
+ VERTO_EV_FLAG_PERSIST,
|
|
+ delayed_proc_nfsd, 10 * 1000);
|
|
+ if (!gpctx->retry_proc_ev) {
|
|
+ fprintf(stderr, "Failed to register delayed_proc_nfsd event!\n");
|
|
+ } else {
|
|
+ verto_set_private(gpctx->retry_proc_ev, gpctx, NULL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+
|
|
+out:
|
|
+ if (gpctx->retry_proc_ev) {
|
|
+ verto_del(gpctx->retry_proc_ev);
|
|
+ gpctx->retry_proc_ev = NULL;
|
|
+ }
|
|
+ return 0;
|
|
}
|
|
|
|
void write_pid(void)
|
|
diff --git a/src/gp_proxy.h b/src/gp_proxy.h
|
|
index c8b55ef..4e0e9c3 100644
|
|
--- a/src/gp_proxy.h
|
|
+++ b/src/gp_proxy.h
|
|
@@ -84,6 +84,8 @@ struct gssproxy_ctx {
|
|
time_t term_timeout;
|
|
verto_ev *term_ev; /* termination ev in user mode */
|
|
|
|
+ verto_ev *retry_proc_ev; /* retry telling the kernel to use GSS-Proxy */
|
|
+
|
|
ssize_t readstats;
|
|
ssize_t writestats;
|
|
time_t last_activity;
|
|
@@ -120,7 +122,7 @@ void fini_server(void);
|
|
int init_sockets(struct gssproxy_ctx *gpctx, struct gp_config *old_config);
|
|
int init_userproxy_socket(struct gssproxy_ctx *gpctx);
|
|
void init_event_loop(struct gssproxy_ctx *gpctx);
|
|
-void init_proc_nfsd(struct gp_config *cfg);
|
|
+int init_proc_nfsd(struct gssproxy_ctx *gpctx);
|
|
int init_event_fini(struct gssproxy_ctx *gpctx);
|
|
void write_pid(void);
|
|
int drop_privs(struct gp_config *cfg);
|
|
diff --git a/src/gssproxy.c b/src/gssproxy.c
|
|
index e216ec5..3e5326c 100644
|
|
--- a/src/gssproxy.c
|
|
+++ b/src/gssproxy.c
|
|
@@ -168,7 +168,7 @@ int main(int argc, const char *argv[])
|
|
* as nfsd needs to know GSS-Proxy is in use before the first time it
|
|
* needs to call accept_sec_context. */
|
|
if (!gpctx->userproxymode) {
|
|
- init_proc_nfsd(gpctx->config);
|
|
+ init_proc_nfsd(gpctx);
|
|
}
|
|
|
|
/* Now it is safe to tell the init system that we're done starting up,
|
|
--
|
|
2.43.0
|
|
|