diff options
-rw-r--r-- | lib/config/config.c | 25 | ||||
-rw-r--r-- | lib/format_text/format-text.c | 94 |
2 files changed, 33 insertions, 86 deletions
diff --git a/lib/config/config.c b/lib/config/config.c index 485063a3d..25a87c983 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -501,6 +501,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r checksum_fn_t checksum_fn, uint32_t checksum, int checksum_only, int no_dup_node_check) { + char namebuf[NAME_LEN + 1] __attribute__((aligned(8))); + int namelen = 0; + int bad_name = 0; char *fb, *fe; int r = 0; int sz, use_plain_read = 1; @@ -548,6 +551,23 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r fb = buf; + if (!(dev->flags & DEV_REGULAR)) { + memcpy(namebuf, buf, NAME_LEN); + + while (namebuf[namelen] && !isspace(namebuf[namelen]) && namebuf[namelen] != '{' && namelen < (NAME_LEN - 1)) + namelen++; + namebuf[namelen] = '\0'; + + /* + * Check that the text metadata begins with a valid name. + */ + if (!validate_name(namebuf)) { + log_warn("WARNING: Metadata location on %s at offset %llu begins with invalid name.", + dev_name(dev), (unsigned long long)offset); + bad_name = 1; + } + } + /* * The checksum passed in is the checksum from the mda_header * preceding this metadata. They should always match. @@ -557,10 +577,13 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r if (checksum_fn && checksum != (checksum_fn(checksum_fn(INITIAL_CRC, (const uint8_t *)fb, size), (const uint8_t *)(fb + size), size2))) { - log_error("%s: Checksum error at offset %" PRIu64, dev_name(dev), (uint64_t) offset); + log_warn("WARNING: Checksum error on %s at offset %llu.", dev_name(dev), (unsigned long long)offset); goto out; } + if (bad_name) + goto out; + if (!checksum_only) { fe = fb + size + size2; if (no_dup_node_check) { diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index dd550a6eb..26e55cec4 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -296,24 +296,11 @@ static struct raw_locn *_read_metadata_location_vg(struct cmd_context *cmd, const char *vgname, int *precommitted) { - size_t len; - char vgnamebuf[NAME_LEN + 2] __attribute__((aligned(8))); struct raw_locn *rlocn, *rlocn_precommitted; - struct lvmcache_info *info; - struct lvmcache_vgsummary vgsummary_orphan = { - .vgname = FMT_TEXT_ORPHAN_VG_NAME, - }; - int rlocn_was_ignored; - - dm_list_init(&vgsummary_orphan.pvsummaries); - - memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME)); rlocn = mdah->raw_locns; /* Slot 0 */ rlocn_precommitted = rlocn + 1; /* Slot 1 */ - rlocn_was_ignored = rlocn_is_ignored(rlocn); - /* Should we use precommitted metadata? */ if (*precommitted && rlocn_precommitted->size && (rlocn_precommitted->offset != rlocn->offset)) { @@ -338,42 +325,7 @@ static struct raw_locn *_read_metadata_location_vg(struct cmd_context *cmd, if (!rlocn->offset && !rlocn->size) return NULL; - /* - * Don't try to check existing metadata - * if given vgname is an empty string. - */ - if (!vgname || !*vgname) - return rlocn; - - /* - * If live rlocn has ignored flag, data will be out-of-date so skip further checks. - */ - if (rlocn_was_ignored) - return rlocn; - - /* - * Verify that the VG metadata pointed to by the rlocn - * begins with a valid vgname. - */ - memset(vgnamebuf, 0, sizeof(vgnamebuf)); - - if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf)) - goto fail; - - if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) && - (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) - return rlocn; - fail: - log_error("Metadata on %s at %llu has wrong VG name \"%s\" expected %s.", - dev_name(dev_area->dev), - (unsigned long long)(dev_area->start + rlocn->offset), - vgnamebuf, vgname); - - if ((info = lvmcache_info_from_pvid(dev_area->dev->pvid, dev_area->dev, 0)) && - !lvmcache_update_vgname_and_id(cmd, info, &vgsummary_orphan)) - stack; - - return NULL; + return rlocn; } /* @@ -487,9 +439,13 @@ static struct volume_group *_vg_read_raw_area(struct cmd_context *cmd, rlocn->checksum, &when, &desc); - if (!vg) { - /* FIXME: detect and handle errors, and distinguish from the optimization - that skips parsing the metadata which also returns NULL. */ + if (!vg && !*use_previous_vg) { + log_warn("WARNING: failed to read metadata text on %s at %llu size %llu for VG %s.", + dev_name(area->dev), + (unsigned long long)(area->start + rlocn->offset), + (unsigned long long)rlocn->size, + vgname); + return NULL; } log_debug_metadata("Found metadata on %s at %llu size %llu for VG %s", @@ -498,7 +454,7 @@ static struct volume_group *_vg_read_raw_area(struct cmd_context *cmd, (unsigned long long)rlocn->size, vgname); - if (vg && precommitted) + if (precommitted) vg->status |= PRECOMMITTED; out: @@ -1533,8 +1489,6 @@ int read_metadata_location_summary(const struct format_type *fmt, { struct raw_locn *rlocn; uint32_t wrap = 0; - unsigned int len = 0; - char namebuf[NAME_LEN + 1] __attribute__((aligned(8))); uint64_t max_size; if (!mdah) { @@ -1564,36 +1518,6 @@ int read_metadata_location_summary(const struct format_type *fmt, } /* - * This code reading the start of the metadata area and verifying that - * it looks like a vgname can be removed. The checksum verifies it. - */ - log_debug_metadata("Reading metadata_vgname summary from %s at %llu", - dev_name(dev_area->dev), - (unsigned long long)(dev_area->start + rlocn->offset)); - - memset(namebuf, 0, sizeof(namebuf)); - - if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, namebuf)) - stack; - - while (namebuf[len] && !isspace(namebuf[len]) && namebuf[len] != '{' && - len < (NAME_LEN - 1)) - len++; - - namebuf[len] = '\0'; - - /* - * Check that the text metadata in the circular buffer begins with a - * valid vg name. - */ - if (!validate_name(namebuf)) { - log_warn("WARNING: Metadata location on %s at %llu begins with invalid VG name.", - dev_name(dev_area->dev), - (unsigned long long)(dev_area->start + rlocn->offset)); - return 0; - } - - /* * This function is used to read the vg summary during label scan. * Save the text start location and checksum during scan. After the VG * lock is acquired in vg_read, we can reread the mda_header, and |