13914ddf8SEdward Tomasz Napierala /*- 23914ddf8SEdward Tomasz Napierala * Copyright (c) 2014 The FreeBSD Foundation 33914ddf8SEdward Tomasz Napierala * All rights reserved. 43914ddf8SEdward Tomasz Napierala * 53914ddf8SEdward Tomasz Napierala * This software was developed by Edward Tomasz Napierala under sponsorship 63914ddf8SEdward Tomasz Napierala * from the FreeBSD Foundation. 73914ddf8SEdward Tomasz Napierala * 83914ddf8SEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 93914ddf8SEdward Tomasz Napierala * modification, are permitted provided that the following conditions 103914ddf8SEdward Tomasz Napierala * are met: 113914ddf8SEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 123914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer. 133914ddf8SEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright 143914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the 153914ddf8SEdward Tomasz Napierala * documentation and/or other materials provided with the distribution. 163914ddf8SEdward Tomasz Napierala * 173914ddf8SEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 183914ddf8SEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 193914ddf8SEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 203914ddf8SEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 213914ddf8SEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 223914ddf8SEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 233914ddf8SEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 243914ddf8SEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 253914ddf8SEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 263914ddf8SEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 273914ddf8SEdward Tomasz Napierala * SUCH DAMAGE. 283914ddf8SEdward Tomasz Napierala * 293914ddf8SEdward Tomasz Napierala */ 303914ddf8SEdward Tomasz Napierala /*- 313914ddf8SEdward Tomasz Napierala * Copyright (c) 1989, 1991, 1993, 1995 323914ddf8SEdward Tomasz Napierala * The Regents of the University of California. All rights reserved. 333914ddf8SEdward Tomasz Napierala * 343914ddf8SEdward Tomasz Napierala * This code is derived from software contributed to Berkeley by 353914ddf8SEdward Tomasz Napierala * Rick Macklem at The University of Guelph. 363914ddf8SEdward Tomasz Napierala * 373914ddf8SEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 383914ddf8SEdward Tomasz Napierala * modification, are permitted provided that the following conditions 393914ddf8SEdward Tomasz Napierala * are met: 403914ddf8SEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 413914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer. 423914ddf8SEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright 433914ddf8SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the 443914ddf8SEdward Tomasz Napierala * documentation and/or other materials provided with the distribution. 45*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 463914ddf8SEdward Tomasz Napierala * may be used to endorse or promote products derived from this software 473914ddf8SEdward Tomasz Napierala * without specific prior written permission. 483914ddf8SEdward Tomasz Napierala * 493914ddf8SEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 503914ddf8SEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 513914ddf8SEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 523914ddf8SEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 533914ddf8SEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 543914ddf8SEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 553914ddf8SEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 563914ddf8SEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 573914ddf8SEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 583914ddf8SEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 593914ddf8SEdward Tomasz Napierala * SUCH DAMAGE. 603914ddf8SEdward Tomasz Napierala * 613914ddf8SEdward Tomasz Napierala */ 623914ddf8SEdward Tomasz Napierala 63925fd945SEdward Tomasz Napierala #include <sys/cdefs.h> 64925fd945SEdward Tomasz Napierala __FBSDID("$FreeBSD$"); 65925fd945SEdward Tomasz Napierala 663914ddf8SEdward Tomasz Napierala #include <sys/param.h> 673914ddf8SEdward Tomasz Napierala #include <sys/systm.h> 683914ddf8SEdward Tomasz Napierala #include <sys/buf.h> 693914ddf8SEdward Tomasz Napierala #include <sys/conf.h> 703914ddf8SEdward Tomasz Napierala #include <sys/dirent.h> 713914ddf8SEdward Tomasz Napierala #include <sys/ioccom.h> 723914ddf8SEdward Tomasz Napierala #include <sys/kernel.h> 733914ddf8SEdward Tomasz Napierala #include <sys/module.h> 743914ddf8SEdward Tomasz Napierala #include <sys/mount.h> 753914ddf8SEdward Tomasz Napierala #include <sys/refcount.h> 763914ddf8SEdward Tomasz Napierala #include <sys/sx.h> 773914ddf8SEdward Tomasz Napierala #include <sys/sysctl.h> 783914ddf8SEdward Tomasz Napierala #include <sys/syscallsubr.h> 79759489f9SEdward Tomasz Napierala #include <sys/taskqueue.h> 8042ed64e3SEdward Tomasz Napierala #include <sys/tree.h> 813914ddf8SEdward Tomasz Napierala #include <sys/vnode.h> 823914ddf8SEdward Tomasz Napierala #include <machine/atomic.h> 833914ddf8SEdward Tomasz Napierala #include <vm/uma.h> 843914ddf8SEdward Tomasz Napierala 85f5440d1aSEdward Tomasz Napierala #include <fs/autofs/autofs.h> 86f5440d1aSEdward Tomasz Napierala #include <fs/autofs/autofs_ioctl.h> 873914ddf8SEdward Tomasz Napierala 883914ddf8SEdward Tomasz Napierala MALLOC_DEFINE(M_AUTOFS, "autofs", "Automounter filesystem"); 893914ddf8SEdward Tomasz Napierala 903914ddf8SEdward Tomasz Napierala uma_zone_t autofs_request_zone; 913914ddf8SEdward Tomasz Napierala uma_zone_t autofs_node_zone; 923914ddf8SEdward Tomasz Napierala 933914ddf8SEdward Tomasz Napierala static int autofs_open(struct cdev *dev, int flags, int fmt, 943914ddf8SEdward Tomasz Napierala struct thread *td); 953914ddf8SEdward Tomasz Napierala static int autofs_close(struct cdev *dev, int flag, int fmt, 963914ddf8SEdward Tomasz Napierala struct thread *td); 973914ddf8SEdward Tomasz Napierala static int autofs_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, 983914ddf8SEdward Tomasz Napierala int mode, struct thread *td); 993914ddf8SEdward Tomasz Napierala 1003914ddf8SEdward Tomasz Napierala static struct cdevsw autofs_cdevsw = { 1013914ddf8SEdward Tomasz Napierala .d_version = D_VERSION, 1023914ddf8SEdward Tomasz Napierala .d_open = autofs_open, 1033914ddf8SEdward Tomasz Napierala .d_close = autofs_close, 1043914ddf8SEdward Tomasz Napierala .d_ioctl = autofs_ioctl, 1053914ddf8SEdward Tomasz Napierala .d_name = "autofs", 1063914ddf8SEdward Tomasz Napierala }; 1073914ddf8SEdward Tomasz Napierala 1083914ddf8SEdward Tomasz Napierala /* 1093914ddf8SEdward Tomasz Napierala * List of signals that can interrupt an autofs trigger. Might be a good 1103914ddf8SEdward Tomasz Napierala * idea to keep it synchronised with list in sys/fs/nfs/nfs_commonkrpc.c. 1113914ddf8SEdward Tomasz Napierala */ 1123914ddf8SEdward Tomasz Napierala int autofs_sig_set[] = { 1133914ddf8SEdward Tomasz Napierala SIGINT, 1143914ddf8SEdward Tomasz Napierala SIGTERM, 1153914ddf8SEdward Tomasz Napierala SIGHUP, 1163914ddf8SEdward Tomasz Napierala SIGKILL, 1173914ddf8SEdward Tomasz Napierala SIGQUIT 1183914ddf8SEdward Tomasz Napierala }; 1193914ddf8SEdward Tomasz Napierala 120f81018caSEdward Tomasz Napierala struct autofs_softc *autofs_softc; 1213914ddf8SEdward Tomasz Napierala 1223914ddf8SEdward Tomasz Napierala SYSCTL_NODE(_vfs, OID_AUTO, autofs, CTLFLAG_RD, 0, "Automounter filesystem"); 1233914ddf8SEdward Tomasz Napierala int autofs_debug = 1; 1243914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.debug", &autofs_debug); 1253914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, debug, CTLFLAG_RWTUN, 1263914ddf8SEdward Tomasz Napierala &autofs_debug, 1, "Enable debug messages"); 1273914ddf8SEdward Tomasz Napierala int autofs_mount_on_stat = 0; 1283914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.mount_on_stat", &autofs_mount_on_stat); 1293914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, mount_on_stat, CTLFLAG_RWTUN, 1303914ddf8SEdward Tomasz Napierala &autofs_mount_on_stat, 0, "Trigger mount on stat(2) on mountpoint"); 1313914ddf8SEdward Tomasz Napierala int autofs_timeout = 30; 1323914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.timeout", &autofs_timeout); 1333914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, timeout, CTLFLAG_RWTUN, 1343914ddf8SEdward Tomasz Napierala &autofs_timeout, 30, "Number of seconds to wait for automountd(8)"); 1353914ddf8SEdward Tomasz Napierala int autofs_cache = 600; 1363914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.cache", &autofs_cache); 1373914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, cache, CTLFLAG_RWTUN, 1383914ddf8SEdward Tomasz Napierala &autofs_cache, 600, "Number of seconds to wait before reinvoking " 1393914ddf8SEdward Tomasz Napierala "automountd(8) for any given file or directory"); 1403914ddf8SEdward Tomasz Napierala int autofs_retry_attempts = 3; 1413914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.retry_attempts", &autofs_retry_attempts); 1423914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, retry_attempts, CTLFLAG_RWTUN, 1433914ddf8SEdward Tomasz Napierala &autofs_retry_attempts, 3, "Number of attempts before failing mount"); 1443914ddf8SEdward Tomasz Napierala int autofs_retry_delay = 1; 1453914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.retry_delay", &autofs_retry_delay); 1463914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, retry_delay, CTLFLAG_RWTUN, 1473914ddf8SEdward Tomasz Napierala &autofs_retry_delay, 1, "Number of seconds before retrying"); 1483914ddf8SEdward Tomasz Napierala int autofs_interruptible = 1; 1493914ddf8SEdward Tomasz Napierala TUNABLE_INT("vfs.autofs.interruptible", &autofs_interruptible); 1503914ddf8SEdward Tomasz Napierala SYSCTL_INT(_vfs_autofs, OID_AUTO, interruptible, CTLFLAG_RWTUN, 1513914ddf8SEdward Tomasz Napierala &autofs_interruptible, 1, "Allow requests to be interrupted by signal"); 1523914ddf8SEdward Tomasz Napierala 15342ed64e3SEdward Tomasz Napierala static int 15442ed64e3SEdward Tomasz Napierala autofs_node_cmp(const struct autofs_node *a, const struct autofs_node *b) 15542ed64e3SEdward Tomasz Napierala { 15642ed64e3SEdward Tomasz Napierala 15742ed64e3SEdward Tomasz Napierala return (strcmp(a->an_name, b->an_name)); 15842ed64e3SEdward Tomasz Napierala } 15942ed64e3SEdward Tomasz Napierala 16042ed64e3SEdward Tomasz Napierala RB_GENERATE(autofs_node_tree, autofs_node, an_link, autofs_node_cmp); 16142ed64e3SEdward Tomasz Napierala 1623914ddf8SEdward Tomasz Napierala int 1633914ddf8SEdward Tomasz Napierala autofs_init(struct vfsconf *vfsp) 1643914ddf8SEdward Tomasz Napierala { 1653914ddf8SEdward Tomasz Napierala int error; 1663914ddf8SEdward Tomasz Napierala 167f81018caSEdward Tomasz Napierala KASSERT(autofs_softc == NULL, 168f81018caSEdward Tomasz Napierala ("softc %p, should be NULL", autofs_softc)); 169f81018caSEdward Tomasz Napierala 170f81018caSEdward Tomasz Napierala autofs_softc = malloc(sizeof(*autofs_softc), M_AUTOFS, 171f81018caSEdward Tomasz Napierala M_WAITOK | M_ZERO); 1723914ddf8SEdward Tomasz Napierala 1733914ddf8SEdward Tomasz Napierala autofs_request_zone = uma_zcreate("autofs_request", 1743914ddf8SEdward Tomasz Napierala sizeof(struct autofs_request), NULL, NULL, NULL, NULL, 1753914ddf8SEdward Tomasz Napierala UMA_ALIGN_PTR, 0); 1763914ddf8SEdward Tomasz Napierala autofs_node_zone = uma_zcreate("autofs_node", 1773914ddf8SEdward Tomasz Napierala sizeof(struct autofs_node), NULL, NULL, NULL, NULL, 1783914ddf8SEdward Tomasz Napierala UMA_ALIGN_PTR, 0); 1793914ddf8SEdward Tomasz Napierala 180f81018caSEdward Tomasz Napierala TAILQ_INIT(&autofs_softc->sc_requests); 181f81018caSEdward Tomasz Napierala cv_init(&autofs_softc->sc_cv, "autofscv"); 182f81018caSEdward Tomasz Napierala sx_init(&autofs_softc->sc_lock, "autofslk"); 1833914ddf8SEdward Tomasz Napierala 184f81018caSEdward Tomasz Napierala error = make_dev_p(MAKEDEV_CHECKNAME, &autofs_softc->sc_cdev, 185f81018caSEdward Tomasz Napierala &autofs_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0600, "autofs"); 1863914ddf8SEdward Tomasz Napierala if (error != 0) { 1873914ddf8SEdward Tomasz Napierala AUTOFS_WARN("failed to create device node, error %d", error); 188f81018caSEdward Tomasz Napierala uma_zdestroy(autofs_request_zone); 189f81018caSEdward Tomasz Napierala uma_zdestroy(autofs_node_zone); 190f81018caSEdward Tomasz Napierala free(autofs_softc, M_AUTOFS); 191f81018caSEdward Tomasz Napierala 1923914ddf8SEdward Tomasz Napierala return (error); 1933914ddf8SEdward Tomasz Napierala } 194f81018caSEdward Tomasz Napierala autofs_softc->sc_cdev->si_drv1 = autofs_softc; 1953914ddf8SEdward Tomasz Napierala 1963914ddf8SEdward Tomasz Napierala return (0); 1973914ddf8SEdward Tomasz Napierala } 1983914ddf8SEdward Tomasz Napierala 1993914ddf8SEdward Tomasz Napierala int 2003914ddf8SEdward Tomasz Napierala autofs_uninit(struct vfsconf *vfsp) 2013914ddf8SEdward Tomasz Napierala { 2023914ddf8SEdward Tomasz Napierala 203f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 204f81018caSEdward Tomasz Napierala if (autofs_softc->sc_dev_opened) { 205f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 2063914ddf8SEdward Tomasz Napierala return (EBUSY); 2073914ddf8SEdward Tomasz Napierala } 208f81018caSEdward Tomasz Napierala if (autofs_softc->sc_cdev != NULL) 209f81018caSEdward Tomasz Napierala destroy_dev(autofs_softc->sc_cdev); 2103914ddf8SEdward Tomasz Napierala 2113914ddf8SEdward Tomasz Napierala uma_zdestroy(autofs_request_zone); 2123914ddf8SEdward Tomasz Napierala uma_zdestroy(autofs_node_zone); 2133914ddf8SEdward Tomasz Napierala 214f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 2153914ddf8SEdward Tomasz Napierala /* 2163914ddf8SEdward Tomasz Napierala * XXX: Race with open? 2173914ddf8SEdward Tomasz Napierala */ 218f81018caSEdward Tomasz Napierala free(autofs_softc, M_AUTOFS); 2193914ddf8SEdward Tomasz Napierala 2203914ddf8SEdward Tomasz Napierala return (0); 2213914ddf8SEdward Tomasz Napierala } 2223914ddf8SEdward Tomasz Napierala 2233914ddf8SEdward Tomasz Napierala bool 2243914ddf8SEdward Tomasz Napierala autofs_ignore_thread(const struct thread *td) 2253914ddf8SEdward Tomasz Napierala { 2263914ddf8SEdward Tomasz Napierala struct proc *p; 2273914ddf8SEdward Tomasz Napierala 2283914ddf8SEdward Tomasz Napierala p = td->td_proc; 2293914ddf8SEdward Tomasz Napierala 230f81018caSEdward Tomasz Napierala if (autofs_softc->sc_dev_opened == false) 2313914ddf8SEdward Tomasz Napierala return (false); 2323914ddf8SEdward Tomasz Napierala 2333914ddf8SEdward Tomasz Napierala PROC_LOCK(p); 234f81018caSEdward Tomasz Napierala if (p->p_session->s_sid == autofs_softc->sc_dev_sid) { 2353914ddf8SEdward Tomasz Napierala PROC_UNLOCK(p); 2363914ddf8SEdward Tomasz Napierala return (true); 2373914ddf8SEdward Tomasz Napierala } 2383914ddf8SEdward Tomasz Napierala PROC_UNLOCK(p); 2393914ddf8SEdward Tomasz Napierala 2403914ddf8SEdward Tomasz Napierala return (false); 2413914ddf8SEdward Tomasz Napierala } 2423914ddf8SEdward Tomasz Napierala 2433914ddf8SEdward Tomasz Napierala static char * 2443914ddf8SEdward Tomasz Napierala autofs_path(struct autofs_node *anp) 2453914ddf8SEdward Tomasz Napierala { 2463914ddf8SEdward Tomasz Napierala struct autofs_mount *amp; 2473914ddf8SEdward Tomasz Napierala char *path, *tmp; 2483914ddf8SEdward Tomasz Napierala 2493914ddf8SEdward Tomasz Napierala amp = anp->an_mount; 2503914ddf8SEdward Tomasz Napierala 2513914ddf8SEdward Tomasz Napierala path = strdup("", M_AUTOFS); 2523914ddf8SEdward Tomasz Napierala for (; anp->an_parent != NULL; anp = anp->an_parent) { 2533914ddf8SEdward Tomasz Napierala tmp = malloc(strlen(anp->an_name) + strlen(path) + 2, 2543914ddf8SEdward Tomasz Napierala M_AUTOFS, M_WAITOK); 2553914ddf8SEdward Tomasz Napierala strcpy(tmp, anp->an_name); 2563914ddf8SEdward Tomasz Napierala strcat(tmp, "/"); 2573914ddf8SEdward Tomasz Napierala strcat(tmp, path); 2583914ddf8SEdward Tomasz Napierala free(path, M_AUTOFS); 2593914ddf8SEdward Tomasz Napierala path = tmp; 2603914ddf8SEdward Tomasz Napierala } 2613914ddf8SEdward Tomasz Napierala 2623914ddf8SEdward Tomasz Napierala tmp = malloc(strlen(amp->am_mountpoint) + strlen(path) + 2, 2633914ddf8SEdward Tomasz Napierala M_AUTOFS, M_WAITOK); 2643914ddf8SEdward Tomasz Napierala strcpy(tmp, amp->am_mountpoint); 2653914ddf8SEdward Tomasz Napierala strcat(tmp, "/"); 2663914ddf8SEdward Tomasz Napierala strcat(tmp, path); 2673914ddf8SEdward Tomasz Napierala free(path, M_AUTOFS); 2683914ddf8SEdward Tomasz Napierala path = tmp; 2693914ddf8SEdward Tomasz Napierala 2703914ddf8SEdward Tomasz Napierala return (path); 2713914ddf8SEdward Tomasz Napierala } 2723914ddf8SEdward Tomasz Napierala 2733914ddf8SEdward Tomasz Napierala static void 274759489f9SEdward Tomasz Napierala autofs_task(void *context, int pending) 2753914ddf8SEdward Tomasz Napierala { 2763914ddf8SEdward Tomasz Napierala struct autofs_request *ar; 2773914ddf8SEdward Tomasz Napierala 2783914ddf8SEdward Tomasz Napierala ar = context; 2793914ddf8SEdward Tomasz Napierala 280f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 2813914ddf8SEdward Tomasz Napierala AUTOFS_WARN("request %d for %s timed out after %d seconds", 2823914ddf8SEdward Tomasz Napierala ar->ar_id, ar->ar_path, autofs_timeout); 2833914ddf8SEdward Tomasz Napierala /* 2843914ddf8SEdward Tomasz Napierala * XXX: EIO perhaps? 2853914ddf8SEdward Tomasz Napierala */ 2863914ddf8SEdward Tomasz Napierala ar->ar_error = ETIMEDOUT; 2874cdc52bdSEdward Tomasz Napierala ar->ar_wildcards = true; 2883914ddf8SEdward Tomasz Napierala ar->ar_done = true; 2893914ddf8SEdward Tomasz Napierala ar->ar_in_progress = false; 290f81018caSEdward Tomasz Napierala cv_broadcast(&autofs_softc->sc_cv); 291f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 2923914ddf8SEdward Tomasz Napierala } 2933914ddf8SEdward Tomasz Napierala 2943914ddf8SEdward Tomasz Napierala bool 2953914ddf8SEdward Tomasz Napierala autofs_cached(struct autofs_node *anp, const char *component, int componentlen) 2963914ddf8SEdward Tomasz Napierala { 2973914ddf8SEdward Tomasz Napierala int error; 2983914ddf8SEdward Tomasz Napierala struct autofs_mount *amp; 2993914ddf8SEdward Tomasz Napierala 3003914ddf8SEdward Tomasz Napierala amp = anp->an_mount; 3013914ddf8SEdward Tomasz Napierala 3023914ddf8SEdward Tomasz Napierala AUTOFS_ASSERT_UNLOCKED(amp); 3033914ddf8SEdward Tomasz Napierala 3043914ddf8SEdward Tomasz Napierala /* 3054cdc52bdSEdward Tomasz Napierala * For root node we need to request automountd(8) assistance even 3064cdc52bdSEdward Tomasz Napierala * if the node is marked as cached, but the requested top-level 3074cdc52bdSEdward Tomasz Napierala * directory does not exist. This is necessary for wildcard indirect 3084cdc52bdSEdward Tomasz Napierala * map keys to work. We don't do this if we know that there are 3094cdc52bdSEdward Tomasz Napierala * no wildcards. 3103914ddf8SEdward Tomasz Napierala */ 3114cdc52bdSEdward Tomasz Napierala if (anp->an_parent == NULL && componentlen != 0 && anp->an_wildcards) { 3122eaebf35SEdward Tomasz Napierala AUTOFS_SLOCK(amp); 3133914ddf8SEdward Tomasz Napierala error = autofs_node_find(anp, component, componentlen, NULL); 3142eaebf35SEdward Tomasz Napierala AUTOFS_SUNLOCK(amp); 3153914ddf8SEdward Tomasz Napierala if (error != 0) 3163914ddf8SEdward Tomasz Napierala return (false); 3173914ddf8SEdward Tomasz Napierala } 3183914ddf8SEdward Tomasz Napierala 3193914ddf8SEdward Tomasz Napierala return (anp->an_cached); 3203914ddf8SEdward Tomasz Napierala } 3213914ddf8SEdward Tomasz Napierala 3223914ddf8SEdward Tomasz Napierala static void 3233914ddf8SEdward Tomasz Napierala autofs_cache_callout(void *context) 3243914ddf8SEdward Tomasz Napierala { 3253914ddf8SEdward Tomasz Napierala struct autofs_node *anp; 3263914ddf8SEdward Tomasz Napierala 3273914ddf8SEdward Tomasz Napierala anp = context; 3283914ddf8SEdward Tomasz Napierala anp->an_cached = false; 3293914ddf8SEdward Tomasz Napierala } 3303914ddf8SEdward Tomasz Napierala 331e3d5f1feSEdward Tomasz Napierala void 332e3d5f1feSEdward Tomasz Napierala autofs_flush(struct autofs_mount *amp) 333e3d5f1feSEdward Tomasz Napierala { 334e3d5f1feSEdward Tomasz Napierala 335e3d5f1feSEdward Tomasz Napierala /* 336e3d5f1feSEdward Tomasz Napierala * XXX: This will do for now, but ideally we should iterate 337e3d5f1feSEdward Tomasz Napierala * over all the nodes. 338e3d5f1feSEdward Tomasz Napierala */ 339e3d5f1feSEdward Tomasz Napierala amp->am_root->an_cached = false; 340e3d5f1feSEdward Tomasz Napierala AUTOFS_DEBUG("%s flushed", amp->am_mountpoint); 341e3d5f1feSEdward Tomasz Napierala } 342e3d5f1feSEdward Tomasz Napierala 3433914ddf8SEdward Tomasz Napierala /* 3443914ddf8SEdward Tomasz Napierala * The set/restore sigmask functions are used to (temporarily) overwrite 3453914ddf8SEdward Tomasz Napierala * the thread td_sigmask during triggering. 3463914ddf8SEdward Tomasz Napierala */ 3473914ddf8SEdward Tomasz Napierala static void 3483914ddf8SEdward Tomasz Napierala autofs_set_sigmask(sigset_t *oldset) 3493914ddf8SEdward Tomasz Napierala { 3503914ddf8SEdward Tomasz Napierala sigset_t newset; 3513914ddf8SEdward Tomasz Napierala int i; 3523914ddf8SEdward Tomasz Napierala 3533914ddf8SEdward Tomasz Napierala SIGFILLSET(newset); 3543914ddf8SEdward Tomasz Napierala /* Remove the autofs set of signals from newset */ 3553914ddf8SEdward Tomasz Napierala PROC_LOCK(curproc); 3563914ddf8SEdward Tomasz Napierala mtx_lock(&curproc->p_sigacts->ps_mtx); 35702abd400SPedro F. Giffuni for (i = 0 ; i < nitems(autofs_sig_set); i++) { 3583914ddf8SEdward Tomasz Napierala /* 3593914ddf8SEdward Tomasz Napierala * But make sure we leave the ones already masked 3603914ddf8SEdward Tomasz Napierala * by the process, i.e. remove the signal from the 3613914ddf8SEdward Tomasz Napierala * temporary signalmask only if it wasn't already 3623914ddf8SEdward Tomasz Napierala * in p_sigmask. 3633914ddf8SEdward Tomasz Napierala */ 3643914ddf8SEdward Tomasz Napierala if (!SIGISMEMBER(curthread->td_sigmask, autofs_sig_set[i]) && 3653914ddf8SEdward Tomasz Napierala !SIGISMEMBER(curproc->p_sigacts->ps_sigignore, 3663914ddf8SEdward Tomasz Napierala autofs_sig_set[i])) { 3673914ddf8SEdward Tomasz Napierala SIGDELSET(newset, autofs_sig_set[i]); 3683914ddf8SEdward Tomasz Napierala } 3693914ddf8SEdward Tomasz Napierala } 3703914ddf8SEdward Tomasz Napierala mtx_unlock(&curproc->p_sigacts->ps_mtx); 3713914ddf8SEdward Tomasz Napierala kern_sigprocmask(curthread, SIG_SETMASK, &newset, oldset, 3723914ddf8SEdward Tomasz Napierala SIGPROCMASK_PROC_LOCKED); 3733914ddf8SEdward Tomasz Napierala PROC_UNLOCK(curproc); 3743914ddf8SEdward Tomasz Napierala } 3753914ddf8SEdward Tomasz Napierala 3763914ddf8SEdward Tomasz Napierala static void 3773914ddf8SEdward Tomasz Napierala autofs_restore_sigmask(sigset_t *set) 3783914ddf8SEdward Tomasz Napierala { 3793914ddf8SEdward Tomasz Napierala 3803914ddf8SEdward Tomasz Napierala kern_sigprocmask(curthread, SIG_SETMASK, set, NULL, 0); 3813914ddf8SEdward Tomasz Napierala } 3823914ddf8SEdward Tomasz Napierala 3833914ddf8SEdward Tomasz Napierala static int 3843914ddf8SEdward Tomasz Napierala autofs_trigger_one(struct autofs_node *anp, 3853914ddf8SEdward Tomasz Napierala const char *component, int componentlen) 3863914ddf8SEdward Tomasz Napierala { 3873914ddf8SEdward Tomasz Napierala sigset_t oldset; 3883914ddf8SEdward Tomasz Napierala struct autofs_mount *amp; 3893914ddf8SEdward Tomasz Napierala struct autofs_node *firstanp; 3903914ddf8SEdward Tomasz Napierala struct autofs_request *ar; 3913914ddf8SEdward Tomasz Napierala char *key, *path; 3923914ddf8SEdward Tomasz Napierala int error = 0, request_error, last; 3934cdc52bdSEdward Tomasz Napierala bool wildcards; 3943914ddf8SEdward Tomasz Napierala 3955d28b9edSEdward Tomasz Napierala amp = anp->an_mount; 3963914ddf8SEdward Tomasz Napierala 397f81018caSEdward Tomasz Napierala sx_assert(&autofs_softc->sc_lock, SA_XLOCKED); 3983914ddf8SEdward Tomasz Napierala 3993914ddf8SEdward Tomasz Napierala if (anp->an_parent == NULL) { 4003914ddf8SEdward Tomasz Napierala key = strndup(component, componentlen, M_AUTOFS); 4013914ddf8SEdward Tomasz Napierala } else { 4023914ddf8SEdward Tomasz Napierala for (firstanp = anp; firstanp->an_parent->an_parent != NULL; 4033914ddf8SEdward Tomasz Napierala firstanp = firstanp->an_parent) 4043914ddf8SEdward Tomasz Napierala continue; 4053914ddf8SEdward Tomasz Napierala key = strdup(firstanp->an_name, M_AUTOFS); 4063914ddf8SEdward Tomasz Napierala } 4073914ddf8SEdward Tomasz Napierala 4083914ddf8SEdward Tomasz Napierala path = autofs_path(anp); 4093914ddf8SEdward Tomasz Napierala 410f81018caSEdward Tomasz Napierala TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 4113914ddf8SEdward Tomasz Napierala if (strcmp(ar->ar_path, path) != 0) 4123914ddf8SEdward Tomasz Napierala continue; 4133914ddf8SEdward Tomasz Napierala if (strcmp(ar->ar_key, key) != 0) 4143914ddf8SEdward Tomasz Napierala continue; 4153914ddf8SEdward Tomasz Napierala 4163914ddf8SEdward Tomasz Napierala KASSERT(strcmp(ar->ar_from, amp->am_from) == 0, 4173914ddf8SEdward Tomasz Napierala ("from changed; %s != %s", ar->ar_from, amp->am_from)); 4183914ddf8SEdward Tomasz Napierala KASSERT(strcmp(ar->ar_prefix, amp->am_prefix) == 0, 4193914ddf8SEdward Tomasz Napierala ("prefix changed; %s != %s", 4203914ddf8SEdward Tomasz Napierala ar->ar_prefix, amp->am_prefix)); 4213914ddf8SEdward Tomasz Napierala KASSERT(strcmp(ar->ar_options, amp->am_options) == 0, 4223914ddf8SEdward Tomasz Napierala ("options changed; %s != %s", 4233914ddf8SEdward Tomasz Napierala ar->ar_options, amp->am_options)); 4243914ddf8SEdward Tomasz Napierala 4253914ddf8SEdward Tomasz Napierala break; 4263914ddf8SEdward Tomasz Napierala } 4273914ddf8SEdward Tomasz Napierala 4283914ddf8SEdward Tomasz Napierala if (ar != NULL) { 4293914ddf8SEdward Tomasz Napierala refcount_acquire(&ar->ar_refcount); 4303914ddf8SEdward Tomasz Napierala } else { 4313914ddf8SEdward Tomasz Napierala ar = uma_zalloc(autofs_request_zone, M_WAITOK | M_ZERO); 4323914ddf8SEdward Tomasz Napierala ar->ar_mount = amp; 4333914ddf8SEdward Tomasz Napierala 434f81018caSEdward Tomasz Napierala ar->ar_id = 435f81018caSEdward Tomasz Napierala atomic_fetchadd_int(&autofs_softc->sc_last_request_id, 1); 4363914ddf8SEdward Tomasz Napierala strlcpy(ar->ar_from, amp->am_from, sizeof(ar->ar_from)); 4373914ddf8SEdward Tomasz Napierala strlcpy(ar->ar_path, path, sizeof(ar->ar_path)); 4383914ddf8SEdward Tomasz Napierala strlcpy(ar->ar_prefix, amp->am_prefix, sizeof(ar->ar_prefix)); 4393914ddf8SEdward Tomasz Napierala strlcpy(ar->ar_key, key, sizeof(ar->ar_key)); 4403914ddf8SEdward Tomasz Napierala strlcpy(ar->ar_options, 4413914ddf8SEdward Tomasz Napierala amp->am_options, sizeof(ar->ar_options)); 4423914ddf8SEdward Tomasz Napierala 443759489f9SEdward Tomasz Napierala TIMEOUT_TASK_INIT(taskqueue_thread, &ar->ar_task, 0, 444759489f9SEdward Tomasz Napierala autofs_task, ar); 445a79e9d0fSEdward Tomasz Napierala taskqueue_enqueue_timeout(taskqueue_thread, &ar->ar_task, 446a79e9d0fSEdward Tomasz Napierala autofs_timeout * hz); 4473914ddf8SEdward Tomasz Napierala refcount_init(&ar->ar_refcount, 1); 448f81018caSEdward Tomasz Napierala TAILQ_INSERT_TAIL(&autofs_softc->sc_requests, ar, ar_next); 4493914ddf8SEdward Tomasz Napierala } 4503914ddf8SEdward Tomasz Napierala 451f81018caSEdward Tomasz Napierala cv_broadcast(&autofs_softc->sc_cv); 4523914ddf8SEdward Tomasz Napierala while (ar->ar_done == false) { 4533914ddf8SEdward Tomasz Napierala if (autofs_interruptible != 0) { 4543914ddf8SEdward Tomasz Napierala autofs_set_sigmask(&oldset); 455f81018caSEdward Tomasz Napierala error = cv_wait_sig(&autofs_softc->sc_cv, 456f81018caSEdward Tomasz Napierala &autofs_softc->sc_lock); 4573914ddf8SEdward Tomasz Napierala autofs_restore_sigmask(&oldset); 4583914ddf8SEdward Tomasz Napierala if (error != 0) { 4593914ddf8SEdward Tomasz Napierala AUTOFS_WARN("cv_wait_sig for %s failed " 4603914ddf8SEdward Tomasz Napierala "with error %d", ar->ar_path, error); 4613914ddf8SEdward Tomasz Napierala break; 4623914ddf8SEdward Tomasz Napierala } 4633914ddf8SEdward Tomasz Napierala } else { 464f81018caSEdward Tomasz Napierala cv_wait(&autofs_softc->sc_cv, &autofs_softc->sc_lock); 4653914ddf8SEdward Tomasz Napierala } 4663914ddf8SEdward Tomasz Napierala } 4673914ddf8SEdward Tomasz Napierala 4683914ddf8SEdward Tomasz Napierala request_error = ar->ar_error; 4693914ddf8SEdward Tomasz Napierala if (request_error != 0) { 4703914ddf8SEdward Tomasz Napierala AUTOFS_WARN("request for %s completed with error %d", 4713914ddf8SEdward Tomasz Napierala ar->ar_path, request_error); 4723914ddf8SEdward Tomasz Napierala } 4733914ddf8SEdward Tomasz Napierala 4744cdc52bdSEdward Tomasz Napierala wildcards = ar->ar_wildcards; 4754cdc52bdSEdward Tomasz Napierala 4763914ddf8SEdward Tomasz Napierala last = refcount_release(&ar->ar_refcount); 4773914ddf8SEdward Tomasz Napierala if (last) { 478f81018caSEdward Tomasz Napierala TAILQ_REMOVE(&autofs_softc->sc_requests, ar, ar_next); 4793914ddf8SEdward Tomasz Napierala /* 48028a23d3dSEdward Tomasz Napierala * Unlock the sc_lock, so that autofs_task() can complete. 4813914ddf8SEdward Tomasz Napierala */ 482f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 483759489f9SEdward Tomasz Napierala taskqueue_cancel_timeout(taskqueue_thread, &ar->ar_task, NULL); 484759489f9SEdward Tomasz Napierala taskqueue_drain_timeout(taskqueue_thread, &ar->ar_task); 4853914ddf8SEdward Tomasz Napierala uma_zfree(autofs_request_zone, ar); 48628a23d3dSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 4873914ddf8SEdward Tomasz Napierala } 4883914ddf8SEdward Tomasz Napierala 4893914ddf8SEdward Tomasz Napierala /* 4903914ddf8SEdward Tomasz Napierala * Note that we do not do negative caching on purpose. This 4913914ddf8SEdward Tomasz Napierala * way the user can retry access at any time, e.g. after fixing 4923914ddf8SEdward Tomasz Napierala * the failure reason, without waiting for cache timer to expire. 4933914ddf8SEdward Tomasz Napierala */ 4943914ddf8SEdward Tomasz Napierala if (error == 0 && request_error == 0 && autofs_cache > 0) { 4953914ddf8SEdward Tomasz Napierala anp->an_cached = true; 4964cdc52bdSEdward Tomasz Napierala anp->an_wildcards = wildcards; 4973914ddf8SEdward Tomasz Napierala callout_reset(&anp->an_callout, autofs_cache * hz, 4983914ddf8SEdward Tomasz Napierala autofs_cache_callout, anp); 4993914ddf8SEdward Tomasz Napierala } 5003914ddf8SEdward Tomasz Napierala 5013914ddf8SEdward Tomasz Napierala free(key, M_AUTOFS); 5023914ddf8SEdward Tomasz Napierala free(path, M_AUTOFS); 5033914ddf8SEdward Tomasz Napierala 5043914ddf8SEdward Tomasz Napierala if (error != 0) 5053914ddf8SEdward Tomasz Napierala return (error); 5063914ddf8SEdward Tomasz Napierala return (request_error); 5073914ddf8SEdward Tomasz Napierala } 5083914ddf8SEdward Tomasz Napierala 5093914ddf8SEdward Tomasz Napierala /* 5103914ddf8SEdward Tomasz Napierala * Send request to automountd(8) and wait for completion. 5113914ddf8SEdward Tomasz Napierala */ 5123914ddf8SEdward Tomasz Napierala int 5133914ddf8SEdward Tomasz Napierala autofs_trigger(struct autofs_node *anp, 5143914ddf8SEdward Tomasz Napierala const char *component, int componentlen) 5153914ddf8SEdward Tomasz Napierala { 5163914ddf8SEdward Tomasz Napierala int error; 5173914ddf8SEdward Tomasz Napierala 5183914ddf8SEdward Tomasz Napierala for (;;) { 5193914ddf8SEdward Tomasz Napierala error = autofs_trigger_one(anp, component, componentlen); 5203914ddf8SEdward Tomasz Napierala if (error == 0) { 5213914ddf8SEdward Tomasz Napierala anp->an_retries = 0; 5223914ddf8SEdward Tomasz Napierala return (0); 5233914ddf8SEdward Tomasz Napierala } 52431a4b1aaSEdward Tomasz Napierala if (error == EINTR || error == ERESTART) { 5253914ddf8SEdward Tomasz Napierala AUTOFS_DEBUG("trigger interrupted by signal, " 5263914ddf8SEdward Tomasz Napierala "not retrying"); 5273914ddf8SEdward Tomasz Napierala anp->an_retries = 0; 5283914ddf8SEdward Tomasz Napierala return (error); 5293914ddf8SEdward Tomasz Napierala } 5303914ddf8SEdward Tomasz Napierala anp->an_retries++; 5313914ddf8SEdward Tomasz Napierala if (anp->an_retries >= autofs_retry_attempts) { 5323914ddf8SEdward Tomasz Napierala AUTOFS_DEBUG("trigger failed %d times; returning " 5333914ddf8SEdward Tomasz Napierala "error %d", anp->an_retries, error); 5343914ddf8SEdward Tomasz Napierala anp->an_retries = 0; 5353914ddf8SEdward Tomasz Napierala return (error); 5363914ddf8SEdward Tomasz Napierala 5373914ddf8SEdward Tomasz Napierala } 5383914ddf8SEdward Tomasz Napierala AUTOFS_DEBUG("trigger failed with error %d; will retry in " 5393914ddf8SEdward Tomasz Napierala "%d seconds, %d attempts left", error, autofs_retry_delay, 5403914ddf8SEdward Tomasz Napierala autofs_retry_attempts - anp->an_retries); 541f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 5423914ddf8SEdward Tomasz Napierala pause("autofs_retry", autofs_retry_delay * hz); 543f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 5443914ddf8SEdward Tomasz Napierala } 5453914ddf8SEdward Tomasz Napierala } 5463914ddf8SEdward Tomasz Napierala 5473914ddf8SEdward Tomasz Napierala static int 548f81018caSEdward Tomasz Napierala autofs_ioctl_request(struct autofs_daemon_request *adr) 5493914ddf8SEdward Tomasz Napierala { 5503914ddf8SEdward Tomasz Napierala struct autofs_request *ar; 5513914ddf8SEdward Tomasz Napierala int error; 5523914ddf8SEdward Tomasz Napierala 553f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 5543914ddf8SEdward Tomasz Napierala for (;;) { 555f81018caSEdward Tomasz Napierala TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 5563914ddf8SEdward Tomasz Napierala if (ar->ar_done) 5573914ddf8SEdward Tomasz Napierala continue; 5583914ddf8SEdward Tomasz Napierala if (ar->ar_in_progress) 5593914ddf8SEdward Tomasz Napierala continue; 5603914ddf8SEdward Tomasz Napierala 5613914ddf8SEdward Tomasz Napierala break; 5623914ddf8SEdward Tomasz Napierala } 5633914ddf8SEdward Tomasz Napierala 5643914ddf8SEdward Tomasz Napierala if (ar != NULL) 5653914ddf8SEdward Tomasz Napierala break; 5663914ddf8SEdward Tomasz Napierala 567f81018caSEdward Tomasz Napierala error = cv_wait_sig(&autofs_softc->sc_cv, 568f81018caSEdward Tomasz Napierala &autofs_softc->sc_lock); 5693914ddf8SEdward Tomasz Napierala if (error != 0) { 570f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 5713914ddf8SEdward Tomasz Napierala return (error); 5723914ddf8SEdward Tomasz Napierala } 5733914ddf8SEdward Tomasz Napierala } 5743914ddf8SEdward Tomasz Napierala 5753914ddf8SEdward Tomasz Napierala ar->ar_in_progress = true; 576f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 5773914ddf8SEdward Tomasz Napierala 5783914ddf8SEdward Tomasz Napierala adr->adr_id = ar->ar_id; 5793914ddf8SEdward Tomasz Napierala strlcpy(adr->adr_from, ar->ar_from, sizeof(adr->adr_from)); 5803914ddf8SEdward Tomasz Napierala strlcpy(adr->adr_path, ar->ar_path, sizeof(adr->adr_path)); 5813914ddf8SEdward Tomasz Napierala strlcpy(adr->adr_prefix, ar->ar_prefix, sizeof(adr->adr_prefix)); 5823914ddf8SEdward Tomasz Napierala strlcpy(adr->adr_key, ar->ar_key, sizeof(adr->adr_key)); 5833914ddf8SEdward Tomasz Napierala strlcpy(adr->adr_options, ar->ar_options, sizeof(adr->adr_options)); 5843914ddf8SEdward Tomasz Napierala 5853914ddf8SEdward Tomasz Napierala PROC_LOCK(curproc); 586f81018caSEdward Tomasz Napierala autofs_softc->sc_dev_sid = curproc->p_session->s_sid; 5873914ddf8SEdward Tomasz Napierala PROC_UNLOCK(curproc); 5883914ddf8SEdward Tomasz Napierala 5893914ddf8SEdward Tomasz Napierala return (0); 5903914ddf8SEdward Tomasz Napierala } 5913914ddf8SEdward Tomasz Napierala 5923914ddf8SEdward Tomasz Napierala static int 59329836e07SEdward Tomasz Napierala autofs_ioctl_done_101(struct autofs_daemon_done_101 *add) 59429836e07SEdward Tomasz Napierala { 59529836e07SEdward Tomasz Napierala struct autofs_request *ar; 59629836e07SEdward Tomasz Napierala 59729836e07SEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 59829836e07SEdward Tomasz Napierala TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 59929836e07SEdward Tomasz Napierala if (ar->ar_id == add->add_id) 60029836e07SEdward Tomasz Napierala break; 60129836e07SEdward Tomasz Napierala } 60229836e07SEdward Tomasz Napierala 60329836e07SEdward Tomasz Napierala if (ar == NULL) { 60429836e07SEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 60529836e07SEdward Tomasz Napierala AUTOFS_DEBUG("id %d not found", add->add_id); 60629836e07SEdward Tomasz Napierala return (ESRCH); 60729836e07SEdward Tomasz Napierala } 60829836e07SEdward Tomasz Napierala 60929836e07SEdward Tomasz Napierala ar->ar_error = add->add_error; 61029836e07SEdward Tomasz Napierala ar->ar_wildcards = true; 61129836e07SEdward Tomasz Napierala ar->ar_done = true; 61229836e07SEdward Tomasz Napierala ar->ar_in_progress = false; 61329836e07SEdward Tomasz Napierala cv_broadcast(&autofs_softc->sc_cv); 61429836e07SEdward Tomasz Napierala 61529836e07SEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 61629836e07SEdward Tomasz Napierala 61729836e07SEdward Tomasz Napierala return (0); 61829836e07SEdward Tomasz Napierala } 61929836e07SEdward Tomasz Napierala 62029836e07SEdward Tomasz Napierala static int 621f81018caSEdward Tomasz Napierala autofs_ioctl_done(struct autofs_daemon_done *add) 6223914ddf8SEdward Tomasz Napierala { 6233914ddf8SEdward Tomasz Napierala struct autofs_request *ar; 6243914ddf8SEdward Tomasz Napierala 625f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 626f81018caSEdward Tomasz Napierala TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 6273914ddf8SEdward Tomasz Napierala if (ar->ar_id == add->add_id) 6283914ddf8SEdward Tomasz Napierala break; 6293914ddf8SEdward Tomasz Napierala } 6303914ddf8SEdward Tomasz Napierala 6313914ddf8SEdward Tomasz Napierala if (ar == NULL) { 632f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 6333914ddf8SEdward Tomasz Napierala AUTOFS_DEBUG("id %d not found", add->add_id); 6343914ddf8SEdward Tomasz Napierala return (ESRCH); 6353914ddf8SEdward Tomasz Napierala } 6363914ddf8SEdward Tomasz Napierala 6373914ddf8SEdward Tomasz Napierala ar->ar_error = add->add_error; 6384cdc52bdSEdward Tomasz Napierala ar->ar_wildcards = add->add_wildcards; 6393914ddf8SEdward Tomasz Napierala ar->ar_done = true; 6403914ddf8SEdward Tomasz Napierala ar->ar_in_progress = false; 641f81018caSEdward Tomasz Napierala cv_broadcast(&autofs_softc->sc_cv); 6423914ddf8SEdward Tomasz Napierala 643f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 6443914ddf8SEdward Tomasz Napierala 6453914ddf8SEdward Tomasz Napierala return (0); 6463914ddf8SEdward Tomasz Napierala } 6473914ddf8SEdward Tomasz Napierala 6483914ddf8SEdward Tomasz Napierala static int 6493914ddf8SEdward Tomasz Napierala autofs_open(struct cdev *dev, int flags, int fmt, struct thread *td) 6503914ddf8SEdward Tomasz Napierala { 6513914ddf8SEdward Tomasz Napierala 652f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 653a32ba4e6SEdward Tomasz Napierala /* 654a32ba4e6SEdward Tomasz Napierala * We must never block automountd(8) and its descendants, and we use 655a32ba4e6SEdward Tomasz Napierala * session ID to determine that: we store session id of the process 656a32ba4e6SEdward Tomasz Napierala * that opened the device, and then compare it with session ids 657a32ba4e6SEdward Tomasz Napierala * of triggering processes. This means running a second automountd(8) 658a32ba4e6SEdward Tomasz Napierala * instance would break the previous one. The check below prevents 659a32ba4e6SEdward Tomasz Napierala * it from happening. 660a32ba4e6SEdward Tomasz Napierala */ 661f81018caSEdward Tomasz Napierala if (autofs_softc->sc_dev_opened) { 662f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 6633914ddf8SEdward Tomasz Napierala return (EBUSY); 6643914ddf8SEdward Tomasz Napierala } 6653914ddf8SEdward Tomasz Napierala 666f81018caSEdward Tomasz Napierala autofs_softc->sc_dev_opened = true; 667f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 6683914ddf8SEdward Tomasz Napierala 6693914ddf8SEdward Tomasz Napierala return (0); 6703914ddf8SEdward Tomasz Napierala } 6713914ddf8SEdward Tomasz Napierala 6723914ddf8SEdward Tomasz Napierala static int 6733914ddf8SEdward Tomasz Napierala autofs_close(struct cdev *dev, int flag, int fmt, struct thread *td) 6743914ddf8SEdward Tomasz Napierala { 6753914ddf8SEdward Tomasz Napierala 676f81018caSEdward Tomasz Napierala sx_xlock(&autofs_softc->sc_lock); 677f81018caSEdward Tomasz Napierala KASSERT(autofs_softc->sc_dev_opened, ("not opened?")); 678f81018caSEdward Tomasz Napierala autofs_softc->sc_dev_opened = false; 679f81018caSEdward Tomasz Napierala sx_xunlock(&autofs_softc->sc_lock); 6803914ddf8SEdward Tomasz Napierala 6813914ddf8SEdward Tomasz Napierala return (0); 6823914ddf8SEdward Tomasz Napierala } 6833914ddf8SEdward Tomasz Napierala 6843914ddf8SEdward Tomasz Napierala static int 6853914ddf8SEdward Tomasz Napierala autofs_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, 6863914ddf8SEdward Tomasz Napierala struct thread *td) 6873914ddf8SEdward Tomasz Napierala { 6883914ddf8SEdward Tomasz Napierala 689f81018caSEdward Tomasz Napierala KASSERT(autofs_softc->sc_dev_opened, ("not opened?")); 6903914ddf8SEdward Tomasz Napierala 6913914ddf8SEdward Tomasz Napierala switch (cmd) { 6923914ddf8SEdward Tomasz Napierala case AUTOFSREQUEST: 693f81018caSEdward Tomasz Napierala return (autofs_ioctl_request( 6943914ddf8SEdward Tomasz Napierala (struct autofs_daemon_request *)arg)); 69529836e07SEdward Tomasz Napierala case AUTOFSDONE101: 69629836e07SEdward Tomasz Napierala return (autofs_ioctl_done_101( 69729836e07SEdward Tomasz Napierala (struct autofs_daemon_done_101 *)arg)); 6983914ddf8SEdward Tomasz Napierala case AUTOFSDONE: 699f81018caSEdward Tomasz Napierala return (autofs_ioctl_done( 7003914ddf8SEdward Tomasz Napierala (struct autofs_daemon_done *)arg)); 7013914ddf8SEdward Tomasz Napierala default: 7023914ddf8SEdward Tomasz Napierala AUTOFS_DEBUG("invalid cmd %lx", cmd); 7033914ddf8SEdward Tomasz Napierala return (EINVAL); 7043914ddf8SEdward Tomasz Napierala } 7053914ddf8SEdward Tomasz Napierala } 706