diff options
author | Karel Zak | 2010-04-22 21:30:04 +0200 |
---|---|---|
committer | Karel Zak | 2010-04-22 21:30:04 +0200 |
commit | c81e70087cfebc299bdfbbd0675958483fc8a768 (patch) | |
tree | 91286e412e19324afe6514870b200d20e290983f /shlibs/blkid/src/probe.c | |
parent | liblkid: export magic strings from raids (diff) | |
download | kernel-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.c | 53 |
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; |