Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2011-02-24 14:35:25 +01:00
parent e342b75ef9
commit f3bea18c63
2 changed files with 226 additions and 1 deletions

View File

@ -0,0 +1,219 @@
From 8b7eae458ccb04befb579dc87bdbfc1b6cbd5553 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 24 Feb 2011 14:03:44 +0100
Subject: [PATCH] libblkid: try to detect if PT is newer than LVM
LVM (pvcreate) wipes the begin of the device. If there is a PT in the
wiped area then LVM signature is obsolete.
# pvcreate /dev/sdb
# fdisk /dev/sdb
old version:
# blkid -p -o udev /dev/sdb
ID_FS_TYPE=LVM2_member
new version:
# blkid -p -o udev /dev/sdb
ID_PART_TABLE_TYPE=dos
Reported-by: Matej Cepl <mcepl@redhat.com>
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=679799
Signed-off-by: Karel Zak <kzak@redhat.com>
---
shlibs/blkid/src/blkidP.h | 10 ++++
shlibs/blkid/src/partitions/dos.c | 3 +
shlibs/blkid/src/partitions/gpt.c | 2 +
shlibs/blkid/src/partitions/partitions.c | 2 +-
shlibs/blkid/src/probe.c | 78 ++++++++++++++++++++++++++++++
shlibs/blkid/src/superblocks/lvm.c | 6 ++
6 files changed, 100 insertions(+), 1 deletions(-)
diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h
index 5bf9cca..94709a5 100644
--- a/shlibs/blkid/src/blkidP.h
+++ b/shlibs/blkid/src/blkidP.h
@@ -198,6 +198,10 @@ struct blkid_struct_probe
int flags; /* private libray flags */
int prob_flags; /* always zeroized by blkid_do_*() */
+ blkid_loff_t wipe_off; /* begin of the wiped area */
+ blkid_loff_t wipe_size; /* size of the wiped area */
+ struct blkid_chain *wipe_chain; /* superblock, partition, ... */
+
struct list_head buffers; /* list of buffers */
struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */
@@ -428,6 +432,12 @@ extern int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
extern void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len);
extern size_t blkid_rtrim_whitespace(unsigned char *str);
+extern void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off,
+ blkid_loff_t size);
+extern int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn,
+ blkid_loff_t off, blkid_loff_t size);
+extern void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size);
+
/* filter bitmap macros */
#define blkid_bmp_wordsize (8 * sizeof(unsigned long))
#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize))
diff --git a/shlibs/blkid/src/partitions/dos.c b/shlibs/blkid/src/partitions/dos.c
index c961ef7..72ac778 100644
--- a/shlibs/blkid/src/partitions/dos.c
+++ b/shlibs/blkid/src/partitions/dos.c
@@ -177,6 +177,9 @@ static int probe_dos_pt(blkid_probe pr, const struct blkid_idmag *mag)
}
}
+ blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET,
+ 512 - BLKID_MSDOS_PT_OFFSET);
+
/*
* Well, all checks pass, it's MS-DOS partiton table
*/
diff --git a/shlibs/blkid/src/partitions/gpt.c b/shlibs/blkid/src/partitions/gpt.c
index 12100e0..8259c2f 100644
--- a/shlibs/blkid/src/partitions/gpt.c
+++ b/shlibs/blkid/src/partitions/gpt.c
@@ -303,6 +303,8 @@ static int probe_gpt_pt(blkid_probe pr, const struct blkid_idmag *mag)
if (!h)
goto nothing;
+ blkid_probe_use_wiper(pr, lba * blkid_probe_get_size(pr), 8);
+
if (blkid_partitions_need_typeonly(pr))
/* caller does not ask for details about partitions */
return 0;
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c
index fb2e015..4fa826b 100644
--- a/shlibs/blkid/src/partitions/partitions.c
+++ b/shlibs/blkid/src/partitions/partitions.c
@@ -556,7 +556,7 @@ static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
if (chn->binary)
partitions_init_data(pr, chn);
- if (pr->prob_flags & BLKID_PARTS_IGNORE_PT)
+ if (!pr->wipe_size && (pr->prob_flags & BLKID_PARTS_IGNORE_PT))
goto details_only;
DBG(DEBUG_LOWPROBE,
diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c
index 677b32f..3429277 100644
--- a/shlibs/blkid/src/probe.c
+++ b/shlibs/blkid/src/probe.c
@@ -752,6 +752,7 @@ static inline void blkid_probe_start(blkid_probe pr)
if (pr) {
pr->cur_chain = NULL;
pr->prob_flags = 0;
+ blkid_probe_set_wiper(pr, 0, 0);
}
}
@@ -760,6 +761,7 @@ static inline void blkid_probe_end(blkid_probe pr)
if (pr) {
pr->cur_chain = NULL;
pr->prob_flags = 0;
+ blkid_probe_set_wiper(pr, 0, 0);
}
}
@@ -1338,3 +1340,79 @@ size_t blkid_rtrim_whitespace(unsigned char *str)
return i;
}
+/*
+ * Some mkfs-like utils wipe some parts (usually begin) of the device.
+ * For example LVM (pvcreate) or mkswap(8). This information could be used
+ * for later resolution to conflicts between superblocks.
+ *
+ * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
+ * the device. If we found another signature (for example MBR) this wiped area
+ * then the signature has been added later and LVM superblock should be ignore.
+ *
+ * Note that this heuristic is not 100% reliable, for example "pvcreate --zero
+ * n" allows to keep the begin of the device unmodified. It's probably better
+ * to use this heuristic for conflicts between superblocks and partition tables
+ * than for conflicts between filesystem superblocks -- existence of unwanted
+ * partition table is very unusual, because PT is pretty visible (parsed and
+ * interpreted by kernel).
+ */
+void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
+{
+ struct blkid_chain *chn;
+
+ if (!pr)
+ return;
+
+ if (!size) {
+ DBG(DEBUG_LOWPROBE, printf("zeroize wiper\n"));
+ pr->wipe_size = pr->wipe_off = 0;
+ pr->wipe_chain = NULL;
+ return;
+ }
+
+ chn = pr->cur_chain;
+
+ if (!chn || !chn->driver ||
+ chn->idx < 0 || chn->idx >= chn->driver->nidinfos)
+ return;
+
+ pr->wipe_size = size;
+ pr->wipe_off = off;
+ pr->wipe_chain = chn;
+
+ DBG(DEBUG_LOWPROBE,
+ printf("wiper set to %s::%s off=%jd size=%jd\n",
+ chn->driver->name,
+ chn->driver->idinfos[chn->idx]->name,
+ pr->wipe_off, pr->wipe_size));
+ return;
+}
+
+/*
+ * Returns 1 if the <@off,@size> area was wiped
+ */
+int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn,
+ blkid_loff_t off, blkid_loff_t size)
+{
+ if (!pr || !size)
+ return 0;
+
+ if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
+ if (chn)
+ *chn = pr->wipe_chain;
+ return 1;
+ }
+ return 0;
+}
+
+void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
+{
+ struct blkid_chain *chn = NULL;
+
+ if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
+ DBG(DEBUG_LOWPROBE, printf("wiped area detected -- ignore previous results\n"));
+ blkid_probe_set_wiper(pr, 0, 0);
+ blkid_probe_chain_reset_vals(pr, chn);
+ }
+}
+
diff --git a/shlibs/blkid/src/superblocks/lvm.c b/shlibs/blkid/src/superblocks/lvm.c
index facf703..3a9807c 100644
--- a/shlibs/blkid/src/superblocks/lvm.c
+++ b/shlibs/blkid/src/superblocks/lvm.c
@@ -112,6 +112,12 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
/* the mag->magic is the same string as label->type,
* but zero terminated */
blkid_probe_set_version(pr, mag->magic);
+
+ /* LVM (pvcreate) wipes begin of the device -- let's remember this
+ * to resolve conflicts bettween LVM and partition tables, ...
+ */
+ blkid_probe_set_wiper(pr, 0, 8 * 1024);
+
return 0;
}
--
1.7.3.4

