All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Kent <raven@themaw.net>
To: autofs mailing list <autofs@vger.kernel.org>
Subject: [PATCH 23/37] autofs-5.1.2 - wait for master map available at start
Date: Tue, 25 Oct 2016 09:19:27 +0800	[thread overview]
Message-ID: <20161025011927.7778.7380.stgit@pluto.themaw.net> (raw)
In-Reply-To: <20161025010014.7778.69274.stgit@pluto.themaw.net>

If the network map source isn't available at start the master map
can't be read. In this case we should wait until it is available
so we can get a startup map.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG                |    1 +
 daemon/automount.c       |   81 ++++++++++++++++++++++++++++++++++++++++------
 daemon/lookup.c          |    8 +++++
 lib/master.c             |    3 ++
 modules/lookup_file.c    |    6 +++
 modules/lookup_nisplus.c |   14 ++++++--
 modules/lookup_yp.c      |   13 +++++--
 7 files changed, 108 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 686d404..d1bc1e1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@ xx/xx/2016 autofs-5.1.3
 - fix _strncmp() usage.
 - fix create_client() RPC client handling.
 - update and add README for old autofs schema.
+- wait for master map available at start.
 
 15/06/2016 autofs-5.1.2
 =======================
diff --git a/daemon/automount.c b/daemon/automount.c
index 9d4c2b7..14af9ff 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1403,9 +1403,10 @@ static void *do_read_master(void *arg)
 	return NULL;
 }
 
-static int do_hup_signal(struct master *master, time_t age)
+static int do_hup_signal(struct master *master)
 {
 	unsigned int logopt = master->logopt;
+	time_t age = monotonic_time(NULL);
 	pthread_t thid;
 	int status;
 
@@ -1494,7 +1495,7 @@ static void *statemachine(void *arg)
 			break;
 
 		case SIGHUP:
-			do_hup_signal(master_list, monotonic_time(NULL));
+			do_hup_signal(master_list);
 			break;
 
 		default:
@@ -2052,12 +2053,56 @@ static void remove_empty_args(char **argv, int *argc)
 	*argc = j;
 }
 
+static int do_master_read_master(struct master *master, int wait)
+{
+	sigset_t signalset;
+	/* Wait must be at least 1 second */
+	unsigned int retry_wait = 2;
+	unsigned int elapsed = 0;
+	int max_wait = wait;
+	int ret = 0;
+	time_t age;
+
+	sigemptyset(&signalset);
+	sigaddset(&signalset, SIGTERM);
+	sigaddset(&signalset, SIGINT);
+	sigaddset(&signalset, SIGHUP);
+	sigprocmask(SIG_UNBLOCK, &signalset, NULL);
+
+	while (1) {
+		struct timespec t = { retry_wait, 0 };
+
+		age = monotonic_time(NULL);
+		if (master_read_master(master, age, 0)) {
+			ret = 1;
+			break;
+		}
+
+		if (nanosleep(&t, NULL) == -1)
+			break;
+
+		if (max_wait > 0) {
+			elapsed += retry_wait;
+			if (elapsed >= max_wait) {
+				logmsg("problem reading master map, "
+					"maximum wait exceeded");
+				break;
+			}
+		}
+	}
+
+	sigprocmask(SIG_BLOCK, &signalset, NULL);
+
+	return ret;
+}
+
 int main(int argc, char *argv[])
 {
 	int res, opt, status;
 	int logpri = -1;
 	unsigned ghost, logging, daemon_check;
 	unsigned dumpmaps, foreground, have_global_options;
+	unsigned master_read;
 	time_t timeout;
 	time_t age = monotonic_time(NULL);
 	struct rlimit rlim;
@@ -2452,14 +2497,16 @@ int main(int argc, char *argv[])
 		dh_tirpc = dlopen("libtirpc.so.3", RTLD_NOW);
 #endif
 
-	if (!master_read_master(master_list, age, 0)) {
-		master_kill(master_list);
-		*pst_stat = 3;
-		res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
-		close(start_pipefd[1]);
-		release_flag_file();
-		macro_free_global_table();
-		exit(3);
+	master_read = master_read_master(master_list, age, 0);
+	if (!master_read) {
+		if (foreground)
+			logerr("%s: failed to read master map, "
+			       "will retry!",
+			       program);
+		else
+			logerr("%s: failed to read master map, "
+			       "will retry in background!",
+			       program);
 	}
 
 	/*
@@ -2472,6 +2519,20 @@ int main(int argc, char *argv[])
 	res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
 	close(start_pipefd[1]);
 
+	if (!master_read) {
+		/*
+		 * Read master map, waiting until it is available, unless
+		 * a signal is received, in which case exit returning an
+		 * error.
+		 */
+		if (!do_master_read_master(master_list, -1)) {
+			logerr("%s: failed to read master map!", program);
+			master_kill(master_list);
+			release_flag_file();
+			exit(3);
+		}
+	}
+
 	state_mach_thid = pthread_self();
 	statemachine(NULL);
 
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 582b5c9..0c2a01f 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -241,6 +241,7 @@ int lookup_nss_read_master(struct master *master, time_t age)
 	}
 
 	/* First one gets it */
