summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/autoconf.c92
-rw-r--r--sys/i386/i386/autoconf.c92
-rw-r--r--sys/kern/vfs_conf.c44
-rw-r--r--sys/kern/vfs_mount.c44
-rw-r--r--sys/sys/systm.h4
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 */
OpenPOWER on IntegriCloud