View File

@ -2,7 +2,7 @@
Summary: A collection of basic system utilities
Name: util-linux
Version: 2.19
Release: 2%{?dist}
Release: 3%{?dist}
License: GPLv2 and GPLv2+ and GPLv3+ and LGPLv2+ and BSD with advertising and Public Domain
Group: System Environment/Base
URL: ftp://ftp.kernel.org/pub/linux/utils/util-linux
@ -88,6 +88,8 @@ Patch8: util-linux-ng-2.15-ipcs-32bit.patch
###
# 677569 - lsblk: SIZE integer overflow on large values
Patch9: util-linux-ng-2.19-lsblk-SIZE.patch
# 679799 - blkid reports partitioned disk sdc as being an LVM PV
Patch10: util-linux-ng-2.16-blkid-wipe.patch
%description
The util-linux package contains a large variety of low-level system
@ -203,6 +205,7 @@ cp %{SOURCE8} %{SOURCE9} .
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%build
unset LINGUAS || :
@ -748,6 +751,9 @@ fi
%changelog
* Thu Feb 24 2011 Karel Zak <kzak@redhat.com> 2.19-3
- fix #679799 - blkid reports partitioned disk sdc as being an LVM PV
* Tue Feb 15 2011 Karel Zak <kzak@redhat.com> 2.19-2
- fix #677569 - lsblk: SIZE integer overflow on large values