2008-01-30 23:25:05

by Eric Sandeen

[permalink] [raw]
Subject: [PATCH e2fsprogs] - detect LVM2 PVs in libblkid

The anaconda folks are now using blkid instead of hand-rolled
tests for filesystem type at install time, but they had one
more request:

Bugzilla Bug 409321: RFE: information on blkdevs "formatted" as PVs
https://bugzilla.redhat.com/show_bug.cgi?id=409321

The attached patch does the right thing for me on my sample
set of exactly 1 PV...

Any issues with reporting back something which is not actually
a filesystem ("lvm2pv") ?

[root@host]# misc/blkid -c /dev/null /dev/sda2
/dev/sda2: UUID="guOQGdcOE3IafCm0190XkPZTy5fCEanQ" TYPE="lvm2pv"
[root@host]# pvs -o pv_name,pv_uuid
PV PV UUID
/dev/sda2 guOQGd-cOE3-IafC-m019-0XkP-ZTy5-fCEanQ

Bits liberally stolen from lvm2 userspace.

Signed-off-by: Eric Sandeen <[email protected]>

---

Index: e2fsprogs-1.40.5/lib/blkid/probe.h
===================================================================
--- e2fsprogs-1.40.5.orig/lib/blkid/probe.h
+++ e2fsprogs-1.40.5/lib/blkid/probe.h
@@ -531,6 +531,20 @@ struct hfs_mdb {
__u16 embed_blockcount;
} __attribute__((packed));

+/* this is lvm's label_header & pv_header combined. */
+
+#define LVM2_ID_LEN 32
+
+struct lvm2_pv_label_header {
+ /* label_header */
+ __u8 id[8]; /* LABELONE */
+ __u64 sector_xl; /* Sector number of this label */
+ __u32 crc_xl; /* From next field to end of sector */
+ __u32 offset_xl; /* Offset from start of struct to contents */
+ __u8 type[8]; /* LVM2 001 */
+ /* pv_header */
+ __u8 pv_uuid[LVM2_ID_LEN];
+} __attribute__ ((packed));

