diff options
author | joerg <joerg@FreeBSD.org> | 1996-01-22 01:01:15 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-01-22 01:01:15 +0000 |
commit | fb2cd624b1e23a9dcc51c56dbb9e66ed16667c8d (patch) | |
tree | 5576c9391cf0e505da676bd2b14affcd1ecc20c4 /sbin/disklabel/disklabel.c | |
parent | dcd9f7224a3a268950bfdc0e06f79ae559c53e50 (diff) | |
download | FreeBSD-src-fb2cd624b1e23a9dcc51c56dbb9e66ed16667c8d.zip FreeBSD-src-fb2cd624b1e23a9dcc51c56dbb9e66ed16667c8d.tar.gz |
Finally implement the "auto" disktype. It attempts to get all the
required information from the driver, and produce a virgin disklabel
for it. The latter might be further edited with `disklabel -e' to
satisfy the user's need.
The magic sequence is:
disklabel -r -w sdX auto
disklabel -e sdX
Diffstat (limited to 'sbin/disklabel/disklabel.c')
-rw-r--r-- | sbin/disklabel/disklabel.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index d3337c1..cf93fc4 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -110,6 +110,7 @@ void Warning (char *, ...); void Perror __P((char *)); void usage __P((void)); extern u_short dkcksum __P((struct disklabel *)); +struct disklabel * getvirginlabel __P((void)); #define DEFEDITOR _PATH_VI #define streq(a,b) (strcmp(a,b) == 0) @@ -336,7 +337,10 @@ makelabel(type, name, lp) register struct disklabel *lp; { register struct disklabel *dp; - char *strcpy(); + + if (strcmp(type, "auto") == 0) + dp = getvirginlabel(); + else dp = getdiskbyname(type); if (dp == NULL) { fprintf(stderr, "%s: unknown disk type\n", type); @@ -1280,6 +1284,48 @@ checklabel(lp) } /* + * When operating on a "virgin" disk, try getting an initial label + * from the associated device driver. This might work for all device + * drivers that are able to fetch some initial device parameters + * without even having access to a (BSD) disklabel, like SCSI disks, + * most IDE drives, or vn devices. + * + * The device name must be given in its "canonical" form. + */ +struct disklabel * +getvirginlabel(void) +{ + static struct disklabel lab; + char namebuf[BBSIZE]; + int f; + + if (dkname[0] == '/') { + fprintf(stderr, + "\"auto\" requires the usage of a canonical disk name.\n"); + return 0; + } + (void)snprintf(namebuf, BBSIZE, "%sr%s", _PATH_DEV, dkname); + if ((f = open(namebuf, O_RDONLY, 0)) == -1) { + Perror("open()"); + return 0; + } + if (ioctl(f, DIOCGDINFO, &lab) < 0) { + Perror("ioctl DIOCGDINFO"); + close(f); + return 0; + } + close(f); + /* insert reasonable defaults where necessary */ + if (lab.d_npartitions < 8) lab.d_npartitions = 8; + if (lab.d_bbsize == 0) lab.d_bbsize = BBSIZE; + if (lab.d_sbsize == 0) lab.d_sbsize = SBSIZE; + if (lab.d_rpm == 0) lab.d_rpm = 3600; + if (lab.d_interleave == 0) lab.d_interleave = 1; + return &lab; +} + + +/* * If we are installing a boot program that doesn't fit in d_bbsize * we need to mark those partitions that the boot overflows into. * This allows newfs to prevent creation of a filesystem where it might |