summaryrefslogtreecommitdiffstats
path: root/shlibs/blkid/src/partitions
diff options
context:
space:
mode:
authorKarel Zak2010-04-22 21:30:04 +0200
committerKarel Zak2010-04-22 21:30:04 +0200
commitc81e70087cfebc299bdfbbd0675958483fc8a768 (patch)
tree91286e412e19324afe6514870b200d20e290983f /shlibs/blkid/src/partitions
parentliblkid: export magic strings from raids (diff)
downloadkernel-qcow2-util-linux-c81e70087cfebc299bdfbbd0675958483fc8a768.tar.gz
kernel-qcow2-util-linux-c81e70087cfebc299bdfbbd0675958483fc8a768.tar.xz
kernel-qcow2-util-linux-c81e70087cfebc299bdfbbd0675958483fc8a768.zip
libblkid: fix collision between RAID and PT probing
The RAID signature is usually at end of the block device. We have to differentiate between: - RAID signature at the end of disk, and - RAID signature at the end of the last partition The position of the signature is same in both cases... It means we have to the parse partition table and check if the area where is RAID signature is covered by any partition. If yes, then the RAID signature belongs to the partition and has to be ignored during whole-disk probing. The second problem are RAID1 underlaying disks (=raid members). The RAID device could be partitioned, in such a case the partition table is visible from underlaying devices. These partition tables has to be ignored. The libblkid ignores partition tables on raid members now. Note that all these changes are implemented for blkid_do_safeprobe() only. The others functions allow to access all detected superblocks or partition tables. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=543749 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/blkid/src/partitions')
-rw-r--r--shlibs/blkid/src/partitions/partitions.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c
index 293ee86aa..9d8f3db7a 100644
--- a/shlibs/blkid/src/partitions/partitions.c
+++ b/shlibs/blkid/src/partitions/partitions.c
@@ -582,6 +582,9 @@ 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)
+ goto details_only;
+
DBG(DEBUG_LOWPROBE,
printf("--> starting probing loop [PARTS idx=%d]\n",
chn->idx));
@@ -620,6 +623,7 @@ static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
chn->idx));
}
+details_only:
/*
* Gather PART_ENTRY_* values if the current device is a partition.
*/
@@ -764,6 +768,82 @@ nothing:
return rc;
}
+/*
+ * This function is compatible with blkid_probe_get_partitions(), but the
+ * result is not stored in @pr and all probing is independent on the
+ * status of @pr. It's possible to call this function from arbitrary
+ * place without a care about @pr.
+ */
+static blkid_partlist blkid_probe_get_independent_partlist(blkid_probe pr)
+{
+
+ blkid_partlist ls = NULL, org_ls = NULL;
+ struct blkid_chain *chn = &pr->chains[BLKID_CHAIN_PARTS];
+ struct blkid_prval vals[BLKID_NVALS_PARTS];
+ int nvals = BLKID_NVALS_PARTS;
+ int idx;
+
+ /* save old results */
+ nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
+ idx = chn->idx;
+ if (chn->data) {
+ org_ls = chn->data;
+ chn->data = NULL;
+ }
+
+ ls = blkid_probe_get_partitions(pr);
+
+ /* restore original results */
+ chn->data = org_ls;
+ chn->idx = idx;
+
+ blkid_probe_chain_reset_vals(pr, chn);
+ blkid_probe_append_vals(pr, vals, nvals);
+
+ return ls;
+}
+
+/*
+ * Returns 1 if the device is whole-disk and the area specified by @offset and
+ * @size is covered by any partition.
+ */
+int blkid_probe_is_covered_by_pt(blkid_probe pr,
+ blkid_loff_t offset, blkid_loff_t size)
+{
+ blkid_partlist ls = NULL;
+ blkid_loff_t start, end;
+ int nparts, i, rc = 0;
+
+ DBG(DEBUG_LOWPROBE, printf(
+ "=> checking if off=%jd size=%jd covered by PT\n",
+ offset, size));
+
+ ls = blkid_probe_get_independent_partlist(pr);
+ if (!ls)
+ goto done;
+
+ nparts = blkid_partlist_numof_partitions(ls);
+ if (!nparts)
+ goto done;
+
+ end = (offset + size) >> 9;
+ start = offset >> 9;
+
+ for (i = 0; i < nparts; i++) {
+ blkid_partition par = &ls->parts[i];
+
+ if (start >= par->start && end <= par->start + par->size) {
+ rc = 1;
+ break;
+ }
+ }
+done:
+ partitions_free_data(pr, (void *)ls);
+
+ DBG(DEBUG_LOWPROBE, printf("<= %s covered by PT\n", rc ? "IS" : "NOT"));
+ return rc;
+}
+
/**
* blkid_known_pttype:
* @pttype: partiton name