diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/autoconf.c | 92 | ||||
-rw-r--r-- | sys/i386/i386/autoconf.c | 92 | ||||
-rw-r--r-- | sys/kern/vfs_conf.c | 44 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 44 | ||||
-rw-r--r-- | sys/sys/systm.h | 4 |
5 files changed, 155 insertions, 121 deletions
diff --git a/sys/amd64/amd64/autoconf.c b/sys/amd64/amd64/autoconf.c index f6177fb..f7c0960 100644 --- a/sys/amd64/amd64/autoconf.c +++ b/sys/amd64/amd64/autoconf.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 - * $Id: autoconf.c,v 1.96 1998/05/06 22:14:40 julian Exp $ + * $Id: autoconf.c,v 1.97 1998/05/12 17:33:58 bde Exp $ */ /* @@ -56,9 +56,10 @@ #include <sys/systm.h> #include <sys/conf.h> #include <sys/disklabel.h> -#include <sys/diskslice.h> /* for BASE_SLICE, MAX_SLICES */ +#include <sys/diskslice.h> #include <sys/reboot.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/mount.h> #include <sys/sysctl.h> @@ -70,7 +71,7 @@ #include <machine/smp.h> #endif /* APIC_IO */ -#include <i386/isa/icu.h> /* For interrupts */ +#include <i386/isa/icu.h> #include "isa.h" #if NISA > 0 @@ -137,7 +138,6 @@ static struct { static int find_cdrom_root __P((void)); - static int find_cdrom_root() { @@ -383,7 +383,7 @@ cpu_rootconf() setconf(); } -#endif +#endif /* !SLICE */ void cpu_dumpconf() @@ -432,69 +432,73 @@ setdumpdev(dev) u_long bootdev = 0; /* not a dev_t - encoding is different */ -/* Name lookup for bootable majors XXX extend me */ -static char *devname[] = { - "wd", - "wfd", #define FDMAJOR 2 - "fd", - "wt", - "sd", - "st", - "cd", -}; - -#define PARTITIONMASK 0x7 -#define PARTITIONSHIFT 3 #define FDUNITSHIFT 6 -#define RAW_PART 2 /* * Attempt to find the device from which we were booted. * If we can do so, and not instructed not to do so, - * change rootdev to correspond to the load device. + * set rootdevs[] and rootdevnames[] to correspond to the + * boot device(s). */ static void setroot() { - int majdev, mindev, unit, part, adaptor, slice; - dev_t orootdev; - char *sname, partname[2]; + int majdev, mindev, unit, slice, part; + dev_t newrootdev; + char partname[2]; + char *sname; -/*printf("howto %x bootdev %x ", boothowto, bootdev);*/ - if (boothowto & RB_DFLTROOT || - (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) + if (boothowto & RB_DFLTROOT || (bootdev & B_MAGICMASK) != B_DEVMAGIC) + return; + majdev = B_TYPE(bootdev); + if (bdevsw[majdev] == NULL) return; - majdev = B_TYPE(bootdev); - adaptor = B_ADAPTOR(bootdev); - unit = B_UNIT(bootdev); - slice = B_SLICE(bootdev); - if ((slice < BASE_SLICE) || (slice >= MAX_SLICES)) + unit = B_UNIT(bootdev); + slice = B_SLICE(bootdev); + if (slice == WHOLE_DISK_SLICE) slice = COMPATIBILITY_SLICE; - if (majdev > sizeof(devname) / sizeof(devname[0])) + if (slice < 0 || slice >= MAX_SLICES) return; + + /* + * XXX kludge for inconsistent unit numbering and lack of slice + * support for floppies. + */ if (majdev == FDMAJOR) { + slice = COMPATIBILITY_SLICE; part = RAW_PART; mindev = unit << FDUNITSHIFT; - } - else { - part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; + } else { + part = B_PARTITION(bootdev); mindev = dkmakeminor(unit, slice, part); } - orootdev = rootdev; - rootdev = makedev(majdev, mindev); + + newrootdev = makedev(majdev, mindev); + rootdevs[0] = newrootdev; + sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); + rootdevnames[0] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); + sprintf(rootdevnames[0], "%s%s", sname, partname); + /* - * If the original rootdev is the same as the one - * just calculated modulo the slice number, don't print an otherwise - * confusing diagnostic. + * For properly dangerously dedicated disks (ones with a historical + * bogus partition table), the boot blocks will give slice = 4, but + * the kernel will only provide the compatibility slice since it + * knows that slice 4 is not a real slice. Arrange to try mounting + * the compatibility slice as root if mounting the slice passed by + * the boot blocks fails. This handles the dangerously dedicated + * case and perhaps others. */ - if ((rootdev & ~0xff0000) == (orootdev & ~0xff0000)) + if (slice == COMPATIBILITY_SLICE) return; - sname = dsname(devname[majdev], unit, slice, part, partname); - printf("changing root device to %s%s\n", sname, partname); + slice = COMPATIBILITY_SLICE; + rootdevs[1] = dkmodslice(newrootdev, slice); + sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); + rootdevnames[1] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); + sprintf(rootdevnames[1], "%s%s", sname, partname); } -#endif +#endif /* !SLICE */ static int sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c index f6177fb..f7c0960 100644 --- a/sys/i386/i386/autoconf.c +++ b/sys/i386/i386/autoconf.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 - * $Id: autoconf.c,v 1.96 1998/05/06 22:14:40 julian Exp $ + * $Id: autoconf.c,v 1.97 1998/05/12 17:33:58 bde Exp $ */ /* @@ -56,9 +56,10 @@ #include <sys/systm.h> #include <sys/conf.h> #include <sys/disklabel.h> -#include <sys/diskslice.h> /* for BASE_SLICE, MAX_SLICES */ +#include <sys/diskslice.h> #include <sys/reboot.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/mount.h> #include <sys/sysctl.h> @@ -70,7 +71,7 @@ #include <machine/smp.h> #endif /* APIC_IO */ -#include <i386/isa/icu.h> /* For interrupts */ +#include <i386/isa/icu.h> #include "isa.h" #if NISA > 0 @@ -137,7 +138,6 @@ static struct { static int find_cdrom_root __P((void)); - static int find_cdrom_root() { @@ -383,7 +383,7 @@ cpu_rootconf() setconf(); } -#endif +#endif /* !SLICE */ void cpu_dumpconf() @@ -432,69 +432,73 @@ setdumpdev(dev) u_long bootdev = 0; /* not a dev_t - encoding is different */ -/* Name lookup for bootable majors XXX extend me */ -static char *devname[] = { - "wd", - "wfd", #define FDMAJOR 2 - "fd", - "wt", - "sd", - "st", - "cd", -}; - -#define PARTITIONMASK 0x7 -#define PARTITIONSHIFT 3 #define FDUNITSHIFT 6 -#define RAW_PART 2 /* * Attempt to find the device from which we were booted. * If we can do so, and not instructed not to do so, - * change rootdev to correspond to the load device. + * set rootdevs[] and rootdevnames[] to correspond to the + * boot device(s). */ static void setroot() { - int majdev, mindev, unit, part, adaptor, slice; - dev_t orootdev; - char *sname, partname[2]; + int majdev, mindev, unit, slice, part; + dev_t newrootdev; + char partname[2]; + char *sname; -/*printf("howto %x bootdev %x ", boothowto, bootdev);*/ - if (boothowto & RB_DFLTROOT || - (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) + if (boothowto & RB_DFLTROOT || (bootdev & B_MAGICMASK) != B_DEVMAGIC) + return; + majdev = B_TYPE(bootdev); + if (bdevsw[majdev] == NULL) return; - majdev = B_TYPE(bootdev); - adaptor = B_ADAPTOR(bootdev); - unit = B_UNIT(bootdev); - slice = B_SLICE(bootdev); - if ((slice < BASE_SLICE) || (slice >= MAX_SLICES)) + unit = B_UNIT(bootdev); + slice = B_SLICE(bootdev); + if (slice == WHOLE_DISK_SLICE) slice = COMPATIBILITY_SLICE; - if (majdev > sizeof(devname) / sizeof(devname[0])) + if (slice < 0 || slice >= MAX_SLICES) return; + + /* + * XXX kludge for inconsistent unit numbering and lack of slice + * support for floppies. + */ if (majdev == FDMAJOR) { + slice = COMPATIBILITY_SLICE; part = RAW_PART; mindev = unit << FDUNITSHIFT; - } - else { - part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; + } else { + part = B_PARTITION(bootdev); mindev = dkmakeminor(unit, slice, part); } - orootdev = rootdev; - rootdev = makedev(majdev, mindev); + + newrootdev = makedev(majdev, mindev); + rootdevs[0] = newrootdev; + sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); + rootdevnames[0] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); + sprintf(rootdevnames[0], "%s%s", sname, partname); + /* - * If the original rootdev is the same as the one - * just calculated modulo the slice number, don't print an otherwise - * confusing diagnostic. + * For properly dangerously dedicated disks (ones with a historical + * bogus partition table), the boot blocks will give slice = 4, but + * the kernel will only provide the compatibility slice since it + * knows that slice 4 is not a real slice. Arrange to try mounting + * the compatibility slice as root if mounting the slice passed by + * the boot blocks fails. This handles the dangerously dedicated + * case and perhaps others. */ - if ((rootdev & ~0xff0000) == (orootdev & ~0xff0000)) + if (slice == COMPATIBILITY_SLICE) return; - sname = dsname(devname[majdev], unit, slice, part, partname); - printf("changing root device to %s%s\n", sname, partname); + slice = COMPATIBILITY_SLICE; + rootdevs[1] = dkmodslice(newrootdev, slice); + sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); + rootdevnames[1] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); + sprintf(rootdevnames[1], "%s%s", sname, partname); } -#endif +#endif /* !SLICE */ static int sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c index 01f4800..3bbc406 100644 --- a/sys/kern/vfs_conf.c +++ b/sys/kern/vfs_conf.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id: vfs_conf.c,v 1.23 1998/04/19 23:31:57 julian Exp $ + * $Id: vfs_conf.c,v 1.24 1998/04/20 03:57:30 julian Exp $ */ /* @@ -71,15 +71,16 @@ MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount struct"); /* * These define the root filesystem, device, and root filesystem type. */ -static struct mount *rootfs; +dev_t rootdevs[] = { NODEV, NODEV }; +char *rootdevnames[2]; struct vnode *rootvnode; char *mountrootfsname; #ifdef SLICE char rootdevice[32]; -#endif /* SLICE */ +#endif #ifdef BOOTP extern void bootpc_init __P((void)); -#endif /* BOOTP */ +#endif /* * vfs_init() will set maxvfsconf @@ -119,8 +120,9 @@ static void vfs_mountrootfs(void *unused) { struct mount *mp; - int err = 0; + int i, err; struct proc *p = curproc; /* XXX */ + dev_t orootdev; #ifdef BOOTP bootpc_init(); @@ -138,20 +140,30 @@ vfs_mountrootfs(void *unused) /* * Attempt the mount */ - err = VFS_MOUNT(mp, NULL, NULL, NULL, p); - /* - * rootdev may be bogus (slice field may be incorrect for disks) - * If slice field is nonzero, clear and retry. - * - * XXX Implicit knowledge of device minor number layout. - * This is placeholder code until saner root mounts arrive with - * DEVFS. - */ - if ((err == ENXIO) && (rootdev & 0xff0000)) { - rootdev &= ~0xff0000; + err = ENXIO; + orootdev = rootdev; + if (rootdevs[0] == NODEV) + rootdevs[0] = rootdev; + for (i = 0; i < sizeof(rootdevs) / sizeof(rootdevs[0]); i++) { + if (rootdevs[i] == NODEV) + break; + rootdev = rootdevs[i]; + if (rootdev != orootdev) { + printf("changing root device to %s\n", rootdevnames[i]); + orootdev = rootdev; + } + strncpy(mp->mnt_stat.f_mntfromname, + rootdevnames[i] ? rootdevnames[i] : ROOTNAME, MNAMELEN - 1); err = VFS_MOUNT(mp, NULL, NULL, NULL, p); + if (err != ENXIO) + break; } if (err) { + /* + * XXX should ask the user for the name in some cases. + * Why do we call vfs_unbusy() here and not after ENXIO + * is returned above? + */ vfs_unbusy(mp, p); /* * free mount struct before failing diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 01f4800..3bbc406 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * @(#)vfs_conf.c 8.8 (Berkeley) 3/31/94 - * $Id: vfs_conf.c,v 1.23 1998/04/19 23:31:57 julian Exp $ + * $Id: vfs_conf.c,v 1.24 1998/04/20 03:57:30 julian Exp $ */ /* @@ -71,15 +71,16 @@ MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount struct"); /* * These define the root filesystem, device, and root filesystem type. */ -static struct mount *rootfs; +dev_t rootdevs[] = { NODEV, NODEV }; +char *rootdevnames[2]; struct vnode *rootvnode; char *mountrootfsname; #ifdef SLICE char rootdevice[32]; -#endif /* SLICE */ +#endif #ifdef BOOTP extern void bootpc_init __P((void)); -#endif /* BOOTP */ +#endif /* * vfs_init() will set maxvfsconf @@ -119,8 +120,9 @@ static void vfs_mountrootfs(void *unused) { struct mount *mp; - int err = 0; + int i, err; struct proc *p = curproc; /* XXX */ + dev_t orootdev; #ifdef BOOTP bootpc_init(); @@ -138,20 +140,30 @@ vfs_mountrootfs(void *unused) /* * Attempt the mount */ - err = VFS_MOUNT(mp, NULL, NULL, NULL, p); - /* - * rootdev may be bogus (slice field may be incorrect for disks) - * If slice field is nonzero, clear and retry. - * - * XXX Implicit knowledge of device minor number layout. - * This is placeholder code until saner root mounts arrive with - * DEVFS. - */ - if ((err == ENXIO) && (rootdev & 0xff0000)) { - rootdev &= ~0xff0000; + err = ENXIO; + orootdev = rootdev; + if (rootdevs[0] == NODEV) + rootdevs[0] = rootdev; + for (i = 0; i < sizeof(rootdevs) / sizeof(rootdevs[0]); i++) { + if (rootdevs[i] == NODEV) + break; + rootdev = rootdevs[i]; + if (rootdev != orootdev) { + printf("changing root device to %s\n", rootdevnames[i]); + orootdev = rootdev; + } + strncpy(mp->mnt_stat.f_mntfromname, + rootdevnames[i] ? rootdevnames[i] : ROOTNAME, MNAMELEN - 1); err = VFS_MOUNT(mp, NULL, NULL, NULL, p); + if (err != ENXIO) + break; } if (err) { + /* + * XXX should ask the user for the name in some cases. + * Why do we call vfs_unbusy() here and not after ENXIO + * is returned above? + */ vfs_unbusy(mp, p); /* * free mount struct before failing diff --git a/sys/sys/systm.h b/sys/sys/systm.h index cc39cad..6879634 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)systm.h 8.7 (Berkeley) 3/29/95 - * $Id: systm.h,v 1.70 1998/02/24 02:01:11 bde Exp $ + * $Id: systm.h,v 1.71 1998/06/07 17:13:04 dfr Exp $ */ #ifndef _SYS_SYSTM_H_ @@ -67,6 +67,8 @@ extern dev_t dumpdev; /* dump device */ extern long dumplo; /* offset into dumpdev */ extern dev_t rootdev; /* root device */ +extern dev_t rootdevs[2]; /* possible root devices */ +extern char *rootdevnames[2]; /* names of possible root devices */ extern struct vnode *rootvp; /* vnode equivalent to above */ extern struct vnode *swapdev_vp;/* vnode for swap device */ |