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

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

 



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):

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


[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