1/*- 2 * Copyright (c) 2010 Marcel Moolenaar 3 * Copyright (c) 1999-2004 Poul-Henning Kamp 4 * Copyright (c) 1999 Michael Smith 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * (c) UNIX System Laboratories, Inc. 8 * All or some portions of this file are derived from material licensed 9 * to the University of California by American Telephone and Telegraph 10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 11 * the permission of UNIX System Laboratories, Inc. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38#include "opt_rootdevname.h" 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: stable/10/sys/kern/vfs_mountroot.c 331276 2018-03-20 22:57:14Z ian $"); 42 43#include <sys/param.h> 44#include <sys/conf.h> 45#include <sys/cons.h> 46#include <sys/fcntl.h> 47#include <sys/jail.h> 48#include <sys/kernel.h> 49#include <sys/malloc.h> 50#include <sys/mdioctl.h> 51#include <sys/mount.h> 52#include <sys/mutex.h> 53#include <sys/namei.h> 54#include <sys/priv.h> 55#include <sys/proc.h> 56#include <sys/filedesc.h> 57#include <sys/reboot.h> 58#include <sys/sbuf.h> 59#include <sys/stat.h> 60#include <sys/syscallsubr.h> 61#include <sys/sysproto.h> 62#include <sys/sx.h> 63#include <sys/sysctl.h> 64#include <sys/sysent.h> 65#include <sys/systm.h> 66#include <sys/vnode.h> 67 68#include <geom/geom.h> 69 70/* 71 * The root filesystem is detailed in the kernel environment variable 72 * vfs.root.mountfrom, which is expected to be in the general format 73 * 74 * <vfsname>:[<path>][ <vfsname>:[<path>] ...] 75 * vfsname := the name of a VFS known to the kernel and capable 76 * of being mounted as root 77 * path := disk device name or other data used by the filesystem 78 * to locate its physical store 79 * 80 * If the environment variable vfs.root.mountfrom is a space separated list, 81 * each list element is tried in turn and the root filesystem will be mounted 82 * from the first one that succeeds. 83 * 84 * The environment variable vfs.root.mountfrom.options is a comma delimited 85 * set of string mount options. These mount options must be parseable 86 * by nmount() in the kernel. 87 */ 88 89static int parse_mount(char **); 90static struct mntarg *parse_mountroot_options(struct mntarg *, const char *); 91 92/* 93 * The vnode of the system's root (/ in the filesystem, without chroot 94 * active.) 95 */ 96struct vnode *rootvnode; 97 98/* 99 * Mount of the system's /dev. 100 */ 101struct mount *rootdevmp; 102 103char *rootdevnames[2] = {NULL, NULL}; 104 105struct mtx root_holds_mtx; 106MTX_SYSINIT(root_holds, &root_holds_mtx, "root_holds", MTX_DEF); 107 108struct root_hold_token { 109 const char *who; 110 LIST_ENTRY(root_hold_token) list; 111}; 112 113static LIST_HEAD(, root_hold_token) root_holds = 114 LIST_HEAD_INITIALIZER(root_holds); 115 116enum action { 117 A_CONTINUE, 118 A_PANIC, 119 A_REBOOT, 120 A_RETRY 121}; 122 123static enum action root_mount_onfail = A_CONTINUE; 124 125static int root_mount_mddev; 126static int root_mount_complete; 127 128/* By default wait up to 3 seconds for devices to appear. */ 129static int root_mount_timeout = 3; 130TUNABLE_INT("vfs.mountroot.timeout", &root_mount_timeout); 131 132struct root_hold_token * 133root_mount_hold(const char *identifier) 134{ 135 struct root_hold_token *h; 136 137 if (root_mounted()) 138 return (NULL); 139 140 h = malloc(sizeof *h, M_DEVBUF, M_ZERO | M_WAITOK); 141 h->who = identifier; 142 mtx_lock(&root_holds_mtx); 143 LIST_INSERT_HEAD(&root_holds, h, list); 144 mtx_unlock(&root_holds_mtx); 145 return (h); 146} 147 148void 149root_mount_rel(struct root_hold_token *h) 150{ 151 152 if (h == NULL) 153 return; 154 mtx_lock(&root_holds_mtx); 155 LIST_REMOVE(h, list); 156 wakeup(&root_holds); 157 mtx_unlock(&root_holds_mtx); 158 free(h, M_DEVBUF); 159} 160 161int 162root_mounted(void) 163{ 164 165 /* No mutex is acquired here because int stores are atomic. */ 166 return (root_mount_complete); 167} 168 169void 170root_mount_wait(void) 171{ 172 173 /* 174 * Panic on an obvious deadlock - the function can't be called from 175 * a thread which is doing the whole SYSINIT stuff. 176 */ 177 KASSERT(curthread->td_proc->p_pid != 0, 178 ("root_mount_wait: cannot be called from the swapper thread")); 179 mtx_lock(&root_holds_mtx); 180 while (!root_mount_complete) { 181 msleep(&root_mount_complete, &root_holds_mtx, PZERO, "rootwait", 182 hz); 183 } 184 mtx_unlock(&root_holds_mtx); 185} 186 187static void 188set_rootvnode(void) 189{ 190 struct proc *p; 191 192 if (VFS_ROOT(TAILQ_FIRST(&mountlist), LK_EXCLUSIVE, &rootvnode)) 193 panic("Cannot find root vnode"); 194 195 VOP_UNLOCK(rootvnode, 0); 196 197 p = curthread->td_proc; 198 FILEDESC_XLOCK(p->p_fd); 199 200 if (p->p_fd->fd_cdir != NULL) 201 vrele(p->p_fd->fd_cdir); 202 p->p_fd->fd_cdir = rootvnode; 203 VREF(rootvnode); 204 205 if (p->p_fd->fd_rdir != NULL) 206 vrele(p->p_fd->fd_rdir); 207 p->p_fd->fd_rdir = rootvnode; 208 VREF(rootvnode); 209 210 FILEDESC_XUNLOCK(p->p_fd); 211} 212 213static int 214vfs_mountroot_devfs(struct thread *td, struct mount **mpp) 215{ 216 struct vfsoptlist *opts; 217 struct vfsconf *vfsp; 218 struct mount *mp; 219 int error; 220 221 *mpp = NULL; 222 223 if (rootdevmp != NULL) { 224 /* 225 * Already have /dev; this happens during rerooting. 226 */ 227 error = vfs_busy(rootdevmp, 0); 228 if (error != 0) 229 return (error); 230 *mpp = rootdevmp; 231 } else { 232 vfsp = vfs_byname("devfs"); 233 KASSERT(vfsp != NULL, ("Could not find devfs by name")); 234 if (vfsp == NULL) 235 return (ENOENT); 236 237 mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); 238 239 error = VFS_MOUNT(mp); 240 KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); 241 if (error) 242 return (error); 243 244 opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK); 245 TAILQ_INIT(opts); 246 mp->mnt_opt = opts; 247 248 mtx_lock(&mountlist_mtx); 249 TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); 250 mtx_unlock(&mountlist_mtx); 251 252 *mpp = mp; 253 rootdevmp = mp; 254 } 255 256 set_rootvnode(); 257 258 error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); 259 if (error) 260 printf("kern_symlink /dev -> / returns %d\n", error); 261 262 return (error); 263} 264 265static void 266vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs) 267{ 268 struct nameidata nd; 269 struct mount *mporoot, *mpnroot; 270 struct vnode *vp, *vporoot, *vpdevfs; 271 char *fspath; 272 int error; 273 274 mpnroot = TAILQ_NEXT(mpdevfs, mnt_list); 275 276 /* Shuffle the mountlist. */ 277 mtx_lock(&mountlist_mtx); 278 mporoot = TAILQ_FIRST(&mountlist); 279 TAILQ_REMOVE(&mountlist, mpdevfs, mnt_list); 280 if (mporoot != mpdevfs) { 281 TAILQ_REMOVE(&mountlist, mpnroot, mnt_list); 282 TAILQ_INSERT_HEAD(&mountlist, mpnroot, mnt_list); 283 } 284 TAILQ_INSERT_TAIL(&mountlist, mpdevfs, mnt_list); 285 mtx_unlock(&mountlist_mtx); 286 287 cache_purgevfs(mporoot); 288 if (mporoot != mpdevfs) 289 cache_purgevfs(mpdevfs); 290 291 VFS_ROOT(mporoot, LK_EXCLUSIVE, &vporoot); 292 293 VI_LOCK(vporoot); 294 vporoot->v_iflag &= ~VI_MOUNT; 295 VI_UNLOCK(vporoot); 296 vporoot->v_mountedhere = NULL; 297 mporoot->mnt_flag &= ~MNT_ROOTFS; 298 mporoot->mnt_vnodecovered = NULL; 299 vput(vporoot); 300 301 /* Set up the new rootvnode, and purge the cache */ 302 mpnroot->mnt_vnodecovered = NULL; 303 set_rootvnode(); 304 cache_purgevfs(rootvnode->v_mount); 305 306 if (mporoot != mpdevfs) { 307 /* Remount old root under /.mount or /mnt */ 308 fspath = "/.mount"; 309 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 310 fspath, td); 311 error = namei(&nd); 312 if (error) { 313 NDFREE(&nd, NDF_ONLY_PNBUF); 314 fspath = "/mnt"; 315 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, 316 fspath, td); 317 error = namei(&nd); 318 } 319 if (!error) { 320 vp = nd.ni_vp; 321 error = (vp->v_type == VDIR) ? 0 : ENOTDIR; 322 if (!error) 323 error = vinvalbuf(vp, V_SAVE, 0, 0); 324 if (!error) { 325 cache_purge(vp); 326 mporoot->mnt_vnodecovered = vp; 327 vp->v_mountedhere = mporoot; 328 strlcpy(mporoot->mnt_stat.f_mntonname, 329 fspath, MNAMELEN); 330 VOP_UNLOCK(vp, 0); 331 } else 332 vput(vp); 333 } 334 NDFREE(&nd, NDF_ONLY_PNBUF); 335 336 if (error && bootverbose) 337 printf("mountroot: unable to remount previous root " 338 "under /.mount or /mnt (error %d).\n", error); 339 } 340 341 /* Remount devfs under /dev */ 342 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev", td); 343 error = namei(&nd); 344 if (!error) { 345 vp = nd.ni_vp; 346 error = (vp->v_type == VDIR) ? 0 : ENOTDIR; 347 if (!error) 348 error = vinvalbuf(vp, V_SAVE, 0, 0); 349 if (!error) { 350 vpdevfs = mpdevfs->mnt_vnodecovered; 351 if (vpdevfs != NULL) { 352 cache_purge(vpdevfs); 353 vpdevfs->v_mountedhere = NULL; 354 vrele(vpdevfs); 355 } 356 mpdevfs->mnt_vnodecovered = vp; 357 vp->v_mountedhere = mpdevfs; 358 VOP_UNLOCK(vp, 0); 359 } else 360 vput(vp); 361 } 362 if (error && bootverbose) 363 printf("mountroot: unable to remount devfs under /dev " 364 "(error %d).\n", error); 365 NDFREE(&nd, NDF_ONLY_PNBUF); 366 367 if (mporoot == mpdevfs) { 368 vfs_unbusy(mpdevfs); 369 /* Unlink the no longer needed /dev/dev -> / symlink */ 370 error = kern_unlink(td, "/dev/dev", UIO_SYSSPACE); 371 if (error && bootverbose) 372 printf("mountroot: unable to unlink /dev/dev " 373 "(error %d)\n", error); 374 } 375} 376 377/* 378 * Configuration parser. 379 */ 380 381/* Parser character classes. */ 382#define CC_WHITESPACE -1 383#define CC_NONWHITESPACE -2 384 385/* Parse errors. */ 386#define PE_EOF -1 387#define PE_EOL -2 388 389static __inline int 390parse_peek(char **conf) 391{ 392 393 return (**conf); 394} 395 396static __inline void 397parse_poke(char **conf, int c) 398{ 399 400 **conf = c; 401} 402 403static __inline void 404parse_advance(char **conf) 405{ 406 407 (*conf)++; 408} 409 410static int 411parse_skipto(char **conf, int mc) 412{ 413 int c, match; 414 415 while (1) { 416 c = parse_peek(conf); 417 if (c == 0) 418 return (PE_EOF); 419 switch (mc) { 420 case CC_WHITESPACE: 421 match = (c == ' ' || c == '\t' || c == '\n') ? 1 : 0; 422 break; 423 case CC_NONWHITESPACE: 424 if (c == '\n') 425 return (PE_EOL); 426 match = (c != ' ' && c != '\t') ? 1 : 0; 427 break; 428 default: 429 match = (c == mc) ? 1 : 0; 430 break; 431 } 432 if (match) 433 break; 434 parse_advance(conf); 435 } 436 return (0); 437} 438 439static int 440parse_token(char **conf, char **tok) 441{ 442 char *p; 443 size_t len; 444 int error; 445 446 *tok = NULL; 447 error = parse_skipto(conf, CC_NONWHITESPACE); 448 if (error) 449 return (error); 450 p = *conf; 451 error = parse_skipto(conf, CC_WHITESPACE); 452 len = *conf - p; 453 *tok = malloc(len + 1, M_TEMP, M_WAITOK | M_ZERO); 454 bcopy(p, *tok, len); 455 return (0); 456} 457 458static void 459parse_dir_ask_printenv(const char *var) 460{ 461 char *val; 462 463 val = getenv(var); 464 if (val != NULL) { 465 printf(" %s=%s\n", var, val); 466 freeenv(val); 467 } 468} 469 470static int 471parse_dir_ask(char **conf) 472{ 473 char name[80]; 474 char *mnt; 475 int error; 476 477 printf("\nLoader variables:\n"); 478 parse_dir_ask_printenv("vfs.root.mountfrom"); 479 parse_dir_ask_printenv("vfs.root.mountfrom.options"); 480 481 printf("\nManual root filesystem specification:\n"); 482 printf(" <fstype>:<device> [options]\n"); 483 printf(" Mount <device> using filesystem <fstype>\n"); 484 printf(" and with the specified (optional) option list.\n"); 485 printf("\n"); 486 printf(" eg. ufs:/dev/da0s1a\n"); 487 printf(" zfs:tank\n"); 488 printf(" cd9660:/dev/acd0 ro\n"); 489 printf(" (which is equivalent to: "); 490 printf("mount -t cd9660 -o ro /dev/acd0 /)\n"); 491 printf("\n"); 492 printf(" ? List valid disk boot devices\n"); 493 printf(" . Yield 1 second (for background tasks)\n"); 494 printf(" <empty line> Abort manual input\n"); 495 496 do { 497 error = EINVAL; 498 printf("\nmountroot> "); 499 cngets(name, sizeof(name), GETS_ECHO); 500 if (name[0] == '\0') 501 break; 502 if (name[0] == '?' && name[1] == '\0') { 503 printf("\nList of GEOM managed disk devices:\n "); 504 g_dev_print(); 505 continue; 506 } 507 if (name[0] == '.' && name[1] == '\0') { 508 pause("rmask", hz); 509 continue; 510 } 511 mnt = name; 512 error = parse_mount(&mnt); 513 if (error == -1) 514 printf("Invalid file system specification.\n"); 515 } while (error != 0); 516 517 return (error); 518} 519 520static int 521parse_dir_md(char **conf) 522{ 523 struct stat sb; 524 struct thread *td; 525 struct md_ioctl *mdio; 526 char *path, *tok; 527 int error, fd, len; 528 529 td = curthread; 530 531 error = parse_token(conf, &tok); 532 if (error) 533 return (error); 534 535 len = strlen(tok); 536 mdio = malloc(sizeof(*mdio) + len + 1, M_TEMP, M_WAITOK | M_ZERO); 537 path = (void *)(mdio + 1); 538 bcopy(tok, path, len); 539 free(tok, M_TEMP); 540 541 /* Get file status. */ 542 error = kern_stat(td, path, UIO_SYSSPACE, &sb); 543 if (error) 544 goto out; 545 546 /* Open /dev/mdctl so that we can attach/detach. */ 547 error = kern_open(td, "/dev/" MDCTL_NAME, UIO_SYSSPACE, O_RDWR, 0); 548 if (error) 549 goto out; 550 551 fd = td->td_retval[0]; 552 mdio->md_version = MDIOVERSION; 553 mdio->md_type = MD_VNODE; 554 555 if (root_mount_mddev != -1) { 556 mdio->md_unit = root_mount_mddev; 557 DROP_GIANT(); 558 error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio); 559 PICKUP_GIANT(); 560 /* Ignore errors. We don't care. */ 561 root_mount_mddev = -1; 562 } 563 564 mdio->md_file = (void *)(mdio + 1); 565 mdio->md_options = MD_AUTOUNIT | MD_READONLY; 566 mdio->md_mediasize = sb.st_size; 567 mdio->md_unit = 0; 568 DROP_GIANT(); 569 error = kern_ioctl(td, fd, MDIOCATTACH, (void *)mdio); 570 PICKUP_GIANT(); 571 if (error) 572 goto out; 573 574 if (mdio->md_unit > 9) { 575 printf("rootmount: too many md units\n"); 576 mdio->md_file = NULL; 577 mdio->md_options = 0; 578 mdio->md_mediasize = 0; 579 DROP_GIANT(); 580 error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio); 581 PICKUP_GIANT(); 582 /* Ignore errors. We don't care. */ 583 error = ERANGE; 584 goto out; 585 } 586 587 root_mount_mddev = mdio->md_unit; 588 printf(MD_NAME "%u attached to %s\n", root_mount_mddev, mdio->md_file); 589 590 error = kern_close(td, fd); 591 592 out: 593 free(mdio, M_TEMP); 594 return (error); 595} 596 597static int 598parse_dir_onfail(char **conf) 599{ 600 char *action; 601 int error; 602 603 error = parse_token(conf, &action); 604 if (error) 605 return (error); 606 607 if (!strcmp(action, "continue")) 608 root_mount_onfail = A_CONTINUE; 609 else if (!strcmp(action, "panic")) 610 root_mount_onfail = A_PANIC; 611 else if (!strcmp(action, "reboot")) 612 root_mount_onfail = A_REBOOT; 613 else if (!strcmp(action, "retry")) 614 root_mount_onfail = A_RETRY; 615 else { 616 printf("rootmount: %s: unknown action\n", action); 617 error = EINVAL; 618 } 619 620 free(action, M_TEMP); 621 return (0); 622} 623 624static int 625parse_dir_timeout(char **conf) 626{ 627 char *tok, *endtok; 628 long secs; 629 int error; 630 631 error = parse_token(conf, &tok); 632 if (error) 633 return (error); 634 635 secs = strtol(tok, &endtok, 0); 636 error = (secs < 0 || *endtok != '\0') ? EINVAL : 0; 637 if (!error) 638 root_mount_timeout = secs; 639 free(tok, M_TEMP); 640 return (error); 641} 642 643static int 644parse_directive(char **conf) 645{ 646 char *dir; 647 int error; 648 649 error = parse_token(conf, &dir); 650 if (error) 651 return (error); 652 653 if (strcmp(dir, ".ask") == 0) 654 error = parse_dir_ask(conf); 655 else if (strcmp(dir, ".md") == 0) 656 error = parse_dir_md(conf); 657 else if (strcmp(dir, ".onfail") == 0) 658 error = parse_dir_onfail(conf); 659 else if (strcmp(dir, ".timeout") == 0) 660 error = parse_dir_timeout(conf); 661 else { 662 printf("mountroot: invalid directive `%s'\n", dir); 663 /* Ignore the rest of the line. */ 664 (void)parse_skipto(conf, '\n'); 665 error = EINVAL; 666 } 667 free(dir, M_TEMP); 668 return (error); 669} 670 671static int 672parse_mount_dev_present(const char *dev) 673{ 674 struct nameidata nd; 675 int error; 676 677 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, dev, curthread); 678 error = namei(&nd); 679 if (!error) 680 vput(nd.ni_vp); 681 NDFREE(&nd, NDF_ONLY_PNBUF); 682 return (error != 0) ? 0 : 1; 683} 684 685#define ERRMSGL 255 686static int 687parse_mount(char **conf) 688{ 689 char *errmsg; 690 struct mntarg *ma; 691 char *dev, *fs, *opts, *tok; 692 int delay, error, timeout; 693 694 error = parse_token(conf, &tok); 695 if (error) 696 return (error); 697 fs = tok; 698 error = parse_skipto(&tok, ':'); 699 if (error) { 700 free(fs, M_TEMP); 701 return (error); 702 } 703 parse_poke(&tok, '\0'); 704 parse_advance(&tok); 705 dev = tok; 706 707 if (root_mount_mddev != -1) { 708 /* Handle substitution for the md unit number. */ 709 tok = strstr(dev, "md#"); 710 if (tok != NULL) 711 tok[2] = '0' + root_mount_mddev; 712 } 713 714 /* Parse options. */ 715 error = parse_token(conf, &tok); 716 opts = (error == 0) ? tok : NULL; 717 718 printf("Trying to mount root from %s:%s [%s]...\n", fs, dev, 719 (opts != NULL) ? opts : ""); 720 721 errmsg = malloc(ERRMSGL, M_TEMP, M_WAITOK | M_ZERO); 722 723 if (vfs_byname(fs) == NULL) { 724 strlcpy(errmsg, "unknown file system", ERRMSGL); 725 error = ENOENT; 726 goto out; 727 } 728 729 if (strcmp(fs, "zfs") != 0 && strstr(fs, "nfs") == NULL && 730 dev[0] != '\0' && !parse_mount_dev_present(dev)) { 731 printf("mountroot: waiting for device %s ...\n", dev); 732 delay = hz / 10; 733 timeout = root_mount_timeout * hz; 734 do { 735 pause("rmdev", delay); 736 timeout -= delay; 737 } while (timeout > 0 && !parse_mount_dev_present(dev)); 738 if (timeout <= 0) { 739 error = ENODEV; 740 goto out; 741 } 742 } 743 744 delay = hz / 10; 745 timeout = root_mount_timeout * hz; 746 747 for (;;) { 748 ma = NULL; 749 ma = mount_arg(ma, "fstype", fs, -1); 750 ma = mount_arg(ma, "fspath", "/", -1); 751 ma = mount_arg(ma, "from", dev, -1); 752 ma = mount_arg(ma, "errmsg", errmsg, ERRMSGL); 753 ma = mount_arg(ma, "ro", NULL, 0); 754 ma = parse_mountroot_options(ma, opts); 755 756 error = kernel_mount(ma, MNT_ROOTFS); 757 if (error == 0 || timeout <= 0) 758 break; 759 760 if (root_mount_timeout * hz == timeout || 761 (bootverbose && timeout % hz == 0)) { 762 printf("Mounting from %s:%s failed with error %d; " 763 "retrying for %d more second%s\n", fs, dev, error, 764 timeout / hz, (timeout / hz > 1) ? "s" : ""); 765 } 766 pause("rmretry", delay); 767 timeout -= delay; 768 } 769 out: 770 if (error) { 771 printf("Mounting from %s:%s failed with error %d", 772 fs, dev, error); 773 if (errmsg[0] != '\0') 774 printf(": %s", errmsg); 775 printf(".\n"); 776 } 777 free(fs, M_TEMP); 778 free(errmsg, M_TEMP); 779 if (opts != NULL) 780 free(opts, M_TEMP); 781 /* kernel_mount can return -1 on error. */ 782 return ((error < 0) ? EDOOFUS : error); 783} 784#undef ERRMSGL 785 786static int 787vfs_mountroot_parse(struct sbuf *sb, struct mount *mpdevfs) 788{ 789 struct mount *mp; 790 char *conf; 791 int error; 792 793 root_mount_mddev = -1; 794 795retry: 796 conf = sbuf_data(sb); 797 mp = TAILQ_NEXT(mpdevfs, mnt_list); 798 error = (mp == NULL) ? 0 : EDOOFUS; 799 root_mount_onfail = A_CONTINUE; 800 while (mp == NULL) { 801 error = parse_skipto(&conf, CC_NONWHITESPACE); 802 if (error == PE_EOL) { 803 parse_advance(&conf); 804 continue; 805 } 806 if (error < 0) 807 break; 808 switch (parse_peek(&conf)) { 809 case '#': 810 error = parse_skipto(&conf, '\n'); 811 break; 812 case '.': 813 error = parse_directive(&conf); 814 break; 815 default: 816 error = parse_mount(&conf); 817 break; 818 } 819 if (error < 0) 820 break; 821 /* Ignore any trailing garbage on the line. */ 822 if (parse_peek(&conf) != '\n') { 823 printf("mountroot: advancing to next directive...\n"); 824 (void)parse_skipto(&conf, '\n'); 825 } 826 mp = TAILQ_NEXT(mpdevfs, mnt_list); 827 } 828 if (mp != NULL) 829 return (0); 830 831 /* 832 * We failed to mount (a new) root. 833 */ 834 switch (root_mount_onfail) { 835 case A_CONTINUE: 836 break; 837 case A_PANIC: 838 panic("mountroot: unable to (re-)mount root."); 839 /* NOTREACHED */ 840 case A_RETRY: 841 goto retry; 842 case A_REBOOT: 843 kern_reboot(RB_NOSYNC); 844 /* NOTREACHED */ 845 } 846 847 return (error); 848} 849 850static void 851vfs_mountroot_conf0(struct sbuf *sb) 852{ 853 char *s, *tok, *mnt, *opt; 854 int error; 855 856 sbuf_printf(sb, ".onfail panic\n"); 857 sbuf_printf(sb, ".timeout %d\n", root_mount_timeout); 858 if (boothowto & RB_ASKNAME) 859 sbuf_printf(sb, ".ask\n"); 860#ifdef ROOTDEVNAME 861 if (boothowto & RB_DFLTROOT) 862 sbuf_printf(sb, "%s\n", ROOTDEVNAME); 863#endif 864 if (boothowto & RB_CDROM) { 865 sbuf_printf(sb, "cd9660:/dev/cd0 ro\n"); 866 sbuf_printf(sb, ".timeout 0\n"); 867 sbuf_printf(sb, "cd9660:/dev/acd0 ro\n"); 868 sbuf_printf(sb, ".timeout %d\n", root_mount_timeout); 869 } 870 s = getenv("vfs.root.mountfrom"); 871 if (s != NULL) { 872 opt = getenv("vfs.root.mountfrom.options"); 873 tok = s; 874 error = parse_token(&tok, &mnt); 875 while (!error) { 876 sbuf_printf(sb, "%s %s\n", mnt, 877 (opt != NULL) ? opt : ""); 878 free(mnt, M_TEMP); 879 error = parse_token(&tok, &mnt); 880 } 881 if (opt != NULL) 882 freeenv(opt); 883 freeenv(s); 884 } 885 if (rootdevnames[0] != NULL) 886 sbuf_printf(sb, "%s\n", rootdevnames[0]); 887 if (rootdevnames[1] != NULL) 888 sbuf_printf(sb, "%s\n", rootdevnames[1]); 889#ifdef ROOTDEVNAME 890 if (!(boothowto & RB_DFLTROOT)) 891 sbuf_printf(sb, "%s\n", ROOTDEVNAME); 892#endif 893 if (!(boothowto & RB_ASKNAME)) 894 sbuf_printf(sb, ".ask\n"); 895} 896 897static int 898vfs_mountroot_readconf(struct thread *td, struct sbuf *sb) 899{ 900 static char buf[128]; 901 struct nameidata nd; 902 off_t ofs; 903 ssize_t resid; 904 int error, flags, len; 905 906 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/.mount.conf", td); 907 flags = FREAD; 908 error = vn_open(&nd, &flags, 0, NULL); 909 if (error) 910 return (error); 911 912 NDFREE(&nd, NDF_ONLY_PNBUF); 913 ofs = 0; 914 len = sizeof(buf) - 1; 915 while (1) { 916 error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs, 917 UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, 918 NOCRED, &resid, td); 919 if (error) 920 break; 921 if (resid == len) 922 break; 923 buf[len - resid] = 0; 924 sbuf_printf(sb, "%s", buf); 925 ofs += len - resid; 926 } 927 928 VOP_UNLOCK(nd.ni_vp, 0); 929 vn_close(nd.ni_vp, FREAD, td->td_ucred, td); 930 return (error); 931} 932 933static void 934vfs_mountroot_wait(void) 935{ 936 struct root_hold_token *h; 937 struct timeval lastfail; 938 int curfail; 939 940 curfail = 0; 941 while (1) { 942 DROP_GIANT(); 943 g_waitidle(); 944 PICKUP_GIANT(); 945 mtx_lock(&root_holds_mtx); 946 if (LIST_EMPTY(&root_holds)) { 947 mtx_unlock(&root_holds_mtx); 948 break; 949 } 950 if (ppsratecheck(&lastfail, &curfail, 1)) { 951 printf("Root mount waiting for:"); 952 LIST_FOREACH(h, &root_holds, list) 953 printf(" %s", h->who); 954 printf("\n"); 955 } 956 msleep(&root_holds, &root_holds_mtx, PZERO | PDROP, "roothold", 957 hz); 958 } 959} 960 961void 962vfs_mountroot(void) 963{ 964 struct mount *mp; 965 struct sbuf *sb; 966 struct thread *td; 967 time_t timebase; 968 int error; 969 970 td = curthread; 971 972 vfs_mountroot_wait(); 973 974 sb = sbuf_new_auto(); 975 vfs_mountroot_conf0(sb); 976 sbuf_finish(sb); 977 978 error = vfs_mountroot_devfs(td, &mp); 979 while (!error) { 980 error = vfs_mountroot_parse(sb, mp); 981 if (!error) { 982 vfs_mountroot_shuffle(td, mp); 983 sbuf_clear(sb); 984 error = vfs_mountroot_readconf(td, sb); 985 sbuf_finish(sb); 986 } 987 } 988 989 sbuf_delete(sb); 990 991 /* 992 * Iterate over all currently mounted file systems and use 993 * the time stamp found to check and/or initialize the RTC. 994 * Call inittodr() only once and pass it the largest of the 995 * timestamps we encounter. 996 */ 997 timebase = 0; 998 mtx_lock(&mountlist_mtx); 999 mp = TAILQ_FIRST(&mountlist); 1000 while (mp != NULL) { 1001 if (mp->mnt_time > timebase) 1002 timebase = mp->mnt_time; 1003 mp = TAILQ_NEXT(mp, mnt_list); 1004 } 1005 mtx_unlock(&mountlist_mtx); 1006 inittodr(timebase); 1007 1008 /* Keep prison0's root in sync with the global rootvnode. */ 1009 mtx_lock(&prison0.pr_mtx); 1010 prison0.pr_root = rootvnode; 1011 vref(prison0.pr_root); 1012 mtx_unlock(&prison0.pr_mtx); 1013 1014 mtx_lock(&root_holds_mtx); 1015 atomic_store_rel_int(&root_mount_complete, 1); 1016 wakeup(&root_mount_complete); 1017 mtx_unlock(&root_holds_mtx); 1018 1019 EVENTHANDLER_INVOKE(mountroot); 1020} 1021 1022static struct mntarg * 1023parse_mountroot_options(struct mntarg *ma, const char *options) 1024{ 1025 char *p; 1026 char *name, *name_arg; 1027 char *val, *val_arg; 1028 char *opts; 1029 1030 if (options == NULL || options[0] == '\0') 1031 return (ma); 1032 1033 p = opts = strdup(options, M_MOUNT); 1034 if (opts == NULL) { 1035 return (ma); 1036 } 1037 1038 while((name = strsep(&p, ",")) != NULL) { 1039 if (name[0] == '\0') 1040 break; 1041 1042 val = strchr(name, '='); 1043 if (val != NULL) { 1044 *val = '\0'; 1045 ++val; 1046 } 1047 if( strcmp(name, "rw") == 0 || 1048 strcmp(name, "noro") == 0) { 1049 /* 1050 * The first time we mount the root file system, 1051 * we need to mount 'ro', so We need to ignore 1052 * 'rw' and 'noro' mount options. 1053 */ 1054 continue; 1055 } 1056 name_arg = strdup(name, M_MOUNT); 1057 val_arg = NULL; 1058 if (val != NULL) 1059 val_arg = strdup(val, M_MOUNT); 1060 1061 ma = mount_arg(ma, name_arg, val_arg, 1062 (val_arg != NULL ? -1 : 0)); 1063 } 1064 free(opts, M_MOUNT); 1065 return (ma); 1066} 1067