summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW1
-rw-r--r--daemons/clvmd/clvmd-command.c2
-rw-r--r--lib/cache/lvmcache.c10
-rw-r--r--lib/cache/lvmcache.h1
-rw-r--r--lib/locking/cluster_locking.c2
-rw-r--r--lib/locking/file_locking.c5
-rw-r--r--lib/locking/locking.c3
-rw-r--r--lib/locking/locking.h4
-rw-r--r--lib/metadata/metadata.c9
9 files changed, 35 insertions, 2 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 23481fb8..18c544fd 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.35 -
=================================
+ Drop cached VG metadata before and after committing changes to it.
Rename P_global to P_#global.
Don't attempt remote metadata backups of non-clustered VGs. (2.02.29)
Don't store fid in VG metadata cache to avoid clvmd segfault. (2.02.34)
diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c
index 2d9e21a1..b47f5273 100644
--- a/daemons/clvmd/clvmd-command.c
+++ b/daemons/clvmd/clvmd-command.c
@@ -121,6 +121,8 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
/* P_#global causes a cache refresh */
if (strcmp(lockname, "P_#global") == 0)
do_refresh_cache();
+ else if (strncmp(lockname, "P_", 2) == 0)
+ lvmcache_drop_metadata(lockname + 2);
break;
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 36296e1f..b543ad66 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -130,6 +130,16 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
+void lvmcache_drop_metadata(const char *vgname)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
+ return;
+
+ _free_cached_vgmetadata(vginfo);
+}
+
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
{
if (!_lock_hash && !lvmcache_init()) {
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 09c0257f..bceecd75 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -111,5 +111,6 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
/* Returns cached volume group metadata. */
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
+void lvmcache_drop_metadata(const char *vgname);
#endif
diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c
index bedc38a2..20ba6ad9 100644
--- a/lib/locking/cluster_locking.c
+++ b/lib/locking/cluster_locking.c
@@ -389,7 +389,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
/* If the VG name is empty then lock the unused PVs */
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockname, sizeof(lockname), "P_orphans");
- else if (*resource == '#')
+ else if (*resource == '#' || (flags & LCK_CACHE))
dm_snprintf(lockname, sizeof(lockname), "P_%s", resource);
else
dm_snprintf(lockname, sizeof(lockname), "V_%s",
diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c
index e830d151..b162a58c 100644
--- a/lib/locking/file_locking.c
+++ b/lib/locking/file_locking.c
@@ -21,6 +21,7 @@
#include "defaults.h"
#include "lvm-file.h"
#include "lvm-string.h"
+#include "lvmcache.h"
#include <limits.h>
#include <unistd.h>
@@ -209,6 +210,10 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
switch (flags & LCK_SCOPE_MASK) {
case LCK_VG:
+ if (flags & LCK_CACHE) {
+ lvmcache_drop_metadata(resource);
+ break;
+ }
if (!*resource) /* FIXME Deprecated */
dm_snprintf(lockfile, sizeof(lockfile),
"%s/P_orphans", _lock_dir);
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index d97c564b..abfadbf1 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -324,7 +324,8 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource, uint32_t fla
assert(resource);
if ((ret = _locking.lock_resource(cmd, resource, flags))) {
- if ((flags & LCK_SCOPE_MASK) == LCK_VG) {
+ if ((flags & LCK_SCOPE_MASK) == LCK_VG &&
+ !(flags & LCK_CACHE)) {
if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
lvmcache_unlock_vgname(resource);
else
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index a5872bcb..4c33d943 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -69,6 +69,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
+#define LCK_CACHE 0x00000100U /* Operation on cache using P_ lock */
/*
* Additional lock bits for cluster communication
@@ -91,6 +92,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
+#define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE)
#define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL | LCK_NONBLOCK)
#define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE | LCK_NONBLOCK)
@@ -116,6 +118,8 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
+#define drop_cached_metadata(vg) \
+ lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE)
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index c0a02a07..91050949 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1333,6 +1333,11 @@ int vg_commit(struct volume_group *vg)
return cache_updated;
}
+ if (!drop_cached_metadata(vg)) {
+ log_error("Unable to drop cached metadata for VG %s.", vg->name);
+ return 0;
+ }
+
/* Commit to each copy of the metadata area */
list_iterate_items(mda, &vg->fid->metadata_areas) {
failed = 0;
@@ -1348,6 +1353,10 @@ int vg_commit(struct volume_group *vg)
}
}
+ if (!drop_cached_metadata(vg))
+ log_error("Attempt to drop cached metadata failed "
+ "after commit for VG %s.", vg->name);
+
/* If at least one mda commit succeeded, it was committed */
return cache_updated;
}