From 73332890ea988292b7aa7e6647f6c1a72dfbb3b6 Mon Sep 17 00:00:00 2001 From: Mike Smith Date: Wed, 21 Jul 1999 00:08:54 +0000 Subject: [PATCH] Walk around the end of all the silly guessing of device types and unit numbers that we have been doing in the past, and read /etc/fstab off the proposed root filesystem to determine the actual device name and vfs type for the root filesystem. These are then exported to the kernel via the environment variable vfs.root.mountfrom. --- sys/boot/alpha/libalpha/bootinfo.c | 20 ++++++++- sys/boot/common/boot.c | 70 +++++++++++++++++++++++++++++- sys/boot/common/bootstrap.h | 3 +- sys/boot/i386/libi386/bootinfo.c | 8 +++- sys/boot/i386/libi386/bootinfo32.c | 8 +++- sys/boot/i386/libi386/bootinfo64.c | 8 +++- 6 files changed, 108 insertions(+), 9 deletions(-) diff --git a/sys/boot/alpha/libalpha/bootinfo.c b/sys/boot/alpha/libalpha/bootinfo.c index f4318c952daf..fa0842b59169 100644 --- a/sys/boot/alpha/libalpha/bootinfo.c +++ b/sys/boot/alpha/libalpha/bootinfo.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootinfo.c,v 1.4 1999/03/08 11:05:42 dcs Exp $ + * $Id: bootinfo.c,v 1.6 1999/03/20 14:13:09 dcs Exp $ */ #include @@ -153,12 +153,30 @@ int bi_load(struct bootinfo_v1 *bi, vm_offset_t *ffp_save, struct loaded_module *mp) { + char *rootdevname; + struct alpha_devdesc *rootdev; struct loaded_module *xp; vm_offset_t addr, bootinfo_addr; u_int pad; vm_offset_t ssym, esym; struct module_metadata *md; + /* + * Allow the environment variable 'rootdev' to override the supplied device + * This should perhaps go to MI code and/or have $rootdev tested/set by + * MI code before launching the kernel. + */ + rootdevname = getenv("rootdev"); + alpha_getdev((void **)(&rootdev), rootdevname, NULL); + if (rootdev == NULL) { /* bad $rootdev/$currdev */ + printf("can't determine root device\n"); + return(EINVAL); + } + + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(alpha_fmtdev((void *)rootdev)); + free(rootdev); + ssym = esym = 0; if ((md = mod_findmetadata(mp, MODINFOMD_SSYM)) != NULL) ssym = *((vm_offset_t *)&(md->md_data)); diff --git a/sys/boot/common/boot.c b/sys/boot/common/boot.c index 28accc38ce63..70b467144636 100644 --- a/sys/boot/common/boot.c +++ b/sys/boot/common/boot.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: boot.c,v 1.12 1999/05/30 10:45:03 dfr Exp $ + * $Id: boot.c,v 1.13 1999/07/15 20:40:52 n_hibma Exp $ */ /* @@ -262,3 +262,71 @@ getbootfile(int try) return(name); } +/* + * Try to find the /etc/fstab file on the filesystem (rootdev), + * which should be be the root filesystem, and parse it to find + * out what the kernel ought to think the root filesystem is. + * + * If we're successful, set vfs.root.mountfrom to : + * so that the kernel can tell both which VFS and which node to use + * to mount the device. If this variable's already set, don't + * overwrite it. + */ +int +getrootmount(char *rootdev) +{ + char lbuf[128], *cp, *ep, *dev, *fstyp; + int fd, error; + + if (getenv("vfs.root.mountfrom") != NULL) + return(0); + + sprintf(lbuf, "%s/etc/fstab", rootdev); + if ((fd = open(lbuf, O_RDONLY)) < 0) + return(1); + + /* loop reading lines from /etc/fstab What was that about sscanf again? */ + error = 1; + while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) { + if ((lbuf[0] == 0) || (lbuf[0] == '#')) + continue; + + /* skip device name */ + for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++) + ; + if (*cp == 0) /* misformatted */ + continue; + /* delimit and save */ + *cp++ = 0; + dev = strdup(lbuf); + + /* skip whitespace up to mountpoint */ + while ((*cp != 0) && isspace(*cp)) + cp++; + /* must have / to be root */ + if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1))) + continue; + /* skip whitespace up to fstype */ + cp += 2; + while ((*cp != 0) && isspace(*cp)) + cp++; + if (*cp == 0) /* misformatted */ + continue; + /* skip text to end of fstype and delimit */ + ep = cp; + while ((*cp != 0) && !isspace(*cp)) + cp++; + *cp = 0; + fstyp = strdup(ep); + + /* build the final result and save it */ + sprintf(lbuf, "%s:%s", fstyp, dev); + free(dev); + free(fstyp); + setenv("vfs.root.mountfrom", lbuf, 0); + error = 0; + break; + } + close(fd); + return(error); +} diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h index 848e74b37ab7..1cabf7033457 100644 --- a/sys/boot/common/bootstrap.h +++ b/sys/boot/common/bootstrap.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootstrap.h,v 1.21 1999/04/16 21:21:47 peter Exp $ + * $Id: bootstrap.h,v 1.22 1999/06/26 12:26:54 peter Exp $ */ #include @@ -68,6 +68,7 @@ extern int bf_run(char *line); /* boot.c */ extern int autoboot(int delay, char *prompt); extern void autoboot_maybe(void); +extern int getrootmount(char *rootdev); /* misc.c */ extern char *unargv(int argc, char *argv[]); diff --git a/sys/boot/i386/libi386/bootinfo.c b/sys/boot/i386/libi386/bootinfo.c index 20517c2a312e..a07012e061b9 100644 --- a/sys/boot/i386/libi386/bootinfo.c +++ b/sys/boot/i386/libi386/bootinfo.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootinfo.c,v 1.19 1999/06/04 03:18:28 ghelmer Exp $ + * $Id: bootinfo.c,v 1.20 1999/06/21 18:27:01 rnordier Exp $ */ #include @@ -258,6 +258,10 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); } + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(i386_fmtdev((void *)rootdev)); + + /* Do legacy rootdev guessing */ switch(rootdev->d_type) { case DEVT_DISK: /* pass in the BIOS device number of the current disk */ @@ -269,7 +273,7 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); default: - printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type); + printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); } free(rootdev); *bootdevp = bootdevnr; diff --git a/sys/boot/i386/libi386/bootinfo32.c b/sys/boot/i386/libi386/bootinfo32.c index 20517c2a312e..a07012e061b9 100644 --- a/sys/boot/i386/libi386/bootinfo32.c +++ b/sys/boot/i386/libi386/bootinfo32.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootinfo.c,v 1.19 1999/06/04 03:18:28 ghelmer Exp $ + * $Id: bootinfo.c,v 1.20 1999/06/21 18:27:01 rnordier Exp $ */ #include @@ -258,6 +258,10 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); } + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(i386_fmtdev((void *)rootdev)); + + /* Do legacy rootdev guessing */ switch(rootdev->d_type) { case DEVT_DISK: /* pass in the BIOS device number of the current disk */ @@ -269,7 +273,7 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); default: - printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type); + printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); } free(rootdev); *bootdevp = bootdevnr; diff --git a/sys/boot/i386/libi386/bootinfo64.c b/sys/boot/i386/libi386/bootinfo64.c index 20517c2a312e..a07012e061b9 100644 --- a/sys/boot/i386/libi386/bootinfo64.c +++ b/sys/boot/i386/libi386/bootinfo64.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bootinfo.c,v 1.19 1999/06/04 03:18:28 ghelmer Exp $ + * $Id: bootinfo.c,v 1.20 1999/06/21 18:27:01 rnordier Exp $ */ #include @@ -258,6 +258,10 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); } + /* Try reading the /etc/fstab file to select the root device */ + getrootmount(i386_fmtdev((void *)rootdev)); + + /* Do legacy rootdev guessing */ switch(rootdev->d_type) { case DEVT_DISK: /* pass in the BIOS device number of the current disk */ @@ -269,7 +273,7 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return(EINVAL); default: - printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type); + printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); } free(rootdev); *bootdevp = bootdevnr;