Re: AutoFS fails to add new entries from auto.master after SIGHUP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2013-02-27 at 22:49 -0300, Leonardo Chiquitto wrote:
> Hello,
> 
> I've got a bug report describing a case where AutoFS fails to read new
> entries from /etc/auto.master after a SIGHUP. Although the problem
> was reported in an older version of automount, it is reproducible using
> the latest revision from git.
> 
> How to reproduce:
> 
> 1. Add at least two sources of AutoFS maps to /etc/nsswitch.conf. I've
> tested only with "files nis". You don't need to configure NIS/YP, just
> having it listed there in the configuration is enough.
> 
> 2. Start the automounter with a simple /etc/auto.master:
> 
> /nfs1	/etc/auto.test1
> +auto.master
> 
> 3. Add another entry to /etc/auto.master:
> 
> /nfs1	/etc/auto.test1
> /nfs2	/etc/auto.test2
> +auto.master
> 
> and reload the daemon. Notice that although AutoFS reads /etc/auto.test2,
> /nfs2 is not created/mounted.
> 
> 4. Try to stop the daemon cleanly (SIGTERM only). You'll notice that it won't
> quit. SIGKILL is necessary.
> 
> I've debugged this problem and found that after a SIGHUP, the following
> sequence is executed:
> 
> do_hup_signal()
>   do_read_master() (new thread)
>     master_read_master() with readall=1
>       lookup_nss_read_master()
>         foreach nss source:
>           read_master_map()
>             do_read_master()  // not the same as the new thread function
>               lookup->lookup_read_master() // from lookup_file
> 
> At this point it attempts to read /etc/auto.master again and the recursion
> is detected (modules/lookup_file.c:400):

I'll check this out.

The way it's supposed to work is that when lookup->lookup_read_master()
(from lookup_file.c) is called it should call check_self_include() and
see that the + included map name is the same as its map name and skip
the files source and move onto the next one.

> 
> lookup_read_master()
> (...)
>  400         if (master->recurse)
>  401                 return NSS_STATUS_UNAVAIL;
> 
> NSS_STATUS_UNAVAIL goes all way back to lookup_nss_read_master(),
> that registers the failure to read the source in read_fail:
> 
>  259                 if (result == NSS_STATUS_UNAVAIL)
>  260                         master->read_fail = 1;
> 
> and returns to master_read_master(), that tests this flag:
> 
>  864         if (!master->read_fail)      // false, read_fail = 1
>  865                 master_mount_mounts(master, age, readall);
>  866         else {
>  867                 master->read_fail = 0;
>  868                 if (!readall)    // false, readall = 1
>  869                         master_mount_mounts(master, age, readall);
>  870         }
> 
> So, master_mount_mounts() is not called to setup the new mount point
> and we have a problem.
> 
> When AutoFS is started (not reloaded), master_read_master() is called
> with readall=0 and master_mount_mounts() end up being called in line
> 869 above. That's why the problem doesn't happen after regular start-up.
> 
> How to workaround the problem: the easiest way is to explicitly specify
> the map types in /etc/auto.master, for example:
> 
> /nfs1	file:/etc/auto.test1
> /nfs2	file:/etc/auto.test2
> +yp:auto.master
> 
> A first proposal to fix the problem would be to return a distinct error code
> to handle the recursion (see patch below). This seems to work well here.
> What do you think?
> 
> Thanks,
> Leonardo
> 
> Index: autofs/daemon/lookup.c
> ===================================================================
> --- autofs.orig/daemon/lookup.c
> +++ autofs/daemon/lookup.c
> @@ -230,6 +230,11 @@ int lookup_nss_read_master(struct master
> 
>  		result = read_master_map(master, this->source, age);
> 
> +		if (result == NSS_STATUS_RECURSE) {
> +			debug(logopt, "recursion - continuing to next source");
> +			continue;
> +		}
> +
>  		/*
>  		 * If the name of the master map hasn't been explicitly
>  		 * configured and we're not reading an included master map
> Index: autofs/include/nsswitch.h
> ===================================================================
> --- autofs.orig/include/nsswitch.h
> +++ autofs/include/nsswitch.h
> @@ -32,6 +32,7 @@ enum nsswitch_status {
>  	NSS_STATUS_NOTFOUND,
>  	NSS_STATUS_UNAVAIL,
>  	NSS_STATUS_TRYAGAIN,
> +	NSS_STATUS_RECURSE,
>  	NSS_STATUS_MAX
>  };
> 
> Index: autofs/modules/lookup_file.c
> ===================================================================
> --- autofs.orig/modules/lookup_file.c
> +++ autofs/modules/lookup_file.c
> @@ -398,7 +398,7 @@ int lookup_read_master(struct master *ma
>  	int entry, cur_state;
> 
>  	if (master->recurse)
> -		return NSS_STATUS_UNAVAIL;
> +		return NSS_STATUS_RECURSE;
> 
>  	if (master->depth > MAX_INCLUDE_DEPTH) {
>  		error(logopt, MODPREFIX
> --
> To unsubscribe from this list: send the line "unsubscribe autofs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe autofs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux Ext4]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux