Blame SOURCES/autofs-5.1.2-wait-for-master-map-available-at-start.patch

23b4c9
autofs-5.1.2 - wait for master map available at start
23b4c9
23b4c9
From: Ian Kent <raven@themaw.net>
23b4c9
23b4c9
If the network map source isn't available at start the master map
23b4c9
can't be read. In this case we should wait until it is available
23b4c9
so we can get a startup map.
23b4c9
23b4c9
Signed-off-by: Ian Kent <raven@themaw.net>
23b4c9
---
23b4c9
 CHANGELOG                |    1 
23b4c9
 daemon/automount.c       |   81 +++++++++++++++++++++++++++++++++++++++++------
23b4c9
 daemon/lookup.c          |    8 ++++
23b4c9
 lib/master.c             |    3 +
23b4c9
 modules/lookup_file.c    |    6 +++
23b4c9
 modules/lookup_nisplus.c |   14 +++++---
23b4c9
 modules/lookup_yp.c      |   13 +++++--
23b4c9
 7 files changed, 108 insertions(+), 18 deletions(-)
23b4c9
23b4c9
--- autofs-5.0.7.orig/CHANGELOG
23b4c9
+++ autofs-5.0.7/CHANGELOG
23b4c9
@@ -206,6 +206,7 @@
23b4c9
 - add configuration option to use fqdn in mounts.
23b4c9
 - fix use-after-free in st_queue_handler().
23b4c9
 - add config option to supress not found log message.
23b4c9
+- wait for master map available at start.
23b4c9
 
23b4c9
 25/07/2012 autofs-5.0.7
23b4c9
 =======================
23b4c9
--- autofs-5.0.7.orig/daemon/automount.c
23b4c9
+++ autofs-5.0.7/daemon/automount.c
23b4c9
@@ -1379,9 +1379,10 @@ static void *do_read_master(void *arg)
23b4c9
 	return NULL;
23b4c9
 }
23b4c9
 
