Page MenuHomeFreeBSD

D57455.id.diff
No OneTemporary

D57455.id.diff

diff --git a/sys/kgssapi/gss_impl.c b/sys/kgssapi/gss_impl.c
--- a/sys/kgssapi/gss_impl.c
+++ b/sys/kgssapi/gss_impl.c
@@ -57,6 +57,7 @@
kgss_load(void)
{
CLIENT *cl;
+ struct timeval nulltimo = {.tv_sec = 0, .tv_usec = 200000};
LIST_INIT(&kgss_mechs);
@@ -65,13 +66,16 @@
/*
* The transport default is no retries at all, since there could
- * be no userland listener to our messages. We will retry for 5
+ * be no userland listener to our messages. Initially, a short timeout
+ * is set, so that a Null RPC upcall will fail quickly if the daemon
+ * is not running. After the Null RPC succeeds, we will retry for 5
* minutes with 10 second interval. This will potentially cure hosts
* with misconfigured startup, where kernel starts sending GSS queries
* before userland had started up the gssd(8) daemon.
+ * The initial timeout of 200usec is for the Null RPC.
*/
clnt_control(cl, CLSET_RETRIES, &(int){30});
- clnt_control(cl, CLSET_TIMEOUT, &(struct timeval){.tv_sec = 300});
+ clnt_control(cl, CLSET_TIMEOUT, &nulltimo);
/*
* We literally wait on gssd(8), let's see that in top(1).
@@ -237,9 +241,43 @@
kgss_gssd_client(void)
{
CLIENT *cl;
+ struct rpc_callextra ext;
+ enum clnt_stat stat;
+ struct timeval rpctimo = {.tv_sec = 300, .tv_usec = 0};
+ static time_t nextrpc = 0;
+ static bool done_upcall = false;
mtx_lock(&kgss_gssd_lock);
cl = kgss_gssd_handle;
+ if (!done_upcall) {
+ mtx_unlock(&kgss_gssd_lock);
+ /*
+ * Can only be NULL if client_nl_create() called from
+ * kgss_load() returns NULL.
+ */
+ if (cl == NULL)
+ return (cl);
+ if (time_uptime < nextrpc)
+ return (NULL);
+ /*
+ * Do a Null RPC with a short timeout. If the RPC succeeds,
+ * the gssd daemon is running. If the Null RPC fails, don't
+ * again for 5sec.
+ */
+ memset(&ext, 0, sizeof(ext));
+ ext.rc_auth = authnone_create();
+ stat = clnt_call_private(cl, &ext, NULLPROC,
+ (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, NULL,
+ rpctimo); /* rpctimo is ignored by clnt_nl_call(). */
+ AUTH_DESTROY(ext.rc_auth);
+ if (stat != RPC_SUCCESS) {
+ nextrpc = time_uptime + 5;
+ return (NULL);
+ }
+ CLNT_CONTROL(cl, CLSET_TIMEOUT, &rpctimo);
+ mtx_lock(&kgss_gssd_lock);
+ done_upcall = true;
+ }
if (cl != NULL)
CLNT_ACQUIRE(cl);
mtx_unlock(&kgss_gssd_lock);
diff --git a/usr.sbin/gssd/gssd.c b/usr.sbin/gssd/gssd.c
--- a/usr.sbin/gssd/gssd.c
+++ b/usr.sbin/gssd/gssd.c
@@ -167,6 +167,11 @@
gssd_load_mech();
+ if ((xprt = svc_nl_create("kgss")) == NULL)
+ errx(1, "Can't create transport for local gssd socket");
+ if (!svc_reg(xprt, GSSD, GSSDVERS, gssd_1, NULL))
+ errx(1, "Can't register service for local gssd socket");
+
if (!debug_level) {
if (daemon(0, 0) != 0)
err(1, "Can't daemonize");
@@ -177,23 +182,6 @@
signal(SIGTERM, gssd_terminate);
signal(SIGPIPE, gssd_terminate);
- if ((xprt = svc_nl_create("kgss")) == NULL) {
- if (debug_level == 0) {
- syslog(LOG_ERR,
- "Can't create transport for local gssd socket");
- exit(1);
- }
- err(1, "Can't create transport for local gssd socket");
- }
- if (!svc_reg(xprt, GSSD, GSSDVERS, gssd_1, NULL)) {
- if (debug_level == 0) {
- syslog(LOG_ERR,
- "Can't register service for local gssd socket");
- exit(1);
- }
- err(1, "Can't register service for local gssd socket");
- }
-
LIST_INIT(&gss_resources);
gss_next_id = 1;
gss_start_time = time(0);

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 11:41 AM (16 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37182699
Default Alt Text
D57455.id.diff (3 KB)

Event Timeline