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
This commit is contained in:
Poul-Henning Kamp 2002-09-20 09:18:31 +00:00
parent 883738f287
commit b9d05a16f4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103669
2 changed files with 94 additions and 40 deletions

View File

@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/file.h> #include <sys/file.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/disk.h>
#define DKTYPENAMES #define DKTYPENAMES
#define FSTYPENAMES #define FSTYPENAMES
#include <sys/disklabel.h> #include <sys/disklabel.h>
@ -1573,8 +1574,11 @@ struct disklabel *
getvirginlabel(void) getvirginlabel(void)
{ {
static struct disklabel loclab; static struct disklabel loclab;
struct partition *dp;
char lnamebuf[BBSIZE]; char lnamebuf[BBSIZE];
int f; int f;
u_int secsize, u;
off_t mediasize;
if (dkname[0] == '/') { if (dkname[0] == '/') {
warnx("\"auto\" requires the usage of a canonical disk name"); warnx("\"auto\" requires the usage of a canonical disk name");
@ -1586,28 +1590,51 @@ getvirginlabel(void)
return (NULL); return (NULL);
} }
/* /* New world order */
* Try to use the new get-virgin-label ioctl. If it fails, if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0) ||
* fallback to the old get-disdk-info ioctl. (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) {
*/ close (f);
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);
return (NULL); return (NULL);
} }
if (ioctl(f, DIOCGDINFO, &loclab) == 0) memset(&loclab, 0, sizeof loclab);
goto out; loclab.d_magic = DISKMAGIC;
close(f); loclab.d_magic2 = DISKMAGIC;
warn("No virgin disklabel found %s", lnamebuf); loclab.d_secsize = secsize;
return (NULL); loclab.d_secperunit = mediasize / secsize;
out:
close(f); /*
* 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); return (&loclab);
} }

View File

@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/file.h> #include <sys/file.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/disk.h>
#define DKTYPENAMES #define DKTYPENAMES
#define FSTYPENAMES #define FSTYPENAMES
#include <sys/disklabel.h> #include <sys/disklabel.h>
@ -1573,8 +1574,11 @@ struct disklabel *
getvirginlabel(void) getvirginlabel(void)
{ {
static struct disklabel loclab; static struct disklabel loclab;
struct partition *dp;
char lnamebuf[BBSIZE]; char lnamebuf[BBSIZE];
int f; int f;
u_int secsize, u;
off_t mediasize;
if (dkname[0] == '/') { if (dkname[0] == '/') {
warnx("\"auto\" requires the usage of a canonical disk name"); warnx("\"auto\" requires the usage of a canonical disk name");
@ -1586,28 +1590,51 @@ getvirginlabel(void)
return (NULL); return (NULL);
} }
/* /* New world order */
* Try to use the new get-virgin-label ioctl. If it fails, if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0) ||
* fallback to the old get-disdk-info ioctl. (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) {
*/ close (f);
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);
return (NULL); return (NULL);
} }
if (ioctl(f, DIOCGDINFO, &loclab) == 0) memset(&loclab, 0, sizeof loclab);
goto out; loclab.d_magic = DISKMAGIC;
close(f); loclab.d_magic2 = DISKMAGIC;
warn("No virgin disklabel found %s", lnamebuf); loclab.d_secsize = secsize;
return (NULL); loclab.d_secperunit = mediasize / secsize;
out:
close(f); /*
* 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); return (&loclab);
} }