+	result = NSS_STATUS_UNKNOWN;
 	head = &nsslist;
 	list_for_each(p, head) {
 		struct nss_source *this;
@@ -248,6 +249,13 @@ int lookup_nss_read_master(struct master *master, time_t age)
 
 		this = list_entry(p, struct nss_source, list);
 
+		if (strncmp(this->source, "files", 5) &&
+		    strncmp(this->source, "nis", 3) &&
+		    strncmp(this->source, "nisplus", 7) &&
+		    strncmp(this->source, "ldap", 4) &&
+		    strncmp(this->source, "sss", 3))
+			continue;
+
 		debug(logopt,
 		      "reading master %s %s", this->source, master->name);
 
diff --git a/lib/master.c b/lib/master.c
index 9ffdd1a..4c6e79b 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -923,7 +923,10 @@ int master_read_master(struct master *master, time_t age, int readall)
 		master_mount_mounts(master, age, readall);
 	else {
 		master->read_fail = 0;
+		/* HUP signal sets readall == 1 only */
 		if (!readall)
+			return 0;
+		else
 			master_mount_mounts(master, age, readall);
 	}
 
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index d87ec73..d5f8c9e 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -507,6 +507,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
 				     MODPREFIX
 				     "failed to read included master map %s",
 				     master->name);
+				/*
+				 * If we're starting up wee need the whole
+				 * master map initially, so tell the upper
+				 * layer to retry.
+				 */
+				master->read_fail = 1;
 			}
 			master->depth--;
 			master->recurse = 0;
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 7832611..c8b75e6 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -149,19 +149,25 @@ int lookup_read_master(struct master *master, time_t age, void *context)
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		logerr(MODPREFIX "malloc: %s", estr);
 		pthread_setcancelstate(cur_state, NULL);
-		return NSS_STATUS_UNAVAIL;
+		return NSS_STATUS_UNKNOWN;
 	}
 	sprintf(tablename, "%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
 
 	/* check that the table exists */
 	result = nis_lookup(tablename, FOLLOW_PATH | FOLLOW_LINKS);
 	if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+		int status = result->status;
 		nis_freeresult(result);
-		crit(logopt,
-		     MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname);
 		free(tablename);
 		pthread_setcancelstate(cur_state, NULL);
-		return NSS_STATUS_NOTFOUND;
+		if (status == NIS_UNAVAIL || status == NIS_FAIL)
+			return NSS_STATUS_UNAVAIL;
+		else {
+			crit(logopt,
+			     MODPREFIX "couldn't locate nis+ table %s",
+			     ctxt->mapname);
+			return NSS_STATUS_NOTFOUND;
+		}
 	}
 
 	sprintf(tablename, "[],%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 502d850..0d319fd 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -282,9 +282,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
 	char *mapname;
 	int err;
 
-	mapname = alloca(strlen(ctxt->mapname) + 1);
+	mapname = malloc(strlen(ctxt->mapname) + 1);
 	if (!mapname)
-		return 0;
+		return NSS_STATUS_UNKNOWN;
 
 	strcpy(mapname, ctxt->mapname);
 
@@ -308,19 +308,24 @@ int lookup_read_master(struct master *master, time_t age, void *context)
 			err = yp_all((char *) ctxt->domainname, mapname, &ypcb);
 		}
 
-		if (err == YPERR_SUCCESS)
+		if (err == YPERR_SUCCESS) {
+			free(mapname);
 			return NSS_STATUS_SUCCESS;
+		}
 
 		info(logopt,
 		     MODPREFIX "read of master map %s failed: %s",
 		     mapname, yperr_string(err));
 
-		if (err == YPERR_PMAP || err == YPERR_YPSERV)
+		free(mapname);
+
+		if (err == YPERR_YPSERV || err == YPERR_DOMAIN)
 			return NSS_STATUS_UNAVAIL;
 
 		return NSS_STATUS_NOTFOUND;
 	}
 
+	free(mapname);
 	return NSS_STATUS_SUCCESS;
 }
 

