13914ddf8SEdward Tomasz Napierala /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3abdd3945SEdward Tomasz Napierala *
43914ddf8SEdward Tomasz Napierala * Copyright (c) 2014 The FreeBSD Foundation
53914ddf8SEdward Tomasz Napierala *
63914ddf8SEdward Tomasz Napierala * This software was developed by Edward Tomasz Napierala under sponsorship
73914ddf8SEdward Tomasz Napierala * from the FreeBSD Foundation.
83914ddf8SEdward Tomasz Napierala *
93914ddf8SEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without
103914ddf8SEdward Tomasz Napierala * modification, are permitted provided that the following conditions
113914ddf8SEdward Tomasz Napierala * are met:
123914ddf8SEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright
133914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer.
143914ddf8SEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright
153914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the
163914ddf8SEdward Tomasz Napierala * documentation and/or other materials provided with the distribution.
173914ddf8SEdward Tomasz Napierala *
183914ddf8SEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
193914ddf8SEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
203914ddf8SEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
213914ddf8SEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
223914ddf8SEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
233914ddf8SEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
243914ddf8SEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
253914ddf8SEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
263914ddf8SEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
273914ddf8SEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
283914ddf8SEdward Tomasz Napierala * SUCH DAMAGE.
293914ddf8SEdward Tomasz Napierala *
303914ddf8SEdward Tomasz Napierala */
313914ddf8SEdward Tomasz Napierala
323914ddf8SEdward Tomasz Napierala #include <sys/types.h>
333914ddf8SEdward Tomasz Napierala #include <sys/event.h>
343914ddf8SEdward Tomasz Napierala #include <sys/mount.h>
353914ddf8SEdward Tomasz Napierala #include <sys/time.h>
363914ddf8SEdward Tomasz Napierala #include <assert.h>
373914ddf8SEdward Tomasz Napierala #include <errno.h>
38592d6e85SEdward Tomasz Napierala #include <libutil.h>
393914ddf8SEdward Tomasz Napierala #include <stdbool.h>
403914ddf8SEdward Tomasz Napierala #include <stdint.h>
413914ddf8SEdward Tomasz Napierala #include <stdio.h>
423914ddf8SEdward Tomasz Napierala #include <stdlib.h>
433914ddf8SEdward Tomasz Napierala #include <string.h>
443914ddf8SEdward Tomasz Napierala #include <unistd.h>
453914ddf8SEdward Tomasz Napierala
463914ddf8SEdward Tomasz Napierala #include "common.h"
473914ddf8SEdward Tomasz Napierala
483914ddf8SEdward Tomasz Napierala #define AUTOUNMOUNTD_PIDFILE "/var/run/autounmountd.pid"
493914ddf8SEdward Tomasz Napierala
503914ddf8SEdward Tomasz Napierala struct automounted_fs {
513914ddf8SEdward Tomasz Napierala TAILQ_ENTRY(automounted_fs) af_next;
523914ddf8SEdward Tomasz Napierala time_t af_mount_time;
533914ddf8SEdward Tomasz Napierala bool af_mark;
543914ddf8SEdward Tomasz Napierala fsid_t af_fsid;
553914ddf8SEdward Tomasz Napierala char af_mountpoint[MNAMELEN];
563914ddf8SEdward Tomasz Napierala };
573914ddf8SEdward Tomasz Napierala
583914ddf8SEdward Tomasz Napierala static TAILQ_HEAD(, automounted_fs) automounted;
593914ddf8SEdward Tomasz Napierala
603914ddf8SEdward Tomasz Napierala static struct automounted_fs *
automounted_find(fsid_t fsid)613914ddf8SEdward Tomasz Napierala automounted_find(fsid_t fsid)
623914ddf8SEdward Tomasz Napierala {
633914ddf8SEdward Tomasz Napierala struct automounted_fs *af;
643914ddf8SEdward Tomasz Napierala
653914ddf8SEdward Tomasz Napierala TAILQ_FOREACH(af, &automounted, af_next) {
66245bfd34SRyan Moeller if (fsidcmp(&af->af_fsid, &fsid) == 0)
673914ddf8SEdward Tomasz Napierala return (af);
683914ddf8SEdward Tomasz Napierala }
693914ddf8SEdward Tomasz Napierala
703914ddf8SEdward Tomasz Napierala return (NULL);
713914ddf8SEdward Tomasz Napierala }
723914ddf8SEdward Tomasz Napierala
733914ddf8SEdward Tomasz Napierala static struct automounted_fs *
automounted_add(fsid_t fsid,const char * mountpoint)743914ddf8SEdward Tomasz Napierala automounted_add(fsid_t fsid, const char *mountpoint)
753914ddf8SEdward Tomasz Napierala {
763914ddf8SEdward Tomasz Napierala struct automounted_fs *af;
773914ddf8SEdward Tomasz Napierala
7827525377SEdward Tomasz Napierala af = calloc(1, sizeof(*af));
793914ddf8SEdward Tomasz Napierala if (af == NULL)
803914ddf8SEdward Tomasz Napierala log_err(1, "calloc");
813914ddf8SEdward Tomasz Napierala af->af_mount_time = time(NULL);
823914ddf8SEdward Tomasz Napierala af->af_fsid = fsid;
833914ddf8SEdward Tomasz Napierala strlcpy(af->af_mountpoint, mountpoint, sizeof(af->af_mountpoint));
843914ddf8SEdward Tomasz Napierala
853914ddf8SEdward Tomasz Napierala TAILQ_INSERT_TAIL(&automounted, af, af_next);
863914ddf8SEdward Tomasz Napierala
873914ddf8SEdward Tomasz Napierala return (af);
883914ddf8SEdward Tomasz Napierala }
893914ddf8SEdward Tomasz Napierala
903914ddf8SEdward Tomasz Napierala static void
automounted_remove(struct automounted_fs * af)913914ddf8SEdward Tomasz Napierala automounted_remove(struct automounted_fs *af)
923914ddf8SEdward Tomasz Napierala {
933914ddf8SEdward Tomasz Napierala
943914ddf8SEdward Tomasz Napierala TAILQ_REMOVE(&automounted, af, af_next);
953914ddf8SEdward Tomasz Napierala free(af);
963914ddf8SEdward Tomasz Napierala }
973914ddf8SEdward Tomasz Napierala
983914ddf8SEdward Tomasz Napierala static void
refresh_automounted(void)993914ddf8SEdward Tomasz Napierala refresh_automounted(void)
1003914ddf8SEdward Tomasz Napierala {
1013914ddf8SEdward Tomasz Napierala struct automounted_fs *af, *tmpaf;
1023914ddf8SEdward Tomasz Napierala struct statfs *mntbuf;
1033914ddf8SEdward Tomasz Napierala int i, nitems;
1043914ddf8SEdward Tomasz Napierala
1053914ddf8SEdward Tomasz Napierala nitems = getmntinfo(&mntbuf, MNT_WAIT);
1063914ddf8SEdward Tomasz Napierala if (nitems <= 0)
1073914ddf8SEdward Tomasz Napierala log_err(1, "getmntinfo");
1083914ddf8SEdward Tomasz Napierala
1093914ddf8SEdward Tomasz Napierala log_debugx("refreshing list of automounted filesystems");
1103914ddf8SEdward Tomasz Napierala
1113914ddf8SEdward Tomasz Napierala TAILQ_FOREACH(af, &automounted, af_next)
1123914ddf8SEdward Tomasz Napierala af->af_mark = false;
1133914ddf8SEdward Tomasz Napierala
1143914ddf8SEdward Tomasz Napierala for (i = 0; i < nitems; i++) {
1153914ddf8SEdward Tomasz Napierala if (strcmp(mntbuf[i].f_fstypename, "autofs") == 0) {
1163914ddf8SEdward Tomasz Napierala log_debugx("skipping %s, filesystem type is autofs",
1173914ddf8SEdward Tomasz Napierala mntbuf[i].f_mntonname);
1183914ddf8SEdward Tomasz Napierala continue;
1193914ddf8SEdward Tomasz Napierala }
1203914ddf8SEdward Tomasz Napierala
1213914ddf8SEdward Tomasz Napierala if ((mntbuf[i].f_flags & MNT_AUTOMOUNTED) == 0) {
1223914ddf8SEdward Tomasz Napierala log_debugx("skipping %s, not automounted",
1233914ddf8SEdward Tomasz Napierala mntbuf[i].f_mntonname);
1243914ddf8SEdward Tomasz Napierala continue;
1253914ddf8SEdward Tomasz Napierala }
1263914ddf8SEdward Tomasz Napierala
1273914ddf8SEdward Tomasz Napierala af = automounted_find(mntbuf[i].f_fsid);
1283914ddf8SEdward Tomasz Napierala if (af == NULL) {
1293914ddf8SEdward Tomasz Napierala log_debugx("new automounted filesystem found on %s "
1303914ddf8SEdward Tomasz Napierala "(FSID:%d:%d)", mntbuf[i].f_mntonname,
1313914ddf8SEdward Tomasz Napierala mntbuf[i].f_fsid.val[0], mntbuf[i].f_fsid.val[1]);
1323914ddf8SEdward Tomasz Napierala af = automounted_add(mntbuf[i].f_fsid,
1333914ddf8SEdward Tomasz Napierala mntbuf[i].f_mntonname);
1343914ddf8SEdward Tomasz Napierala } else {
1353914ddf8SEdward Tomasz Napierala log_debugx("already known automounted filesystem "
1363914ddf8SEdward Tomasz Napierala "found on %s (FSID:%d:%d)", mntbuf[i].f_mntonname,
1373914ddf8SEdward Tomasz Napierala mntbuf[i].f_fsid.val[0], mntbuf[i].f_fsid.val[1]);
1383914ddf8SEdward Tomasz Napierala }
1393914ddf8SEdward Tomasz Napierala af->af_mark = true;
1403914ddf8SEdward Tomasz Napierala }
1413914ddf8SEdward Tomasz Napierala
1423914ddf8SEdward Tomasz Napierala TAILQ_FOREACH_SAFE(af, &automounted, af_next, tmpaf) {
1433914ddf8SEdward Tomasz Napierala if (af->af_mark)
1443914ddf8SEdward Tomasz Napierala continue;
1453914ddf8SEdward Tomasz Napierala log_debugx("lost filesystem mounted on %s (FSID:%d:%d)",
1463914ddf8SEdward Tomasz Napierala af->af_mountpoint, af->af_fsid.val[0], af->af_fsid.val[1]);
1473914ddf8SEdward Tomasz Napierala automounted_remove(af);
1483914ddf8SEdward Tomasz Napierala }
1493914ddf8SEdward Tomasz Napierala }
1503914ddf8SEdward Tomasz Napierala
1513914ddf8SEdward Tomasz Napierala static int
unmount_by_fsid(const fsid_t fsid,const char * mountpoint)1523914ddf8SEdward Tomasz Napierala unmount_by_fsid(const fsid_t fsid, const char *mountpoint)
1533914ddf8SEdward Tomasz Napierala {
1543914ddf8SEdward Tomasz Napierala char *fsid_str;
1553914ddf8SEdward Tomasz Napierala int error, ret;
1563914ddf8SEdward Tomasz Napierala
1573914ddf8SEdward Tomasz Napierala ret = asprintf(&fsid_str, "FSID:%d:%d", fsid.val[0], fsid.val[1]);
1583914ddf8SEdward Tomasz Napierala if (ret < 0)
1593914ddf8SEdward Tomasz Napierala log_err(1, "asprintf");
1603914ddf8SEdward Tomasz Napierala
161debc480eSEdward Tomasz Napierala error = unmount(fsid_str, MNT_NONBUSY | MNT_BYFSID);
1623914ddf8SEdward Tomasz Napierala if (error != 0) {
1633914ddf8SEdward Tomasz Napierala if (errno == EBUSY) {
1643914ddf8SEdward Tomasz Napierala log_debugx("cannot unmount %s (%s): %s",
1653914ddf8SEdward Tomasz Napierala mountpoint, fsid_str, strerror(errno));
1663914ddf8SEdward Tomasz Napierala } else {
1673914ddf8SEdward Tomasz Napierala log_warn("cannot unmount %s (%s)",
1683914ddf8SEdward Tomasz Napierala mountpoint, fsid_str);
1693914ddf8SEdward Tomasz Napierala }
17088e531f3SRobert Wing } else
17188e531f3SRobert Wing rpc_umntall();
1723914ddf8SEdward Tomasz Napierala
1733914ddf8SEdward Tomasz Napierala free(fsid_str);
1743914ddf8SEdward Tomasz Napierala
1753914ddf8SEdward Tomasz Napierala return (error);
1763914ddf8SEdward Tomasz Napierala }
1773914ddf8SEdward Tomasz Napierala
178ca05fff0SJustin Hibbits static time_t
expire_automounted(time_t expiration_time)179ca05fff0SJustin Hibbits expire_automounted(time_t expiration_time)
1803914ddf8SEdward Tomasz Napierala {
1813914ddf8SEdward Tomasz Napierala struct automounted_fs *af, *tmpaf;
1823914ddf8SEdward Tomasz Napierala time_t now;
183ca05fff0SJustin Hibbits time_t mounted_for, mounted_max = -1;
1843914ddf8SEdward Tomasz Napierala int error;
1853914ddf8SEdward Tomasz Napierala
1863914ddf8SEdward Tomasz Napierala now = time(NULL);
1873914ddf8SEdward Tomasz Napierala
1883914ddf8SEdward Tomasz Napierala log_debugx("expiring automounted filesystems");
1893914ddf8SEdward Tomasz Napierala
1903914ddf8SEdward Tomasz Napierala TAILQ_FOREACH_SAFE(af, &automounted, af_next, tmpaf) {
1913914ddf8SEdward Tomasz Napierala mounted_for = difftime(now, af->af_mount_time);
1923914ddf8SEdward Tomasz Napierala
1933914ddf8SEdward Tomasz Napierala if (mounted_for < expiration_time) {
1943914ddf8SEdward Tomasz Napierala log_debugx("skipping %s (FSID:%d:%d), mounted "
1953447ea90SJustin Hibbits "for %jd seconds", af->af_mountpoint,
1963914ddf8SEdward Tomasz Napierala af->af_fsid.val[0], af->af_fsid.val[1],
1973447ea90SJustin Hibbits (intmax_t)mounted_for);
1983914ddf8SEdward Tomasz Napierala
1993914ddf8SEdward Tomasz Napierala if (mounted_for > mounted_max)
2003914ddf8SEdward Tomasz Napierala mounted_max = mounted_for;
2013914ddf8SEdward Tomasz Napierala
2023914ddf8SEdward Tomasz Napierala continue;
2033914ddf8SEdward Tomasz Napierala }
2043914ddf8SEdward Tomasz Napierala
2053914ddf8SEdward Tomasz Napierala log_debugx("filesystem mounted on %s (FSID:%d:%d), "
206ca05fff0SJustin Hibbits "was mounted for %ld seconds; unmounting",
2073914ddf8SEdward Tomasz Napierala af->af_mountpoint, af->af_fsid.val[0], af->af_fsid.val[1],
208ca05fff0SJustin Hibbits (long)mounted_for);
2093914ddf8SEdward Tomasz Napierala error = unmount_by_fsid(af->af_fsid, af->af_mountpoint);
2103914ddf8SEdward Tomasz Napierala if (error != 0) {
2113914ddf8SEdward Tomasz Napierala if (mounted_for > mounted_max)
2123914ddf8SEdward Tomasz Napierala mounted_max = mounted_for;
2133914ddf8SEdward Tomasz Napierala }
2143914ddf8SEdward Tomasz Napierala }
2153914ddf8SEdward Tomasz Napierala
2163914ddf8SEdward Tomasz Napierala return (mounted_max);
2173914ddf8SEdward Tomasz Napierala }
2183914ddf8SEdward Tomasz Napierala
2193914ddf8SEdward Tomasz Napierala static void
usage_autounmountd(void)2203914ddf8SEdward Tomasz Napierala usage_autounmountd(void)
2213914ddf8SEdward Tomasz Napierala {
2223914ddf8SEdward Tomasz Napierala
2233914ddf8SEdward Tomasz Napierala fprintf(stderr, "usage: autounmountd [-r time][-t time][-dv]\n");
2243914ddf8SEdward Tomasz Napierala exit(1);
2253914ddf8SEdward Tomasz Napierala }
2263914ddf8SEdward Tomasz Napierala
2273914ddf8SEdward Tomasz Napierala static void
do_wait(int kq,time_t sleep_time)228ca05fff0SJustin Hibbits do_wait(int kq, time_t sleep_time)
2293914ddf8SEdward Tomasz Napierala {
2303914ddf8SEdward Tomasz Napierala struct timespec timeout;
2313914ddf8SEdward Tomasz Napierala struct kevent unused;
23221cee0c5SEdward Tomasz Napierala int nevents;
2333914ddf8SEdward Tomasz Napierala
234ca05fff0SJustin Hibbits if (sleep_time != -1) {
235ca05fff0SJustin Hibbits assert(sleep_time > 0);
2363914ddf8SEdward Tomasz Napierala timeout.tv_sec = sleep_time;
2373914ddf8SEdward Tomasz Napierala timeout.tv_nsec = 0;
2383914ddf8SEdward Tomasz Napierala
239ca05fff0SJustin Hibbits log_debugx("waiting for filesystem event for %ld seconds",
240ca05fff0SJustin Hibbits (long)sleep_time);
24121cee0c5SEdward Tomasz Napierala nevents = kevent(kq, NULL, 0, &unused, 1, &timeout);
24221cee0c5SEdward Tomasz Napierala } else {
24321cee0c5SEdward Tomasz Napierala log_debugx("waiting for filesystem event");
24421cee0c5SEdward Tomasz Napierala nevents = kevent(kq, NULL, 0, &unused, 1, NULL);
24521cee0c5SEdward Tomasz Napierala }
2468379360aSEdward Tomasz Napierala if (nevents < 0) {
2478379360aSEdward Tomasz Napierala if (errno == EINTR)
2488379360aSEdward Tomasz Napierala return;
2493914ddf8SEdward Tomasz Napierala log_err(1, "kevent");
2508379360aSEdward Tomasz Napierala }
2513914ddf8SEdward Tomasz Napierala
25221cee0c5SEdward Tomasz Napierala if (nevents == 0) {
2533914ddf8SEdward Tomasz Napierala log_debugx("timeout reached");
254ca05fff0SJustin Hibbits assert(sleep_time > 0);
25521cee0c5SEdward Tomasz Napierala } else {
2563914ddf8SEdward Tomasz Napierala log_debugx("got filesystem event");
2573914ddf8SEdward Tomasz Napierala }
25821cee0c5SEdward Tomasz Napierala }
2593914ddf8SEdward Tomasz Napierala
2603914ddf8SEdward Tomasz Napierala int
main_autounmountd(int argc,char ** argv)2613914ddf8SEdward Tomasz Napierala main_autounmountd(int argc, char **argv)
2623914ddf8SEdward Tomasz Napierala {
2633914ddf8SEdward Tomasz Napierala struct kevent event;
2643914ddf8SEdward Tomasz Napierala struct pidfh *pidfh;
2653914ddf8SEdward Tomasz Napierala pid_t otherpid;
2663914ddf8SEdward Tomasz Napierala const char *pidfile_path = AUTOUNMOUNTD_PIDFILE;
2673914ddf8SEdward Tomasz Napierala int ch, debug = 0, error, kq;
268ca05fff0SJustin Hibbits time_t expiration_time = 600, retry_time = 600, mounted_max, sleep_time;
2693914ddf8SEdward Tomasz Napierala bool dont_daemonize = false;
2703914ddf8SEdward Tomasz Napierala
2713914ddf8SEdward Tomasz Napierala while ((ch = getopt(argc, argv, "dr:t:v")) != -1) {
2723914ddf8SEdward Tomasz Napierala switch (ch) {
2733914ddf8SEdward Tomasz Napierala case 'd':
2743914ddf8SEdward Tomasz Napierala dont_daemonize = true;
2753914ddf8SEdward Tomasz Napierala debug++;
2763914ddf8SEdward Tomasz Napierala break;
2773914ddf8SEdward Tomasz Napierala case 'r':
2783914ddf8SEdward Tomasz Napierala retry_time = atoi(optarg);
2793914ddf8SEdward Tomasz Napierala break;
2803914ddf8SEdward Tomasz Napierala case 't':
2813914ddf8SEdward Tomasz Napierala expiration_time = atoi(optarg);
2823914ddf8SEdward Tomasz Napierala break;
2833914ddf8SEdward Tomasz Napierala case 'v':
2843914ddf8SEdward Tomasz Napierala debug++;
2853914ddf8SEdward Tomasz Napierala break;
2863914ddf8SEdward Tomasz Napierala case '?':
2873914ddf8SEdward Tomasz Napierala default:
2883914ddf8SEdward Tomasz Napierala usage_autounmountd();
2893914ddf8SEdward Tomasz Napierala }
2903914ddf8SEdward Tomasz Napierala }
2913914ddf8SEdward Tomasz Napierala argc -= optind;
2923914ddf8SEdward Tomasz Napierala if (argc != 0)
2933914ddf8SEdward Tomasz Napierala usage_autounmountd();
2943914ddf8SEdward Tomasz Napierala
2953914ddf8SEdward Tomasz Napierala if (retry_time <= 0)
2963914ddf8SEdward Tomasz Napierala log_errx(1, "retry time must be greater than zero");
2973914ddf8SEdward Tomasz Napierala if (expiration_time <= 0)
2983914ddf8SEdward Tomasz Napierala log_errx(1, "expiration time must be greater than zero");
2993914ddf8SEdward Tomasz Napierala
3003914ddf8SEdward Tomasz Napierala log_init(debug);
3013914ddf8SEdward Tomasz Napierala
3023914ddf8SEdward Tomasz Napierala pidfh = pidfile_open(pidfile_path, 0600, &otherpid);
3033914ddf8SEdward Tomasz Napierala if (pidfh == NULL) {
3043914ddf8SEdward Tomasz Napierala if (errno == EEXIST) {
3053914ddf8SEdward Tomasz Napierala log_errx(1, "daemon already running, pid: %jd.",
3063914ddf8SEdward Tomasz Napierala (intmax_t)otherpid);
3073914ddf8SEdward Tomasz Napierala }
3083914ddf8SEdward Tomasz Napierala log_err(1, "cannot open or create pidfile \"%s\"",
3093914ddf8SEdward Tomasz Napierala pidfile_path);
3103914ddf8SEdward Tomasz Napierala }
3113914ddf8SEdward Tomasz Napierala
3123914ddf8SEdward Tomasz Napierala if (dont_daemonize == false) {
3133914ddf8SEdward Tomasz Napierala if (daemon(0, 0) == -1) {
3143914ddf8SEdward Tomasz Napierala log_warn("cannot daemonize");
3153914ddf8SEdward Tomasz Napierala pidfile_remove(pidfh);
3163914ddf8SEdward Tomasz Napierala exit(1);
3173914ddf8SEdward Tomasz Napierala }
3183914ddf8SEdward Tomasz Napierala }
3193914ddf8SEdward Tomasz Napierala
3203914ddf8SEdward Tomasz Napierala pidfile_write(pidfh);
3213914ddf8SEdward Tomasz Napierala
3223914ddf8SEdward Tomasz Napierala TAILQ_INIT(&automounted);
3233914ddf8SEdward Tomasz Napierala
3243914ddf8SEdward Tomasz Napierala kq = kqueue();
3253914ddf8SEdward Tomasz Napierala if (kq < 0)
3263914ddf8SEdward Tomasz Napierala log_err(1, "kqueue");
3273914ddf8SEdward Tomasz Napierala
328ce22a792SRobert Wing EV_SET(&event, 0, EVFILT_FS, EV_ADD | EV_CLEAR, VQ_MOUNT | VQ_UNMOUNT, 0, NULL);
3293914ddf8SEdward Tomasz Napierala error = kevent(kq, &event, 1, NULL, 0, NULL);
3303914ddf8SEdward Tomasz Napierala if (error < 0)
3313914ddf8SEdward Tomasz Napierala log_err(1, "kevent");
3323914ddf8SEdward Tomasz Napierala
3333914ddf8SEdward Tomasz Napierala for (;;) {
3343914ddf8SEdward Tomasz Napierala refresh_automounted();
3353914ddf8SEdward Tomasz Napierala mounted_max = expire_automounted(expiration_time);
336ca05fff0SJustin Hibbits if (mounted_max == -1) {
33721cee0c5SEdward Tomasz Napierala sleep_time = mounted_max;
33821cee0c5SEdward Tomasz Napierala log_debugx("no filesystems to expire");
33921cee0c5SEdward Tomasz Napierala } else if (mounted_max < expiration_time) {
3403914ddf8SEdward Tomasz Napierala sleep_time = difftime(expiration_time, mounted_max);
341ca05fff0SJustin Hibbits log_debugx("some filesystems expire in %ld seconds",
342ca05fff0SJustin Hibbits (long)sleep_time);
3433914ddf8SEdward Tomasz Napierala } else {
3443914ddf8SEdward Tomasz Napierala sleep_time = retry_time;
3453914ddf8SEdward Tomasz Napierala log_debugx("some expired filesystems remain mounted, "
346ca05fff0SJustin Hibbits "will retry in %ld seconds", (long)sleep_time);
3473914ddf8SEdward Tomasz Napierala }
3483914ddf8SEdward Tomasz Napierala
3493914ddf8SEdward Tomasz Napierala do_wait(kq, sleep_time);
3503914ddf8SEdward Tomasz Napierala }
3513914ddf8SEdward Tomasz Napierala
3523914ddf8SEdward Tomasz Napierala return (0);
3533914ddf8SEdward Tomasz Napierala }
354