Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gssproxy] retry writing to /proc/net/rpc/use-gss-proxy #85

Merged
merged 1 commit into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 78 additions & 24 deletions src/gp_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -376,47 +376,101 @@ 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;
Alphix marked this conversation as resolved.
Show resolved Hide resolved
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) {
simo5 marked this conversation as resolved.
Show resolved Hide resolved
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);
if (ret != 1) {
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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means there will be cases where this may fire over and over forever if init_proc_nfsd_once() always fail ... is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it'll fire every 10 seconds forever....but it will only do so if:
a) the user has a nfs-server configuration for gssproxy; and
b) /proc/net/rpc/use-gss-proxy doesn't exist (i.e. the auth_rpcgss module isn't loaded)

I do realize that the default gssproxy installation includes /etc/gssproxy/24-nfs-server.conf though....I still think a wakeup every 10s is acceptable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think maybe we should have a very simple backoff.
Store the delay in another static variable, start with one second delay and double it each time we call the function until it reaches 1024 seconds (slightly more than 15 minutes), and then keep it there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that has the potential of being quite confusing. The admin installs gssproxy...starts it, then installs nfs-utils a couple of minutes later....it doesn't work straight away but 15 minutes later it magically starts working?

libverto already has a 60s wakeup interval even when gssproxy isn't doing anything....maybe use that as the upper limit?

root@qtest1:~# ps ax | grep gssproxy
    961 ?        Ssl    0:00 /usr/sbin/gssproxy -D
root@qtest1:~# strace -t -p 961 (that's gssproxy)
strace: Process 961 attached
19:08:09 epoll_wait(8, [], 64, 59743)   = 0
19:09:09 epoll_wait(8, [], 64, 59743)   = 0
19:10:09 epoll_wait(8, [], 64, 59743)   = 0
19:11:09 epoll_wait(8, [], 64, 59743)   = 0
19:12:09 epoll_wait(8, [], 64, 59743)   = 0
19:13:08 epoll_wait(8, [], 64, 59743)   = 0
19:14:08 epoll_wait(8, [], 64, 59743)   = 0

Though I really don't think a 10s interval is a real problem either....it's basically 1-2 system calls per 10s....won't even show up in top on the original Raspberry Pi :)

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)
Expand Down
4 changes: 3 additions & 1 deletion src/gp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/gssproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading