Implement "automount -c".

MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Edward Tomasz Napierala 2014-11-22 16:48:29 +00:00
parent a0252a0a82
commit e3d5f1fe3b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=274859
5 changed files with 83 additions and 5 deletions

View File

@ -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.

View File

@ -133,6 +133,7 @@ int autofs_trigger(struct autofs_node *anp, const char *component,
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);

View File

@ -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);

View File

@ -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 standard output.
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 .

View File

@ -229,6 +229,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)
{
@ -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);