summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/activate/activate.c82
-rw-r--r--lib/cache/lvmcache.c405
-rw-r--r--lib/cache/lvmcache.h3
-rw-r--r--lib/commands/toolcontext.c4
-rw-r--r--lib/commands/toolcontext.h1
-rw-r--r--lib/config/config_settings.h7
-rw-r--r--lib/config/defaults.h1
-rw-r--r--lib/metadata/metadata.c71
-rw-r--r--lib/metadata/vg.c5
-rw-r--r--lib/misc/lvm-globals.c12
-rw-r--r--lib/misc/lvm-globals.h2
-rw-r--r--tools/commands.h8
-rw-r--r--tools/lvmcmdline.c1
-rw-r--r--tools/tools.h1
14 files changed, 260 insertions, 343 deletions
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 5542f8434..1fc07e3ea 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -28,6 +28,7 @@
#include "config.h"
#include "segtype.h"
#include "sharedlib.h"
+#include "lvmcache.h"
#include <limits.h>
#include <fcntl.h>
@@ -2123,6 +2124,17 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
goto_out;
+ /*
+ * Save old and new (current and precommitted) versions of the
+ * VG metadata for lv_resume() to use, since lv_resume can't
+ * read metadata given that devices are suspended. lv_resume()
+ * will resume LVs using the old/current metadata if the vg_commit
+ * did happen (or failed), and it will resume LVs using the
+ * new/precommitted metadata if the vg_commit succeeded.
+ */
+ lvmcache_save_suspended_vg(lv->vg, 0);
+ lvmcache_save_suspended_vg(lv_pre->vg, 1);
+
if (!info.exists || info.suspended) {
if (!error_if_not_suspended) {
r = 1;
@@ -2281,15 +2293,54 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int error_if_not_active,
const struct logical_volume *lv)
{
- const struct logical_volume *lv_to_free = NULL;
+ struct volume_group *vg = NULL;
+ struct logical_volume *lv_found = NULL;
+ const union lvid *lvid;
+ const char *vgid;
struct lvinfo info;
int r = 0;
if (!activation())
return 1;
- if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
- goto_out;
+ /*
+ * When called in clvmd, lvid_s is set and lv is not. We need to
+ * get the VG metadata without reading disks because devs are
+ * suspended. lv_suspend() saved old and new VG metadata for us
+ * to use here. If vg_commit() happened, lvmcache_get_suspended_vg
+ * will return the new metadata for us to use in resuming LVs.
+ * If vg_commit() did not happen, lvmcache_get_suspended_vg
+ * returns the old metadata which we use to resume LVs.
+ */
+ if (!lv && lvid_s) {
+ lvid = (const union lvid *) lvid_s;
+ vgid = (const char *)lvid->id[0].uuid;
+
+ if ((vg = lvmcache_get_suspended_vg(vgid))) {
+ log_debug_activation("Resuming LVID %s found saved vg seqno %d %s", lvid_s, vg->seqno, vg->name);
+ if ((lv_found = find_lv_in_vg_by_lvid(vg, lvid))) {
+ log_debug_activation("Resuming LVID %s found saved LV %s", lvid_s, display_lvname(lv_found));
+ lv = lv_found;
+ } else
+ log_debug_activation("Resuming LVID %s did not find saved LV", lvid_s);
+ } else
+ log_debug_activation("Resuming LVID %s did not find saved VG", lvid_s);
+
+ /*
+ * resume must have been called without a preceding suspend,
+ * so we need to read the vg.
+ */
+
+ if (!lv) {
+ log_debug_activation("Resuming LVID %s reading VG", lvid_s);
+ if (!(lv_found = lv_from_lvid(cmd, lvid_s, 0))) {
+ log_debug_activation("Resuming LVID %s failed to read VG", lvid_s);
+ goto out;
+ }
+
+ lv = lv_found;
+ }
+ }
if (!lv_is_origin(lv) && !lv_is_thin_volume(lv) && !lv_is_thin_pool(lv))
laopts->origin_only = 0;
@@ -2334,9 +2385,6 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
r = 1;
out:
- if (lv_to_free)
- release_vg(lv_to_free->vg);
-
return r;
}
@@ -2463,6 +2511,10 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, const struct logical_volume *lv)
{
const struct logical_volume *lv_to_free = NULL;
+ struct volume_group *vg = NULL;
+ struct logical_volume *lv_found = NULL;
+ const union lvid *lvid;
+ const char *vgid;
int r = 0;
if (!activation()) {
@@ -2470,6 +2522,24 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
+ /*
+ * This function is called while devices are suspended,
+ * so try to use the copy of the vg that was saved in
+ * lv_suspend.
+ */
+ if (!lv && lvid_s) {
+ lvid = (const union lvid *) lvid_s;
+ vgid = (const char *)lvid->id[0].uuid;
+
+ if ((vg = lvmcache_get_suspended_vg(vgid))) {
+ log_debug_activation("activation_filter for %s found saved VG seqno %d %s", lvid_s, vg->seqno, vg->name);
+ if ((lv_found = find_lv_in_vg_by_lvid(vg, lvid))) {
+ log_debug_activation("activation_filter for %s found saved LV %s", lvid_s, display_lvname(lv_found));
+ lv = lv_found;
+ }
+ }
+ }
+
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
goto_out;
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 8253fd237..2a9157988 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -63,16 +63,42 @@ struct lvmcache_vginfo {
char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
- size_t vgmetadata_size;
- char *vgmetadata; /* Copy of VG metadata as format_text string */
- struct dm_config_tree *cft; /* Config tree created from vgmetadata */
- /* Lifetime is directly tied to vgmetadata */
- struct volume_group *cached_vg;
- unsigned holders;
- unsigned vg_use_count; /* Counter of vg reusage */
- unsigned precommitted; /* Is vgmetadata live or precommitted? */
- unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
int independent_metadata_location; /* metadata read from independent areas */
+
+ /*
+ * The following are not related to lvmcache or vginfo,
+ * but are borrowing the vginfo to store the data.
+ *
+ * suspended_vg_* are used only by clvmd suspend/resume.
+ * In suspend, both old (current) and new (precommitted)
+ * metadata is saved. (Each in three forms: buffer, cft,
+ * and vg). In resume, if the vg was committed
+ * (suspended_vg_committed is set), then LVs are resumed
+ * using the new metadata, but if the vg wasn't committed,
+ * then LVs are resumed using the old metadata.
+ *
+ * suspended_vg_committed is set to 1 when clvmd gets
+ * LCK_VG_COMMIT from vg_commit().
+ *
+ * These fields are only used between suspend and resume
+ * in clvmd, and should never be used in any other way.
+ * The contents of this data are never changed. This
+ * data does not really belong in lvmcache, it's unrelated
+ * to lvmcache or vginfo, but it's just a convenient place
+ * for clvmd to stash the VG between suspend and resume
+ * (since the same caller isn't present to pass the VG to
+ * both suspend and resume in the case of clvmd.)
+ *
+ * This data is not really a "cache" of the VG, it is just
+ * a location to pass the VG between suspend and resume.
+ */
+ int suspended_vg_committed;
+ char *suspended_vg_old_buf;
+ struct dm_config_tree *suspended_vg_old_cft;
+ struct volume_group *suspended_vg_old;
+ char *suspended_vg_new_buf;
+ struct dm_config_tree *suspended_vg_new_cft;
+ struct volume_group *suspended_vg_new;
};
static struct dm_hash_table *_pvid_hash = NULL;
@@ -139,73 +165,7 @@ void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd)
_has_scanned = 1;
}
-/* Volume Group metadata cache functions */
-static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
-{
- if (!vginfo || !vginfo->vgmetadata)
- return;
-
- dm_free(vginfo->vgmetadata);
-
- vginfo->vgmetadata = NULL;
-
- /* Release also cached config tree */
- if (vginfo->cft) {
- dm_config_destroy(vginfo->cft);
- vginfo->cft = NULL;
- }
-
- log_debug_cache("Metadata cache: VG %s wiped.", vginfo->vgname);
-
- release_vg(vginfo->cached_vg);
-}
-
-/*
- * Cache VG metadata against the vginfo with matching vgid.
- */
-static void _store_metadata(struct volume_group *vg, unsigned precommitted)
-{
- char uuid[64] __attribute__((aligned(8)));
- struct lvmcache_vginfo *vginfo;
- char *data;
- size_t size;
-
- if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id))) {
- stack;
- return;
- }
-
- if (!(size = export_vg_to_buffer(vg, &data))) {
- stack;
- _free_cached_vgmetadata(vginfo);
- return;
- }
-
- /* Avoid reparsing of the same data string */
- if (vginfo->vgmetadata && vginfo->vgmetadata_size == size &&
- strcmp(vginfo->vgmetadata, data) == 0)
- dm_free(data);
- else {
- _free_cached_vgmetadata(vginfo);
- vginfo->vgmetadata_size = size;
- vginfo->vgmetadata = data;
- }
-
- vginfo->precommitted = precommitted;
-
- if (!id_write_format((const struct id *)vginfo->vgid, uuid, sizeof(uuid))) {
- stack;
- return;
- }
-
- log_debug_cache("Metadata cache: VG %s (%s) stored (%" PRIsize_t " bytes%s).",
- vginfo->vgname, uuid, size,
- precommitted ? ", precommitted" : "");
-}
-
-static void _update_cache_info_lock_state(struct lvmcache_info *info,
- int locked,
- int *cached_vgmetadata_valid)
+static void _update_cache_info_lock_state(struct lvmcache_info *info, int locked)
{
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
@@ -213,10 +173,8 @@ static void _update_cache_info_lock_state(struct lvmcache_info *info,
* Cache becomes invalid whenever lock state changes unless
* exclusive VG_GLOBAL is held (i.e. while scanning).
*/
- if (!lvmcache_vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) {
+ if (!lvmcache_vgname_is_locked(VG_GLOBAL) && (was_locked != locked))
info->status |= CACHE_INVALID;
- *cached_vgmetadata_valid = 0;
- }
if (locked)
info->status |= CACHE_LOCKED;
@@ -228,14 +186,9 @@ static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo,
int locked)
{
struct lvmcache_info *info;
- int cached_vgmetadata_valid = 1;
dm_list_iterate_items(info, &vginfo->infos)
- _update_cache_info_lock_state(info, locked,
- &cached_vgmetadata_valid);
-
- if (!cached_vgmetadata_valid)
- _free_cached_vgmetadata(vginfo);
+ _update_cache_info_lock_state(info, locked);
}
static void _update_cache_lock_state(const char *vgname, int locked)
@@ -248,6 +201,35 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
+static void _suspended_vg_free(struct lvmcache_vginfo *vginfo, int free_old, int free_new)
+{
+ if (free_old) {
+ if (vginfo->suspended_vg_old_buf)
+ dm_free(vginfo->suspended_vg_old_buf);
+ if (vginfo->suspended_vg_old_cft)
+ dm_config_destroy(vginfo->suspended_vg_old_cft);
+ if (vginfo->suspended_vg_old)
+ release_vg(vginfo->suspended_vg_old);
+
+ vginfo->suspended_vg_old_buf = NULL;
+ vginfo->suspended_vg_old_cft = NULL;
+ vginfo->suspended_vg_old = NULL;
+ }
+
+ if (free_new) {
+ if (vginfo->suspended_vg_new_buf)
+ dm_free(vginfo->suspended_vg_new_buf);
+ if (vginfo->suspended_vg_new_cft)
+ dm_config_destroy(vginfo->suspended_vg_new_cft);
+ if (vginfo->suspended_vg_new)
+ release_vg(vginfo->suspended_vg_new);
+
+ vginfo->suspended_vg_new_buf = NULL;
+ vginfo->suspended_vg_new_cft = NULL;
+ vginfo->suspended_vg_new = NULL;
+ }
+}
+
static void _drop_metadata(const char *vgname, int drop_precommitted)
{
struct lvmcache_vginfo *vginfo;
@@ -256,25 +238,98 @@ static void _drop_metadata(const char *vgname, int drop_precommitted)
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
return;
- /*
- * Invalidate cached PV labels.
- * If cached precommitted metadata exists that means we
- * already invalidated the PV labels (before caching it)
- * and we must not do it again.
- */
- if (!drop_precommitted && vginfo->precommitted && !vginfo->vgmetadata)
- log_error(INTERNAL_ERROR "metadata commit (or revert) missing before "
- "dropping metadata from cache.");
-
- if (drop_precommitted || !vginfo->precommitted)
+ if (drop_precommitted)
dm_list_iterate_items(info, &vginfo->infos)
info->status |= CACHE_INVALID;
- _free_cached_vgmetadata(vginfo);
-
- /* VG revert */
if (drop_precommitted)
- vginfo->precommitted = 0;
+ _suspended_vg_free(vginfo, 0, 1);
+ else
+ _suspended_vg_free(vginfo, 1, 1);
+}
+
+void lvmcache_save_suspended_vg(struct volume_group *vg, int precommitted)
+{
+ struct lvmcache_vginfo *vginfo;
+ struct format_instance *fid;
+ struct format_instance_ctx fic;
+ struct volume_group *susp_vg = NULL;
+ struct dm_config_tree *susp_cft = NULL;
+ char *susp_buf = NULL;
+ size_t size;
+ int new = precommitted;
+ int old = !precommitted;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id)))
+ goto_bad;
+
+ /* already saved */
+ if (old && vginfo->suspended_vg_old &&
+ (vginfo->suspended_vg_old->seqno == vg->seqno))
+ return;
+
+ /* already saved */
+ if (new && vginfo->suspended_vg_new &&
+ (vginfo->suspended_vg_new->seqno == vg->seqno))
+ return;
+
+ _suspended_vg_free(vginfo, old, new);
+
+ if (!(size = export_vg_to_buffer(vg, &susp_buf)))
+ goto_bad;
+
+ fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
+ fic.context.vg_ref.vg_name = vginfo->vgname;
+ fic.context.vg_ref.vg_id = vginfo->vgid;
+ if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic)))
+ goto_bad;
+
+ if (!(susp_cft = config_tree_from_string_without_dup_node_check(susp_buf)))
+ goto_bad;
+
+ if (!(susp_vg = import_vg_from_config_tree(susp_cft, fid)))
+ goto_bad;
+
+ if (old) {
+ vginfo->suspended_vg_old_buf = susp_buf;
+ vginfo->suspended_vg_old_cft = susp_cft;
+ vginfo->suspended_vg_old = susp_vg;
+ log_debug_cache("lvmcache saved suspended vg old seqno %d %s", vg->seqno, vg->name);
+ } else {
+ vginfo->suspended_vg_new_buf = susp_buf;
+ vginfo->suspended_vg_new_cft = susp_cft;
+ vginfo->suspended_vg_new = susp_vg;
+ log_debug_cache("lvmcache saved suspended vg new seqno %d %s", vg->seqno, vg->name);
+ }
+ return;
+
+bad:
+ _suspended_vg_free(vginfo, old, new);
+ log_debug_cache("lvmcache failed to save suspended pre %d vg %s", precommitted, vg->name);
+}
+
+struct volume_group *lvmcache_get_suspended_vg(const char *vgid)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgid(vgid)))
+ return_NULL;
+
+
+ if (vginfo->suspended_vg_committed)
+ return vginfo->suspended_vg_new;
+ else
+ return vginfo->suspended_vg_old;
+}
+
+void lvmcache_drop_suspended_vg(struct volume_group *vg)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id)))
+ return;
+
+ _suspended_vg_free(vginfo, 1, 1);
}
/*
@@ -289,11 +344,7 @@ void lvmcache_commit_metadata(const char *vgname)
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
return;
- if (vginfo->precommitted) {
- log_debug_cache("Precommitted metadata cache: VG %s upgraded to committed.",
- vginfo->vgname);
- vginfo->precommitted = 0;
- }
+ vginfo->suspended_vg_committed = 1;
}
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
@@ -675,18 +726,6 @@ static int _info_is_valid(struct lvmcache_info *info)
return 1;
}
-static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
-{
- struct lvmcache_info *info;
-
- /* Invalid if any info is invalid */
- dm_list_iterate_items(info, &vginfo->infos)
- if (!_info_is_valid(info))
- return 0;
-
- return 1;
-}
-
/* vginfo is invalid if it does not contain at least one valid info */
static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo)
{
@@ -1317,121 +1356,6 @@ int lvmcache_label_scan(struct cmd_context *cmd)
return r;
}
-struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname,
- const char *vgid, unsigned precommitted)
-{
- struct lvmcache_vginfo *vginfo;
- struct volume_group *vg = NULL;
- struct format_instance *fid;
- struct format_instance_ctx fic;
-
- /*
- * We currently do not store precommitted metadata in lvmetad at
- * all. This means that any request for precommitted metadata is served
- * using the classic scanning mechanics, and read from disk or from
- * lvmcache.
- */
- if (lvmetad_used() && !precommitted) {
- /* Still serve the locally cached VG if available */
- if (vgid && (vginfo = lvmcache_vginfo_from_vgid(vgid)) &&
- vginfo->vgmetadata && (vg = vginfo->cached_vg))
- goto out;
- return lvmetad_vg_lookup(cmd, vgname, vgid);
- }
-
- if (!vgid || !(vginfo = lvmcache_vginfo_from_vgid(vgid)) || !vginfo->vgmetadata)
- return NULL;
-
- if (!_vginfo_is_valid(vginfo))
- return NULL;
-
- /*
- * Don't return cached data if either:
- * (i) precommitted metadata is requested but we don't have it cached
- * - caller should read it off disk;
- * (ii) live metadata is requested but we have precommitted metadata cached
- * and no devices are suspended so caller may read it off disk.
- *
- * If live metadata is requested but we have precommitted metadata cached
- * and devices are suspended, we assume this precommitted metadata has
- * already been preloaded and committed so it's OK to return it as live.
- * Note that we do not clear the PRECOMMITTED flag.
- */
- if ((precommitted && !vginfo->precommitted) ||
- (!precommitted && vginfo->precommitted && !critical_section()))
- return NULL;
-
- /* Use already-cached VG struct when available */
- if ((vg = vginfo->cached_vg) && !vginfo->cached_vg_invalidated)
- goto out;
-
- release_vg(vginfo->cached_vg);
-
- fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
- fic.context.vg_ref.vg_name = vginfo->vgname;
- fic.context.vg_ref.vg_id = vgid;
- if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic)))
- return_NULL;
-
- /* Build config tree from vgmetadata, if not yet cached */
- if (!vginfo->cft &&
- !(vginfo->cft =
- config_tree_from_string_without_dup_node_check(vginfo->vgmetadata)))
- goto_bad;
-
- if (!(vg = import_vg_from_config_tree(vginfo->cft, fid)))
- goto_bad;
-
- /* Cache VG struct for reuse */
- vginfo->cached_vg = vg;
- vginfo->holders = 1;
- vginfo->vg_use_count = 0;
- vginfo->cached_vg_invalidated = 0;
- vg->vginfo = vginfo;
-
- if (!dm_pool_lock(vg->vgmem, detect_internal_vg_cache_corruption()))
- goto_bad;
-
-out:
- vginfo->holders++;
- vginfo->vg_use_count++;
- log_debug_cache("Using cached %smetadata for VG %s with %u holder(s).",
- vginfo->precommitted ? "pre-committed " : "",
- vginfo->vgname, vginfo->holders);
-
- return vg;
-
-bad:
- _free_cached_vgmetadata(vginfo);
- return NULL;
-}
-
-// #if 0
-int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo)
-{
- log_debug_cache("VG %s decrementing %d holder(s) at %p.",
- vginfo->cached_vg->name, vginfo->holders, vginfo->cached_vg);
-
- if (--vginfo->holders)
- return 0;
-
- if (vginfo->vg_use_count > 1)
- log_debug_cache("VG %s reused %d times.",
- vginfo->cached_vg->name, vginfo->vg_use_count);
-
- /* Debug perform crc check only when it's been used more then once */
- if (!dm_pool_unlock(vginfo->cached_vg->vgmem,
- detect_internal_vg_cache_corruption() &&
- (vginfo->vg_use_count > 1)))
- stack;
-
- vginfo->cached_vg->vginfo = NULL;
- vginfo->cached_vg = NULL;
-
- return 1;
-}
-// #endif
-
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
struct dm_list *vgnameids)
{
@@ -1617,8 +1541,6 @@ static int _free_vginfo(struct lvmcache_vginfo *vginfo)
struct lvmcache_vginfo *primary_vginfo, *vginfo2;
int r = 1;
- _free_cached_vgmetadata(vginfo);
-
vginfo2 = primary_vginfo = lvmcache_vginfo_from_vgname(vginfo->vgname, NULL);
if (vginfo == primary_vginfo) {
@@ -1641,6 +1563,7 @@ static int _free_vginfo(struct lvmcache_vginfo *vginfo)
dm_free(vginfo->system_id);
dm_free(vginfo->vgname);
dm_free(vginfo->creation_host);
+ _suspended_vg_free(vginfo, 1, 1);
if (*vginfo->vgid && _vgid_hash &&
lvmcache_vginfo_from_vgid(vginfo->vgid) == vginfo)
@@ -2079,12 +2002,6 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
!is_orphan_vg(info->vginfo->vgname) && critical_section())
return 1;
- /* If making a PV into an orphan, any cached VG metadata may become
- * invalid, incorrectly still referencing device structs.
- * (Example: pvcreate -ff) */
- if (is_orphan_vg(vgname) && info->vginfo && !is_orphan_vg(info->vginfo->vgname))
- info->vginfo->cached_vg_invalidated = 1;
-
/* If moving PV from orphan to real VG, always mark it valid */
if (!is_orphan_vg(vgname))
info->status &= ~CACHE_INVALID;
@@ -2122,10 +2039,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
return_0;
}
- /* store text representation of vg to cache */
- if (vg->cmd->current_settings.cache_vgmetadata)
- _store_metadata(vg, precommitted);
-
return 1;
}
@@ -2689,6 +2602,10 @@ struct label *lvmcache_get_label(struct lvmcache_info *info) {
return info->label;
}
+/*
+ * After label_scan reads pv_header, mda_header and mda locations
+ * from a PV, it clears the INVALID flag.
+ */
void lvmcache_make_valid(struct lvmcache_info *info) {
info->status &= ~CACHE_INVALID;
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index abdea30b2..54340788b 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -133,9 +133,6 @@ int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
-/* Returns cached volume group metadata. */
-struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname,
- const char *vgid, unsigned precommitted);
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted);
void lvmcache_commit_metadata(const char *vgname);
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 9f86c13e4..defc7993c 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -709,9 +709,6 @@ static int _process_config(struct cmd_context *cmd)
if (find_config_tree_bool(cmd, report_two_word_unknown_device_CFG, NULL))
init_unknown_device_name("unknown device");
- init_detect_internal_vg_cache_corruption
- (find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
-
if (!_init_system_id(cmd))
return_0;
@@ -2020,7 +2017,6 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (set_filters && !init_filters(cmd, 1))
goto_out;
- cmd->default_settings.cache_vgmetadata = 1;
cmd->current_settings = cmd->default_settings;
cmd->initialized.config = 1;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 35802d54e..702cc1680 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -39,7 +39,6 @@ struct config_info {
int udev_rules;
int udev_sync;
int udev_fallback;
- int cache_vgmetadata;
int scan_size_kb;
const char *msg_prefix;
const char *fmt_name;
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 09f668ec7..0dbda50ec 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -888,11 +888,8 @@ cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_
"Treat any internal errors as fatal errors, aborting the process that\n"
"encountered the internal error. Please only enable for debugging.\n")
-cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION, vsn(2, 2, 96), NULL, 0, NULL,
- "Internal verification of VG structures.\n"
- "Check if CRC matches when a parsed VG is used multiple times. This\n"
- "is useful to catch unexpected changes to cached VG structures.\n"
- "Please only enable for debugging.\n")
+cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 96), NULL, vsn(2, 2, 174), NULL,
+ "No longer used.\n")
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL, 0, NULL,
"No operations that change on-disk metadata are permitted.\n"
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 533aad11a..b12d879ca 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -179,7 +179,6 @@
#define DEFAULT_LOGLEVEL 0
#define DEFAULT_INDENT 1
#define DEFAULT_ABORT_ON_INTERNAL_ERRORS 0
-#define DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION 0
#define DEFAULT_UNITS "r"
#define DEFAULT_SUFFIX 1
#define DEFAULT_HOSTTAGS 0
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index ff22277fc..df9d5608f 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3797,7 +3797,6 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
struct dm_list *pvids;
struct pv_list *pvl;
struct dm_list all_pvs;
- unsigned seqno = 0;
int reappeared = 0;
struct cached_vg_fmtdata *vg_fmtdata = NULL; /* Additional format-specific data about the vg */
unsigned use_previous_vg;
@@ -3814,7 +3813,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
if (lvmetad_used() && !use_precommitted) {
- if ((correct_vg = lvmcache_get_vg(cmd, vgname, vgid, precommitted))) {
+ if ((correct_vg = lvmetad_vg_lookup(cmd, vgname, vgid))) {
dm_list_iterate_items(pvl, &correct_vg->pvs)
reappeared += _check_reappeared_pv(correct_vg, pvl->pv, *consistent);
if (reappeared && *consistent)
@@ -3845,23 +3844,6 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
/*
- * If cached metadata was inconsistent and *consistent is set
- * then repair it now. Otherwise just return it.
- * Also return if use_precommitted is set due to the FIXME in
- * the missing PV logic below.
- */
- if ((correct_vg = lvmcache_get_vg(cmd, vgname, vgid, precommitted)) &&
- (use_precommitted || !*consistent)) {
- *consistent = 1;
- return correct_vg;
- } else {
- if (correct_vg && correct_vg->seqno > seqno)
- seqno = correct_vg->seqno;
- release_vg(correct_vg);
- correct_vg = NULL;
- }
-
- /*
* Rescan the devices that are associated with this vg in lvmcache.
* This repeats what was done by the command's initial label scan,
* but only the devices associated with this VG.
@@ -4548,21 +4530,10 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
unsigned precommitted)
{
const char *vgname;
- struct dm_list *vgnames;
struct volume_group *vg;
- struct dm_str_list *strl;
uint32_t warn_flags = WARN_PV_READ | WARN_INCONSISTENT;
int consistent = 0;
- /* Is corresponding vgname already cached? */
- if (lvmcache_vgid_is_cached(vgid)) {
- if ((vg = _vg_read(cmd, NULL, vgid, warn_flags, &consistent, precommitted)) &&
- id_equal(&vg->id, (const struct id *)vgid)) {
- return vg;
- }
- release_vg(vg);
- }
-
/*
* When using lvmlockd we should never reach this point.
* The VG is locked, then vg_read() is done, which gets
@@ -4575,36 +4546,28 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
/* Mustn't scan if memory locked: ensure cache gets pre-populated! */
if (critical_section())
- return_NULL;
+ log_debug_metadata("Reading VG by vgid in critical section pre %d vgid %.8s", precommitted, vgid);
- /* FIXME Need a genuine read by ID here - don't vg_read_internal by name! */
- /* FIXME Disabled vgrenames while active for now because we aren't
- * allowed to do a full scan here any more. */
+ if (!(vgname = lvmcache_vgname_from_vgid(cmd->mem, vgid))) {
+ log_debug_metadata("Reading VG by vgid %.8s no VG name found, retrying.", vgid);
+ lvmcache_destroy(cmd, 0, 0);
+ lvmcache_force_next_label_scan();
+ lvmcache_label_scan(cmd);
+ }
- // The slow way - full scan required to cope with vgrename
- lvmcache_force_next_label_scan();
- lvmcache_label_scan(cmd);
- if (!(vgnames = get_vgnames(cmd, 0))) {
- log_error("vg_read_by_vgid: get_vgnames failed");
+ if (!(vgname = lvmcache_vgname_from_vgid(cmd->mem, vgid))) {
+ log_debug_metadata("Reading VG by vgid %.8s no VG name found.", vgid);
return NULL;
}
- dm_list_iterate_items(strl, vgnames) {
- vgname = strl->str;
- if (!vgname)
- continue; // FIXME Unnecessary?
- consistent = 0;
- if ((vg = _vg_read(cmd, vgname, vgid, warn_flags, &consistent, precommitted)) &&
- id_equal(&vg->id, (const struct id *)vgid)) {
- if (!consistent) {
- release_vg(vg);
- return NULL;
- }
- return vg;
- }
- release_vg(vg);
+ consistent = 0;
+
+ if ((vg = _vg_read(cmd, vgname, vgid, warn_flags, &consistent, precommitted))) {
+ /* Does it matter if consistent is 0 or 1? */
+ return vg;
}
+ log_debug_metadata("Reading VG by vgid %.8s not found.", vgid);
return NULL;
}
@@ -4620,7 +4583,7 @@ struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
log_very_verbose("Finding %svolume group for uuid %s", precommitted ? "precommitted " : "", lvid_s);
if (!(vg = _vg_read_by_vgid(cmd, (const char *)lvid->id[0].uuid, precommitted))) {
- log_error("Volume group for uuid not found: %s", lvid_s);
+ log_error("Reading VG not found for LVID %s", lvid_s);
return NULL;
}
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 9f48a9ba7..35cdfea7e 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -97,11 +97,6 @@ void release_vg(struct volume_group *vg)
if (!vg || (vg->fid && vg == vg->fid->fmt->orphan_vg))
return;
- /* Check if there are any vginfo holders */
- if (vg->vginfo &&
- !lvmcache_vginfo_holders_dec_and_test_for_zero(vg->vginfo))
- return;
-
release_vg(vg->vg_committed);
release_vg(vg->vg_precommitted);
if (vg->cft_precommitted)
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 9c78f3e33..fe5b6bb4c 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -54,8 +54,6 @@ static int _activation_checks = 0;
static char _sysfs_dir_path[PATH_MAX] = "";
static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT;
static uint64_t _pv_min_size = (DEFAULT_PV_MIN_SIZE_KB * 1024L >> SECTOR_SHIFT);
-static int _detect_internal_vg_cache_corruption =
- DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION;
static const char *_unknown_device_name = DEFAULT_UNKNOWN_DEVICE_NAME;
void init_verbose(int level)
@@ -198,11 +196,6 @@ void init_pv_min_size(uint64_t sectors)
_pv_min_size = sectors;
}
-void init_detect_internal_vg_cache_corruption(int detect)
-{
- _detect_internal_vg_cache_corruption = detect;
-}
-
void set_cmd_name(const char *cmd)
{
strncpy(_cmd_name, cmd, sizeof(_cmd_name) - 1);
@@ -387,11 +380,6 @@ uint64_t pv_min_size(void)
return _pv_min_size;
}
-int detect_internal_vg_cache_corruption(void)
-{
- return _detect_internal_vg_cache_corruption;
-}
-
const char *unknown_device_name(void)
{
return _unknown_device_name;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index 14a7d4366..e23d5984d 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -51,7 +51,6 @@ void init_udev_checking(int checking);
void init_dev_disable_after_error_count(int value);
void init_pv_min_size(uint64_t sectors);
void init_activation_checks(int checks);
-void init_detect_internal_vg_cache_corruption(int detect);
void init_retry_deactivation(int retry);
void init_unknown_device_name(const char *name);
@@ -85,7 +84,6 @@ int udev_checking(void);
const char *sysfs_dir_path(void);
uint64_t pv_min_size(void);
int activation_checks(void);
-int detect_internal_vg_cache_corruption(void);
int retry_deactivation(void);
const char *unknown_device_name(void);
diff --git a/tools/commands.h b/tools/commands.h
index 4739479dd..17a8ca524 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -43,7 +43,7 @@ xx(lastlog,
xx(lvchange,
"Change the attributes of logical volume(s)",
- CACHE_VGMETADATA | PERMITTED_READ_ONLY)
+ PERMITTED_READ_ONLY)
xx(lvconvert,
"Change logical volume layout",
@@ -127,7 +127,7 @@ xx(pvdata,
xx(pvdisplay,
"Display various attributes of physical volume(s)",
- CACHE_VGMETADATA | PERMITTED_READ_ONLY | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH)
+ PERMITTED_READ_ONLY | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH)
/* ALL_VGS_IS_DEFAULT is for polldaemon to find pvmoves in-progress using process_each_vg. */
@@ -145,7 +145,7 @@ xx(pvremove,
xx(pvs,
"Display information about physical volumes",
- CACHE_VGMETADATA | PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH)
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT | ENABLE_ALL_DEVS | ENABLE_DUPLICATE_DEVS | LOCKD_VG_SH)
xx(pvscan,
"List all physical volumes",
@@ -173,7 +173,7 @@ xx(vgcfgrestore,
xx(vgchange,
"Change volume group attributes",
- CACHE_VGMETADATA | PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT)
+ PERMITTED_READ_ONLY | ALL_VGS_IS_DEFAULT)
xx(vgck,
"Check the consistency of volume group(s)",
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index f2e208c7c..774cb53cc 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2280,7 +2280,6 @@ static int _get_current_settings(struct cmd_context *cmd)
cmd->current_settings.archive = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.archive);
cmd->current_settings.backup = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.backup);
- cmd->current_settings.cache_vgmetadata = cmd->cname->flags & CACHE_VGMETADATA ? 1 : 0;
if (arg_is_set(cmd, readonly_ARG)) {
cmd->current_settings.activation = 0;
diff --git a/tools/tools.h b/tools/tools.h
index 53f8ddc0f..0ba42f5ae 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -113,7 +113,6 @@ struct arg_value_group_list {
uint32_t prio;
};
-#define CACHE_VGMETADATA 0x00000001
#define PERMITTED_READ_ONLY 0x00000002
/* Process all VGs if none specified on the command line. */
#define ALL_VGS_IS_DEFAULT 0x00000004