mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
pvck: use new dump routines for old output
Use the recently added dump routines to produce the old/traditional pvck output, and remove the code that had been used for that. The validation/checking done by the new routines means that new lines prefixed with CHECK are printed for incorrect values.
This commit is contained in:
parent
356ea897cc
commit
2b241eb1f6
@ -121,157 +121,6 @@ static struct device *_mda_get_device_raw(struct metadata_area *mda)
|
||||
return mdac->area.dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* For circular region between region_start and region_start + region_size,
|
||||
* back up one SECTOR_SIZE from 'region_ptr' and return the value.
|
||||
* This allows reverse traversal through text metadata area to find old
|
||||
* metadata.
|
||||
*
|
||||
* Parameters:
|
||||
* region_start: start of the region (bytes)
|
||||
* region_size: size of the region (bytes)
|
||||
* region_ptr: pointer within the region (bytes)
|
||||
* NOTE: region_start <= region_ptr <= region_start + region_size
|
||||
*/
|
||||
static uint64_t _get_prev_sector_circular(uint64_t region_start,
|
||||
uint64_t region_size,
|
||||
uint64_t region_ptr)
|
||||
{
|
||||
if (region_ptr >= region_start + SECTOR_SIZE)
|
||||
return region_ptr - SECTOR_SIZE;
|
||||
|
||||
return (region_start + region_size - SECTOR_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analyze a metadata area for old metadata records in the circular buffer.
|
||||
* This function just looks through and makes a first pass at the data in
|
||||
* the sectors for particular things.
|
||||
* FIXME: do something with each metadata area (try to extract vg, write
|
||||
* raw data to file, etc)
|
||||
*/
|
||||
static int _pv_analyze_mda_raw (const struct format_type * fmt,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct mda_header *mdah;
|
||||
struct raw_locn *rlocn;
|
||||
uint64_t area_start;
|
||||
uint64_t area_size;
|
||||
uint64_t prev_sector, prev_sector2;
|
||||
uint64_t latest_mrec_offset;
|
||||
uint64_t offset;
|
||||
uint64_t offset2;
|
||||
size_t size;
|
||||
size_t size2;
|
||||
char *buf=NULL;
|
||||
struct device_area *area;
|
||||
struct mda_context *mdac;
|
||||
int r=0;
|
||||
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
|
||||
log_print("Found text metadata area: offset=" FMTu64 ", size="
|
||||
FMTu64, mdac->area.start, mdac->area.size);
|
||||
area = &mdac->area;
|
||||
|
||||
if (!(mdah = raw_read_mda_header(fmt, area, mda_is_primary(mda))))
|
||||
goto_out;
|
||||
|
||||
rlocn = mdah->raw_locns;
|
||||
|
||||
/*
|
||||
* The device area includes the metadata header as well as the
|
||||
* records, so remove the metadata header from the start and size
|
||||
*/
|
||||
area_start = area->start + MDA_HEADER_SIZE;
|
||||
area_size = area->size - MDA_HEADER_SIZE;
|
||||
latest_mrec_offset = rlocn->offset + area->start;
|
||||
|
||||
/*
|
||||
* Start searching at rlocn (point of live metadata) and go
|
||||
* backwards.
|
||||
*/
|
||||
prev_sector = _get_prev_sector_circular(area_start, area_size,
|
||||
latest_mrec_offset);
|
||||
offset = prev_sector;
|
||||
size = SECTOR_SIZE;
|
||||
offset2 = size2 = 0;
|
||||
|
||||
while (prev_sector != latest_mrec_offset) {
|
||||
prev_sector2 = prev_sector;
|
||||
prev_sector = _get_prev_sector_circular(area_start, area_size,
|
||||
prev_sector);
|
||||
if (prev_sector > prev_sector2)
|
||||
goto_out;
|
||||
/*
|
||||
* FIXME: for some reason, the whole metadata region from
|
||||
* area->start to area->start+area->size is not used.
|
||||
* Only ~32KB seems to contain valid metadata records
|
||||
* (LVM2 format - format_text). As a result, I end up with
|
||||
* "dm_config_maybe_section" returning true when there's no valid
|
||||
* metadata in a sector (sectors with all nulls).
|
||||
*/
|
||||
if (!(buf = malloc(size + size2)))
|
||||
goto_out;
|
||||
|
||||
if (!dev_read_bytes(area->dev, offset, size, buf)) {
|
||||
log_error("Failed to read dev %s offset %llu size %llu",
|
||||
dev_name(area->dev),
|
||||
(unsigned long long)offset,
|
||||
(unsigned long long)size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (size2) {
|
||||
if (!dev_read_bytes(area->dev, offset2, size2, buf + size)) {
|
||||
log_error("Failed to read dev %s offset %llu size %llu",
|
||||
dev_name(area->dev),
|
||||
(unsigned long long)offset2,
|
||||
(unsigned long long)size2);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: We could add more sophisticated metadata detection
|
||||
*/
|
||||
if (dm_config_maybe_section(buf, size + size2)) {
|
||||
/* FIXME: Validate region, pull out timestamp?, etc */
|
||||
/* FIXME: Do something with this region */
|
||||
log_verbose ("Found LVM2 metadata record at "
|
||||
"offset=" FMTu64 ", size=" FMTsize_t ", "
|
||||
"offset2=" FMTu64 " size2=" FMTsize_t,
|
||||
offset, size, offset2, size2);
|
||||
offset = prev_sector;
|
||||
size = SECTOR_SIZE;
|
||||
offset2 = size2 = 0;
|
||||
} else {
|
||||
/*
|
||||
* Not a complete metadata record, assume we have
|
||||
* metadata and just increase the size and offset.
|
||||
* Start the second region if the previous sector is
|
||||
* wrapping around towards the end of the disk.
|
||||
*/
|
||||
if (prev_sector > offset) {
|
||||
offset2 = prev_sector;
|
||||
size2 += SECTOR_SIZE;
|
||||
} else {
|
||||
offset = prev_sector;
|
||||
size += SECTOR_SIZE;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int _text_lv_setup(struct format_instance *fid __attribute__((unused)),
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
@ -1962,7 +1811,6 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
|
||||
.mda_free_sectors = _mda_free_sectors_raw,
|
||||
.mda_total_sectors = _mda_total_sectors_raw,
|
||||
.mda_in_vg = _mda_in_vg_raw,
|
||||
.pv_analyze_mda = _pv_analyze_mda_raw,
|
||||
.mda_locns_match = _mda_locns_match_raw,
|
||||
.mda_get_device = _mda_get_device_raw,
|
||||
};
|
||||
|
@ -1198,66 +1198,6 @@ int label_read(struct device *dev)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a label from a specfic, non-zero sector. This is used in only
|
||||
* one place: pvck/pv_analyze.
|
||||
*/
|
||||
|
||||
int label_read_sector(struct device *dev, uint64_t read_sector)
|
||||
{
|
||||
struct block *bb = NULL;
|
||||
uint64_t block_num;
|
||||
uint64_t block_sector;
|
||||
uint64_t start_sector;
|
||||
int is_lvm_device = 0;
|
||||
int result;
|
||||
int ret;
|
||||
|
||||
block_num = read_sector / BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
block_sector = block_num * BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
start_sector = read_sector % BCACHE_BLOCK_SIZE_IN_SECTORS;
|
||||
|
||||
if (!label_scan_open(dev)) {
|
||||
log_error("Error opening device %s for prefetch %llu sector.",
|
||||
dev_name(dev), (unsigned long long)block_num);
|
||||
return false;
|
||||
}
|
||||
|
||||
bcache_prefetch(scan_bcache, dev->bcache_fd, block_num);
|
||||
|
||||
if (!bcache_get(scan_bcache, dev->bcache_fd, block_num, 0, &bb)) {
|
||||
log_error("Scan failed to read %s at %llu",
|
||||
dev_name(dev), (unsigned long long)block_num);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: check if scan_sector is larger than the bcache block size.
|
||||
* If it is, we need to fetch a later block from bcache.
|
||||
*/
|
||||
|
||||
result = _process_block(NULL, NULL, dev, bb, block_sector, start_sector, &is_lvm_device);
|
||||
|
||||
if (!result && is_lvm_device) {
|
||||
log_error("Scan failed to process %s", dev_name(dev));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!result || !is_lvm_device) {
|
||||
log_error("Could not find LVM label on %s", dev_name(dev));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
out:
|
||||
if (bb)
|
||||
bcache_put(bb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int label_scan_setup_bcache(void)
|
||||
{
|
||||
if (!scan_bcache) {
|
||||
|
@ -4664,41 +4664,6 @@ int is_real_vg(const char *vg_name)
|
||||
return (vg_name && *vg_name != '#');
|
||||
}
|
||||
|
||||
static int _analyze_mda(struct metadata_area *mda, void *baton)
|
||||
{
|
||||
const struct format_type *fmt = baton;
|
||||
mda->ops->pv_analyze_mda(fmt, mda);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* 0 - fail
|
||||
* 1 - success
|
||||
*/
|
||||
int pv_analyze(struct cmd_context *cmd, struct device *dev,
|
||||
uint64_t label_sector)
|
||||
{
|
||||
struct label *label;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (!(label = lvmcache_get_dev_label(dev))) {
|
||||
log_error("Could not find LVM label on %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_print("Found label on %s, sector %"PRIu64", type=%.8s",
|
||||
dev_name(dev), label->sector, label->type);
|
||||
|
||||
/*
|
||||
* Next, loop through metadata areas
|
||||
*/
|
||||
info = label->info;
|
||||
lvmcache_foreach_mda(info, _analyze_mda, (void *)lvmcache_fmt(info));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FIXME: remove / combine this with locking? */
|
||||
int vg_check_write_mode(struct volume_group *vg)
|
||||
{
|
||||
|
143
tools/pvck.c
143
tools/pvck.c
@ -83,13 +83,16 @@ static char *_chars_to_hexstr(void *in, void *out, int num, int max, const char
|
||||
return out;
|
||||
}
|
||||
|
||||
static int _check_label_header(struct label_header *lh, uint64_t labelsector)
|
||||
static int _check_label_header(struct label_header *lh, uint64_t labelsector,
|
||||
int *found_label)
|
||||
{
|
||||
uint32_t crc;
|
||||
int good_id = 1, good_type = 1;
|
||||
int bad = 0;
|
||||
|
||||
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
|
||||
log_print("CHECK: label_header.id expected %s", LABEL_ID);
|
||||
good_id = 0;
|
||||
bad++;
|
||||
}
|
||||
|
||||
@ -113,9 +116,14 @@ static int _check_label_header(struct label_header *lh, uint64_t labelsector)
|
||||
|
||||
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
|
||||
log_print("CHECK: label_header.type expected %s", LVM2_LABEL);
|
||||
good_type = 0;
|
||||
bad++;
|
||||
}
|
||||
|
||||
/* Report a label is found if at least id and type are correct. */
|
||||
if (found_label && good_id && good_type)
|
||||
*found_label = 1;
|
||||
|
||||
if (bad)
|
||||
return 0;
|
||||
return 1;
|
||||
@ -140,10 +148,11 @@ static int _check_pv_header(struct pv_header *ph)
|
||||
* mda_offset/mda_size are from the pv_header/disk_locn and could
|
||||
* be incorrect.
|
||||
*/
|
||||
static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_offset, uint64_t mda_size)
|
||||
static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_offset, uint64_t mda_size, int *found_header)
|
||||
{
|
||||
char str[256];
|
||||
uint32_t crc;
|
||||
int good_magic = 1;
|
||||
int bad = 0;
|
||||
|
||||
crc = calc_crc(INITIAL_CRC, (uint8_t *)mh->magic,
|
||||
@ -156,6 +165,7 @@ static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_of
|
||||
|
||||
if (memcmp(mh->magic, FMTT_MAGIC, sizeof(mh->magic))) {
|
||||
log_print("CHECK: mda_header_%d.magic expected 0x%s", mda_num, _chars_to_hexstr((void *)&FMTT_MAGIC, str, 16, 256, "mda_header.magic"));
|
||||
good_magic = 0;
|
||||
bad++;
|
||||
}
|
||||
|
||||
@ -174,6 +184,10 @@ static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_of
|
||||
bad++;
|
||||
}
|
||||
|
||||
/* Report a header is found if at least magic is correct. */
|
||||
if (found_header && good_magic)
|
||||
*found_header = 1;
|
||||
|
||||
if (bad)
|
||||
return 0;
|
||||
return 1;
|
||||
@ -684,6 +698,7 @@ static int _dump_meta_text(struct device *dev,
|
||||
config_destroy(cft);
|
||||
}
|
||||
|
||||
if (print_fields || print_metadata)
|
||||
log_print("metadata text at %llu crc 0x%x # vgname %s seqno %u",
|
||||
(unsigned long long)(mda_offset + meta_offset), crc,
|
||||
vgname ? vgname : "?", seqno);
|
||||
@ -720,6 +735,7 @@ static int _dump_meta_text(struct device *dev,
|
||||
|
||||
static int _dump_label_and_pv_header(struct cmd_context *cmd, int print_fields,
|
||||
struct device *dev,
|
||||
int *found_label,
|
||||
uint64_t *mda1_offset, uint64_t *mda1_size,
|
||||
uint64_t *mda2_offset, uint64_t *mda2_size)
|
||||
{
|
||||
@ -771,7 +787,7 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, int print_fields,
|
||||
log_print("label_header.type %s", _chars_to_str(lh->type, str, 8, 256, "label_header.type"));
|
||||
}
|
||||
|
||||
if (!_check_label_header(lh, labelsector))
|
||||
if (!_check_label_header(lh, labelsector, found_label))
|
||||
bad++;
|
||||
|
||||
/*
|
||||
@ -972,7 +988,8 @@ static int _dump_mda_header(struct cmd_context *cmd,
|
||||
const char *tofile,
|
||||
struct device *dev,
|
||||
uint64_t mda_offset, uint64_t mda_size,
|
||||
uint32_t *checksum0_ret)
|
||||
uint32_t *checksum0_ret,
|
||||
int *found_header)
|
||||
{
|
||||
char str[256];
|
||||
char *buf;
|
||||
@ -1018,7 +1035,7 @@ static int _dump_mda_header(struct cmd_context *cmd,
|
||||
log_print("mda_header_%d.size %llu", mda_num, (unsigned long long)xlate64(mh->size));
|
||||
}
|
||||
|
||||
if (!_check_mda_header(mh, mda_num, mda_offset, mda_size))
|
||||
if (!_check_mda_header(mh, mda_num, mda_offset, mda_size, found_header))
|
||||
bad++;
|
||||
|
||||
if (print_area) {
|
||||
@ -1108,7 +1125,7 @@ static int _dump_headers(struct cmd_context *cmd,
|
||||
|
||||
label_scan_setup_bcache();
|
||||
|
||||
if (!_dump_label_and_pv_header(cmd, 1, dev,
|
||||
if (!_dump_label_and_pv_header(cmd, 1, dev, NULL,
|
||||
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
|
||||
bad++;
|
||||
|
||||
@ -1125,7 +1142,7 @@ static int _dump_headers(struct cmd_context *cmd,
|
||||
* which may have been corrupted.
|
||||
*/
|
||||
|
||||
if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum))
|
||||
if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, NULL))
|
||||
bad++;
|
||||
|
||||
/*
|
||||
@ -1136,7 +1153,7 @@ static int _dump_headers(struct cmd_context *cmd,
|
||||
* but there is a valid header elsewhere.
|
||||
*/
|
||||
if (mda2_offset) {
|
||||
if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum))
|
||||
if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
|
||||
bad++;
|
||||
|
||||
/* This probably indicates that one was committed and the other not. */
|
||||
@ -1181,7 +1198,7 @@ static int _dump_metadata(struct cmd_context *cmd,
|
||||
|
||||
label_scan_setup_bcache();
|
||||
|
||||
if (!_dump_label_and_pv_header(cmd, 0, dev,
|
||||
if (!_dump_label_and_pv_header(cmd, 0, dev, NULL,
|
||||
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
|
||||
bad++;
|
||||
|
||||
@ -1204,14 +1221,14 @@ static int _dump_metadata(struct cmd_context *cmd,
|
||||
*/
|
||||
|
||||
if (mda_num == 1) {
|
||||
if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, 4096, mda1_size, &mda1_checksum))
|
||||
if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, 4096, mda1_size, &mda1_checksum, NULL))
|
||||
bad++;
|
||||
} else if (mda_num == 2) {
|
||||
if (!mda2_offset) {
|
||||
log_print("CHECK: second mda not found");
|
||||
bad++;
|
||||
} else {
|
||||
if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, mda2_offset, mda2_size, &mda2_checksum))
|
||||
if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
|
||||
bad++;
|
||||
}
|
||||
}
|
||||
@ -1223,16 +1240,59 @@ static int _dump_metadata(struct cmd_context *cmd,
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
static int _dump_found(struct cmd_context *cmd, struct device *dev,
|
||||
uint64_t labelsector)
|
||||
{
|
||||
uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0;
|
||||
uint32_t mda1_checksum = 0, mda2_checksum = 0;
|
||||
int found_label = 0, found_header1 = 0, found_header2 = 0;
|
||||
int bad = 0;
|
||||
|
||||
if (!_dump_label_and_pv_header(cmd, 0, dev, &found_label,
|
||||
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
|
||||
bad++;
|
||||
|
||||
if (found_label && mda1_offset) {
|
||||
if (!_dump_mda_header(cmd, 0, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, &found_header1))
|
||||
bad++;
|
||||
}
|
||||
|
||||
if (found_label && mda2_offset) {
|
||||
if (!_dump_mda_header(cmd, 0, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, &found_header2))
|
||||
bad++;
|
||||
}
|
||||
|
||||
if (found_label)
|
||||
log_print("Found label on %s, sector %llu, type=LVM2 001",
|
||||
dev_name(dev), (unsigned long long)labelsector);
|
||||
else {
|
||||
log_error("Could not find LVM label on %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (found_header1)
|
||||
log_print("Found text metadata area: offset=%llu, size=%llu",
|
||||
(unsigned long long)mda1_offset,
|
||||
(unsigned long long)mda1_size);
|
||||
|
||||
if (found_header2)
|
||||
log_print("Found text metadata area: offset=%llu, size=%llu",
|
||||
(unsigned long long)mda2_offset,
|
||||
(unsigned long long)mda2_size);
|
||||
|
||||
if (bad)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pvck(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct dm_list devs;
|
||||
struct device_list *devl;
|
||||
struct device *dev;
|
||||
const char *dump;
|
||||
const char *pv_name;
|
||||
uint64_t labelsector;
|
||||
uint64_t labelsector = 1;
|
||||
int bad = 0;
|
||||
int i;
|
||||
int ret_max = ECMD_PROCESSED;
|
||||
|
||||
if (arg_is_set(cmd, dump_ARG)) {
|
||||
dump = arg_str_value(cmd, dump_ARG, NULL);
|
||||
@ -1253,56 +1313,29 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* The old/original form of pvck, which did not do much,
|
||||
* but this is here to preserve the historical output.
|
||||
*/
|
||||
|
||||
if (arg_is_set(cmd, labelsector_ARG))
|
||||
labelsector = arg_uint64_value(cmd, labelsector_ARG, UINT64_C(0));
|
||||
|
||||
dm_list_init(&devs);
|
||||
label_scan_setup_bcache();
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
dm_unescape_colons_and_at_signs(argv[i], NULL, NULL);
|
||||
|
||||
pv_name = argv[i];
|
||||
|
||||
dev = dev_cache_get(cmd, pv_name, cmd->filter);
|
||||
|
||||
if (!dev) {
|
||||
if (!(dev = dev_cache_get(cmd, argv[i], cmd->filter))) {
|
||||
log_error("Device %s %s.", pv_name, dev_cache_filtered_reason(pv_name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(devl = zalloc(sizeof(*devl))))
|
||||
continue;
|
||||
|
||||
devl->dev = dev;
|
||||
dm_list_add(&devs, &devl->list);
|
||||
if (!_dump_found(cmd, dev, labelsector))
|
||||
bad++;
|
||||
}
|
||||
|
||||
label_scan_setup_bcache();
|
||||
label_scan_devs(cmd, cmd->filter, &devs);
|
||||
|
||||
dm_list_iterate_items(devl, &devs) {
|
||||
/*
|
||||
* The scan above will populate lvmcache with any info from the
|
||||
* standard locations at the start of the device. Now populate
|
||||
* lvmcache with any info from non-standard offsets.
|
||||
*
|
||||
* FIXME: is it possible for a real lvm label sector to be
|
||||
* anywhere other than the first four sectors of the disk?
|
||||
* If not, drop the code in label_read_sector/find_lvm_header
|
||||
* that supports searching at any sector.
|
||||
*/
|
||||
if (labelsector) {
|
||||
if (!label_read_sector(devl->dev, labelsector)) {
|
||||
stack;
|
||||
ret_max = ECMD_FAILED;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pv_analyze(cmd, devl->dev, labelsector)) {
|
||||
stack;
|
||||
ret_max = ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_max;
|
||||
if (bad)
|
||||
return ECMD_FAILED;
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user