--- etc/rc.d/root (révision 200035) +++ etc/rc.d/root (copie de travail) @@ -36,6 +36,16 @@ if [ -x /sbin/nextboot ]; then /sbin/nextboot -D > /dev/null 2>&1 fi + + # Create rootdev link + rootmnt=`kenv vfs.root.mountfrom` + rootdev=${rootmnt#*:} + ( + cd /dev + if [ -e "${rootdev}" ]; then + ln -s ${rootdev} rootdev + fi + ) } load_rc_config $name --- lib/libstand/ioctl.c (révision 200035) +++ lib/libstand/ioctl.c (copie de travail) @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include "stand.h" +#include "saioctl.h" int ioctl(fd, cmd, arg) @@ -77,12 +78,31 @@ errno = EBADF; return (-1); } - if (f->f_flags & F_RAW) { - errno = (f->f_dev->dv_ioctl)(f, cmd, arg); - if (errno) - return (-1); - return (0); + switch (SAIO_LAYER(cmd)) { + case SAIO_DEV: + if (f->f_flags & F_RAW) + errno = (f->f_dev->dv_ioctl)(f, cmd, arg); + else + errno = EIO; + break; + case SAIO_FS: + switch (cmd) { + case SAIOGFSTYPE: + *(const char **)arg = f->f_ops->fs_name; + errno = 0; + break; + case SAIOGFSLABEL: + *(const char **)arg = f->f_labeldev; + errno = 0; + break; + default: + errno = EINVAL; + } + break; + default: + errno = EINVAL; } - errno = EIO; - return (-1); + if (errno) + return (-1); + return (0); } --- lib/libstand/ext2fs.c (révision 200035) +++ lib/libstand/ext2fs.c (copie de travail) @@ -386,6 +386,11 @@ fs->fs_ipb = fs->fs_bsize / fs->fs_isize; fs->fs_fsbtodb = (fs->fs_bsize / DEV_BSIZE) - 1; + if (fs->fs_fd.fd_volname[0] != '\0') { + sprintf(namebuf, "/dev/ext2fs/%s", fs->fs_fd.fd_volname); + f->f_labeldev = strdup(namebuf); + } + /* * we have to load in the "group descriptors" here */ @@ -794,6 +799,10 @@ struct file *fp = (struct file *)f->f_fsdata; int level; + if (f->f_labeldev != NULL) { + free(f->f_labeldev); + f->f_labeldev = NULL; + } f->f_fsdata = (void *)0; if (fp == (struct file *)0) return (0); --- lib/libstand/Makefile (révision 200035) +++ lib/libstand/Makefile (copie de travail) @@ -12,7 +12,7 @@ LIB= stand NO_PROFILE= NO_PIC= -INCS= stand.h +INCS= stand.h saioctl.h MAN= libstand.3 CFLAGS+= -ffreestanding -Wformat --- lib/libstand/ufs.c (révision 200035) +++ lib/libstand/ufs.c (copie de travail) @@ -538,6 +538,15 @@ goto out; } /* + * Find a unique device name. + */ + if (fs->fs_volname[0] != '\0') { + sprintf (namebuf, "/dev/ufs/%s", fs->fs_volname); + } else { + sprintf (namebuf, "/dev/ufsid/%08x%08x", fs->fs_id[0], fs->fs_id[1]); + } + f->f_labeldev = strdup(namebuf); + /* * Calculate indirect block levels. */ { @@ -711,6 +720,8 @@ if (fp->f_buf) free(fp->f_buf); free(fp->f_fs); + free(f->f_labeldev); + f->f_labeldev = NULL; free(fp); return (0); } --- lib/libstand/open.c (révision 200035) +++ lib/libstand/open.c (copie de travail) @@ -123,7 +123,6 @@ error = ((*file_system[i]).fo_open)(file, f); if (error == 0) { - f->f_ops = file_system[i]; o_rainit(f); return (fd); --- lib/libstand/saioctl.h (révision 200035) +++ lib/libstand/saioctl.h (copie de travail) @@ -33,18 +33,30 @@ * $FreeBSD$ */ -/* ioctl's -- for disks just now */ -#define SAIOHDR (('d'<<8)|1) /* next i/o includes header */ -#define SAIOCHECK (('d'<<8)|2) /* next i/o checks data */ -#define SAIOHCHECK (('d'<<8)|3) /* next i/o checks header & data */ -#define SAIONOBAD (('d'<<8)|4) /* inhibit bad sector forwarding */ -#define SAIODOBAD (('d'<<8)|5) /* enable bad sector forwarding */ -#define SAIOECCLIM (('d'<<8)|6) /* set limit to ecc correction, bits */ -#define SAIOECCUNL (('d'<<8)|7) /* use standard ecc procedures */ -#define SAIORETRIES (('d'<<8)|8) /* set retry count for unit */ -#define SAIODEVDATA (('d'<<8)|9) /* get pointer to pack label */ -#define SAIOSSI (('d'<<8)|10) /* set skip sector inhibit */ -#define SAIONOSSI (('d'<<8)|11) /* inhibit skip sector handling */ -#define SAIOSSDEV (('d'<<8)|12) /* is device skip sector type? */ -#define SAIODEBUG (('d'<<8)|13) /* enable/disable debugging */ -#define SAIOGBADINFO (('d'<<8)|14) /* get bad-sector table */ +/* ioctl's */ + +#define SAIO_LAYER(cmd) (cmd & 0xf0000000) +#define SAIO_DEV (0 << 28) +#define SAIO_FS (1 << 28) + +/* DEV layer */ + +#define SAIOHDR (SAIO_DEV|('d'<<8)|1) /* next i/o includes header */ +#define SAIOCHECK (SAIO_DEV|('d'<<8)|2) /* next i/o checks data */ +#define SAIOHCHECK (SAIO_DEV|('d'<<8)|3) /* next i/o checks header & data */ +#define SAIONOBAD (SAIO_DEV|('d'<<8)|4) /* inhibit bad sector forwarding */ +#define SAIODOBAD (SAIO_DEV|('d'<<8)|5) /* enable bad sector forwarding */ +#define SAIOECCLIM (SAIO_DEV|('d'<<8)|6) /* set limit to ecc correction, bits */ +#define SAIOECCUNL (SAIO_DEV|('d'<<8)|7) /* use standard ecc procedures */ +#define SAIORETRIES (SAIO_DEV|('d'<<8)|8) /* set retry count for unit */ +#define SAIODEVDATA (SAIO_DEV|('d'<<8)|9) /* get pointer to pack label */ +#define SAIOSSI (SAIO_DEV|('d'<<8)|10) /* set skip sector inhibit */ +#define SAIONOSSI (SAIO_DEV|('d'<<8)|11) /* inhibit skip sector handling */ +#define SAIOSSDEV (SAIO_DEV|('d'<<8)|12) /* is device skip sector type? */ +#define SAIODEBUG (SAIO_DEV|('d'<<8)|13) /* enable/disable debugging */ +#define SAIOGBADINFO (SAIO_DEV|('d'<<8)|14) /* get bad-sector table */ + +/* FS layer */ + +#define SAIOGFSTYPE (SAIO_FS|('f'<<8)|1) /* get file system type */ +#define SAIOGFSLABEL (SAIO_FS|('f'<<8)|2) /* get unique device name */ --- lib/libstand/cd9660.c (révision 200035) +++ lib/libstand/cd9660.c (copie de travail) @@ -276,6 +276,7 @@ struct iso_directory_record rec; struct iso_directory_record *dp = 0; int rc, first, use_rrip, lenskip; + char labelbuf[64]; /* First find the volume descriptor */ buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE); @@ -301,6 +302,9 @@ if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) goto out; + sprintf(labelbuf, "/dev/iso9660/%s", vd->volume_id); + f->f_labeldev = strdup(labelbuf); + rec = *(struct iso_directory_record *) vd->root_directory_record; if (*path == '/') path++; /* eat leading '/' */ @@ -410,6 +414,8 @@ { struct file *fp = (struct file *)f->f_fsdata; + free(f->f_labeldev); + f->f_labeldev = NULL; f->f_fsdata = 0; free(fp); --- lib/libstand/stand.h (révision 200035) +++ lib/libstand/stand.h (copie de travail) @@ -164,6 +164,7 @@ char *f_rabuf; /* readahead buffer pointer */ size_t f_ralen; /* valid data in readahead buffer */ off_t f_raoffset; /* consumer offset in readahead buffer */ + char *f_labeldev; /* unique device name for this file system */ #define SOPEN_RASIZE 512 }; --- sys/boot/common/boot.c (révision 200035) +++ sys/boot/common/boot.c (copie de travail) @@ -32,6 +32,8 @@ */ #include +#include +#include #include #include "bootstrap.h" @@ -361,11 +363,18 @@ cp++; *cp = 0; options = strdup(ep); - /* Build the : and save it in vfs.root.mountfrom */ - sprintf(lbuf, "%s:%s", fstyp, dev); + + /* Build the : and save it in vfs.root.mountfrom, + * except if dev is special value "/dev/rootdev", in which case + * we rely to the value determined below to provide the proper + * device name. + */ + if (strcmp (dev, "/dev/rootdev")) { + sprintf(lbuf, "%s:%s", fstyp, dev); + setenv("vfs.root.mountfrom", lbuf, 0); + } free(dev); free(fstyp); - setenv("vfs.root.mountfrom", lbuf, 0); /* Don't override vfs.root.mountfrom.options if it is already set */ if (getenv("vfs.root.mountfrom.options") == NULL) { @@ -376,6 +385,18 @@ error = 0; break; } + + if (getenv("vfs.root.mountfrom") == NULL) { + /* Try to get device name from on-disk label */ + if (ioctl(fd, SAIOGFSTYPE, &fstyp) == 0 && + ioctl(fd, SAIOGFSLABEL, &dev) == 0) + { + sprintf(lbuf, "%s:%s", fstyp, dev); + setenv("vfs.root.mountfrom", lbuf, 0); + error = 0; + } + } + close(fd); return(error); }