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:
parent
883738f287
commit
b9d05a16f4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103669
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user