summaryrefslogtreecommitdiffstats
path: root/sbin/disklabel/disklabel.c
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-01-22 01:01:15 +0000
committerjoerg <joerg@FreeBSD.org>1996-01-22 01:01:15 +0000
commitfb2cd624b1e23a9dcc51c56dbb9e66ed16667c8d (patch)
tree5576c9391cf0e505da676bd2b14affcd1ecc20c4 /sbin/disklabel/disklabel.c
parentdcd9f7224a3a268950bfdc0e06f79ae559c53e50 (diff)
downloadFreeBSD-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.c48
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
OpenPOWER on IntegriCloud