1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * Copyright (c) 1999 Michael Smith 35 * All rights reserved. 36 * Copyright (c) 1999 Poul-Henning Kamp 37 * All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61 #include <sys/cdefs.h> 62 __FBSDID("$FreeBSD$"); 63 64 #include <sys/param.h> 65 #include <sys/conf.h> 66 #include <sys/cons.h> 67 #include <sys/jail.h> 68 #include <sys/kernel.h> 69 #include <sys/linker.h> 70 #include <sys/mac.h> 71 #include <sys/malloc.h> 72 #include <sys/mount.h> 73 #include <sys/mutex.h> 74 #include <sys/namei.h> 75 #include <sys/proc.h> 76 #include <sys/filedesc.h> 77 #include <sys/reboot.h> 78 #include <sys/sysproto.h> 79 #include <sys/sx.h> 80 #include <sys/sysctl.h> 81 #include <sys/sysent.h> 82 #include <sys/systm.h> 83 #include <sys/vnode.h> 84 85 #include <geom/geom.h> 86 87 #include <machine/stdarg.h> 88 89 #include "opt_rootdevname.h" 90 #include "opt_ddb.h" 91 #include "opt_mac.h" 92 93 #ifdef DDB 94 #include <ddb/ddb.h> 95 #endif 96 97 #define ROOTNAME "root_device" 98 #define VFS_MOUNTARG_SIZE_MAX (1024 * 64) 99 100 static void checkdirs(struct vnode *olddp, struct vnode *newdp); 101 static struct cdev *getdiskbyname(char *_name); 102 static void gets(char *cp); 103 static int vfs_domount(struct thread *td, const char *fstype, 104 char *fspath, int fsflags, void *fsdata, int compat); 105 static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp, 106 const char *fspath, struct thread *td, struct mount **mpp); 107 static int vfs_mountroot_ask(void); 108 static int vfs_mountroot_try(const char *mountfrom); 109 static int vfs_donmount(struct thread *td, int fsflags, 110 struct uio *fsoptions); 111 112 static int usermount = 0; 113 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 114 "Unprivileged users may mount and unmount file systems"); 115 116 MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); 117 118 /* List of mounted filesystems. */ 119 struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); 120 121 /* For any iteration/modification of mountlist */ 122 struct mtx mountlist_mtx; 123 124 /* 125 * The vnode of the system's root (/ in the filesystem, without chroot 126 * active.) 127 */ 128 struct vnode *rootvnode; 129 130 /* 131 * The root filesystem is detailed in the kernel environment variable 132 * vfs.root.mountfrom, which is expected to be in the general format 133 * 134 * <vfsname>:[<path>] 135 * vfsname := the name of a VFS known to the kernel and capable 136 * of being mounted as root 137 * path := disk device name or other data used by the filesystem 138 * to locate its physical store 139 */ 140 141 /* 142 * The root specifiers we will try if RB_CDROM is specified. 143 */ 144 static char *cdrom_rootdevnames[] = { 145 "cd9660:cd0", 146 "cd9660:acd0", 147 NULL 148 }; 149 150 /* legacy find-root code */ 151 char *rootdevnames[2] = {NULL, NULL}; 152 struct cdev *rootdev = NULL; 153 #ifdef ROOTDEVNAME 154 const char *ctrootdevname = ROOTDEVNAME; 155 #else 156 const char *ctrootdevname = NULL; 157 #endif 158 159 /* 160 * Has to be dynamic as the value of rootdev can change; however, it can't 161 * change after the root is mounted, so a user process can't access this 162 * sysctl until after the value is unchangeable. 163 */ 164 static int 165 sysctl_rootdev(SYSCTL_HANDLER_ARGS) 166 { 167 int error; 168 169 /* _RD prevents this from happening. */ 170 KASSERT(req->newptr == NULL, ("Attempt to change root device name")); 171 172 if (rootdev != NULL) 173 error = sysctl_handle_string(oidp, rootdev->si_name, 0, req); 174 else 175 error = sysctl_handle_string(oidp, "", 0, req); 176 177 return (error); 178 } 179 180 SYSCTL_PROC(_kern, OID_AUTO, rootdev, CTLTYPE_STRING | CTLFLAG_RD, 181 0, 0, sysctl_rootdev, "A", "Root file system device"); 182 183 /* Remove one mount option. */ 184 static void 185 vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt) 186 { 187 188 TAILQ_REMOVE(opts, opt, link); 189 free(opt->name, M_MOUNT); 190 if (opt->value != NULL) 191 free(opt->value, M_MOUNT); 192 #ifdef INVARIANTS 193 else if (opt->len != 0) 194 panic("%s: mount option with NULL value but length != 0", 195 __func__); 196 #endif 197 free(opt, M_MOUNT); 198 } 199 200 /* Release all resources related to the mount options. */ 201 static void 202 vfs_freeopts(struct vfsoptlist *opts) 203 { 204 struct vfsopt *opt; 205 206 while (!TAILQ_EMPTY(opts)) { 207 opt = TAILQ_FIRST(opts); 208 vfs_freeopt(opts, opt); 209 } 210 free(opts, M_MOUNT); 211 } 212 213 /* 214 * Check if options are equal (with or without the "no" prefix). 215 */ 216 static int 217 vfs_equalopts(const char *opt1, const char *opt2) 218 { 219 220 /* "opt" vs. "opt" or "noopt" vs. "noopt" */ 221 if (strcmp(opt1, opt2) == 0) 222 return (1); 223 /* "noopt" vs. "opt" */ 224 if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0) 225 return (1); 226 /* "opt" vs. "noopt" */ 227 if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0) 228 return (1); 229 return (0); 230 } 231 232 /* 233 * If a mount option is specified several times, 234 * (with or without the "no" prefix) only keep 235 * the last occurence of it. 236 */ 237 static void 238 vfs_sanitizeopts(struct vfsoptlist *opts) 239 { 240 struct vfsopt *opt, *opt2, *tmp; 241 242 TAILQ_FOREACH_REVERSE(opt, opts, vfsoptlist, link) { 243 opt2 = TAILQ_PREV(opt, vfsoptlist, link); 244 while (opt2 != NULL) { 245 if (vfs_equalopts(opt->name, opt2->name)) { 246 tmp = TAILQ_PREV(opt2, vfsoptlist, link); 247 vfs_freeopt(opts, opt2); 248 opt2 = tmp; 249 } else { 250 opt2 = TAILQ_PREV(opt2, vfsoptlist, link); 251 } 252 } 253 } 254 } 255 256 /* 257 * Build a linked list of mount options from a struct uio. 258 */ 259 static int 260 vfs_buildopts(struct uio *auio, struct vfsoptlist **options) 261 { 262 struct vfsoptlist *opts; 263 struct vfsopt *opt; 264 size_t memused; 265 unsigned int i, iovcnt; 266 int error, namelen, optlen; 267 268 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); 269 TAILQ_INIT(opts); 270 memused = 0; 271 iovcnt = auio->uio_iovcnt; 272 for (i = 0; i < iovcnt; i += 2) { 273 opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 274 namelen = auio->uio_iov[i].iov_len; 275 optlen = auio->uio_iov[i + 1].iov_len; 276 opt->name = malloc(namelen, M_MOUNT, M_WAITOK); 277 opt->value = NULL; 278 opt->len = 0; 279 280 /* 281 * Do this early, so jumps to "bad" will free the current 282 * option. 283 */ 284 TAILQ_INSERT_TAIL(opts, opt, link); 285 memused += sizeof(struct vfsopt) + optlen + namelen; 286 287 /* 288 * Avoid consuming too much memory, and attempts to overflow 289 * memused. 290 */ 291 if (memused > VFS_MOUNTARG_SIZE_MAX || 292 optlen > VFS_MOUNTARG_SIZE_MAX || 293 namelen > VFS_MOUNTARG_SIZE_MAX) { 294 error = EINVAL; 295 goto bad; 296 } 297 298 if (auio->uio_segflg == UIO_SYSSPACE) { 299 bcopy(auio->uio_iov[i].iov_base, opt->name, namelen); 300 } else { 301 error = copyin(auio->uio_iov[i].iov_base, opt->name, 302 namelen); 303 if (error) 304 goto bad; 305 } 306 /* Ensure names are null-terminated strings. */ 307 if (opt->name[namelen - 1] != '\0') { 308 error = EINVAL; 309 goto bad; 310 } 311 if (optlen != 0) { 312 opt->len = optlen; 313 opt->value = malloc(optlen, M_MOUNT, M_WAITOK); 314 if (auio->uio_segflg == UIO_SYSSPACE) { 315 bcopy(auio->uio_iov[i + 1].iov_base, opt->value, 316 optlen); 317 } else { 318 error = copyin(auio->uio_iov[i + 1].iov_base, 319 opt->value, optlen); 320 if (error) 321 goto bad; 322 } 323 } 324 } 325 vfs_sanitizeopts(opts); 326 *options = opts; 327 return (0); 328 bad: 329 vfs_freeopts(opts); 330 return (error); 331 } 332 333 /* 334 * Merge the old mount options with the new ones passed 335 * in the MNT_UPDATE case. 336 */ 337 static void 338 vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *opts) 339 { 340 struct vfsopt *opt, *opt2, *new; 341 342 TAILQ_FOREACH(opt, opts, link) { 343 /* 344 * Check that this option hasn't been redefined 345 * nor cancelled with a "no" mount option. 346 */ 347 opt2 = TAILQ_FIRST(toopts); 348 while (opt2 != NULL) { 349 if (strcmp(opt2->name, opt->name) == 0) 350 goto next; 351 if (strncmp(opt2->name, "no", 2) == 0 && 352 strcmp(opt2->name + 2, opt->name) == 0) { 353 vfs_freeopt(toopts, opt2); 354 goto next; 355 } 356 opt2 = TAILQ_NEXT(opt2, link); 357 } 358 /* We want this option, duplicate it. */ 359 new = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK); 360 new->name = malloc(strlen(opt->name) + 1, M_MOUNT, M_WAITOK); 361 strcpy(new->name, opt->name); 362 if (opt->len != 0) { 363 new->value = malloc(opt->len, M_MOUNT, M_WAITOK); 364 bcopy(opt->value, new->value, opt->len); 365 } else { 366 new->value = NULL; 367 } 368 new->len = opt->len; 369 TAILQ_INSERT_TAIL(toopts, new, link); 370 next: 371 continue; 372 } 373 } 374 375 /* 376 * New mount API. 377 */ 378 int 379 nmount(td, uap) 380 struct thread *td; 381 struct nmount_args /* { 382 struct iovec *iovp; 383 unsigned int iovcnt; 384 int flags; 385 } */ *uap; 386 { 387 struct uio *auio; 388 struct iovec *iov; 389 unsigned int i; 390 int error; 391 u_int iovcnt; 392 393 iovcnt = uap->iovcnt; 394 /* 395 * Check that we have an even number of iovec's 396 * and that we have at least two options. 397 */ 398 if ((iovcnt & 1) || (iovcnt < 4)) 399 return (EINVAL); 400 error = copyinuio(uap->iovp, iovcnt, &auio); 401 if (error) 402 return (error); 403 iov = auio->uio_iov; 404 for (i = 0; i < iovcnt; i++) { 405 if (iov->iov_len > MMAXOPTIONLEN) { 406 free(auio, M_IOV); 407 return (EINVAL); 408 } 409 iov++; 410 } 411 error = vfs_donmount(td, uap->flags, auio); 412 free(auio, M_IOV); 413 return (error); 414 } 415 416 int 417 kernel_mount(struct iovec *iovp, u_int iovcnt, int flags) 418 { 419 struct uio auio; 420 int error; 421 422 /* 423 * Check that we have an even number of iovec's 424 * and that we have at least two options. 425 */ 426 if ((iovcnt & 1) || (iovcnt < 4)) 427 return (EINVAL); 428 429 auio.uio_iov = iovp; 430 auio.uio_iovcnt = iovcnt; 431 auio.uio_segflg = UIO_SYSSPACE; 432 433 error = vfs_donmount(curthread, flags, &auio); 434 return (error); 435 } 436 437 int 438 kernel_vmount(int flags, ...) 439 { 440 struct iovec *iovp; 441 struct uio auio; 442 va_list ap; 443 u_int iovcnt, iovlen, len; 444 const char *cp; 445 char *buf, *pos; 446 size_t n; 447 int error, i; 448 449 len = 0; 450 va_start(ap, flags); 451 for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++) 452 len += strlen(cp) + 1; 453 va_end(ap); 454 455 if (iovcnt < 4 || iovcnt & 1) 456 return (EINVAL); 457 458 iovlen = iovcnt * sizeof (struct iovec); 459 MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK); 460 MALLOC(buf, char *, len, M_MOUNT, M_WAITOK); 461 pos = buf; 462 va_start(ap, flags); 463 for (i = 0; i < iovcnt; i++) { 464 cp = va_arg(ap, const char *); 465 copystr(cp, pos, len - (pos - buf), &n); 466 iovp[i].iov_base = pos; 467 iovp[i].iov_len = n; 468 pos += n; 469 } 470 va_end(ap); 471 472 auio.uio_iov = iovp; 473 auio.uio_iovcnt = iovcnt; 474 auio.uio_segflg = UIO_SYSSPACE; 475 476 error = vfs_donmount(curthread, flags, &auio); 477 FREE(iovp, M_MOUNT); 478 FREE(buf, M_MOUNT); 479 return (error); 480 } 481 482 /* 483 * Allocate and initialize the mount point struct. 484 */ 485 static int 486 vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, 487 const char *fspath, struct thread *td, struct mount **mpp) 488 { 489 struct mount *mp; 490 491 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO); 492 TAILQ_INIT(&mp->mnt_nvnodelist); 493 mp->mnt_nvnodelistsize = 0; 494 mtx_init(&mp->mnt_mtx, "struct mount mtx", NULL, MTX_DEF); 495 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); 496 vfs_busy(mp, LK_NOWAIT, 0, td); 497 mp->mnt_op = vfsp->vfc_vfsops; 498 mp->mnt_vfc = vfsp; 499 vfsp->vfc_refcount++; 500 mp->mnt_stat.f_type = vfsp->vfc_typenum; 501 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 502 strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 503 mp->mnt_vnodecovered = vp; 504 mp->mnt_cred = crdup(td->td_ucred); 505 mp->mnt_stat.f_owner = td->td_ucred->cr_uid; 506 strlcpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN); 507 mp->mnt_iosize_max = DFLTPHYS; 508 #ifdef MAC 509 mac_init_mount(mp); 510 mac_create_mount(td->td_ucred, mp); 511 #endif 512 *mpp = mp; 513 return (0); 514 } 515 516 /* 517 * Destroy the mount struct previously allocated by vfs_mount_alloc(). 518 */ 519 void 520 vfs_mount_destroy(struct mount *mp, struct thread *td) 521 { 522 523 mp->mnt_vfc->vfc_refcount--; 524 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) 525 panic("unmount: dangling vnode"); 526 vfs_unbusy(mp,td); 527 lockdestroy(&mp->mnt_lock); 528 mtx_destroy(&mp->mnt_mtx); 529 if (mp->mnt_kern_flag & MNTK_MWAIT) 530 wakeup(mp); 531 #ifdef MAC 532 mac_destroy_mount(mp); 533 #endif 534 if (mp->mnt_opt != NULL) 535 vfs_freeopts(mp->mnt_opt); 536 crfree(mp->mnt_cred); 537 free(mp, M_MOUNT); 538 } 539 540 static int 541 vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) 542 { 543 struct vfsoptlist *optlist; 544 char *fstype, *fspath; 545 int error, fstypelen, fspathlen; 546 547 error = vfs_buildopts(fsoptions, &optlist); 548 if (error) 549 return (error); 550 551 /* 552 * We need these two options before the others, 553 * and they are mandatory for any filesystem. 554 * Ensure they are NUL terminated as well. 555 */ 556 fstypelen = 0; 557 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen); 558 if (error || fstype[fstypelen - 1] != '\0') { 559 error = EINVAL; 560 goto bail; 561 } 562 fspathlen = 0; 563 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen); 564 if (error || fspath[fspathlen - 1] != '\0') { 565 error = EINVAL; 566 goto bail; 567 } 568 569 /* 570 * Be ultra-paranoid about making sure the type and fspath 571 * variables will fit in our mp buffers, including the 572 * terminating NUL. 573 */ 574 if (fstypelen >= MFSNAMELEN - 1 || fspathlen >= MNAMELEN - 1) { 575 error = ENAMETOOLONG; 576 goto bail; 577 } 578 579 error = vfs_domount(td, fstype, fspath, fsflags, optlist, 0); 580 bail: 581 if (error) 582 vfs_freeopts(optlist); 583 return (error); 584 } 585 586 /* 587 * Old mount API. 588 */ 589 #ifndef _SYS_SYSPROTO_H_ 590 struct mount_args { 591 char *type; 592 char *path; 593 int flags; 594 caddr_t data; 595 }; 596 #endif 597 /* ARGSUSED */ 598 int 599 mount(td, uap) 600 struct thread *td; 601 struct mount_args /* { 602 char *type; 603 char *path; 604 int flags; 605 caddr_t data; 606 } */ *uap; 607 { 608 char *fstype; 609 char *fspath; 610 int error; 611 612 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK); 613 fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK); 614 615 /* 616 * vfs_mount() actually takes a kernel string for `type' and 617 * `path' now, so extract them. 618 */ 619 error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL); 620 if (error == 0) 621 error = copyinstr(uap->path, fspath, MNAMELEN, NULL); 622 if (error == 0) 623 error = vfs_domount(td, fstype, fspath, uap->flags, 624 uap->data, 1); 625 free(fstype, M_TEMP); 626 free(fspath, M_TEMP); 627 return (error); 628 } 629 630 /* 631 * vfs_mount(): actually attempt a filesystem mount. 632 * 633 * This routine is designed to be a "generic" entry point for routines 634 * that wish to mount a filesystem. All parameters except `fsdata' are 635 * pointers into kernel space. `fsdata' is currently still a pointer 636 * into userspace. 637 */ 638 int 639 vfs_mount(td, fstype, fspath, fsflags, fsdata) 640 struct thread *td; 641 const char *fstype; 642 char *fspath; 643 int fsflags; 644 void *fsdata; 645 { 646 647 return (vfs_domount(td, fstype, fspath, fsflags, fsdata, 1)); 648 } 649 650 /* 651 * vfs_domount(): actually attempt a filesystem mount. 652 */ 653 static int 654 vfs_domount( 655 struct thread *td, /* Flags common to all filesystems. */ 656 const char *fstype, /* Filesystem type. */ 657 char *fspath, /* Mount path. */ 658 int fsflags, /* Flags common to all filesystems. */ 659 void *fsdata, /* Options local to the filesystem. */ 660 int compat /* Invocation from compat syscall. */ 661 ) 662 { 663 linker_file_t lf; 664 struct vnode *vp; 665 struct mount *mp; 666 struct vfsconf *vfsp; 667 int error, flag = 0, kern_flag = 0; 668 struct vattr va; 669 struct nameidata nd; 670 671 /* 672 * Be ultra-paranoid about making sure the type and fspath 673 * variables will fit in our mp buffers, including the 674 * terminating NUL. 675 */ 676 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN) 677 return (ENAMETOOLONG); 678 679 if (jailed(td->td_ucred)) 680 return (EPERM); 681 if (usermount == 0) { 682 if ((error = suser(td)) != 0) 683 return (error); 684 } 685 686 /* 687 * Do not allow NFS export or MNT_SUIDDIR by unprivileged users. 688 */ 689 if (fsflags & (MNT_EXPORTED | MNT_SUIDDIR)) { 690 if ((error = suser(td)) != 0) 691 return (error); 692 } 693 /* 694 * Silently enforce MNT_NODEV, MNT_NOSUID and MNT_USER for 695 * unprivileged users. 696 */ 697 if (suser(td) != 0) 698 fsflags |= MNT_NODEV | MNT_NOSUID | MNT_USER; 699 /* 700 * Get vnode to be covered 701 */ 702 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td); 703 if ((error = namei(&nd)) != 0) 704 return (error); 705 NDFREE(&nd, NDF_ONLY_PNBUF); 706 vp = nd.ni_vp; 707 if (fsflags & MNT_UPDATE) { 708 if ((vp->v_vflag & VV_ROOT) == 0) { 709 vput(vp); 710 return (EINVAL); 711 } 712 mp = vp->v_mount; 713 flag = mp->mnt_flag; 714 kern_flag = mp->mnt_kern_flag; 715 /* 716 * We only allow the filesystem to be reloaded if it 717 * is currently mounted read-only. 718 */ 719 if ((fsflags & MNT_RELOAD) && 720 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 721 vput(vp); 722 return (EOPNOTSUPP); /* Needs translation */ 723 } 724 /* 725 * Only privileged root, or (if MNT_USER is set) the user that 726 * did the original mount is permitted to update it. 727 */ 728 error = vfs_suser(mp, td); 729 if (error) { 730 vput(vp); 731 return (error); 732 } 733 if (vfs_busy(mp, LK_NOWAIT, 0, td)) { 734 vput(vp); 735 return (EBUSY); 736 } 737 VI_LOCK(vp); 738 if ((vp->v_iflag & VI_MOUNT) != 0 || 739 vp->v_mountedhere != NULL) { 740 VI_UNLOCK(vp); 741 vfs_unbusy(mp, td); 742 vput(vp); 743 return (EBUSY); 744 } 745 vp->v_iflag |= VI_MOUNT; 746 VI_UNLOCK(vp); 747 mp->mnt_flag |= fsflags & 748 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT); 749 VOP_UNLOCK(vp, 0, td); 750 if (compat == 0) { 751 mp->mnt_optnew = fsdata; 752 vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); 753 } 754 } else { 755 /* 756 * If the user is not root, ensure that they own the directory 757 * onto which we are attempting to mount. 758 */ 759 error = VOP_GETATTR(vp, &va, td->td_ucred, td); 760 if (error) { 761 vput(vp); 762 return (error); 763 } 764 if (va.va_uid != td->td_ucred->cr_uid) { 765 if ((error = suser(td)) != 0) { 766 vput(vp); 767 return (error); 768 } 769 } 770 if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) { 771 vput(vp); 772 return (error); 773 } 774 if (vp->v_type != VDIR) { 775 vput(vp); 776 return (ENOTDIR); 777 } 778 vfsp = vfs_byname(fstype); 779 if (vfsp == NULL) { 780 /* Only load modules for root (very important!). */ 781 if ((error = suser(td)) != 0) { 782 vput(vp); 783 return (error); 784 } 785 error = securelevel_gt(td->td_ucred, 0); 786 if (error) { 787 vput(vp); 788 return (error); 789 } 790 error = linker_load_module(NULL, fstype, NULL, NULL, &lf); 791 if (error || lf == NULL) { 792 vput(vp); 793 if (lf == NULL) 794 error = ENODEV; 795 return (error); 796 } 797 lf->userrefs++; 798 /* Look up again to see if the VFS was loaded. */ 799 vfsp = vfs_byname(fstype); 800 if (vfsp == NULL) { 801 lf->userrefs--; 802 linker_file_unload(lf, LINKER_UNLOAD_FORCE); 803 vput(vp); 804 return (ENODEV); 805 } 806 } 807 VI_LOCK(vp); 808 if ((vp->v_iflag & VI_MOUNT) != 0 || 809 vp->v_mountedhere != NULL) { 810 VI_UNLOCK(vp); 811 vput(vp); 812 return (EBUSY); 813 } 814 vp->v_iflag |= VI_MOUNT; 815 VI_UNLOCK(vp); 816 817 /* 818 * Allocate and initialize the filesystem. 819 */ 820 error = vfs_mount_alloc(vp, vfsp, fspath, td, &mp); 821 if (error) { 822 vput(vp); 823 return (error); 824 } 825 VOP_UNLOCK(vp, 0, td); 826 827 /* XXXMAC: pass to vfs_mount_alloc? */ 828 if (compat == 0) 829 mp->mnt_optnew = fsdata; 830 } 831 /* 832 * Check if the fs implements the type VFS_[O]MOUNT() 833 * function we are looking for. 834 */ 835 if ((compat == 0) == (mp->mnt_op->vfs_omount != NULL)) { 836 printf("%s doesn't support the %s mount syscall\n", 837 mp->mnt_vfc->vfc_name, compat ? "old" : "new"); 838 VI_LOCK(vp); 839 vp->v_iflag &= ~VI_MOUNT; 840 VI_UNLOCK(vp); 841 if (mp->mnt_flag & MNT_UPDATE) 842 vfs_unbusy(mp, td); 843 else 844 vfs_mount_destroy(mp, td); 845 vrele(vp); 846 return (EOPNOTSUPP); 847 } 848 849 /* 850 * Set the mount level flags. 851 */ 852 if (fsflags & MNT_RDONLY) 853 mp->mnt_flag |= MNT_RDONLY; 854 else if (mp->mnt_flag & MNT_RDONLY) 855 mp->mnt_kern_flag |= MNTK_WANTRDWR; 856 mp->mnt_flag &=~ MNT_UPDATEMASK; 857 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE); 858 /* 859 * Mount the filesystem. 860 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 861 * get. No freeing of cn_pnbuf. 862 */ 863 if (compat) 864 error = VFS_OMOUNT(mp, fspath, fsdata, td); 865 else 866 error = VFS_MOUNT(mp, td); 867 if (!error) { 868 if (mp->mnt_opt != NULL) 869 vfs_freeopts(mp->mnt_opt); 870 mp->mnt_opt = mp->mnt_optnew; 871 } 872 /* 873 * Prevent external consumers of mount options from reading 874 * mnt_optnew. 875 */ 876 mp->mnt_optnew = NULL; 877 if (mp->mnt_flag & MNT_UPDATE) { 878 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 879 mp->mnt_flag &= ~MNT_RDONLY; 880 mp->mnt_flag &= 881 ~(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT); 882 mp->mnt_kern_flag &= ~MNTK_WANTRDWR; 883 if (error) { 884 mp->mnt_flag = flag; 885 mp->mnt_kern_flag = kern_flag; 886 } 887 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 888 if (mp->mnt_syncer == NULL) 889 error = vfs_allocate_syncvnode(mp); 890 } else { 891 if (mp->mnt_syncer != NULL) 892 vrele(mp->mnt_syncer); 893 mp->mnt_syncer = NULL; 894 } 895 vfs_unbusy(mp, td); 896 VI_LOCK(vp); 897 vp->v_iflag &= ~VI_MOUNT; 898 VI_UNLOCK(vp); 899 vrele(vp); 900 return (error); 901 } 902 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 903 /* 904 * Put the new filesystem on the mount list after root. 905 */ 906 cache_purge(vp); 907 if (!error) { 908 struct vnode *newdp; 909 910 VI_LOCK(vp); 911 vp->v_iflag &= ~VI_MOUNT; 912 VI_UNLOCK(vp); 913 vp->v_mountedhere = mp; 914 mtx_lock(&mountlist_mtx); 915 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 916 mtx_unlock(&mountlist_mtx); 917 vfs_event_signal(NULL, VQ_MOUNT, 0); 918 if (VFS_ROOT(mp, &newdp, td)) 919 panic("mount: lost mount"); 920 checkdirs(vp, newdp); 921 vput(newdp); 922 VOP_UNLOCK(vp, 0, td); 923 if ((mp->mnt_flag & MNT_RDONLY) == 0) 924 error = vfs_allocate_syncvnode(mp); 925 vfs_unbusy(mp, td); 926 if (error || (error = VFS_START(mp, 0, td)) != 0) 927 vrele(vp); 928 } else { 929 VI_LOCK(vp); 930 vp->v_iflag &= ~VI_MOUNT; 931 VI_UNLOCK(vp); 932 vfs_mount_destroy(mp, td); 933 vput(vp); 934 } 935 return (error); 936 } 937 938 /* 939 * Scan all active processes to see if any of them have a current 940 * or root directory of `olddp'. If so, replace them with the new 941 * mount point. 942 */ 943 static void 944 checkdirs(olddp, newdp) 945 struct vnode *olddp, *newdp; 946 { 947 struct filedesc *fdp; 948 struct proc *p; 949 int nrele; 950 951 if (vrefcnt(olddp) == 1) 952 return; 953 sx_slock(&allproc_lock); 954 LIST_FOREACH(p, &allproc, p_list) { 955 mtx_lock(&fdesc_mtx); 956 fdp = p->p_fd; 957 if (fdp == NULL) { 958 mtx_unlock(&fdesc_mtx); 959 continue; 960 } 961 nrele = 0; 962 FILEDESC_LOCK(fdp); 963 if (fdp->fd_cdir == olddp) { 964 VREF(newdp); 965 fdp->fd_cdir = newdp; 966 nrele++; 967 } 968 if (fdp->fd_rdir == olddp) { 969 VREF(newdp); 970 fdp->fd_rdir = newdp; 971 nrele++; 972 } 973 FILEDESC_UNLOCK(fdp); 974 mtx_unlock(&fdesc_mtx); 975 while (nrele--) 976 vrele(olddp); 977 } 978 sx_sunlock(&allproc_lock); 979 if (rootvnode == olddp) { 980 vrele(rootvnode); 981 VREF(newdp); 982 rootvnode = newdp; 983 } 984 } 985 986 /* 987 * Unmount a filesystem. 988 * 989 * Note: unmount takes a path to the vnode mounted on as argument, 990 * not special file (as before). 991 */ 992 #ifndef _SYS_SYSPROTO_H_ 993 struct unmount_args { 994 char *path; 995 int flags; 996 }; 997 #endif 998 /* ARGSUSED */ 999 int 1000 unmount(td, uap) 1001 struct thread *td; 1002 register struct unmount_args /* { 1003 char *path; 1004 int flags; 1005 } */ *uap; 1006 { 1007 struct mount *mp; 1008 char *pathbuf; 1009 int error, id0, id1; 1010 1011 if (jailed(td->td_ucred)) 1012 return (EPERM); 1013 if (usermount == 0) { 1014 if ((error = suser(td)) != 0) 1015 return (error); 1016 } 1017 1018 pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK); 1019 error = copyinstr(uap->path, pathbuf, MNAMELEN, NULL); 1020 if (error) { 1021 free(pathbuf, M_TEMP); 1022 return (error); 1023 } 1024 if (uap->flags & MNT_BYFSID) { 1025 /* Decode the filesystem ID. */ 1026 if (sscanf(pathbuf, "FSID:%d:%d", &id0, &id1) != 2) { 1027 free(pathbuf, M_TEMP); 1028 return (EINVAL); 1029 } 1030 1031 mtx_lock(&mountlist_mtx); 1032 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1033 if (mp->mnt_stat.f_fsid.val[0] == id0 && 1034 mp->mnt_stat.f_fsid.val[1] == id1) 1035 break; 1036 } 1037 mtx_unlock(&mountlist_mtx); 1038 } else { 1039 mtx_lock(&mountlist_mtx); 1040 TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { 1041 if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) 1042 break; 1043 } 1044 mtx_unlock(&mountlist_mtx); 1045 } 1046 free(pathbuf, M_TEMP); 1047 if (mp == NULL) { 1048 /* 1049 * Previously we returned ENOENT for a nonexistent path and 1050 * EINVAL for a non-mountpoint. We cannot tell these apart 1051 * now, so in the !MNT_BYFSID case return the more likely 1052 * EINVAL for compatibility. 1053 */ 1054 return ((uap->flags & MNT_BYFSID) ? ENOENT : EINVAL); 1055 } 1056 1057 /* 1058 * Only privileged root, or (if MNT_USER is set) the user that did the 1059 * original mount is permitted to unmount this filesystem. 1060 */ 1061 error = vfs_suser(mp, td); 1062 if (error) 1063 return (error); 1064 1065 /* 1066 * Don't allow unmounting the root filesystem. 1067 */ 1068 if (mp->mnt_flag & MNT_ROOTFS) 1069 return (EINVAL); 1070 return (dounmount(mp, uap->flags, td)); 1071 } 1072 1073 /* 1074 * Do the actual filesystem unmount. 1075 */ 1076 int 1077 dounmount(mp, flags, td) 1078 struct mount *mp; 1079 int flags; 1080 struct thread *td; 1081 { 1082 struct vnode *coveredvp, *fsrootvp; 1083 int error; 1084 int async_flag; 1085 1086 mtx_lock(&mountlist_mtx); 1087 if (mp->mnt_kern_flag & MNTK_UNMOUNT) { 1088 mtx_unlock(&mountlist_mtx); 1089 return (EBUSY); 1090 } 1091 mp->mnt_kern_flag |= MNTK_UNMOUNT; 1092 /* Allow filesystems to detect that a forced unmount is in progress. */ 1093 if (flags & MNT_FORCE) 1094 mp->mnt_kern_flag |= MNTK_UNMOUNTF; 1095 error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK | 1096 ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_mtx, td); 1097 if (error) { 1098 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 1099 if (mp->mnt_kern_flag & MNTK_MWAIT) 1100 wakeup(mp); 1101 return (error); 1102 } 1103 vn_start_write(NULL, &mp, V_WAIT); 1104 1105 if (mp->mnt_flag & MNT_EXPUBLIC) 1106 vfs_setpublicfs(NULL, NULL, NULL); 1107 1108 vfs_msync(mp, MNT_WAIT); 1109 async_flag = mp->mnt_flag & MNT_ASYNC; 1110 mp->mnt_flag &= ~MNT_ASYNC; 1111 cache_purgevfs(mp); /* remove cache entries for this file sys */ 1112 if (mp->mnt_syncer != NULL) 1113 vrele(mp->mnt_syncer); 1114 /* 1115 * For forced unmounts, move process cdir/rdir refs on the fs root 1116 * vnode to the covered vnode. For non-forced unmounts we want 1117 * such references to cause an EBUSY error. 1118 */ 1119 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) { 1120 if (mp->mnt_vnodecovered != NULL) 1121 checkdirs(fsrootvp, mp->mnt_vnodecovered); 1122 if (fsrootvp == rootvnode) { 1123 vrele(rootvnode); 1124 rootvnode = NULL; 1125 } 1126 vput(fsrootvp); 1127 } 1128 if (((mp->mnt_flag & MNT_RDONLY) || 1129 (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) || 1130 (flags & MNT_FORCE)) { 1131 error = VFS_UNMOUNT(mp, flags, td); 1132 } 1133 vn_finished_write(mp); 1134 if (error) { 1135 /* Undo cdir/rdir and rootvnode changes made above. */ 1136 if ((flags & MNT_FORCE) && VFS_ROOT(mp, &fsrootvp, td) == 0) { 1137 if (mp->mnt_vnodecovered != NULL) 1138 checkdirs(mp->mnt_vnodecovered, fsrootvp); 1139 if (rootvnode == NULL) { 1140 rootvnode = fsrootvp; 1141 vref(rootvnode); 1142 } 1143 vput(fsrootvp); 1144 } 1145 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 1146 (void) vfs_allocate_syncvnode(mp); 1147 mtx_lock(&mountlist_mtx); 1148 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF); 1149 mp->mnt_flag |= async_flag; 1150 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, 1151 &mountlist_mtx, td); 1152 if (mp->mnt_kern_flag & MNTK_MWAIT) 1153 wakeup(mp); 1154 return (error); 1155 } 1156 mtx_lock(&mountlist_mtx); 1157 TAILQ_REMOVE(&mountlist, mp, mnt_list); 1158 if ((coveredvp = mp->mnt_vnodecovered) != NULL) 1159 coveredvp->v_mountedhere = NULL; 1160 mtx_unlock(&mountlist_mtx); 1161 vfs_event_signal(NULL, VQ_UNMOUNT, 0); 1162 vfs_mount_destroy(mp, td); 1163 if (coveredvp != NULL) 1164 vrele(coveredvp); 1165 return (0); 1166 } 1167 1168 /* 1169 * Lookup a filesystem type, and if found allocate and initialize 1170 * a mount structure for it. 1171 * 1172 * Devname is usually updated by mount(8) after booting. 1173 */ 1174 int 1175 vfs_rootmountalloc(fstypename, devname, mpp) 1176 char *fstypename; 1177 char *devname; 1178 struct mount **mpp; 1179 { 1180 struct thread *td = curthread; /* XXX */ 1181 struct vfsconf *vfsp; 1182 struct mount *mp; 1183 int error; 1184 1185 if (fstypename == NULL) 1186 return (ENODEV); 1187 vfsp = vfs_byname(fstypename); 1188 if (vfsp == NULL) 1189 return (ENODEV); 1190 error = vfs_mount_alloc(NULLVP, vfsp, "/", td, &mp); 1191 if (error) 1192 return (error); 1193 mp->mnt_flag |= MNT_RDONLY | MNT_ROOTFS; 1194 strlcpy(mp->mnt_stat.f_mntfromname, devname, MNAMELEN); 1195 *mpp = mp; 1196 return (0); 1197 } 1198 1199 /* 1200 * Find and mount the root filesystem 1201 */ 1202 void 1203 vfs_mountroot(void) 1204 { 1205 char *cp; 1206 int error, i, asked = 0; 1207 1208 1209 /* 1210 * Wait for GEOM to settle down 1211 */ 1212 DROP_GIANT(); 1213 g_waitidle(); 1214 PICKUP_GIANT(); 1215 1216 /* 1217 * We are booted with instructions to prompt for the root filesystem. 1218 */ 1219 if (boothowto & RB_ASKNAME) { 1220 if (!vfs_mountroot_ask()) 1221 return; 1222 asked = 1; 1223 } 1224 1225 /* 1226 * The root filesystem information is compiled in, and we are 1227 * booted with instructions to use it. 1228 */ 1229 if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { 1230 if (!vfs_mountroot_try(ctrootdevname)) 1231 return; 1232 ctrootdevname = NULL; 1233 } 1234 1235 /* 1236 * We've been given the generic "use CDROM as root" flag. This is 1237 * necessary because one media may be used in many different 1238 * devices, so we need to search for them. 1239 */ 1240 if (boothowto & RB_CDROM) { 1241 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { 1242 if (!vfs_mountroot_try(cdrom_rootdevnames[i])) 1243 return; 1244 } 1245 } 1246 1247 /* 1248 * Try to use the value read by the loader from /etc/fstab, or 1249 * supplied via some other means. This is the preferred 1250 * mechanism. 1251 */ 1252 cp = getenv("vfs.root.mountfrom"); 1253 if (cp != NULL) { 1254 error = vfs_mountroot_try(cp); 1255 freeenv(cp); 1256 if (!error) 1257 return; 1258 } 1259 1260 /* 1261 * Try values that may have been computed by code during boot 1262 */ 1263 if (!vfs_mountroot_try(rootdevnames[0])) 1264 return; 1265 if (!vfs_mountroot_try(rootdevnames[1])) 1266 return; 1267 1268 /* 1269 * If we (still) have a compiled-in default, try it. 1270 */ 1271 if (ctrootdevname != NULL) 1272 if (!vfs_mountroot_try(ctrootdevname)) 1273 return; 1274 1275 /* 1276 * Everything so far has failed, prompt on the console if we haven't 1277 * already tried that. 1278 */ 1279 if (!asked) 1280 if (!vfs_mountroot_ask()) 1281 return; 1282 panic("Root mount failed, startup aborted."); 1283 } 1284 1285 /* 1286 * Mount (mountfrom) as the root filesystem. 1287 */ 1288 static int 1289 vfs_mountroot_try(const char *mountfrom) 1290 { 1291 struct mount *mp; 1292 char *vfsname, *path; 1293 int error; 1294 char patt[32]; 1295 int s; 1296 1297 vfsname = NULL; 1298 path = NULL; 1299 mp = NULL; 1300 error = EINVAL; 1301 1302 if (mountfrom == NULL) 1303 return (error); /* don't complain */ 1304 1305 s = splcam(); /* Overkill, but annoying without it */ 1306 printf("Mounting root from %s\n", mountfrom); 1307 splx(s); 1308 1309 /* parse vfs name and path */ 1310 vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK); 1311 path = malloc(MNAMELEN, M_MOUNT, M_WAITOK); 1312 vfsname[0] = path[0] = 0; 1313 sprintf(patt, "%%%d[a-z0-9]:%%%ds", MFSNAMELEN, MNAMELEN); 1314 if (sscanf(mountfrom, patt, vfsname, path) < 1) 1315 goto done; 1316 1317 /* allocate a root mount */ 1318 error = vfs_rootmountalloc(vfsname, path[0] != 0 ? path : ROOTNAME, 1319 &mp); 1320 if (error != 0) { 1321 printf("Can't allocate root mount for filesystem '%s': %d\n", 1322 vfsname, error); 1323 goto done; 1324 } 1325 1326 /* 1327 * do our best to set rootdev 1328 * XXX: This does not belong here! 1329 */ 1330 if (path[0] != '\0') { 1331 struct cdev *diskdev; 1332 diskdev = getdiskbyname(path); 1333 if (diskdev != NULL) 1334 rootdev = diskdev; 1335 else 1336 printf("setrootbyname failed\n"); 1337 } 1338 1339 error = VFS_OMOUNT(mp, path, NULL, curthread); 1340 1341 done: 1342 if (vfsname != NULL) 1343 free(vfsname, M_MOUNT); 1344 if (path != NULL) 1345 free(path, M_MOUNT); 1346 if (error != 0) { 1347 if (mp != NULL) 1348 vfs_mount_destroy(mp, curthread); 1349 printf("Root mount failed: %d\n", error); 1350 } else { 1351 1352 /* register with list of mounted filesystems */ 1353 mtx_lock(&mountlist_mtx); 1354 TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); 1355 mtx_unlock(&mountlist_mtx); 1356 1357 /* sanity check system clock against root fs timestamp */ 1358 inittodr(mp->mnt_time); 1359 vfs_unbusy(mp, curthread); 1360 error = VFS_START(mp, 0, curthread); 1361 } 1362 return (error); 1363 } 1364 1365 /* 1366 * Spin prompting on the console for a suitable root filesystem 1367 */ 1368 static int 1369 vfs_mountroot_ask(void) 1370 { 1371 char name[128]; 1372 1373 for(;;) { 1374 printf("\nManual root filesystem specification:\n"); 1375 printf(" <fstype>:<device> Mount <device> using filesystem <fstype>\n"); 1376 #if defined(__i386__) || defined(__ia64__) 1377 printf(" eg. ufs:da0s1a\n"); 1378 #else 1379 printf(" eg. ufs:/dev/da0a\n"); 1380 #endif 1381 printf(" ? List valid disk boot devices\n"); 1382 printf(" <empty line> Abort manual input\n"); 1383 printf("\nmountroot> "); 1384 gets(name); 1385 if (name[0] == '\0') 1386 return (1); 1387 if (name[0] == '?') { 1388 printf("\nList of GEOM managed disk devices:\n "); 1389 g_dev_print(); 1390 continue; 1391 } 1392 if (!vfs_mountroot_try(name)) 1393 return (0); 1394 } 1395 } 1396 1397 /* 1398 * Local helper function for vfs_mountroot_ask. 1399 */ 1400 static void 1401 gets(char *cp) 1402 { 1403 char *lp; 1404 int c; 1405 1406 lp = cp; 1407 for (;;) { 1408 printf("%c", c = cngetc() & 0177); 1409 switch (c) { 1410 case -1: 1411 case '\n': 1412 case '\r': 1413 *lp++ = '\0'; 1414 return; 1415 case '\b': 1416 case '\177': 1417 if (lp > cp) { 1418 printf(" \b"); 1419 lp--; 1420 } 1421 continue; 1422 case '#': 1423 lp--; 1424 if (lp < cp) 1425 lp = cp; 1426 continue; 1427 case '@': 1428 case 'u' & 037: 1429 lp = cp; 1430 printf("%c", '\n'); 1431 continue; 1432 default: 1433 *lp++ = c; 1434 } 1435 } 1436 } 1437 1438 /* 1439 * Convert a given name to the cdev pointer of the device, which is probably 1440 * but not by definition, a disk. Mount a DEVFS (on nothing), look the name 1441 * up, extract the cdev from the vnode and unmount it again. Unfortunately 1442 * we cannot use the vnode directly (because we unmount the DEVFS again) 1443 * so the filesystems still have to do the bdevvp() stunt. 1444 */ 1445 static struct cdev * 1446 getdiskbyname(char *name) 1447 { 1448 char *cp = name; 1449 struct cdev *dev = NULL; 1450 struct thread *td = curthread; 1451 struct vfsconf *vfsp; 1452 struct mount *mp = NULL; 1453 struct vnode *vroot = NULL; 1454 struct nameidata nid; 1455 int error; 1456 1457 if (!bcmp(cp, "/dev/", 5)) 1458 cp += 5; 1459 1460 do { 1461 vfsp = vfs_byname("devfs"); 1462 if (vfsp == NULL) 1463 break; 1464 error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp); 1465 if (error) 1466 break; 1467 mp->mnt_flag |= MNT_RDONLY; 1468 1469 error = VFS_MOUNT(mp, curthread); 1470 if (error) 1471 break; 1472 VFS_START(mp, 0, td); 1473 VFS_ROOT(mp, &vroot, td); 1474 VOP_UNLOCK(vroot, 0, td); 1475 1476 NDINIT(&nid, LOOKUP, NOCACHE|FOLLOW, 1477 UIO_SYSSPACE, cp, curthread); 1478 nid.ni_startdir = vroot; 1479 nid.ni_pathlen = strlen(cp); 1480 nid.ni_cnd.cn_cred = curthread->td_ucred; 1481 nid.ni_cnd.cn_nameptr = cp; 1482 1483 error = lookup(&nid); 1484 if (error) 1485 break; 1486 if (nid.ni_vp->v_type != VCHR) 1487 dev = NULL; 1488 else 1489 dev = nid.ni_vp->v_rdev; 1490 NDFREE(&nid, 0); 1491 } while (0); 1492 1493 if (vroot != NULL) 1494 VFS_UNMOUNT(mp, 0, td); 1495 if (mp != NULL) 1496 vfs_mount_destroy(mp, td); 1497 return (dev); 1498 } 1499 1500 /* Show the struct cdev *for a disk specified by name */ 1501 #ifdef DDB 1502 DB_SHOW_COMMAND(disk, db_getdiskbyname) 1503 { 1504 struct cdev *dev; 1505 1506 if (modif[0] == '\0') { 1507 db_error("usage: show disk/devicename"); 1508 return; 1509 } 1510 dev = getdiskbyname(modif); 1511 if (dev != NULL) 1512 db_printf("struct cdev *= %p\n", dev); 1513 else 1514 db_printf("No disk device matched.\n"); 1515 } 1516 #endif 1517 1518 /* 1519 * Get a mount option by its name. 1520 * 1521 * Return 0 if the option was found, ENOENT otherwise. 1522 * If len is non-NULL it will be filled with the length 1523 * of the option. If buf is non-NULL, it will be filled 1524 * with the address of the option. 1525 */ 1526 int 1527 vfs_getopt(opts, name, buf, len) 1528 struct vfsoptlist *opts; 1529 const char *name; 1530 void **buf; 1531 int *len; 1532 { 1533 struct vfsopt *opt; 1534 1535 KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL")); 1536 1537 TAILQ_FOREACH(opt, opts, link) { 1538 if (strcmp(name, opt->name) == 0) { 1539 if (len != NULL) 1540 *len = opt->len; 1541 if (buf != NULL) 1542 *buf = opt->value; 1543 return (0); 1544 } 1545 } 1546 return (ENOENT); 1547 } 1548 1549 /* 1550 * Find and copy a mount option. 1551 * 1552 * The size of the buffer has to be specified 1553 * in len, if it is not the same length as the 1554 * mount option, EINVAL is returned. 1555 * Returns ENOENT if the option is not found. 1556 */ 1557 int 1558 vfs_copyopt(opts, name, dest, len) 1559 struct vfsoptlist *opts; 1560 const char *name; 1561 void *dest; 1562 int len; 1563 { 1564 struct vfsopt *opt; 1565 1566 KASSERT(opts != NULL, ("vfs_copyopt: caller passed 'opts' as NULL")); 1567 1568 TAILQ_FOREACH(opt, opts, link) { 1569 if (strcmp(name, opt->name) == 0) { 1570 if (len != opt->len) 1571 return (EINVAL); 1572 bcopy(opt->value, dest, opt->len); 1573 return (0); 1574 } 1575 } 1576 return (ENOENT); 1577 } 1578 1579 1580 /* 1581 * This is a helper function for filesystems to traverse their 1582 * vnodes. See MNT_VNODE_FOREACH() in sys/mount.h 1583 */ 1584 1585 struct vnode * 1586 __mnt_vnode_next(struct vnode **nvp, struct mount *mp) 1587 { 1588 struct vnode *vp; 1589 1590 mtx_assert(&mp->mnt_mtx, MA_OWNED); 1591 vp = *nvp; 1592 /* Check if we are done */ 1593 if (vp == NULL) 1594 return (NULL); 1595 /* If our next vnode is no longer ours, start over */ 1596 if (vp->v_mount != mp) 1597 vp = TAILQ_FIRST(&mp->mnt_nvnodelist); 1598 /* Save pointer to next vnode in list */ 1599 if (vp != NULL) 1600 *nvp = TAILQ_NEXT(vp, v_nmntvnodes); 1601 else 1602 *nvp = NULL; 1603 return (vp); 1604 } 1605