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