23b4c9
-static int do_hup_signal(struct master *master, time_t age)
23b4c9
+static int do_hup_signal(struct master *master)
23b4c9
 {
23b4c9
 	unsigned int logopt = master->logopt;
23b4c9
+	time_t age = time(NULL);
23b4c9
 	pthread_t thid;
23b4c9
 	int status;
23b4c9
 
23b4c9
@@ -1470,7 +1471,7 @@ static void *statemachine(void *arg)
23b4c9
 			break;
23b4c9
 
23b4c9
 		case SIGHUP:
23b4c9
-			do_hup_signal(master_list, time(NULL));
23b4c9
+			do_hup_signal(master_list);
23b4c9
 			break;
23b4c9
 
23b4c9
 		default:
23b4c9
@@ -2031,12 +2032,56 @@ static void remove_empty_args(char **arg
23b4c9
 	*argc = j;
23b4c9
 }
23b4c9
 
23b4c9
+static int do_master_read_master(struct master *master, int wait)
23b4c9
+{
23b4c9
+	sigset_t signalset;
23b4c9
+	/* Wait must be at least 1 second */
23b4c9
+	unsigned int retry_wait = 2;
23b4c9
+	unsigned int elapsed = 0;
23b4c9
+	int max_wait = wait;
23b4c9
+	int ret = 0;
23b4c9
+	time_t age;
23b4c9
+
23b4c9
+	sigemptyset(&signalset);
23b4c9
+	sigaddset(&signalset, SIGTERM);
23b4c9
+	sigaddset(&signalset, SIGINT);
23b4c9
+	sigaddset(&signalset, SIGHUP);
23b4c9
+	sigprocmask(SIG_UNBLOCK, &signalset, NULL);
23b4c9
+
23b4c9
+	while (1) {
23b4c9
+		struct timespec t = { retry_wait, 0 };
23b4c9
+
23b4c9
+		age = time(NULL);
23b4c9
+		if (master_read_master(master, age, 0)) {
23b4c9
+			ret = 1;
23b4c9
+			break;
23b4c9
+		}
23b4c9
+
23b4c9
+		if (nanosleep(&t, NULL) == -1)
23b4c9
+			break;
23b4c9
+
23b4c9
+		if (max_wait > 0) {
23b4c9
+			elapsed += retry_wait;
23b4c9
+			if (elapsed >= max_wait) {
23b4c9
+				logmsg("problem reading master map, "
23b4c9
+					"maximum wait exceeded");
23b4c9
+				break;
23b4c9
+			}
23b4c9
+		}
23b4c9
+	}
23b4c9
+
23b4c9
+	sigprocmask(SIG_BLOCK, &signalset, NULL);
23b4c9
+
23b4c9
+	return ret;
23b4c9
+}
23b4c9
+
23b4c9
 int main(int argc, char *argv[])
23b4c9
 {
23b4c9
 	int res, opt, status;
23b4c9
 	int logpri = -1;
23b4c9
 	unsigned ghost, logging, daemon_check;
23b4c9
 	unsigned dumpmaps, foreground, have_global_options;
23b4c9
+	unsigned master_read;
23b4c9
 	time_t timeout;
23b4c9
 	time_t age = time(NULL);
23b4c9
 	struct rlimit rlim;
23b4c9
@@ -2429,14 +2474,16 @@ int main(int argc, char *argv[])
23b4c9
 		dh_tirpc = dlopen("libtirpc.so.1", RTLD_NOW);
23b4c9
 #endif
23b4c9
 
23b4c9
-	if (!master_read_master(master_list, age, 0)) {
23b4c9
-		master_kill(master_list);
23b4c9
-		*pst_stat = 3;
23b4c9
-		res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
23b4c9
-		close(start_pipefd[1]);
23b4c9
-		release_flag_file();
23b4c9
-		macro_free_global_table();
23b4c9
-		exit(3);
23b4c9
+	master_read = master_read_master(master_list, age, 0);
23b4c9
+	if (!master_read) {
23b4c9
+		if (foreground)
23b4c9
+			logerr("%s: failed to read master map, "
23b4c9
+			       "will retry!",
23b4c9
+			       program);
23b4c9
+		else
23b4c9
+			logerr("%s: failed to read master map, "
23b4c9
+			       "will retry in background!",
23b4c9
+			       program);
23b4c9
 	}
23b4c9
 
23b4c9
 	/*
23b4c9
@@ -2449,6 +2496,20 @@ int main(int argc, char *argv[])
23b4c9
 	res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
23b4c9
 	close(start_pipefd[1]);
23b4c9
 
23b4c9
+	if (!master_read) {
23b4c9
+		/*
23b4c9
+		 * Read master map, waiting until it is available, unless
23b4c9
+		 * a signal is received, in which case exit returning an
23b4c9
+		 * error.
23b4c9
+		 */
23b4c9
+		if (!do_master_read_master(master_list, -1)) {
23b4c9
+			logerr("%s: failed to read master map!", program);
23b4c9
+			master_kill(master_list);
23b4c9
+			release_flag_file();
23b4c9
+			exit(3);
23b4c9
+		}
23b4c9
+	}
23b4c9
+
23b4c9
 	state_mach_thid = pthread_self();
23b4c9
 	statemachine(NULL);
23b4c9
 
23b4c9
--- autofs-5.0.7.orig/daemon/lookup.c
23b4c9
+++ autofs-5.0.7/daemon/lookup.c
23b4c9
@@ -241,6 +241,7 @@ int lookup_nss_read_master(struct master
23b4c9
 	}
23b4c9
 
23b4c9
 	/* First one gets it */
23b4c9
+	result = NSS_STATUS_UNKNOWN;
23b4c9
 	head = &nsslist;
23b4c9
 	list_for_each(p, head) {
23b4c9
 		struct nss_source *this;
23b4c9
@@ -248,6 +249,13 @@ int lookup_nss_read_master(struct master
23b4c9
 
23b4c9
 		this = list_entry(p, struct nss_source, list);
23b4c9
 
23b4c9
+		if (strncmp(this->source, "files", 5) &&
23b4c9
+		    strncmp(this->source, "nis", 3) &&
23b4c9
+		    strncmp(this->source, "nisplus", 7) &&
23b4c9
+		    strncmp(this->source, "ldap", 4) &&
23b4c9
+		    strncmp(this->source, "sss", 3))
23b4c9
+			continue;
23b4c9
+
23b4c9
 		debug(logopt,
23b4c9
 		      "reading master %s %s", this->source, master->name);
23b4c9
 
23b4c9
--- autofs-5.0.7.orig/lib/master.c
23b4c9
+++ autofs-5.0.7/lib/master.c
23b4c9
@@ -922,7 +922,10 @@ int master_read_master(struct master *ma
23b4c9
 		master_mount_mounts(master, age, readall);
23b4c9
 	else {
23b4c9
 		master->read_fail = 0;
23b4c9
+		/* HUP signal sets readall == 1 only */
23b4c9
 		if (!readall)
23b4c9
+			return 0;
23b4c9
+		else
23b4c9
 			master_mount_mounts(master, age, readall);
23b4c9
 	}
23b4c9
 
23b4c9
--- autofs-5.0.7.orig/modules/lookup_file.c
23b4c9
+++ autofs-5.0.7/modules/lookup_file.c
23b4c9
@@ -506,6 +506,12 @@ int lookup_read_master(struct master *ma
23b4c9
 				     MODPREFIX
23b4c9
 				     "failed to read included master map %s",
23b4c9
 				     master->name);
23b4c9
+				/*
23b4c9
+				 * If we're starting up wee need the whole
23b4c9
+				 * master map initially, so tell the upper
23b4c9
+				 * layer to retry.
23b4c9
+				 */
23b4c9
+				master->read_fail = 1;
23b4c9
 			}
23b4c9
 			master->depth--;
23b4c9
 			master->recurse = 0;
23b4c9
--- autofs-5.0.7.orig/modules/lookup_nisplus.c
23b4c9
+++ autofs-5.0.7/modules/lookup_nisplus.c
23b4c9
@@ -149,19 +149,25 @@ int lookup_read_master(struct master *ma
23b4c9
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
23b4c9
 		logerr(MODPREFIX "malloc: %s", estr);
23b4c9
 		pthread_setcancelstate(cur_state, NULL);
23b4c9
-		return NSS_STATUS_UNAVAIL;
23b4c9
+		return NSS_STATUS_UNKNOWN;
23b4c9
 	}
23b4c9
 	sprintf(tablename, "%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
23b4c9
 
23b4c9
 	/* check that the table exists */
23b4c9
 	result = nis_lookup(tablename, FOLLOW_PATH | FOLLOW_LINKS);
23b4c9
 	if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
23b4c9
+		int status = result->status;
23b4c9
 		nis_freeresult(result);
23b4c9
-		crit(logopt,
23b4c9
-		     MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname);
23b4c9
 		free(tablename);
23b4c9
 		pthread_setcancelstate(cur_state, NULL);
23b4c9
-		return NSS_STATUS_NOTFOUND;
23b4c9
+		if (status == NIS_UNAVAIL || status == NIS_FAIL)
23b4c9
+			return NSS_STATUS_UNAVAIL;
23b4c9
+		else {
23b4c9
+			crit(logopt,
23b4c9
+			     MODPREFIX "couldn't locate nis+ table %s",
23b4c9
+			     ctxt->mapname);
23b4c9
+			return NSS_STATUS_NOTFOUND;
23b4c9
+		}
23b4c9
 	}
23b4c9
 
23b4c9
 	sprintf(tablename, "[],%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
23b4c9
--- autofs-5.0.7.orig/modules/lookup_yp.c
23b4c9
+++ autofs-5.0.7/modules/lookup_yp.c
23b4c9
@@ -282,9 +282,9 @@ int lookup_read_master(struct master *ma
23b4c9
 	char *mapname;
23b4c9
 	int err;
23b4c9
 
23b4c9
-	mapname = alloca(strlen(ctxt->mapname) + 1);
23b4c9
+	mapname = malloc(strlen(ctxt->mapname) + 1);
23b4c9
 	if (!mapname)
23b4c9
-		return 0;
23b4c9
+		return NSS_STATUS_UNKNOWN;
23b4c9
 
23b4c9
 	strcpy(mapname, ctxt->mapname);
23b4c9
 
23b4c9
@@ -308,19 +308,24 @@ int lookup_read_master(struct master *ma
23b4c9
 			err = yp_all((char *) ctxt->domainname, mapname, &ypcb);
23b4c9
 		}
23b4c9
 
23b4c9
-		if (err == YPERR_SUCCESS)
23b4c9
+		if (err == YPERR_SUCCESS) {
23b4c9
+			free(mapname);
23b4c9
 			return NSS_STATUS_SUCCESS;
23b4c9
+		}
23b4c9
 
23b4c9
 		info(logopt,
23b4c9
 		     MODPREFIX "read of master map %s failed: %s",
23b4c9
 		     mapname, yperr_string(err));
23b4c9
 
23b4c9
-		if (err == YPERR_PMAP || err == YPERR_YPSERV)
23b4c9
+		free(mapname);
23b4c9
+
23b4c9
+		if (err == YPERR_YPSERV || err == YPERR_DOMAIN)
23b4c9
 			return NSS_STATUS_UNAVAIL;
23b4c9
 
23b4c9
 		return NSS_STATUS_NOTFOUND;
23b4c9
 	}
23b4c9
 
23b4c9
+	free(mapname);
23b4c9
 	return NSS_STATUS_SUCCESS;
23b4c9
 }
23b4c9