aboutsummaryrefslogtreecommitdiff
path: root/sbin/bsdlabel
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2009-08-19 16:29:20 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2009-08-19 16:29:20 +0000
commiteb0ea23e837bc3e3993a7f84efdb868cbb49f93a (patch)
treedf07874e60fb95f9707ba813108286f27b1aa52a /sbin/bsdlabel
parentfcaeaff4b6aad1829edba34184950a3b3a9a403d (diff)
downloadsrc-eb0ea23e837bc3e3993a7f84efdb868cbb49f93a.tar.gz
src-eb0ea23e837bc3e3993a7f84efdb868cbb49f93a.zip
Remove the dependency on the kernel -- in particular the gctl request to
the GEOM_BSD class -- to translate the absolute offsets in the label to relative ones. This makes bslabel(8) work correctly with GEOM_PART and also when the BSD label is nested under arbitrary partitioning schemes. Inspired by: Eygene Ryabinkin <rea-fbsd@codelabs.ru> Approved by: re (kib)
Notes
Notes: svn path=/head/; revision=196383
Diffstat (limited to 'sbin/bsdlabel')
-rw-r--r--sbin/bsdlabel/bsdlabel.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c
index 1cb99950bbd8..9a6027c7951a 100644
--- a/sbin/bsdlabel/bsdlabel.c
+++ b/sbin/bsdlabel/bsdlabel.c
@@ -118,7 +118,7 @@ static int installboot; /* non-zero if we should install a boot program */
static int allfields; /* present all fields in edit */
static char const *xxboot; /* primary boot */
-static off_t mbroffset;
+static uint32_t lba_offset;
#ifndef LABELSECTOR
#define LABELSECTOR -1
#endif
@@ -403,7 +403,7 @@ writelabel(void)
readboot();
for (i = 0; i < lab.d_npartitions; i++)
if (lab.d_partitions[i].p_size)
- lab.d_partitions[i].p_offset += mbroffset;
+ lab.d_partitions[i].p_offset += lba_offset;
bsd_disklabel_le_enc(bootarea + labeloffset + labelsoffset * secsize,
lp);
if (alphacksum) {
@@ -479,10 +479,9 @@ get_file_parms(int f)
static int
readlabel(int flag)
{
+ uint32_t lba;
int f, i;
int error;
- struct gctl_req *grq;
- char const *errstr;
f = open(specname, O_RDONLY);
if (f < 0)
@@ -510,22 +509,28 @@ readlabel(int flag)
if (is_file)
return(0);
- grq = gctl_get_handle();
- gctl_ro_param(grq, "verb", -1, "read mbroffset");
- gctl_ro_param(grq, "class", -1, "BSD");
- gctl_ro_param(grq, "geom", -1, pname);
- gctl_rw_param(grq, "mbroffset", sizeof(mbroffset), &mbroffset);
- errstr = gctl_issue(grq);
- if (errstr != NULL) {
- mbroffset = 0;
- gctl_free(grq);
- return (error);
+
+ /*
+ * Compensate for absolute block addressing by finding the
+ * smallest partition offset and if the offset of the 'c'
+ * partition is equal to that, subtract it from all offsets.
+ */
+ lba = ~0;
+ for (i = 0; i < lab.d_npartitions; i++) {
+ if (lab.d_partitions[i].p_size)
+ lba = MIN(lba, lab.d_partitions[i].p_offset);
}
- mbroffset /= lab.d_secsize;
- if (lab.d_partitions[RAW_PART].p_offset == mbroffset)
- for (i = 0; i < lab.d_npartitions; i++)
+ if (lba != 0 && lab.d_partitions[RAW_PART].p_offset == lba) {
+ for (i = 0; i < lab.d_npartitions; i++) {
if (lab.d_partitions[i].p_size)
- lab.d_partitions[i].p_offset -= mbroffset;
+ lab.d_partitions[i].p_offset -= lba;
+ }
+ /*
+ * Save the offset so that we can write the label
+ * back with absolute block addresses.
+ */
+ lba_offset = lba;
+ }
return (error);
}