NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/40169: Cannot hardwire root fs type if fs not built-in



>Number:         40169
>Category:       kern
>Synopsis:       Cannot hardwire root fs type if fs not built-in
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Dec 14 16:45:00 +0000 2008
>Originator:     Paul Goyette
>Release:        NetBSD 5.99.5
>Organization:
----------------------------------------------------------------------
|   Paul Goyette   | PGP DSS Key fingerprint: |  E-mail addresses:   |
| Customer Service | FA29 0E3B 35AF E8AE 6651 |  paul%whooppee.com@localhost   |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette%juniper.net@localhost |
----------------------------------------------------------------------
>Environment:
        
        
System: NetBSD quicky.whooppee.com 5.99.5 NetBSD 5.99.5 (QUICKY (ASUS M2N32 WS) 
2008-12-13 16:13:04) #3: Sat Dec 13 08:19:58 PST 2008 
paul%speedy.whooppee.com@localhost:/build/netbsd-local/obj/amd64/sys/arch/amd64/compile/QUICKY
 amd64
Architecture: x86_64
Machine: amd64
>Description:
Because the generated $COMPILE_DIR/swapnetbsd.d includes a direct (and
strong) reference to the xxx_mount_root() routine of the specified file-
system type, it is not possible to hardwire the fs-type in the config
file unless that file system is included directly in the kernel (rather
than being loaded as a module).
        
>How-To-Repeat:
Add 'config ... type ffs' to a MODULAR kernel, and remove 'filesystem FFS'. 
The kernel fails to build, with an undefined reference.
>Fix:
The following patch modifies config(1) to store the textual name of the
root fs type in swapnetbsd.c and changes the rest of the boot code to use
this type to lookup the appropriate xxx_mount_root() routine.


Index: sys/sys/systm.h
===================================================================
RCS file: /cvsroot/src/sys/sys/systm.h,v
retrieving revision 1.230
diff -u -p -r1.230 systm.h
--- sys/sys/systm.h     12 Nov 2008 14:29:31 -0000      1.230
+++ sys/sys/systm.h     30 Nov 2008 18:53:32 -0000
@@ -333,7 +333,7 @@ void        dopowerhooks(int);
  * these to be executed just before (*mountroot)() if the passed device is
  * selected as the root device.
  */
-extern int (*mountroot)(void);
+extern const char *rootfstype;
 void   *mountroothook_establish(void (*)(struct device *), struct device *);
 void   mountroothook_disestablish(void *);
 void   mountroothook_destroy(void);
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.357
diff -u -p -r1.357 vfs_subr.c
--- sys/kern/vfs_subr.c 24 Sep 2008 09:33:40 -0000      1.357
+++ sys/kern/vfs_subr.c 30 Nov 2008 18:53:33 -0000
@@ -2382,20 +2382,19 @@ vfs_mountroot(void)
        }
 
        /*
-        * If user specified a file system, use it.
-        */
-       if (mountroot != NULL) {
-               error = (*mountroot)();
-               goto done;
-       }
-
-       /*
         * Try each file system currently configured into the kernel.
         */
        mutex_enter(&vfs_list_lock);
        LIST_FOREACH(v, &vfs_list, vfs_list) {
                if (v->vfs_mountroot == NULL)
                        continue;
+               /*
+                * If user specified a file system type, use only
+                * that type
+                */
+               if (strcmp(rootfstype, "?") != 0 &&
+                   strcmp(rootfstype, v->vfs_name) != 0)
+                       continue;
 #ifdef DEBUG
                aprint_normal("mountroot: trying %s...\n", v->vfs_name);
 #endif
@@ -2420,7 +2419,6 @@ vfs_mountroot(void)
                error = EFTYPE;
        }
 
