From owner-svn-src-all@FreeBSD.ORG Sat Mar 7 19:32:22 2015 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 0D73DC6A; Sat, 7 Mar 2015 19:32:22 +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 EA251AE1; Sat, 7 Mar 2015 19:32:21 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t27JWLE0021265; Sat, 7 Mar 2015 19:32:21 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t27JWK26021258; Sat, 7 Mar 2015 19:32:20 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201503071932.t27JWK26021258@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sat, 7 Mar 2015 19:32:20 +0000 (UTC) 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 X-SVN-Group: stable-10 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: Sat, 07 Mar 2015 19:32:22 -0000 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);