/*
* Byte swap functions
Index: e2fsprogs-1.40.5/lib/blkid/probe.c
===================================================================
--- e2fsprogs-1.40.5.orig/lib/blkid/probe.c
+++ e2fsprogs-1.40.5/lib/blkid/probe.c
@@ -895,6 +895,64 @@ static int probe_hfsplus(struct blkid_pr
return 1;
}

+#define LVM2_LABEL_SIZE 512
+static int lvm2_calc_crc(const void *buf, uint size)
+{
+ static const uint crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ uint i, crc = 0xf597a6cf;
+ const __u8 *data = (const __u8 *) buf;
+
+ for (i = 0; i < size; i++) {
+ crc ^= *data++;
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+ return crc;
+}
+
+static int probe_lvm2(struct blkid_probe *probe,
+ struct blkid_magic *id __BLKID_ATTR((unused)),
+ unsigned char *buf)
+{
+ int sector = (id->bim_kboff) << 1;;
+ struct lvm2_pv_label_header *label;
+ label = (struct lvm2_pv_label_header *)buf;
+
+ /* buf is at 0k or 1k offset; find label inside */
+ if (memcmp(buf, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *)buf;
+ } else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *)(buf + 512);
+ sector++;
+ } else {
+ return 1;
+ }
+
+ if (blkid_le64(label->sector_xl) != sector) {
+ DBG(DEBUG_PROBE,
+ printf("LVM2: label for sector %d found at sector %d\n",
+ blkid_le64(label->sector_xl), sector));
+ return 1;
+ }
+
+ if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
+ ((void *)&label->offset_xl - (void *)label)) !=
+ blkid_le32(label->crc_xl)) {
+ DBG(DEBUG_PROBE,
+ printf("LVM2: label checksum incorrect at sector %d\n",
+ sector));
+ return 1;
+ }
+
+ blkid_set_tag(probe->dev, "UUID", label->pv_uuid, LVM2_ID_LEN);
+
+ return 0;
+}
/*
* BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
* in the type_array table below + bim_kbalign.
@@ -988,6 +1046,10 @@ static struct blkid_magic type_array[] =
{ "crypt_LUKS", 0, 0, 6, "LUKS\xba\xbe", probe_luks },
{ "squashfs", 0, 0, 4, "sqsh", 0 },
{ "squashfs", 0, 0, 4, "hsqs", 0 },
+ { "lvm2pv", 0, 0x218, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 0, 0x018, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 1, 0x018, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 1, 0x218, 8, "LVM2 001", probe_lvm2 },
{ NULL, 0, 0, 0, NULL, NULL }
};



2008-02-19 11:27:43

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH e2fsprogs] - detect LVM2 PVs in libblkid

On Wed, Jan 30, 2008 at 05:25:03PM -0600, Eric Sandeen wrote:
> The anaconda folks are now using blkid instead of hand-rolled
> tests for filesystem type at install time, but they had one
> more request:
>
> Bugzilla Bug 409321: RFE: information on blkdevs "formatted" as PVs
> https://bugzilla.redhat.com/show_bug.cgi?id=409321
>
> The attached patch does the right thing for me on my sample
> set of exactly 1 PV...
>
> Any issues with reporting back something which is not actually
> a filesystem ("lvm2pv") ?
>
> [root@host]# misc/blkid -c /dev/null /dev/sda2
> /dev/sda2: UUID="guOQGdcOE3IafCm0190XkPZTy5fCEanQ" TYPE="lvm2pv"
> [root@host]# pvs -o pv_name,pv_uuid
> PV PV UUID
> /dev/sda2 guOQGd-cOE3-IafC-m019-0XkP-ZTy5-fCEanQ

The patch works for me, but it would seem the right thing would be
print the UUID without the hyphens, i.e.:

guOQGdcOE3IafCm0190XkPZTy5fCEanQ

instead of

guOQGd-cOE3-IafC-m019-0XkP-ZTy5-fCEanQ

After all, pvscan prints it with the hyphens, and blkid returns uuid's
with the hyphens for other filesystems as well. And removing the
hyphens aren't hard; "tr -d -" will do it.

It's not that hard to convert from one to the other; this will do it:

for (i=0, b=1, p=uuid, q=label->pv_uuid; i <= 32; i++, b = b << 1) {
if (b & 0x4444440)
*p++ = '-';
*p++ = *q++;
}

This shouldn't screw up the anaconda folks, since they just need to
know the filesystem type, right? That's all vol_id seems to return in
any case.

- Ted

2008-02-19 15:02:43

by Eric Sandeen

[permalink] [raw]
Subject: Re: [PATCH e2fsprogs] - detect LVM2 PVs in libblkid

Theodore Tso wrote:

> The patch works for me, but it would seem the right thing would be
> print the UUID without the hyphens, i.e.:
>
> guOQGdcOE3IafCm0190XkPZTy5fCEanQ
>
> instead of
>
> guOQGd-cOE3-IafC-m019-0XkP-ZTy5-fCEanQ

But it already does print it without the hyphens.

Or did you mean to say "print the UUID *with* the hyphens?"

-Eric

2008-02-19 15:42:53

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH e2fsprogs] - detect LVM2 PVs in libblkid

On Tue, Feb 19, 2008 at 09:02:30AM -0600, Eric Sandeen wrote:
> Theodore Tso wrote:
>
> > The patch works for me, but it would seem the right thing would be
> > print the UUID without the hyphens, i.e.:
> >
> > guOQGdcOE3IafCm0190XkPZTy5fCEanQ
> >
> > instead of
> >
> > guOQGd-cOE3-IafC-m019-0XkP-ZTy5-fCEanQ
>
> But it already does print it without the hyphens.
>
> Or did you mean to say "print the UUID *with* the hyphens?"

Sorry, I meant print it with the hyphens, like pvscan does and all of
the other filesystem UUID's returned by blkid.

- Ted