From owner-svn-src-all@FreeBSD.ORG Wed Oct 15 09:28:47 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2B27066E; Wed, 15 Oct 2014 09:28:47 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1641E996; Wed, 15 Oct 2014 09:28:47 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9F9Skoc028353; Wed, 15 Oct 2014 09:28:46 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9F9SjvK028344; Wed, 15 Oct 2014 09:28:45 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201410150928.s9F9SjvK028344@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Wed, 15 Oct 2014 09:28:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273127 - in head: sys/fs/autofs usr.sbin/autofs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Oct 2014 09:28:47 -0000 Author: trasz Date: Wed Oct 15 09:28:45 2014 New Revision: 273127 URL: https://svnweb.freebsd.org/changeset/base/273127 Log: 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). Tested by: dhw@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Modified: head/sys/fs/autofs/autofs.c head/sys/fs/autofs/autofs.h head/sys/fs/autofs/autofs_ioctl.h head/usr.sbin/autofs/automountd.c head/usr.sbin/autofs/common.c head/usr.sbin/autofs/common.h Modified: head/sys/fs/autofs/autofs.c ============================================================================== --- head/sys/fs/autofs/autofs.c Wed Oct 15 08:04:43 2014 (r273126) +++ head/sys/fs/autofs/autofs.c Wed Oct 15 09:28:45 2014 (r273127) @@ -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; @@ -450,6 +453,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); @@ -470,6 +475,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); } @@ -584,6 +590,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); Modified: head/sys/fs/autofs/autofs.h ============================================================================== --- head/sys/fs/autofs/autofs.h Wed Oct 15 08:04:43 2014 (r273126) +++ head/sys/fs/autofs/autofs.h Wed Oct 15 09:28:45 2014 (r273127) @@ -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: head/sys/fs/autofs/autofs_ioctl.h ============================================================================== --- head/sys/fs/autofs/autofs_ioctl.h Wed Oct 15 08:04:43 2014 (r273126) +++ head/sys/fs/autofs/autofs_ioctl.h Wed Oct 15 09:28:45 2014 (r273127) @@ -78,6 +78,12 @@ 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; Modified: head/usr.sbin/autofs/automountd.c ============================================================================== --- head/usr.sbin/autofs/automountd.c Wed Oct 15 08:04:43 2014 (r273126) +++ head/usr.sbin/autofs/automountd.c Wed Oct 15 09:28:45 2014 (r273127) @@ -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: head/usr.sbin/autofs/common.c ============================================================================== --- head/usr.sbin/autofs/common.c Wed Oct 15 08:04:43 2014 (r273126) +++ head/usr.sbin/autofs/common.c Wed Oct 15 09:28:45 2014 (r273127) @@ -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: head/usr.sbin/autofs/common.h ============================================================================== --- head/usr.sbin/autofs/common.h Wed Oct 15 08:04:43 2014 (r273126) +++ head/usr.sbin/autofs/common.h Wed Oct 15 09:28:45 2014 (r273127) @@ -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);