--
To unsubscribe from this list: send the line "unsubscribe autofs" in

  parent reply	other threads:[~2016-10-25  1:19 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-25  1:17 [PATCH 00/37] Current patch queue for review Ian Kent
2016-10-25  1:17 ` [PATCH 01/37] autofs-5.1.2 - fix release date in CHANGELOG Ian Kent
2016-10-25  1:17 ` [PATCH 02/37] autofs-5.1.2 - build: check for clock_gettime in librt Ian Kent
2016-10-25  1:17 ` [PATCH 03/37] autofs-5.1.2 - Fix compiler warning in try_remount() Ian Kent
2016-10-25  1:17 ` [PATCH 04/37] autofs-5.1.2 - Drop redundant \n in logerr() Ian Kent
2016-10-25  1:17 ` [PATCH 05/37] autofs-5.1.2 - Fix size arg of fgets(3) Ian Kent
2016-10-25  1:17 ` [PATCH 06/37] autofs-5.1.2 - fix libtirpc detection with -Wl, --as-needed Ian Kent
2016-10-25  1:18 ` [PATCH 07/37] autofs-5.1.2 - Fix a typo in CREDITS Ian Kent
2016-10-25  1:18 ` [PATCH 08/37] autofs-5.1.2 - Change .requestor to .requester for consistency Ian Kent
2016-10-25  1:18 ` [PATCH 09/37] autofs-5.1.2 - fix file map changed check Ian Kent
2016-10-25  1:18 ` [PATCH 10/37] autofs-5.1.2 - Remove unused local 2KB buffer Ian Kent
2016-10-25  1:18 ` [PATCH 11/37] autofs-5.1.2 - Fix typos in error messages Ian Kent
2016-10-25  1:18 ` [PATCH 12/37] autofs-5.1.2 - Fix fgets(3) size argument (another one) Ian Kent
2016-10-25  1:18 ` [PATCH 13/37] autofs-5.1.2 - fix short memory allocation in lookup_amd_instance() Ian Kent
2016-10-25  1:18 ` [PATCH 14/37] autofs-5.1.2 - fix count_mounts() function Ian Kent
2016-10-25  1:18 ` [PATCH 15/37] autofs-5.1.2 - configure: add cache variable for Linux proc filesystem check Ian Kent
2016-10-25  1:18 ` [PATCH 16/37] autofs-5.1.2 - Avoid local variable name shadowing another Ian Kent
2016-10-25  1:18 ` [PATCH 17/37] autofs-5.1.2 - fix typo in MOUNT_FLAG_GHOST comment Ian Kent
2016-10-25  1:19 ` [PATCH 18/37] autofs-5.1.2 - fix cachefs parse message not being logged Ian Kent
2016-10-25  1:19 ` [PATCH 19/37] autofs-5.1.2 - fix argc off by one in mount_autofs.c Ian Kent
2016-10-25  1:19 ` [PATCH 20/37] autofs-5.1.2 - fix _strncmp() usage Ian Kent
2016-10-25  1:19 ` [PATCH 21/37] autofs-5.1.1 - fix create_client() RPC client handling Ian Kent
2016-10-25  1:19 ` [PATCH 22/37] autofs-5.1.2 - update and add README for old autofs schema Ian Kent
2016-10-25  1:19 ` Ian Kent [this message]
2016-10-25  1:19 ` [PATCH 24/37] autofs-5.1.2 - add master read wait option Ian Kent
2016-10-25  1:19 ` [PATCH 25/37] autofs-5.1.2 - work around sss startup delay Ian Kent
2016-10-25  1:19 ` [PATCH 26/37] autofs-5.1.2 - add sss master map wait config option Ian Kent
2016-10-25  1:19 ` [PATCH 27/37] autofs-5.1.2 - fix typos in README.amd-maps Ian Kent
2016-10-25  1:19 ` [PATCH 28/37] autofs-5.1.2 - add ref counting to struct map_source Ian Kent
2016-10-25  1:19 ` [PATCH 29/37] autofs-5.1.2 - add support for amd browsable option Ian Kent
2016-10-25  1:20 ` [PATCH 30/37] autofs-5.1.2 - add function conf_amd_get_map_name() Ian Kent
2016-10-25  1:20 ` [PATCH 31/37] autofs-5.1.2 - add function conf_amd_get_mount_paths() Ian Kent
2016-10-25  1:20 ` [PATCH 32/37] autofs-5.1.2 - include amd mount section mounts in master mounts list Ian Kent
2016-10-25  1:20 ` [PATCH 33/37] autofs-5.1.2 - check for conflicting amd section mounts Ian Kent
2016-10-25  1:20 ` [PATCH 34/37] autofs-5.1.2 - add function conf_get_map_options() Ian Kent
2016-10-25  1:20 ` [PATCH 35/37] autofs-5.1.2 - capture cache option and its settings during parsing Ian Kent
2016-10-25  1:20 ` [PATCH 36/37] autofs-5.1.2 - handle map_option cache for top level mounts Ian Kent
2016-10-25  1:20 ` [PATCH 37/37] autofs-5.1.2 - handle amd cache option all in amd type auto mounts Ian Kent
2016-11-04  8:53 ` [PATCH 00/37] Current patch queue for review Ian Kent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161025011927.7778.7380.stgit@pluto.themaw.net \
    --to=raven@themaw.net \
    --cc=autofs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.