1 /*- 2 * Copyright (c) 2016 The DragonFly Project 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 /*- 32 * Copyright (c) 1989, 1991, 1993, 1995 33 * The Regents of the University of California. All rights reserved. 34 * 35 * This code is derived from software contributed to Berkeley by 36 * Rick Macklem at The University of Guelph. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. Neither the name of the University nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 */ 63 64 #include <sys/kernel.h> 65 #include <sys/module.h> 66 #include <sys/sysctl.h> 67 #include <sys/queue.h> 68 #include <sys/signalvar.h> 69 #include <sys/refcount.h> 70 #include <sys/kern_syscall.h> 71 72 #include "autofs.h" 73 #include "autofs_ioctl.h" 74 75 MALLOC_DEFINE(M_AUTOFS, "autofs", "Automounter filesystem"); 76 77 struct objcache *autofs_request_objcache = NULL; 78 struct objcache *autofs_node_objcache = NULL; 79 80 static d_open_t autofs_open; 81 static d_close_t autofs_close; 82 static d_ioctl_t autofs_ioctl; 83 84 struct dev_ops autofs_ops = { 85 { "autofs", 0, 0 }, 86 .d_open = autofs_open, 87 .d_close = autofs_close, 88 .d_ioctl = autofs_ioctl, 89 }; 90 91 /* 92 * List of signals that can interrupt an autofs trigger. 93 */ 94 static int autofs_sig_set[] = { 95 SIGINT, 96 SIGTERM, 97 SIGHUP, 98 SIGKILL, 99 SIGQUIT 100 }; 101 102 struct autofs_softc *autofs_softc = NULL; 103 104 SYSCTL_NODE(_vfs, OID_AUTO, autofs, CTLFLAG_RD, 0, "Automounter filesystem"); 105 int autofs_debug = 1; 106 TUNABLE_INT("vfs.autofs.debug", &autofs_debug); 107 SYSCTL_INT(_vfs_autofs, OID_AUTO, debug, CTLFLAG_RW, 108 &autofs_debug, 1, "Enable debug messages"); 109 int autofs_mount_on_stat = 0; /* XXX: Not supported on DragonFly */ 110 TUNABLE_INT("vfs.autofs.mount_on_stat", &autofs_mount_on_stat); 111 SYSCTL_INT(_vfs_autofs, OID_AUTO, mount_on_stat, CTLFLAG_RW, 112 &autofs_mount_on_stat, 0, "Trigger mount on stat(2) on mountpoint " 113 "(not supported on DragonFly)"); 114 static int autofs_timeout = 30; 115 TUNABLE_INT("vfs.autofs.timeout", &autofs_timeout); 116 SYSCTL_INT(_vfs_autofs, OID_AUTO, timeout, CTLFLAG_RW, 117 &autofs_timeout, 30, "Number of seconds to wait for automountd(8)"); 118 static int autofs_cache = 600; 119 TUNABLE_INT("vfs.autofs.cache", &autofs_cache); 120 SYSCTL_INT(_vfs_autofs, OID_AUTO, cache, CTLFLAG_RW, 121 &autofs_cache, 600, "Number of seconds to wait before reinvoking " 122 "automountd(8) for any given file or directory"); 123 static int autofs_retry_attempts = 3; 124 TUNABLE_INT("vfs.autofs.retry_attempts", &autofs_retry_attempts); 125 SYSCTL_INT(_vfs_autofs, OID_AUTO, retry_attempts, CTLFLAG_RW, 126 &autofs_retry_attempts, 3, "Number of attempts before failing mount"); 127 static int autofs_retry_delay = 1; 128 TUNABLE_INT("vfs.autofs.retry_delay", &autofs_retry_delay); 129 SYSCTL_INT(_vfs_autofs, OID_AUTO, retry_delay, CTLFLAG_RW, 130 &autofs_retry_delay, 1, "Number of seconds before retrying"); 131 static int autofs_interruptible = 1; 132 TUNABLE_INT("vfs.autofs.interruptible", &autofs_interruptible); 133 SYSCTL_INT(_vfs_autofs, OID_AUTO, interruptible, CTLFLAG_RW, 134 &autofs_interruptible, 1, "Allow requests to be interrupted by signal"); 135 136 static __inline pid_t 137 proc_pgid(const struct proc *p) 138 { 139 return (p->p_pgrp->pg_id); 140 } 141 142 static int 143 autofs_node_cmp(const struct autofs_node *a, const struct autofs_node *b) 144 { 145 return (strcmp(a->an_name, b->an_name)); 146 } 147 148 RB_GENERATE(autofs_node_tree, autofs_node, an_link, autofs_node_cmp); 149 150 bool 151 autofs_ignore_thread(void) 152 { 153 struct proc *curp = curproc; 154 155 if (autofs_softc->sc_dev_opened == false) 156 return (false); 157 158 lwkt_gettoken(&curp->p_token); 159 if (autofs_softc->sc_dev_sid == proc_pgid(curp)) { 160 lwkt_reltoken(&curp->p_token); 161 return (true); 162 } 163 lwkt_reltoken(&curp->p_token); 164 165 return (false); 166 } 167 168 char * 169 autofs_path(struct autofs_node *anp) 170 { 171 struct autofs_mount *amp = anp->an_mount; 172 size_t len; 173 char *path, *tmp; 174 175 path = kstrdup("", M_AUTOFS); 176 for (; anp->an_parent != NULL; anp = anp->an_parent) { 177 len = strlen(anp->an_name) + strlen(path) + 2; 178 tmp = kmalloc(len, M_AUTOFS, M_WAITOK); 179 ksnprintf(tmp, len, "%s/%s", anp->an_name, path); 180 kfree(path, M_AUTOFS); 181 path = tmp; 182 } 183 184 len = strlen(amp->am_on) + strlen(path) + 2; 185 tmp = kmalloc(len, M_AUTOFS, M_WAITOK); 186 ksnprintf(tmp, len, "%s/%s", amp->am_on, path); 187 kfree(path, M_AUTOFS); 188 path = tmp; 189 190 return (path); 191 } 192 193 static void 194 autofs_task(void *context, int pending) 195 { 196 struct autofs_request *ar = context; 197 198 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 199 AUTOFS_WARN("request %d for %s timed out after %d seconds", 200 ar->ar_id, ar->ar_path, autofs_timeout); 201 202 ar->ar_error = ETIMEDOUT; 203 ar->ar_wildcards = true; 204 ar->ar_done = true; 205 ar->ar_in_progress = false; 206 cv_broadcast(&autofs_softc->sc_cv); 207 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 208 } 209 210 bool 211 autofs_cached(struct autofs_node *anp, const char *component, int componentlen) 212 { 213 struct autofs_mount *amp = anp->an_mount; 214 215 KKASSERT(mtx_notlocked(&->am_lock)); 216 217 /* 218 * For root node we need to request automountd(8) assistance even 219 * if the node is marked as cached, but the requested top-level 220 * directory does not exist. This is necessary for wildcard indirect 221 * map keys to work. We don't do this if we know that there are 222 * no wildcards. 223 */ 224 if (anp->an_parent == NULL && componentlen != 0 && anp->an_wildcards) { 225 int error; 226 KKASSERT(amp->am_root == anp); 227 mtx_lock_sh_quick(&->am_lock); 228 error = autofs_node_find(anp, component, componentlen, NULL); 229 mtx_unlock_sh(&->am_lock); 230 if (error) 231 return (false); 232 } 233 234 return (anp->an_cached); 235 } 236 237 static void 238 autofs_cache_callout(void *context) 239 { 240 struct autofs_node *anp = context; 241 242 autofs_node_uncache(anp); 243 } 244 245 void 246 autofs_flush(struct autofs_mount *amp) 247 { 248 struct autofs_node *anp = amp->am_root; 249 struct autofs_node *child; 250 251 mtx_lock_ex_quick(&->am_lock); 252 RB_FOREACH(child, autofs_node_tree, &anp->an_children) { 253 autofs_node_uncache(child); 254 } 255 autofs_node_uncache(amp->am_root); 256 mtx_unlock_ex(&->am_lock); 257 258 AUTOFS_DEBUG("%s flushed", amp->am_on); 259 } 260 261 /* 262 * The set/restore sigmask functions are used to (temporarily) overwrite 263 * the thread sigmask during triggering. 264 */ 265 static void 266 autofs_set_sigmask(sigset_t *oldset) 267 { 268 struct lwp *lp = curthread->td_lwp; 269 sigset_t newset; 270 int i; 271 272 SIGFILLSET(newset); 273 /* Remove the autofs set of signals from newset */ 274 lwkt_gettoken(&lp->lwp_token); 275 for (i = 0; i < nitems(autofs_sig_set); i++) { 276 /* 277 * But make sure we leave the ones already masked 278 * by the process, i.e. remove the signal from the 279 * temporary signalmask only if it wasn't already 280 * in sigmask. 281 */ 282 if (!SIGISMEMBER(lp->lwp_sigmask, autofs_sig_set[i]) && 283 !SIGISMEMBER(lp->lwp_proc->p_sigacts->ps_sigignore, 284 autofs_sig_set[i])) { 285 SIGDELSET(newset, autofs_sig_set[i]); 286 } 287 } 288 kern_sigprocmask(SIG_SETMASK, &newset, oldset); 289 lwkt_reltoken(&lp->lwp_token); 290 } 291 292 static void 293 autofs_restore_sigmask(sigset_t *set) 294 { 295 kern_sigprocmask(SIG_SETMASK, set, NULL); 296 } 297 298 static int 299 autofs_trigger_one(struct autofs_node *anp, 300 const char *component, int componentlen) 301 { 302 #define _taskqueue_thread (taskqueue_thread[mycpuid]) 303 struct autofs_mount *amp = anp->an_mount; 304 struct autofs_request *ar; 305 char *key, *path; 306 int error = 0, request_error; 307 bool wildcards; 308 309 KKASSERT(lockstatus(&autofs_softc->sc_lock, curthread) == LK_EXCLUSIVE); 310 311 if (anp->an_parent == NULL) { 312 key = kstrndup(component, componentlen, M_AUTOFS); 313 } else { 314 struct autofs_node *firstanp; 315 for (firstanp = anp; firstanp->an_parent->an_parent != NULL; 316 firstanp = firstanp->an_parent) 317 continue; 318 key = kstrdup(firstanp->an_name, M_AUTOFS); 319 } 320 321 path = autofs_path(anp); 322 323 TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 324 if (strcmp(ar->ar_path, path)) 325 continue; 326 if (strcmp(ar->ar_key, key)) 327 continue; 328 329 KASSERT(strcmp(ar->ar_from, amp->am_from) == 0, 330 ("from changed; %s != %s", ar->ar_from, amp->am_from)); 331 KASSERT(strcmp(ar->ar_prefix, amp->am_prefix) == 0, 332 ("prefix changed; %s != %s", 333 ar->ar_prefix, amp->am_prefix)); 334 KASSERT(strcmp(ar->ar_options, amp->am_options) == 0, 335 ("options changed; %s != %s", 336 ar->ar_options, amp->am_options)); 337 break; 338 } 339 340 if (ar != NULL) { 341 refcount_acquire(&ar->ar_refcount); 342 } else { 343 ar = objcache_get(autofs_request_objcache, M_WAITOK); 344 ar->ar_mount = amp; 345 ar->ar_id = autofs_softc->sc_last_request_id++; 346 ar->ar_done = false; 347 ar->ar_error = 0; 348 ar->ar_wildcards = false; 349 ar->ar_in_progress = false; 350 strlcpy(ar->ar_from, amp->am_from, sizeof(ar->ar_from)); 351 strlcpy(ar->ar_path, path, sizeof(ar->ar_path)); 352 strlcpy(ar->ar_prefix, amp->am_prefix, sizeof(ar->ar_prefix)); 353 strlcpy(ar->ar_key, key, sizeof(ar->ar_key)); 354 strlcpy(ar->ar_options, 355 amp->am_options, sizeof(ar->ar_options)); 356 TIMEOUT_TASK_INIT(_taskqueue_thread, &ar->ar_task, 0, 357 autofs_task, ar); 358 taskqueue_enqueue_timeout(_taskqueue_thread, &ar->ar_task, 359 autofs_timeout * hz); 360 refcount_init(&ar->ar_refcount, 1); 361 TAILQ_INSERT_TAIL(&autofs_softc->sc_requests, ar, ar_next); 362 } 363 364 cv_broadcast(&autofs_softc->sc_cv); 365 while (ar->ar_done == false) { 366 if (autofs_interruptible) { 367 sigset_t oldset; 368 autofs_set_sigmask(&oldset); 369 error = cv_wait_sig(&autofs_softc->sc_cv, 370 &autofs_softc->sc_lock); 371 autofs_restore_sigmask(&oldset); 372 if (error) { 373 AUTOFS_WARN("cv_wait_sig for %s failed " 374 "with error %d", ar->ar_path, error); 375 break; 376 } 377 } else { 378 cv_wait(&autofs_softc->sc_cv, &autofs_softc->sc_lock); 379 } 380 } 381 382 request_error = ar->ar_error; 383 if (request_error) 384 AUTOFS_WARN("request for %s completed with error %d", 385 ar->ar_path, request_error); 386 387 wildcards = ar->ar_wildcards; 388 389 /* 390 * Check if this is the last reference. 391 */ 392 if (refcount_release(&ar->ar_refcount)) { 393 TAILQ_REMOVE(&autofs_softc->sc_requests, ar, ar_next); 394 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 395 taskqueue_cancel_timeout(_taskqueue_thread, &ar->ar_task, NULL); 396 taskqueue_drain_timeout(_taskqueue_thread, &ar->ar_task); 397 objcache_put(autofs_request_objcache, ar); 398 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 399 } 400 401 /* 402 * Note that we do not do negative caching on purpose. This 403 * way the user can retry access at any time, e.g. after fixing 404 * the failure reason, without waiting for cache timer to expire. 405 */ 406 if (error == 0 && request_error == 0 && autofs_cache > 0) { 407 autofs_node_cache(anp); 408 anp->an_wildcards = wildcards; 409 callout_reset(&anp->an_callout, autofs_cache * hz, 410 autofs_cache_callout, anp); 411 } 412 413 kfree(key, M_AUTOFS); 414 kfree(path, M_AUTOFS); 415 416 if (error) 417 return (error); 418 return (request_error); 419 } 420 421 int 422 autofs_trigger(struct autofs_node *anp, 423 const char *component, int componentlen) 424 { 425 for (;;) { 426 int error, dummy; 427 428 error = autofs_trigger_one(anp, component, componentlen); 429 if (error == 0) { 430 anp->an_retries = 0; 431 return (0); 432 } 433 if (error == EINTR || error == ERESTART) { 434 AUTOFS_DEBUG("trigger interrupted by signal, " 435 "not retrying"); 436 anp->an_retries = 0; 437 return (error); 438 } 439 anp->an_retries++; 440 if (anp->an_retries >= autofs_retry_attempts) { 441 AUTOFS_DEBUG("trigger failed %d times; returning " 442 "error %d", anp->an_retries, error); 443 anp->an_retries = 0; 444 return (error); 445 446 } 447 AUTOFS_DEBUG("trigger failed with error %d; will retry in " 448 "%d seconds, %d attempts left", error, autofs_retry_delay, 449 autofs_retry_attempts - anp->an_retries); 450 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 451 tsleep(&dummy, 0, "autofs_retry", autofs_retry_delay * hz); 452 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 453 } 454 } 455 456 static int 457 autofs_ioctl_request(struct autofs_daemon_request *adr) 458 { 459 struct proc *curp = curproc; 460 struct autofs_request *ar; 461 462 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 463 for (;;) { 464 int error; 465 TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 466 if (ar->ar_done) 467 continue; 468 if (ar->ar_in_progress) 469 continue; 470 break; 471 } 472 473 if (ar != NULL) 474 break; 475 476 error = cv_wait_sig(&autofs_softc->sc_cv, 477 &autofs_softc->sc_lock); 478 if (error) { 479 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 480 return (error); 481 } 482 } 483 484 ar->ar_in_progress = true; 485 486 adr->adr_id = ar->ar_id; 487 strlcpy(adr->adr_from, ar->ar_from, sizeof(adr->adr_from)); 488 strlcpy(adr->adr_path, ar->ar_path, sizeof(adr->adr_path)); 489 strlcpy(adr->adr_prefix, ar->ar_prefix, sizeof(adr->adr_prefix)); 490 strlcpy(adr->adr_key, ar->ar_key, sizeof(adr->adr_key)); 491 strlcpy(adr->adr_options, ar->ar_options, sizeof(adr->adr_options)); 492 493 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 494 495 lwkt_gettoken(&curp->p_token); 496 autofs_softc->sc_dev_sid = proc_pgid(curp); 497 lwkt_reltoken(&curp->p_token); 498 499 return (0); 500 } 501 502 static int 503 autofs_ioctl_done(struct autofs_daemon_done *add) 504 { 505 struct autofs_request *ar; 506 507 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 508 TAILQ_FOREACH(ar, &autofs_softc->sc_requests, ar_next) { 509 if (ar->ar_id == add->add_id) 510 break; 511 } 512 513 if (ar == NULL) { 514 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 515 AUTOFS_DEBUG("id %d not found", add->add_id); 516 return (ESRCH); 517 } 518 519 ar->ar_error = add->add_error; 520 ar->ar_wildcards = add->add_wildcards; 521 ar->ar_done = true; 522 ar->ar_in_progress = false; 523 cv_broadcast(&autofs_softc->sc_cv); 524 525 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 526 527 return (0); 528 } 529 530 static int 531 autofs_open(struct dev_open_args *ap) 532 { 533 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 534 /* 535 * We must never block automountd(8) and its descendants, and we use 536 * session ID to determine that: we store session id of the process 537 * that opened the device, and then compare it with session ids 538 * of triggering processes. This means running a second automountd(8) 539 * instance would break the previous one. The check below prevents 540 * it from happening. 541 */ 542 if (autofs_softc->sc_dev_opened) { 543 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 544 return (EBUSY); 545 } 546 547 autofs_softc->sc_dev_opened = true; 548 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 549 550 return (0); 551 } 552 553 static int 554 autofs_close(struct dev_close_args *ap) 555 { 556 lockmgr(&autofs_softc->sc_lock, LK_EXCLUSIVE); 557 KASSERT(autofs_softc->sc_dev_opened, ("not opened?")); 558 autofs_softc->sc_dev_opened = false; 559 lockmgr(&autofs_softc->sc_lock, LK_RELEASE); 560 561 return (0); 562 } 563 564 static int 565 autofs_ioctl(struct dev_ioctl_args *ap) 566 { 567 u_long cmd = ap->a_cmd; 568 void *arg = ap->a_data; 569 570 KASSERT(autofs_softc->sc_dev_opened, ("not opened?")); 571 572 switch (cmd) { 573 case AUTOFSREQUEST: 574 return (autofs_ioctl_request( 575 (struct autofs_daemon_request *)arg)); 576 case AUTOFSDONE: 577 return (autofs_ioctl_done( 578 (struct autofs_daemon_done *)arg)); 579 default: 580 AUTOFS_DEBUG("invalid cmd %lx", cmd); 581 return (EINVAL); 582 } 583 return (EINVAL); 584 } 585