]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: ignore empty MBR on LVM device
authorKarel Zak <kzak@redhat.com>
Tue, 30 Aug 2016 10:07:40 +0000 (12:07 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 30 Aug 2016 10:07:40 +0000 (12:07 +0200)
It's possible to use boot sector and empty MBR on LVM physical volume
to make LVM disk bootable. In this case MBR should be ignored and disk
reported as LVM.

Just for the record, this is ugly non-default LVM setup maintained for
backward compatibility (yes, LVM guys don't like it too).

Unfortunately people still use it. The proper way is to use regular
partitioned disk.

Reported-by: Xen <list@xenhideout.nl>
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/partitions/dos.c

index 2a6414025950e379a2054cee07db0e156bd6ff21..30e3e9e732041532f88c233c1b681d8c76258328 100644 (file)
@@ -146,6 +146,27 @@ leave:
        return BLKID_PROBE_OK;
 }
 
+static inline int is_lvm(blkid_probe pr)
+{
+       struct blkid_prval *v = __blkid_probe_lookup_value(pr, "TYPE");
+
+       return (v && v->data && strcmp((char *) v->data, "LVM2_member") == 0);
+}
+
+static inline int is_empty_mbr(unsigned char *mbr)
+{
+       struct dos_partition *p = mbr_get_partition(mbr, 0);
+       int i, nparts = 0;
+
+       for (i = 0; i < 4; i++) {
+               if (dos_partition_get_size(p) > 0)
+                       nparts++;
+               p++;
+       }
+
+       return nparts == 0;
+}
+
 static int probe_dos_pt(blkid_probe pr,
                const struct blkid_idmag *mag __attribute__((__unused__)))
 {
@@ -201,6 +222,16 @@ static int probe_dos_pt(blkid_probe pr,
                goto nothing;
        }
 
+       /*
+        * Ugly exception, if the device contains a valid LVM physical volume
+        * and empty MBR (=no partition defined) then it's LVM and MBR should
+        * be ignored. Crazy people use it to boot from LVM devices.
+        */
+       if (is_lvm(pr) && is_empty_mbr(data)) {
+               DBG(LOWPROBE, ul_debug("empty MBR on LVM device -- ignore"));
+               goto nothing;
+       }
+
        blkid_probe_use_wiper(pr, MBR_PT_OFFSET, 512 - MBR_PT_OFFSET);
 
        id = mbr_get_id(data);