@@ -277,7 +277,7 @@ static void hup_handler(verto_ctx *vctx UNUSED, verto_ev *ev)
277277 }
278278
279279 /* conditionally reload kernel interface */
280- init_proc_nfsd (gpctx -> config );
280+ init_proc_nfsd (gpctx );
281281
282282 free_config (& old_config );
283283
@@ -376,47 +376,101 @@ int init_event_fini(struct gssproxy_ctx *gpctx)
376376 return 0 ;
377377}
378378
379- void init_proc_nfsd ( struct gp_config * cfg )
379+ static int try_init_proc_nfsd ( void )
380380{
381381 char buf [] = "1" ;
382- bool enabled = false;
383382 int fd , ret ;
384- static int poked = 0 ;
383+ static bool poked = false;
384+ static bool warned_once = false;
385385
386- /* check first if any service enabled kernel support */
387- for (int i = 0 ; i < cfg -> num_svcs ; i ++ ) {
388- if (cfg -> svcs [i ]-> kernel_nfsd ) {
389- enabled = true;
390- break ;
391- }
392- }
393-
394- if (!enabled || poked ) {
395- return ;
396- }
386+ if (poked )
387+ return 0 ;
397388
398389 fd = open (LINUX_PROC_USE_GSS_PROXY_FILE , O_RDWR );
399390 if (fd == -1 ) {
400391 ret = errno ;
401- GPDEBUG ("Kernel doesn't support GSS-Proxy (can't open %s: %d (%s))\n" ,
402- LINUX_PROC_USE_GSS_PROXY_FILE , ret , gp_strerror (ret ));
403- goto fail ;
392+ if (!warned_once ) {
393+ GPDEBUG ("Kernel doesn't support GSS-Proxy "
394+ "(can't open %s: %d (%s))\n" ,
395+ LINUX_PROC_USE_GSS_PROXY_FILE , ret , gp_strerror (ret ));
396+ warned_once = true;
397+ }
398+ goto out ;
404399 }
405400
406401 ret = write (fd , buf , 1 );
407402 if (ret != 1 ) {
408403 ret = errno ;
409404 GPDEBUG ("Failed to write to %s: %d (%s)\n" ,
410405 LINUX_PROC_USE_GSS_PROXY_FILE , ret , gp_strerror (ret ));
411- close (fd );
412- goto fail ;
406+ goto out ;
413407 }
414408
415- poked = 1 ;
409+ GPDEBUG ("Kernel GSS-Proxy support enabled\n" );
410+ poked = true;
411+ ret = 0 ;
412+
413+ out :
416414 close (fd );
417- return ;
418- fail :
419- GPDEBUG ("Problem with kernel communication! NFS server will not work\n" );
415+ return ret ;
416+ }
417+
418+ static void delayed_proc_nfsd (verto_ctx * vctx UNUSED , verto_ev * ev )
419+ {
420+ struct gssproxy_ctx * gpctx ;
421+ int ret ;
422+
423+ gpctx = verto_get_private (ev );
424+
425+ ret = try_init_proc_nfsd ();
426+ if (ret == 0 ) {
427+ verto_del (gpctx -> retry_proc_ev );
428+ gpctx -> retry_proc_ev = NULL ;
429+ }
430+ }
431+
432+ int init_proc_nfsd (struct gssproxy_ctx * gpctx )
433+ {
434+ bool enabled = false;
435+ int ret ;
436+
437+ /* check first if any service enabled kernel support */
438+ for (int i = 0 ; i < gpctx -> config -> num_svcs ; i ++ ) {
439+ if (gpctx -> config -> svcs [i ]-> kernel_nfsd ) {
440+ enabled = true;
441+ break ;
442+ }
443+ }
444+
445+ if (!enabled ) {
446+ goto out ;
447+ }
448+
449+ ret = try_init_proc_nfsd ();
450+ if (ret == 0 ) {
451+ goto out ;
452+ }
453+
454+ /* failure, but the auth_rpcgss module might not be loaded yet */
455+ if (!gpctx -> retry_proc_ev ) {
456+ gpctx -> retry_proc_ev = verto_add_timeout (gpctx -> vctx ,
457+ VERTO_EV_FLAG_PERSIST ,
458+ delayed_proc_nfsd , 10 * 1000 );
459+ if (!gpctx -> retry_proc_ev ) {
460+ fprintf (stderr , "Failed to register delayed_proc_nfsd event!\n" );
461+ } else {
462+ verto_set_private (gpctx -> retry_proc_ev , gpctx , NULL );
463+ }
464+ }
465+
466+ return 1 ;
467+
468+ out :
469+ if (gpctx -> retry_proc_ev ) {
470+ verto_del (gpctx -> retry_proc_ev );
471+ gpctx -> retry_proc_ev = NULL ;
472+ }
473+ return 0 ;
420474}
421475
422476void write_pid (void )
0 commit comments