Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Mar 2015 19:32:20 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r279741 - in stable/10: sys/fs/autofs usr.sbin/autofs
Message-ID:  <201503071932.t27JWK26021258@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Sat Mar  7 19:32:19 2015
New Revision: 279741
URL: https://svnweb.freebsd.org/changeset/base/279741

Log:
  MFC r273127:
  
  Make automountd(8) inform autofs(4) whether directory being handled can
  have wildcards.  This makes it possible for autofs(4) to avoid requesting
  automountd(8) action on access to nonexistent nodes - unless wildcards
  are actually used.
  
  Note that this change breaks ABI for automountd(8).
  
  MFC r278521:
  
  Restore ABI compatibility, broken in r273127.  Note that while this fixes
  ABI with 10.1, it breaks ABI for 11-CURRENT, so rebuild of automountd(8)
  is neccessary.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  stable/10/sys/fs/autofs/autofs.c
  stable/10/sys/fs/autofs/autofs.h
  stable/10/sys/fs/autofs/autofs_ioctl.h
  stable/10/usr.sbin/autofs/automountd.c
  stable/10/usr.sbin/autofs/common.c
  stable/10/usr.sbin/autofs/common.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/fs/autofs/autofs.c
==============================================================================
--- stable/10/sys/fs/autofs/autofs.c	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/sys/fs/autofs/autofs.c	Sat Mar  7 19:32:19 2015	(r279741)
@@ -274,6 +274,7 @@ autofs_task(void *context, int pending)
 	 * XXX: EIO perhaps?
 	 */
 	ar->ar_error = ETIMEDOUT;
+	ar->ar_wildcards = true;
 	ar->ar_done = true;
 	ar->ar_in_progress = false;
 	cv_broadcast(&autofs_softc->sc_cv);
