]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/kern/vfs_mountroot.c
MFC r368207,368607:
[FreeBSD/stable/10.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 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
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         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
786 static int
787 vfs_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
795 retry:
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
850 static void
851 vfs_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
897 static int
898 vfs_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
933 static void
934 vfs_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
961 void
962 vfs_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
1022 static struct mntarg *
1023 parse_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 }