]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/kern/vfs_mountroot.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / kern / vfs_mountroot.c
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$");
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 suceeds.
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
89 static int parse_mount(char **);
90 static 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  */
96 struct vnode *rootvnode;
97
98 /*
99  * Mount of the system's /dev.
100  */
101 struct mount *rootdevmp;
102
103 char *rootdevnames[2] = {NULL, NULL};
104
105 struct mtx root_holds_mtx;
106 MTX_SYSINIT(root_holds, &root_holds_mtx, "root_holds", MTX_DEF);
107
108 struct root_hold_token {
109         const char                      *who;
110         LIST_ENTRY(root_hold_token)     list;
111 };
112
113 static LIST_HEAD(, root_hold_token)     root_holds =
114     LIST_HEAD_INITIALIZER(root_holds);
115
116 enum action {
117         A_CONTINUE,
118         A_PANIC,
119         A_REBOOT,
120         A_RETRY
121 };
122
123 static enum action root_mount_onfail = A_CONTINUE;
124
125 static int root_mount_mddev;
126 static int root_mount_complete;
127
128 /* By default wait up to 3 seconds for devices to appear. */
129 static int root_mount_timeout = 3;
130 TUNABLE_INT("vfs.mountroot.timeout", &root_mount_timeout);
131
132 struct root_hold_token *
133 root_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
148 void
149 root_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
161 int
162 root_mounted(void)
163 {
164
165         /* No mutex is acquired here because int stores are atomic. */
166         return (root_mount_complete);
167 }
168
169 void
170 root_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
187 static void
188 set_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
213 static int
214 vfs_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
265 static void
266 vfs_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
389 static __inline int
390 parse_peek(char **conf)
391 {
392
393         return (**conf);
394 }
395
396 static __inline void
397 parse_poke(char **conf, int c)
398 {
399
400         **conf = c;
401 }
402
403 static __inline void
404 parse_advance(char **conf)
405 {
406
407         (*conf)++;
408 }
409
410 static int
411 parse_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
439 static int
440 parse_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
458 static void
459 parse_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
470 static int
471 parse_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
520 static int
521 parse_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
597 static int
598 parse_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
624 static int
625 parse_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
643 static int
644 parse_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
671 static int
672 parse_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
686 static int
687 parse_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         ma = NULL;
745         ma = mount_arg(ma, "fstype", fs, -1);
746         ma = mount_arg(ma, "fspath", "/", -1);
747         ma = mount_arg(ma, "from", dev, -1);
748         ma = mount_arg(ma, "errmsg", errmsg, ERRMSGL);
749         ma = mount_arg(ma, "ro", NULL, 0);
750         ma = parse_mountroot_options(ma, opts);
751         error = kernel_mount(ma, MNT_ROOTFS);
752
753  out:
754         if (error) {
755                 printf("Mounting from %s:%s failed with error %d",
756                     fs, dev, error);
757                 if (errmsg[0] != '\0')
758                         printf(": %s", errmsg);
759                 printf(".\n");
760         }
761         free(fs, M_TEMP);
762         free(errmsg, M_TEMP);
763         if (opts != NULL)
764                 free(opts, M_TEMP);
765         /* kernel_mount can return -1 on error. */
766         return ((error < 0) ? EDOOFUS : error);
767 }
768 #undef ERRMSGL
769
770 static int
771 vfs_mountroot_parse(struct sbuf *sb, struct mount *mpdevfs)
772 {
773         struct mount *mp;
774         char *conf;
775         int error;
776
777         root_mount_mddev = -1;
778
779 retry:
780         conf = sbuf_data(sb);
781         mp = TAILQ_NEXT(mpdevfs, mnt_list);
782         error = (mp == NULL) ? 0 : EDOOFUS;
783         root_mount_onfail = A_CONTINUE;
784         while (mp == NULL) {
785                 error = parse_skipto(&conf, CC_NONWHITESPACE);
786                 if (error == PE_EOL) {
787                         parse_advance(&conf);
788                         continue;
789                 }
790                 if (error < 0)
791                         break;
792                 switch (parse_peek(&conf)) {
793                 case '#':
794                         error = parse_skipto(&conf, '\n');
795                         break;
796                 case '.':
797                         error = parse_directive(&conf);
798                         break;
799                 default:
800                         error = parse_mount(&conf);
801                         break;
802                 }
803                 if (error < 0)
804                         break;
805                 /* Ignore any trailing garbage on the line. */
806                 if (parse_peek(&conf) != '\n') {
807                         printf("mountroot: advancing to next directive...\n");
808                         (void)parse_skipto(&conf, '\n');
809                 }
810                 mp = TAILQ_NEXT(mpdevfs, mnt_list);
811         }
812         if (mp != NULL)
813                 return (0);
814
815         /*
816          * We failed to mount (a new) root.
817          */
818         switch (root_mount_onfail) {
819         case A_CONTINUE:
820                 break;
821         case A_PANIC:
822                 panic("mountroot: unable to (re-)mount root.");
823                 /* NOTREACHED */
824         case A_RETRY:
825                 goto retry;
826         case A_REBOOT:
827                 kern_reboot(RB_NOSYNC);
828                 /* NOTREACHED */
829         }
830
831         return (error);
832 }
833
834 static void
835 vfs_mountroot_conf0(struct sbuf *sb)
836 {
837         char *s, *tok, *mnt, *opt;
838         int error;
839
840         sbuf_printf(sb, ".onfail panic\n");
841         sbuf_printf(sb, ".timeout %d\n", root_mount_timeout);
842         if (boothowto & RB_ASKNAME)
843                 sbuf_printf(sb, ".ask\n");
844 #ifdef ROOTDEVNAME
845         if (boothowto & RB_DFLTROOT)
846                 sbuf_printf(sb, "%s\n", ROOTDEVNAME);
847 #endif
848         if (boothowto & RB_CDROM) {
849                 sbuf_printf(sb, "cd9660:/dev/cd0 ro\n");
850                 sbuf_printf(sb, ".timeout 0\n");
851                 sbuf_printf(sb, "cd9660:/dev/acd0 ro\n");
852                 sbuf_printf(sb, ".timeout %d\n", root_mount_timeout);
853         }
854         s = getenv("vfs.root.mountfrom");
855         if (s != NULL) {
856                 opt = getenv("vfs.root.mountfrom.options");
857                 tok = s;
858                 error = parse_token(&tok, &mnt);
859                 while (!error) {
860                         sbuf_printf(sb, "%s %s\n", mnt,
861                             (opt != NULL) ? opt : "");
862                         free(mnt, M_TEMP);
863                         error = parse_token(&tok, &mnt);
864                 }
865                 if (opt != NULL)
866                         freeenv(opt);
867                 freeenv(s);
868         }
869         if (rootdevnames[0] != NULL)
870                 sbuf_printf(sb, "%s\n", rootdevnames[0]);
871         if (rootdevnames[1] != NULL)
872                 sbuf_printf(sb, "%s\n", rootdevnames[1]);
873 #ifdef ROOTDEVNAME
874         if (!(boothowto & RB_DFLTROOT))
875                 sbuf_printf(sb, "%s\n", ROOTDEVNAME);
876 #endif
877         if (!(boothowto & RB_ASKNAME))
878                 sbuf_printf(sb, ".ask\n");
879 }
880
881 static int
882 vfs_mountroot_readconf(struct thread *td, struct sbuf *sb)
883 {
884         static char buf[128];
885         struct nameidata nd;
886         off_t ofs;
887         ssize_t resid;
888         int error, flags, len;
889
890         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/.mount.conf", td);
891         flags = FREAD;
892         error = vn_open(&nd, &flags, 0, NULL);
893         if (error)
894                 return (error);
895
896         NDFREE(&nd, NDF_ONLY_PNBUF);
897         ofs = 0;
898         len = sizeof(buf) - 1;
899         while (1) {
900                 error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
901                     UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
902                     NOCRED, &resid, td);
903                 if (error)
904                         break;
905                 if (resid == len)
906                         break;
907                 buf[len - resid] = 0;
908                 sbuf_printf(sb, "%s", buf);
909                 ofs += len - resid;
910         }
911
912         VOP_UNLOCK(nd.ni_vp, 0);
913         vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
914         return (error);
915 }
916
917 static void
918 vfs_mountroot_wait(void)
919 {
920         struct root_hold_token *h;
921         struct timeval lastfail;
922         int curfail;
923
924         curfail = 0;
925         while (1) {
926                 DROP_GIANT();
927                 g_waitidle();
928                 PICKUP_GIANT();
929                 mtx_lock(&root_holds_mtx);
930                 if (LIST_EMPTY(&root_holds)) {
931                         mtx_unlock(&root_holds_mtx);
932                         break;
933                 }
934                 if (ppsratecheck(&lastfail, &curfail, 1)) {
935                         printf("Root mount waiting for:");
936                         LIST_FOREACH(h, &root_holds, list)
937                                 printf(" %s", h->who);
938                         printf("\n");
939                 }
940                 msleep(&root_holds, &root_holds_mtx, PZERO | PDROP, "roothold",
941                     hz);
942         }
943 }
944
945 void
946 vfs_mountroot(void)
947 {
948         struct mount *mp;
949         struct sbuf *sb;
950         struct thread *td;
951         time_t timebase;
952         int error;
953
954         td = curthread;
955
956         vfs_mountroot_wait();
957
958         sb = sbuf_new_auto();
959         vfs_mountroot_conf0(sb);
960         sbuf_finish(sb);
961
962         error = vfs_mountroot_devfs(td, &mp);
963         while (!error) {
964                 error = vfs_mountroot_parse(sb, mp);
965                 if (!error) {
966                         vfs_mountroot_shuffle(td, mp);
967                         sbuf_clear(sb);
968                         error = vfs_mountroot_readconf(td, sb);
969                         sbuf_finish(sb);
970                 }
971         }
972
973         sbuf_delete(sb);
974
975         /*
976          * Iterate over all currently mounted file systems and use
977          * the time stamp found to check and/or initialize the RTC.
978          * Call inittodr() only once and pass it the largest of the
979          * timestamps we encounter.
980          */
981         timebase = 0;
982         mtx_lock(&mountlist_mtx);
983         mp = TAILQ_FIRST(&mountlist);
984         while (mp != NULL) {
985                 if (mp->mnt_time > timebase)
986                         timebase = mp->mnt_time;
987                 mp = TAILQ_NEXT(mp, mnt_list);
988         }
989         mtx_unlock(&mountlist_mtx);
990         inittodr(timebase);
991
992         /* Keep prison0's root in sync with the global rootvnode. */
993         mtx_lock(&prison0.pr_mtx);
994         prison0.pr_root = rootvnode;
995         vref(prison0.pr_root);
996         mtx_unlock(&prison0.pr_mtx);
997
998         mtx_lock(&root_holds_mtx);
999         atomic_store_rel_int(&root_mount_complete, 1);
1000         wakeup(&root_mount_complete);
1001         mtx_unlock(&root_holds_mtx);
1002
1003         EVENTHANDLER_INVOKE(mountroot);
1004 }
1005
1006 static struct mntarg *
1007 parse_mountroot_options(struct mntarg *ma, const char *options)
1008 {
1009         char *p;
1010         char *name, *name_arg;
1011         char *val, *val_arg;
1012         char *opts;
1013
1014         if (options == NULL || options[0] == '\0')
1015                 return (ma);
1016
1017         p = opts = strdup(options, M_MOUNT);
1018         if (opts == NULL) {
1019                 return (ma);
1020         }
1021
1022         while((name = strsep(&p, ",")) != NULL) {
1023                 if (name[0] == '\0')
1024                         break;
1025
1026                 val = strchr(name, '=');
1027                 if (val != NULL) {
1028                         *val = '\0';
1029                         ++val;
1030                 }
1031                 if( strcmp(name, "rw") == 0 ||
1032                     strcmp(name, "noro") == 0) {
1033                         /*
1034                          * The first time we mount the root file system,
1035                          * we need to mount 'ro', so We need to ignore
1036                          * 'rw' and 'noro' mount options.
1037                          */
1038                         continue;
1039                 }
1040                 name_arg = strdup(name, M_MOUNT);
1041                 val_arg = NULL;
1042                 if (val != NULL)
1043                         val_arg = strdup(val, M_MOUNT);
1044
1045                 ma = mount_arg(ma, name_arg, val_arg,
1046                     (val_arg != NULL ? -1 : 0));
1047         }
1048         free(opts, M_MOUNT);
1049         return (ma);
1050 }