-done:
        if (error && device_class(root_device) == DV_DISK) {
                VOP_CLOSE(rootvp, FREAD, FSCRED);
                vrele(rootvp);
Index: sys/kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.196
diff -u -p -r1.196 kern_subr.c
--- sys/kern/kern_subr.c        27 Nov 2008 21:36:51 -0000      1.196
+++ sys/kern/kern_subr.c        30 Nov 2008 18:53:34 -0000
@@ -763,6 +763,7 @@ setroot(struct device *bootdv, int bootp
        struct ifnet *ifp;
        const char *deffsname;
        struct vfsops *vops;
+       static char my_vfs_name[MNAMELEN + 1];
 
 #ifdef TFTPROOT
        if (tftproot_dhcpboot(bootdv) != 0)
@@ -786,7 +787,7 @@ setroot(struct device *bootdv, int bootp
         * find a reasonable network interface for "rootspec".
         */
        vops = vfs_getopsbyname("nfs");
-       if (vops != NULL && vops->vfs_mountroot == mountroot &&
+       if (vops != NULL && strcmp(rootfstype, "nfs") == 0 &&
            rootspec == NULL &&
            (bootdv == NULL || device_class(bootdv) != DV_IFNET)) {
                IFNET_FOREACH(ifp) {
@@ -897,21 +898,23 @@ setroot(struct device *bootdv, int bootp
                for (vops = LIST_FIRST(&vfs_list); vops != NULL;
                     vops = LIST_NEXT(vops, vfs_list)) {
                        if (vops->vfs_mountroot != NULL &&
-                           vops->vfs_mountroot == mountroot)
+                           strcmp(rootfstype, vops->vfs_name) == 0)
                        break;
                }
 
-               if (vops == NULL) {
-                       mountroot = NULL;
+               if (vops == NULL)
                        deffsname = "generic";
-               } else
+               else
                        deffsname = vops->vfs_name;
 
                for (;;) {
                        printf("file system (default %s): ", deffsname);
                        len = cngetsn(buf, sizeof(buf));
-                       if (len == 0)
+                       if (len == 0) {
+                               if (strcmp(deffsname, "generic") == 0)
+                                       rootfstype = "?";
                                break;
+                       }
                        if (len == 4 && strcmp(buf, "halt") == 0)
                                cpu_reboot(RB_HALT, NULL);
                        else if (len == 6 && strcmp(buf, "reboot") == 0)
@@ -922,7 +925,7 @@ setroot(struct device *bootdv, int bootp
                        }
 #endif
                        else if (len == 7 && strcmp(buf, "generic") == 0) {
-                               mountroot = NULL;
+                               rootfstype = "?";
                                break;
                        }
                        vops = vfs_getopsbyname(buf);
@@ -934,12 +937,20 @@ setroot(struct device *bootdv, int bootp
                                        if (vops->vfs_mountroot != NULL)
                                                printf(" %s", vops->vfs_name);
                                }
+                               if (vops != NULL)
+                                       vfs_delref(vops);
 #if defined(DDB)
                                printf(" ddb");
 #endif
                                printf(" halt reboot\n");
                        } else {
-                               mountroot = vops->vfs_mountroot;
+                               /*
+                                * Copy vfs_name locally since *vops might
+                                * be deallocated.
+                                */
+                               strncpy(my_vfs_name, vops->vfs_name,
+                                       sizeof(my_vfs_name));
+                               rootfstype = my_vfs_name;
                                vfs_delref(vops);
                                break;
                        }
Index: sys/ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.99
diff -u -p -r1.99 mfs_vfsops.c
--- sys/ufs/mfs/mfs_vfsops.c    13 Nov 2008 11:10:41 -0000      1.99
+++ sys/ufs/mfs/mfs_vfsops.c    30 Nov 2008 18:53:34 -0000
@@ -253,7 +253,7 @@ mfs_initminiroot(void *base)
        if (fs->fs_magic != FS_UFS1_MAGIC || fs->fs_bsize > MAXBSIZE ||
            fs->fs_bsize < sizeof(struct fs))
                return (0);
-       mountroot = mfs_mountroot;
+       rootfstype = "mfs";
        mfs_rootbase = base;
        mfs_rootsize = fs->fs_fsize * fs->fs_size;
        rootdev = makedev(255, mfs_minor);
Index: sys/rump/librump/rumpvfs/vfsops_stub.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/vfsops_stub.c,v
retrieving revision 1.1
diff -u -p -r1.1 vfsops_stub.c
--- sys/rump/librump/rumpvfs/vfsops_stub.c      19 Nov 2008 14:10:49 -0000      
1.1
+++ sys/rump/librump/rumpvfs/vfsops_stub.c      30 Nov 2008 18:53:35 -0000
@@ -37,7 +37,7 @@
 #include <miscfs/fifofs/fifo.h>
 #include <miscfs/syncfs/syncfs.h>
 
-int (*mountroot)(void);
+const char *rootfstype;
 
 #define VFSSTUB(name)                                                  \
     int name(void *arg) {panic("%s: unimplemented vfs stub", __func__);}
Index: sys/arch/hpcmips/hpcmips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcmips/hpcmips/machdep.c,v
retrieving revision 1.99
diff -u -p -r1.99 machdep.c
--- sys/arch/hpcmips/hpcmips/machdep.c  30 Nov 2008 18:21:34 -0000      1.99
+++ sys/arch/hpcmips/hpcmips/machdep.c  30 Nov 2008 18:53:36 -0000
@@ -418,7 +418,7 @@ mach_init(int argc, char *argv[], struct
                                /* boot device: -b=sd0 etc. */
 #ifdef NFS
                                if (strcmp(cp+2, "nfs") == 0)
-                                       mountroot = nfs_mountroot;
+                                       rootfstype = "nfs";
                                else
                                        makebootdev(cp+2);
 #else /* NFS */
Index: sys/arch/hpcsh/hpcsh/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcsh/hpcsh/machdep.c,v
retrieving revision 1.65
diff -u -p -r1.65 machdep.c
--- sys/arch/hpcsh/hpcsh/machdep.c      30 Nov 2008 18:21:34 -0000      1.65
+++ sys/arch/hpcsh/hpcsh/machdep.c      30 Nov 2008 18:53:37 -0000
@@ -243,7 +243,7 @@ machine_startup(int argc, char *argv[], 
                        p = cp + 2;
 #ifdef NFS
                        if (strcmp(p, "nfs") == 0)
-                               mountroot = nfs_mountroot;
+                               rootfstype = "nfs";
                        else
                                makebootdev(p);
 #else /* NFS */
Index: sys/arch/hp300/hp300/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/hp300/autoconf.c,v
retrieving revision 1.91
diff -u -p -r1.91 autoconf.c
--- sys/arch/hp300/hp300/autoconf.c     22 Jun 2008 16:29:36 -0000      1.91
+++ sys/arch/hp300/hp300/autoconf.c     30 Nov 2008 18:53:37 -0000
@@ -381,7 +381,8 @@ cpu_rootconf(void)
         */
        if (rootspec == NULL) {
                vops = vfs_getopsbyname("nfs");
-               if (vops != NULL && vops->vfs_mountroot == mountroot) {
+               if (vops != NULL && vops->vfs_mountroot != NULL &&
+                   strcmp(rootfstype, "nfs") == 0) {
                        for (dd = LIST_FIRST(&dev_data_list);
                            dd != NULL; dd = LIST_NEXT(dd, dd_list)) {
                                if (device_class(dd->dd_dev) == DV_IFNET) {
@@ -395,6 +396,8 @@ cpu_rootconf(void)
                                dv = NULL;
                        }
                }
+               if (vops != NULL)
+                       vfs_delref(vops);
        }
 
        /*
Index: sys/arch/hpcarm/hpcarm/hpc_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpcarm/hpcarm/hpc_machdep.c,v
retrieving revision 1.89
diff -u -p -r1.89 hpc_machdep.c
--- sys/arch/hpcarm/hpcarm/hpc_machdep.c        30 Nov 2008 18:21:34 -0000      
1.89
+++ sys/arch/hpcarm/hpcarm/hpc_machdep.c        30 Nov 2008 18:53:38 -0000
@@ -364,7 +364,7 @@ initarm(int argc, char **argv, struct bo
                        cp = cp + 2;
 #ifdef NFS
                        if (strcmp(cp, "nfs") == 0)
-                               mountroot = nfs_mountroot;
+                               rootfstype = "nfs";
                        else
                                strncpy(boot_file, cp, sizeof(boot_file));
 #else /* !NFS */
Index: usr.bin/config/mkswap.c
===================================================================
RCS file: /cvsroot/src/usr.bin/config/mkswap.c,v
retrieving revision 1.4
diff -u -p -r1.4 mkswap.c
--- usr.bin/config/mkswap.c     12 Dec 2007 00:03:34 -0000      1.4
+++ usr.bin/config/mkswap.c     30 Nov 2008 18:53:40 -0000
@@ -133,14 +133,8 @@ mkoneswap(struct config *cf)
        /*
         * Emit the root file system.
         */
-       if (cf->cf_fstype == NULL)
-               strlcpy(specinfo, "NULL", sizeof(specinfo));
-       else {
-               snprintf(specinfo, sizeof(specinfo), "%s_mountroot",
-                   cf->cf_fstype);
-               fprintf(fp, "int %s(void);\n", specinfo);
-       }
-       fprintf(fp, "int (*mountroot)(void) = %s;\n", specinfo);
+       fprintf(fp, "const char *rootfstype = \"%s\";\n",
+               cf->cf_fstype ? cf->cf_fstype : "?");
 
        fflush(fp);
        if (ferror(fp))

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index