From owner-svn-src-head@FreeBSD.ORG Sat Nov 22 16:48:31 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 8A2983CC; Sat, 22 Nov 2014 16:48:31 +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 6B1C5770; Sat, 22 Nov 2014 16:48:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sAMGmVvo065756; Sat, 22 Nov 2014 16:48:31 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sAMGmUtR065746; Sat, 22 Nov 2014 16:48:30 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201411221648.sAMGmUtR065746@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sat, 22 Nov 2014 16:48:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r274859 - 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-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 Nov 2014 16:48:31 -0000 Author: trasz Date: Sat Nov 22 16:48:29 2014 New Revision: 274859 URL: https://svnweb.freebsd.org/changeset/base/274859 Log: Implement "automount -c". 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_vfsops.c head/usr.sbin/autofs/automount.8 head/usr.sbin/autofs/automount.c Modified: head/sys/fs/autofs/autofs.c ============================================================================== --- head/sys/fs/autofs/autofs.c Sat Nov 22 16:46:00 2014 (r274858) +++ head/sys/fs/autofs/autofs.c Sat Nov 22 16:48:29 2014 (r274859) @@ -318,6 +318,18 @@ autofs_cache_callout(void *context) anp->an_cached = false; } +void +autofs_flush(struct autofs_mount *amp) +{ + + /* + * XXX: This will do for now, but ideally we should iterate + * over all the nodes. + */ + amp->am_root->an_cached = false; + AUTOFS_DEBUG("%s flushed", amp->am_mountpoint); +} + /* * The set/restore sigmask functions are used to (temporarily) overwrite * the thread td_sigmask during triggering. Modified: head/sys/fs/autofs/autofs.h ============================================================================== --- head/sys/fs/autofs/autofs.h Sat Nov 22 16:46:00 2014 (r274858) +++ head/sys/fs/autofs/autofs.h Sat Nov 22 16:48:29 2014 (r274859) @@ -133,6 +133,7 @@ int autofs_trigger(struct autofs_node *a int componentlen); bool autofs_cached(struct autofs_node *anp, const char *component, int componentlen); +void autofs_flush(struct autofs_mount *amp); bool autofs_ignore_thread(const struct thread *td); int autofs_node_new(struct autofs_node *parent, struct autofs_mount *amp, const char *name, int namelen, struct autofs_node **anpp); Modified: head/sys/fs/autofs/autofs_vfsops.c ============================================================================== --- head/sys/fs/autofs/autofs_vfsops.c Sat Nov 22 16:46:00 2014 (r274858) +++ head/sys/fs/autofs/autofs_vfsops.c Sat Nov 22 16:48:29 2014 (r274859) @@ -61,8 +61,10 @@ autofs_mount(struct mount *mp) if (vfs_filteropt(mp->mnt_optnew, autofs_opts)) return (EINVAL); - if (mp->mnt_flag & MNT_UPDATE) + if (mp->mnt_flag & MNT_UPDATE) { + autofs_flush(VFSTOAUTOFS(mp)); return (0); + } if (vfs_getopt(mp->mnt_optnew, "from", (void **)&from, NULL)) return (EINVAL); Modified: head/usr.sbin/autofs/automount.8 ============================================================================== --- head/usr.sbin/autofs/automount.8 Sat Nov 22 16:46:00 2014 (r274858) +++ head/usr.sbin/autofs/automount.8 Sat Nov 22 16:48:29 2014 (r274859) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 20, 2014 +.Dd November 22, 2014 .Dt AUTOMOUNT 8 .Os .Sh NAME @@ -37,6 +37,7 @@ .Nm .Op Fl D Ar name=value .Op Fl L +.Op Fl c .Op Fl f .Op Fl o Ar options .Op Fl v @@ -64,6 +65,9 @@ and any direct maps, then print them to When specified more than once, all the maps, including indirect ones, will be parsed and shown. This is useful when debugging configuration problems. +.It Fl c +Flush caches, discarding possibly stale information obtained from maps +and directory services. .It Fl f Force unmount, to be used with .Fl u . Modified: head/usr.sbin/autofs/automount.c ============================================================================== --- head/usr.sbin/autofs/automount.c Sat Nov 22 16:46:00 2014 (r274858) +++ head/usr.sbin/autofs/automount.c Sat Nov 22 16:48:29 2014 (r274859) @@ -230,6 +230,57 @@ mount_unmount(struct node *root) } static void +flush_autofs(const char *fspath) +{ + struct iovec *iov = NULL; + char errmsg[255]; + int error, iovlen = 0; + + log_debugx("flushing %s", fspath); + memset(errmsg, 0, sizeof(errmsg)); + + build_iovec(&iov, &iovlen, "fstype", + __DECONST(void *, "autofs"), (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", + __DECONST(void *, fspath), (size_t)-1); + build_iovec(&iov, &iovlen, "errmsg", + errmsg, sizeof(errmsg)); + + error = nmount(iov, iovlen, MNT_UPDATE); + if (error != 0) { + if (*errmsg != '\0') { + log_err(1, "cannot flush %s: %s", + fspath, errmsg); + } else { + log_err(1, "cannot flush %s", fspath); + } + } +} + +static void +flush_caches(void) +{ + struct statfs *mntbuf; + int i, nitems; + + nitems = getmntinfo(&mntbuf, MNT_WAIT); + if (nitems <= 0) + log_err(1, "getmntinfo"); + + log_debugx("flushing autofs caches"); + + for (i = 0; i < nitems; i++) { + if (strcmp(mntbuf[i].f_fstypename, "autofs") != 0) { + log_debugx("skipping %s, filesystem type is not autofs", + mntbuf[i].f_mntonname); + continue; + } + + flush_autofs(mntbuf[i].f_mntonname); + } +} + +static void unmount_automounted(bool force) { struct statfs *mntbuf; @@ -262,7 +313,7 @@ static void usage_automount(void) { - fprintf(stderr, "usage: automount [-D name=value][-o opts][-Lfuv]\n"); + fprintf(stderr, "usage: automount [-D name=value][-o opts][-Lcfuv]\n"); exit(1); } @@ -272,7 +323,7 @@ main_automount(int argc, char **argv) struct node *root; int ch, debug = 0, show_maps = 0; char *options = NULL; - bool do_unmount = false, force_unmount = false; + bool do_unmount = false, force_unmount = false, flush = false; /* * Note that in automount(8), the only purpose of variable @@ -280,7 +331,7 @@ main_automount(int argc, char **argv) */ defined_init(); - while ((ch = getopt(argc, argv, "D:Lfo:uv")) != -1) { + while ((ch = getopt(argc, argv, "D:Lfco:uv")) != -1) { switch (ch) { case 'D': defined_parse_and_add(optarg); @@ -288,6 +339,9 @@ main_automount(int argc, char **argv) case 'L': show_maps++; break; + case 'c': + flush = true; + break; case 'f': force_unmount = true; break; @@ -319,6 +373,11 @@ main_automount(int argc, char **argv) log_init(debug); + if (flush) { + flush_caches(); + return (0); + } + if (do_unmount) { unmount_automounted(force_unmount); return (0);