summaryrefslogtreecommitdiffstats
path: root/shlibs/blkid/src/probe.c
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/probe.c
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/probe.c')
-rw-r--r--shlibs/blkid/src/probe.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c
index 56e66a311..9021a7e84 100644
--- a/shlibs/blkid/src/probe.c
+++ b/shlibs/blkid/src/probe.c
@@ -290,21 +290,33 @@ struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
{
- int rc;
+ int rc, org_prob_flags;
+ struct blkid_chain *org_chn;
if (!pr || !chn)
return NULL;
+ /* save the current setting -- the binary API has to be completely
+ * independent on the current probing status
+ */
+ org_chn = pr->cur_chain;
+ org_prob_flags = pr->prob_flags;
+
pr->cur_chain = chn;
+ pr->prob_flags = 0;
chn->binary = TRUE;
blkid_probe_chain_reset_position(chn);
rc = chn->driver->probe(pr, chn);
chn->binary = FALSE;
- pr->cur_chain = NULL;
blkid_probe_chain_reset_position(chn);
+ /* restore the original setting
+ */
+ pr->cur_chain = org_chn;
+ pr->prob_flags = org_prob_flags;
+
if (rc != 0)
return NULL;
@@ -679,6 +691,22 @@ int blkid_probe_set_dimension(blkid_probe pr,
return 0;
}
+static inline void blkid_probe_start(blkid_probe pr)
+{
+ if (pr) {
+ pr->cur_chain = NULL;
+ pr->prob_flags = 0;
+ }
+}
+
+static inline void blkid_probe_end(blkid_probe pr)
+{
+ if (pr) {
+ pr->cur_chain = NULL;
+ pr->prob_flags = 0;
+ }
+}
+
/**
* blkid_do_probe:
* @pr: prober
@@ -730,9 +758,10 @@ int blkid_do_probe(blkid_probe pr)
do {
struct blkid_chain *chn = pr->cur_chain;
- if (!chn)
+ if (!chn) {
+ blkid_probe_start(pr);
chn = pr->cur_chain = &pr->chains[0];
-
+ }
/* we go to the next chain only when the previous probing
* result was nothing (rc == 1) and when the current chain is
* disabled or we are at end of the current chain (chain->idx +
@@ -747,8 +776,10 @@ int blkid_do_probe(blkid_probe pr)
if (idx < BLKID_NCHAINS)
chn = pr->cur_chain = &pr->chains[idx];
- else
+ else {
+ blkid_probe_end(pr);
return 1; /* all chains already probed */
+ }
}
chn->binary = FALSE; /* for sure... */
@@ -780,7 +811,9 @@ int blkid_do_probe(blkid_probe pr)
*
* Note about suberblocks chain -- the function does not check for filesystems
* when a RAID signature is detected. The function also does not check for
- * collision between RAIDs. The first detected RAID is returned.
+ * collision between RAIDs. The first detected RAID is returned. The function
+ * checks for collision between partition table and RAID signature -- it's
+ * recommended to enable partitions chain together with superblocks chain.
*
* Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
* detected and -1 on case of error.
@@ -792,6 +825,8 @@ int blkid_do_safeprobe(blkid_probe pr)
if (!pr)
return -1;
+ blkid_probe_start(pr);
+
for (i = 0; i < BLKID_NCHAINS; i++) {
struct blkid_chain *chn;
@@ -819,7 +854,7 @@ int blkid_do_safeprobe(blkid_probe pr)
}
done:
- pr->cur_chain = NULL;
+ blkid_probe_end(pr);
if (rc < 0)
return rc;
return count ? 0 : 1;
@@ -844,6 +879,8 @@ int blkid_do_fullprobe(blkid_probe pr)
if (!pr)
return -1;
+ blkid_probe_start(pr);
+
for (i = 0; i < BLKID_NCHAINS; i++) {
int rc;
struct blkid_chain *chn;
@@ -872,7 +909,7 @@ int blkid_do_fullprobe(blkid_probe pr)
}
done:
- pr->cur_chain = NULL;
+ blkid_probe_end(pr);
if (rc < 0)
return rc;
return count ? 0 : 1;