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