Implement "automount -c".
MFC after: 1 month Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
a0252a0a82
commit
e3d5f1fe3b
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 .
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user