summaryrefslogtreecommitdiffstats
path: root/sbin/disklabel/disklabel.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-09-20 09:18:31 +0000
committerphk <phk@FreeBSD.org>2002-09-20 09:18:31 +0000
commit2f9ce7f609dfad2d63b5ecc1dac003accf2a5758 (patch)
tree7ccc283573b553325fc84d03c5efb421d0dc3e03 /sbin/disklabel/disklabel.c
parenta33d7be6d91b82aecdb4f7f084eb48e928ba376e (diff)
downloadFreeBSD-src-2f9ce7f609dfad2d63b5ecc1dac003accf2a5758.zip
FreeBSD-src-2f9ce7f609dfad2d63b5ecc1dac003accf2a5758.tar.gz
Construct new disklabels based on the medias stated parameters in
userland, rather than expect all possible GEOMetries to know about BSD disklabels. Sponsored by: DARPA & NAI Labs
Diffstat (limited to 'sbin/disklabel/disklabel.c')
-rw-r--r--sbin/disklabel/disklabel.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c
index 4a364ac..17c24d9 100644
--- a/sbin/disklabel/disklabel.c
+++ b/sbin/disklabel/disklabel.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/disk.h>
#define DKTYPENAMES
#define FSTYPENAMES
#include <sys/disklabel.h>
@@ -1573,8 +1574,11 @@ struct disklabel *
getvirginlabel(void)
{
static struct disklabel loclab;
+ struct partition *dp;
char lnamebuf[BBSIZE];
int f;
+ u_int secsize, u;
+ off_t mediasize;
if (dkname[0] == '/') {
warnx("\"auto\" requires the usage of a canonical disk name");
@@ -1586,28 +1590,51 @@ getvirginlabel(void)
return (NULL);
}
- /*
- * Try to use the new get-virgin-label ioctl. If it fails,
- * fallback to the old get-disdk-info ioctl.
- */
- if (ioctl(f, DIOCGDVIRGIN, &loclab) == 0)
- goto out;
- if (ioctl(f, DIOCGDINFO, &loclab) == 0)
- goto out;
- close(f);
- (void)snprintf(lnamebuf, BBSIZE, "%s%s%c", _PATH_DEV, dkname,
- 'a' + RAW_PART);
- if ((f = open(lnamebuf, O_RDONLY)) == -1) {
- warn("cannot open %s", lnamebuf);
+ /* New world order */
+ if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0) ||
+ (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) {
+ close (f);
return (NULL);
}
- if (ioctl(f, DIOCGDINFO, &loclab) == 0)
- goto out;
- close(f);
- warn("No virgin disklabel found %s", lnamebuf);
- return (NULL);
- out:
- close(f);
+ memset(&loclab, 0, sizeof loclab);
+ loclab.d_magic = DISKMAGIC;
+ loclab.d_magic2 = DISKMAGIC;
+ loclab.d_secsize = secsize;
+ loclab.d_secperunit = mediasize / secsize;
+
+ /*
+ * Nobody in these enligthened days uses the CHS geometry for
+ * anything, but nontheless try to get it right. If we fail
+ * to get any good ideas from the device, construct something
+ * which is IBM-PC friendly.
+ */
+ if (ioctl(f, DIOCGFWSECTORS, &u) == 0)
+ loclab.d_nsectors = u;
+ else
+ loclab.d_nsectors = 63;
+ if (ioctl(f, DIOCGFWHEADS, &u) == 0)
+ loclab.d_ntracks = u;
+ else if (loclab.d_secperunit <= 63*1*1024)
+ loclab.d_ntracks = 1;
+ else if (loclab.d_secperunit <= 63*16*1024)
+ loclab.d_ntracks = 16;
+ else
+ loclab.d_ntracks = 255;
+ loclab.d_secpercyl = loclab.d_ntracks * loclab.d_nsectors;
+ loclab.d_ncylinders = loclab.d_secperunit / loclab.d_secpercyl;
+ loclab.d_npartitions = MAXPARTITIONS;
+
+ /* Various (unneeded) compat stuff */
+ loclab.d_rpm = 3600;
+ loclab.d_bbsize = BBSIZE;
+ loclab.d_interleave = 1;;
+ strncpy(loclab.d_typename, "amnesiac",
+ sizeof(loclab.d_typename));
+
+ dp = &loclab.d_partitions[RAW_PART];
+ dp->p_size = loclab.d_secperunit;
+ loclab.d_checksum = dkcksum(&loclab);
+ close (f);
return (&loclab);
}
OpenPOWER on IntegriCloud