@@ -291,12 +292,13 @@ autofs_cached(struct autofs_node *anp, c
 	AUTOFS_ASSERT_UNLOCKED(amp);
 
 	/*
-	 * For top-level nodes we need to request automountd(8)
-	 * assistance even if the node is marked as cached,
-	 * but the requested subdirectory does not exist.  This
-	 * is necessary for wildcard indirect map keys to work.
+	 * For root node we need to request automountd(8) assistance even
+	 * if the node is marked as cached, but the requested top-level
+	 * directory does not exist.  This is necessary for wildcard indirect
+	 * map keys to work.  We don't do this if we know that there are
+	 * no wildcards.
 	 */
-	if (anp->an_parent == NULL && componentlen != 0) {
+	if (anp->an_parent == NULL && componentlen != 0 && anp->an_wildcards) {
 		AUTOFS_SLOCK(amp);
 		error = autofs_node_find(anp, component, componentlen, NULL);
 		AUTOFS_SUNLOCK(amp);
@@ -366,6 +368,7 @@ autofs_trigger_one(struct autofs_node *a
 	struct autofs_request *ar;
 	char *key, *path;
 	int error = 0, request_error, last;
+	bool wildcards;
 
 	amp = anp->an_mount;
 
@@ -455,6 +458,8 @@ autofs_trigger_one(struct autofs_node *a
 		    ar->ar_path, request_error);
 	}
 
+	wildcards = ar->ar_wildcards;
+
 	last = refcount_release(&ar->ar_refcount);
 	if (last) {
 		TAILQ_REMOVE(&autofs_softc->sc_requests, ar, ar_next);
@@ -475,6 +480,7 @@ autofs_trigger_one(struct autofs_node *a
 	 */
 	if (error == 0 && request_error == 0 && autofs_cache > 0) {
 		anp->an_cached = true;
+		anp->an_wildcards = wildcards;
 		callout_reset(&anp->an_callout, autofs_cache * hz,
 		    autofs_cache_callout, anp);
 	}
@@ -577,6 +583,34 @@ autofs_ioctl_request(struct autofs_daemo
 }
 
 static int
+autofs_ioctl_done_101(struct autofs_daemon_done_101 *add)
+{
+	struct autofs_request *ar;
+
+	sx_xlock(&autofs_softc->sc_lock);
+	TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) {
+		if (ar->ar_id == add->add_id)
+			break;
+	}
+
+	if (ar == NULL) {
+		sx_xunlock(&autofs_softc->sc_lock);
+		AUTOFS_DEBUG("id %d not found", add->add_id);
+		return (ESRCH);
+	}
+
+	ar->ar_error = add->add_error;
+	ar->ar_wildcards = true;
+	ar->ar_done = true;
+	ar->ar_in_progress = false;
+	cv_broadcast(&autofs_softc->sc_cv);
+
+	sx_xunlock(&autofs_softc->sc_lock);
+
+	return (0);
+}
+
+static int
 autofs_ioctl_done(struct autofs_daemon_done *add)
 {
 	struct autofs_request *ar;
@@ -594,6 +628,7 @@ autofs_ioctl_done(struct autofs_daemon_d
 	}
 
 	ar->ar_error = add->add_error;
+	ar->ar_wildcards = add->add_wildcards;
 	ar->ar_done = true;
 	ar->ar_in_progress = false;
 	cv_broadcast(&autofs_softc->sc_cv);
@@ -650,6 +685,9 @@ autofs_ioctl(struct cdev *dev, u_long cm
 	case AUTOFSREQUEST:
 		return (autofs_ioctl_request(
 		    (struct autofs_daemon_request *)arg));
+	case AUTOFSDONE101:
+		return (autofs_ioctl_done_101(
+		    (struct autofs_daemon_done_101 *)arg));
 	case AUTOFSDONE:
 		return (autofs_ioctl_done(
 		    (struct autofs_daemon_done *)arg));

Modified: stable/10/sys/fs/autofs/autofs.h
==============================================================================
--- stable/10/sys/fs/autofs/autofs.h	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/sys/fs/autofs/autofs.h	Sat Mar  7 19:32:19 2015	(r279741)
@@ -74,6 +74,7 @@ struct autofs_node {
 	struct vnode			*an_vnode;
 	struct sx			an_vnode_lock;
 	bool				an_cached;
+	bool				an_wildcards;
 	struct callout			an_callout;
 	int				an_retries;
 	struct timespec			an_ctime;
@@ -97,6 +98,7 @@ struct autofs_request {
 	int				ar_id;
 	bool				ar_done;
 	int				ar_error;
+	bool				ar_wildcards;
 	bool				ar_in_progress;
 	char				ar_from[MAXPATHLEN];
 	char				ar_path[MAXPATHLEN];

Modified: stable/10/sys/fs/autofs/autofs_ioctl.h
==============================================================================
--- stable/10/sys/fs/autofs/autofs_ioctl.h	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/sys/fs/autofs/autofs_ioctl.h	Sat Mar  7 19:32:19 2015	(r279741)
@@ -71,6 +71,21 @@ struct autofs_daemon_request {
 	char		adr_options[MAXPATHLEN];
 };
 
+/*
+ * Compatibility with 10.1-RELEASE automountd(8).
+ */
+struct autofs_daemon_done_101 {
+	/*
+	 * Identifier, copied from adr_id.
+	 */
+	int		add_id;
+
+	/*
+	 * Error number, possibly returned to userland.
+	 */
+	int		add_error;
+};
+
 struct autofs_daemon_done {
 	/*
 	 * Identifier, copied from adr_id.
@@ -78,12 +93,24 @@ struct autofs_daemon_done {
 	int		add_id;
 
 	/*
+	 * Set to 1 if the map may contain wildcard entries;
+	 * otherwise autofs will do negative caching.
+	 */
+	int		add_wildcards;
+
+	/*
 	 * Error number, possibly returned to userland.
 	 */
 	int		add_error;
+
+	/*
+	 * Reserved for future use.
+	 */
+	int		add_spare[7];
 };
 
 #define	AUTOFSREQUEST	_IOR('I', 0x01, struct autofs_daemon_request)
-#define	AUTOFSDONE	_IOW('I', 0x02, struct autofs_daemon_done)
+#define	AUTOFSDONE101	_IOW('I', 0x02, struct autofs_daemon_done_101)
+#define	AUTOFSDONE	_IOW('I', 0x03, struct autofs_daemon_done)
 
 #endif /* !AUTOFS_IOCTL_H */

Modified: stable/10/usr.sbin/autofs/automountd.c
==============================================================================
--- stable/10/usr.sbin/autofs/automountd.c	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/usr.sbin/autofs/automountd.c	Sat Mar  7 19:32:19 2015	(r279741)
@@ -68,13 +68,14 @@ static int autofs_fd;
 static int request_id;
 
 static void
-done(int request_error)
+done(int request_error, bool wildcards)
 {
 	struct autofs_daemon_done add;
 	int error;
 
 	memset(&add, 0, sizeof(add));
 	add.add_id = request_id;
+	add.add_wildcards = wildcards;
 	add.add_error = request_error;
 
 	log_debugx("completing request %d with error %d",
@@ -172,7 +173,7 @@ static void
 exit_callback(void)
 {
 
-	done(EIO);
+	done(EIO, true);
 }
 
 static void
@@ -184,6 +185,7 @@ handle_request(const struct autofs_daemo
 	FILE *f;
 	char *options, *fstype, *nobrowse, *retrycnt, *tmp;
 	int error;
+	bool wildcards;
 
 	log_debugx("got request %d: from %s, path %s, prefix \"%s\", "
 	    "key \"%s\", options \"%s\"", adr->adr_id, adr->adr_from,
@@ -209,9 +211,26 @@ handle_request(const struct autofs_daemo
 		    checked_strdup(adr->adr_options), checked_strdup(map),
 		    checked_strdup("[kernel request]"), lineno);
 	}
-	parse_map(parent, map, adr->adr_key[0] != '\0' ? adr->adr_key : NULL);
+
+	/*
+	 * "Wildcards" here actually means "make autofs(4) request
+	 * automountd(8) action if the node being looked up does not
+	 * exist, even though the parent is marked as cached".  This
+	 * needs to be done for maps with wildcard entries, but also
+	 * for special and executable maps.
+	 */
+	parse_map(parent, map, adr->adr_key[0] != '\0' ? adr->adr_key : NULL,
+	    &wildcards);
+	if (!wildcards)
+		wildcards = node_has_wildcards(parent);
+	if (wildcards)
+		log_debugx("map may contain wildcard entries");
+	else
+		log_debugx("map does not contain wildcard entries");
+
 	if (adr->adr_key[0] != '\0')
 		node_expand_wildcard(root, adr->adr_key);
+
 	node = node_find(root, adr->adr_path);
 	if (node == NULL) {
 		log_errx(1, "map %s does not contain key for \"%s\"; "
@@ -236,7 +255,7 @@ handle_request(const struct autofs_daemo
 		if (nobrowse != NULL && adr->adr_key[0] == '\0') {
 			log_debugx("skipping map %s due to \"nobrowse\" "
 			    "option; exiting", map);
-			done(0);
+			done(0, true);
 
 			/*
 			 * Exit without calling exit_callback().
@@ -263,7 +282,7 @@ handle_request(const struct autofs_daemo
 		}
 
 		log_debugx("nothing to mount; exiting");
-		done(0);
+		done(0, wildcards);
 
 		/*
 		 * Exit without calling exit_callback().
@@ -337,7 +356,7 @@ handle_request(const struct autofs_daemo
 		log_errx(1, "mount failed");
 
 	log_debugx("mount done; exiting");
-	done(0);
+	done(0, wildcards);
 
 	/*
 	 * Exit without calling exit_callback().

Modified: stable/10/usr.sbin/autofs/common.c
==============================================================================
--- stable/10/usr.sbin/autofs/common.c	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/usr.sbin/autofs/common.c	Sat Mar  7 19:32:19 2015	(r279741)
@@ -498,6 +498,19 @@ node_is_direct_map(const struct node *n)
 	return (true);
 }
 
+bool
+node_has_wildcards(const struct node *n)
+{
+	const struct node *child;
+
+	TAILQ_FOREACH(child, &n->n_children, n_next) {
+		if (strcmp(child->n_key, "*") == 0)
+			return (true);
+	}
+
+	return (false);
+}
+
 static void
 node_expand_maps(struct node *n, bool indirect)
 {
@@ -526,7 +539,7 @@ node_expand_maps(struct node *n, bool in
 			log_debugx("map \"%s\" is a direct map, parsing",
 			    child->n_map);
 		}
-		parse_map(child, child->n_map, NULL);
+		parse_map(child, child->n_map, NULL, NULL);
 	}
 }
 
@@ -996,7 +1009,8 @@ parse_included_map(struct node *parent, 
 }
 
 void
-parse_map(struct node *parent, const char *map, const char *key)
+parse_map(struct node *parent, const char *map, const char *key,
+    bool *wildcards)
 {
 	char *path = NULL;
 	int error, ret;
@@ -1007,8 +1021,14 @@ parse_map(struct node *parent, const cha
 
 	log_debugx("parsing map \"%s\"", map);
 
-	if (map[0] == '-')
+	if (wildcards != NULL)
+		*wildcards = false;
+
+	if (map[0] == '-') {
+		if (wildcards != NULL)
+			*wildcards = true;
 		return (parse_special_map(parent, map, key));
+	}
 
 	if (map[0] == '/') {
 		path = checked_strdup(map);
@@ -1035,6 +1055,9 @@ parse_map(struct node *parent, const cha
 	if (executable) {
 		log_debugx("map \"%s\" is executable", map);
 
+		if (wildcards != NULL)
+			*wildcards = true;
+
 		if (key != NULL) {
 			yyin = auto_popen(path, key, NULL);
 		} else {

Modified: stable/10/usr.sbin/autofs/common.h
==============================================================================
--- stable/10/usr.sbin/autofs/common.h	Sat Mar  7 19:29:53 2015	(r279740)
+++ stable/10/usr.sbin/autofs/common.h	Sat Mar  7 19:32:19 2015	(r279741)
@@ -80,6 +80,7 @@ struct node	*node_new_map(struct node *p
 		    char *map, const char *config_file, int config_line);
 struct node	*node_find(struct node *root, const char *mountpoint);
 bool		node_is_direct_map(const struct node *n);
+bool		node_has_wildcards(const struct node *n);
 char	*node_path(const struct node *n);
 char	*node_options(const struct node *n);
 void	node_expand_ampersand(struct node *root, const char *key);
@@ -88,7 +89,8 @@ int	node_expand_defined(struct node *roo
 void	node_expand_indirect_maps(struct node *n);
 void	node_print(const struct node *n);
 void	parse_master(struct node *root, const char *path);
-void	parse_map(struct node *parent, const char *map, const char *args);
+void	parse_map(struct node *parent, const char *map, const char *args,
+	    bool *wildcards);
 char	*defined_expand(const char *string);
 void	defined_init(void);
 void	defined_parse_and_add(char *def);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503071932.t27JWK26021258>