|
|
191583 |
WHATS_NEW | 7 ++++
|
|
|
191583 |
configure.in | 6 ++--
|
|
|
191583 |
daemons/lvmetad/lvmetad-core.c | 25 +++++++++----
|
|
|
191583 |
lib/cache/lvmetad.c | 2 --
|
|
|
191583 |
lib/metadata/metadata.c | 76 ++++++++++++++++++++++++++--------------
|
|
|
191583 |
lib/metadata/metadata.h | 3 --
|
|
|
191583 |
libdaemon/client/daemon-io.c | 2 +-
|
|
|
191583 |
libdaemon/server/daemon-server.c | 6 ++--
|
|
|
191583 |
libdm/Makefile.in | 2 +-
|
|
|
191583 |
libdm/mm/pool-fast.c | 4 +++
|
|
|
191583 |
libdm/mm/pool.c | 9 +++--
|
|
|
191583 |
test/Makefile.in | 3 +-
|
|
|
191583 |
test/shell/lvmcache-exercise.sh | 17 +++++++--
|
|
|
191583 |
test/shell/vgrename-usage.sh | 15 ++++++++
|
|
|
191583 |
tools/vgrename.c | 2 ++
|
|
|
191583 |
15 files changed, 129 insertions(+), 50 deletions(-)
|
|
|
191583 |
|
|
|
191583 |
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
|
191583 |
index cd55d54..e49a98d 100644
|
|
|
191583 |
--- a/WHATS_NEW
|
|
|
191583 |
+++ b/WHATS_NEW
|
|
|
191583 |
@@ -1,5 +1,12 @@
|
|
|
191583 |
Version 2.02.104 -
|
|
|
191583 |
===================================
|
|
|
191583 |
+ Fix possible race during daemon worker thread creation (lvmetad).
|
|
|
191583 |
+ Fix possible deadlock while clearing lvmetad cache for full rescan.
|
|
|
191583 |
+ Fix possible race while creating/destroying memory pools.
|
|
|
191583 |
+ Fix failing metadata repair when lvmetad is used.
|
|
|
191583 |
+ Fix incorrect memory handling when reading messages from lvmetad.
|
|
|
191583 |
+ Fix locking in lvmetad when handling the PV which is gone.
|
|
|
191583 |
+ Run full scan before vgrename operation to avoid any cache name collision.
|
|
|
191583 |
Recognize new flag to skip udev scanning in udev rules and act appropriately.
|
|
|
191583 |
Add support for flagging an LV to skip udev scanning during activation.
|
|
|
191583 |
Improve message when unable to change discards setting on active thin pool.
|
|
|
191583 |
diff --git a/configure.in b/configure.in
|
|
|
191583 |
index 611ab37..3bd2439 100644
|
|
|
191583 |
--- a/configure.in
|
|
|
191583 |
+++ b/configure.in
|
|
|
191583 |
@@ -1181,10 +1181,8 @@ Features cannot be 'shared' when building statically
|
|
|
191583 |
fi
|
|
|
191583 |
|
|
|
191583 |
################################################################################
|
|
|
191583 |
-if [[ "$DMEVENTD" = yes -o "$CLVMD" != none ]] ; then
|
|
|
191583 |
- AC_CHECK_LIB([pthread], [pthread_mutex_lock],
|
|
|
191583 |
- [PTHREAD_LIBS="-lpthread"], hard_bailout)
|
|
|
191583 |
-fi
|
|
|
191583 |
+AC_CHECK_LIB([pthread], [pthread_mutex_lock],
|
|
|
191583 |
+ [PTHREAD_LIBS="-lpthread"], hard_bailout)
|
|
|
191583 |
|
|
|
191583 |
################################################################################
|
|
|
191583 |
dnl -- Disable selinux
|
|
|
191583 |
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
|
|
|
191583 |
index e1ec5a8..285c8cc 100644
|
|
|
191583 |
--- a/daemons/lvmetad/lvmetad-core.c
|
|
|
191583 |
+++ b/daemons/lvmetad/lvmetad-core.c
|
|
|
191583 |
@@ -551,7 +551,7 @@ static int compare_config(struct dm_config_node *a, struct dm_config_node *b)
|
|
|
191583 |
return result;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
-static int vg_remove_if_missing(lvmetad_state *s, const char *vgid);
|
|
|
191583 |
+static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_pvids);
|
|
|
191583 |
|
|
|
191583 |
/* You need to be holding the pvid_to_vgid lock already to call this. */
|
|
|
191583 |
static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
|
|
|
191583 |
@@ -590,7 +590,7 @@ static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
|
|
|
191583 |
n = dm_hash_get_next(to_check, n)) {
|
|
|
191583 |
check_vgid = dm_hash_get_key(to_check, n);
|
|
|
191583 |
lock_vg(s, check_vgid);
|
|
|
191583 |
- vg_remove_if_missing(s, check_vgid);
|
|
|
191583 |
+ vg_remove_if_missing(s, check_vgid, 0);
|
|
|
191583 |
unlock_vg(s, check_vgid);
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
@@ -631,7 +631,7 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
/* The VG must be locked. */
|
|
|
191583 |
-static int vg_remove_if_missing(lvmetad_state *s, const char *vgid)
|
|
|
191583 |
+static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_pvids)
|
|
|
191583 |
{
|
|
|
191583 |
struct dm_config_tree *vg;
|
|
|
191583 |
struct dm_config_node *pv;
|
|
|
191583 |
@@ -658,7 +658,7 @@ static int vg_remove_if_missing(lvmetad_state *s, const char *vgid)
|
|
|
191583 |
|
|
|
191583 |
if (missing) {
|
|
|
191583 |
DEBUGLOG(s, "removing empty VG %s", vgid);
|
|
|
191583 |
- remove_metadata(s, vgid, 0);
|
|
|
191583 |
+ remove_metadata(s, vgid, update_pvids);
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
unlock_pvid_to_pvmeta(s);
|
|
|
191583 |
@@ -796,11 +796,24 @@ static response pv_gone(lvmetad_state *s, request r)
|
|
|
191583 |
|
|
|
191583 |
pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvid);
|
|
|
191583 |
pvid_old = dm_hash_lookup_binary(s->device_to_pvid, &device, sizeof(device));
|
|
|
191583 |
+ char *vgid = dm_hash_lookup(s->pvid_to_vgid, pvid);
|
|
|
191583 |
+
|
|
|
191583 |
+ if (vgid && !(vgid = dm_strdup(vgid))) {
|
|
|
191583 |
+ unlock_pvid_to_pvmeta(s);
|
|
|
191583 |
+ return reply_fail("out of memory");
|
|
|
191583 |
+ }
|
|
|
191583 |
+
|
|
|
191583 |
dm_hash_remove_binary(s->device_to_pvid, &device, sizeof(device));
|
|
|
191583 |
dm_hash_remove(s->pvid_to_pvmeta, pvid);
|
|
|
191583 |
- vg_remove_if_missing(s, dm_hash_lookup(s->pvid_to_vgid, pvid));
|
|
|
191583 |
unlock_pvid_to_pvmeta(s);
|
|
|
191583 |
|
|
|
191583 |
+ if (vgid) {
|
|
|
191583 |
+ lock_vg(s, vgid);
|
|
|
191583 |
+ vg_remove_if_missing(s, vgid, 1);
|
|
|
191583 |
+ unlock_vg(s, vgid);
|
|
|
191583 |
+ dm_free(vgid);
|
|
|
191583 |
+ }
|
|
|
191583 |
+
|
|
|
191583 |
if (pvid_old)
|
|
|
191583 |
dm_free(pvid_old);
|
|
|
191583 |
|
|
|
191583 |
@@ -816,8 +829,8 @@ static response pv_clear_all(lvmetad_state *s, request r)
|
|
|
191583 |
DEBUGLOG(s, "pv_clear_all");
|
|
|
191583 |
|
|
|
191583 |
lock_pvid_to_pvmeta(s);
|
|
|
191583 |
- lock_vgid_to_metadata(s);
|
|
|
191583 |
lock_pvid_to_vgid(s);
|
|
|
191583 |
+ lock_vgid_to_metadata(s);
|
|
|
191583 |
|
|
|
191583 |
destroy_metadata_hashes(s);
|
|
|
191583 |
create_metadata_hashes(s);
|
|
|
191583 |
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
|
|
|
191583 |
index f43283f..8940704 100644
|
|
|
191583 |
--- a/lib/cache/lvmetad.c
|
|
|
191583 |
+++ b/lib/cache/lvmetad.c
|
|
|
191583 |
@@ -392,8 +392,6 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
|
|
|
191583 |
pvl->pv->dev = lvmcache_device(info);
|
|
|
191583 |
if (!pvl->pv->dev)
|
|
|
191583 |
pvl->pv->status |= MISSING_PV;
|
|
|
191583 |
- else
|
|
|
191583 |
- check_reappeared_pv(vg, pvl->pv);
|
|
|
191583 |
if (!lvmcache_fid_add_mdas_pv(info, fid)) {
|
|
|
191583 |
vg = NULL;
|
|
|
191583 |
goto_out; /* FIXME error path */
|
|
|
191583 |
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
|
|
|
191583 |
index 4ffd502..8571e0a 100644
|
|
|
191583 |
--- a/lib/metadata/metadata.c
|
|
|
191583 |
+++ b/lib/metadata/metadata.c
|
|
|
191583 |
@@ -2883,10 +2883,11 @@ int vg_missing_pv_count(const struct volume_group *vg)
|
|
|
191583 |
return ret;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
-void check_reappeared_pv(struct volume_group *correct_vg,
|
|
|
191583 |
- struct physical_volume *pv)
|
|
|
191583 |
+static int _check_reappeared_pv(struct volume_group *correct_vg,
|
|
|
191583 |
+ struct physical_volume *pv, int act)
|
|
|
191583 |
{
|
|
|
191583 |
struct pv_list *pvl;
|
|
|
191583 |
+ int rv = 0;
|
|
|
191583 |
|
|
|
191583 |
/*
|
|
|
191583 |
* Skip these checks in case the tool is going to deal with missing
|
|
|
191583 |
@@ -2894,21 +2895,47 @@ void check_reappeared_pv(struct volume_group *correct_vg,
|
|
|
191583 |
* confusing.
|
|
|
191583 |
*/
|
|
|
191583 |
if (correct_vg->cmd->handles_missing_pvs)
|
|
|
191583 |
- return;
|
|
|
191583 |
+ return rv;
|
|
|
191583 |
|
|
|
191583 |
dm_list_iterate_items(pvl, &correct_vg->pvs)
|
|
|
191583 |
if (pv->dev == pvl->pv->dev && is_missing_pv(pvl->pv)) {
|
|
|
191583 |
- log_warn("Missing device %s reappeared, updating "
|
|
|
191583 |
- "metadata for VG %s to version %u.",
|
|
|
191583 |
- pv_dev_name(pvl->pv), pv_vg_name(pvl->pv),
|
|
|
191583 |
- correct_vg->seqno);
|
|
|
191583 |
+ if (act)
|
|
|
191583 |
+ log_warn("Missing device %s reappeared, updating "
|
|
|
191583 |
+ "metadata for VG %s to version %u.",
|
|
|
191583 |
+ pv_dev_name(pvl->pv), pv_vg_name(pvl->pv),
|
|
|
191583 |
+ correct_vg->seqno);
|
|
|
191583 |
if (pvl->pv->pe_alloc_count == 0) {
|
|
|
191583 |
- pv->status &= ~MISSING_PV;
|
|
|
191583 |
- pvl->pv->status &= ~MISSING_PV;
|
|
|
191583 |
- } else
|
|
|
191583 |
+ if (act) {
|
|
|
191583 |
+ pv->status &= ~MISSING_PV;
|
|
|
191583 |
+ pvl->pv->status &= ~MISSING_PV;
|
|
|
191583 |
+ }
|
|
|
191583 |
+ ++ rv;
|
|
|
191583 |
+ } else if (act)
|
|
|
191583 |
log_warn("Device still marked missing because of allocated data "
|
|
|
191583 |
"on it, remove volumes and consider vgreduce --removemissing.");
|
|
|
191583 |
}
|
|
|
191583 |
+ return rv;
|
|
|
191583 |
+}
|
|
|
191583 |
+
|
|
|
191583 |
+static int _repair_inconsistent_vg(struct volume_group *vg)
|
|
|
191583 |
+{
|
|
|
191583 |
+ unsigned saved_handles_missing_pvs = vg->cmd->handles_missing_pvs;
|
|
|
191583 |
+
|
|
|
191583 |
+ vg->cmd->handles_missing_pvs = 1;
|
|
|
191583 |
+ if (!vg_write(vg)) {
|
|
|
191583 |
+ log_error("Automatic metadata correction failed");
|
|
|
191583 |
+ vg->cmd->handles_missing_pvs = saved_handles_missing_pvs;
|
|
|
191583 |
+ return 0;
|
|
|
191583 |
+ }
|
|
|
191583 |
+
|
|
|
191583 |
+ vg->cmd->handles_missing_pvs = saved_handles_missing_pvs;
|
|
|
191583 |
+
|
|
|
191583 |
+ if (!vg_commit(vg)) {
|
|
|
191583 |
+ log_error("Automatic metadata correction commit failed");
|
|
|
191583 |
+ return 0;
|
|
|
191583 |
+ }
|
|
|
191583 |
+
|
|
|
191583 |
+ return 1;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
static int _check_mda_in_use(struct metadata_area *mda, void *_in_use)
|
|
|
191583 |
@@ -2951,12 +2978,12 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
|
|
191583 |
int inconsistent_mdas = 0;
|
|
|
191583 |
int inconsistent_mda_count = 0;
|
|
|
191583 |
unsigned use_precommitted = precommitted;
|
|
|
191583 |
- unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
|
|
|
191583 |
struct dm_list *pvids;
|
|
|
191583 |
struct pv_list *pvl, *pvl2;
|
|
|
191583 |
struct dm_list all_pvs;
|
|
|
191583 |
char uuid[64] __attribute__((aligned(8)));
|
|
|
191583 |
unsigned seqno = 0;
|
|
|
191583 |
+ int reappeared = 0;
|
|
|
191583 |
|
|
|
191583 |
if (is_orphan_vg(vgname)) {
|
|
|
191583 |
if (use_precommitted) {
|
|
|
191583 |
@@ -2969,8 +2996,16 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
if (lvmetad_active() && !use_precommitted) {
|
|
|
191583 |
- *consistent = 1;
|
|
|
191583 |
- return lvmcache_get_vg(cmd, vgname, vgid, precommitted);
|
|
|
191583 |
+ if ((correct_vg = lvmcache_get_vg(cmd, vgname, vgid, precommitted))) {
|
|
|
191583 |
+ dm_list_iterate_items(pvl, &correct_vg->pvs)
|
|
|
191583 |
+ if (pvl->pv->dev)
|
|
|
191583 |
+ reappeared += _check_reappeared_pv(correct_vg, pvl->pv, *consistent);
|
|
|
191583 |
+ if (reappeared && *consistent)
|
|
|
191583 |
+ *consistent = _repair_inconsistent_vg(correct_vg);
|
|
|
191583 |
+ else
|
|
|
191583 |
+ *consistent = !reappeared;
|
|
|
191583 |
+ }
|
|
|
191583 |
+ return correct_vg;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
/*
|
|
|
191583 |
@@ -3339,22 +3374,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
|
|
191583 |
* update metadata and remove MISSING flag
|
|
|
191583 |
*/
|
|
|
191583 |
dm_list_iterate_items(pvl, &all_pvs)
|
|
|
191583 |
- check_reappeared_pv(correct_vg, pvl->pv);
|
|
|
191583 |
+ _check_reappeared_pv(correct_vg, pvl->pv, 1);
|
|
|
191583 |
|
|
|
191583 |
- cmd->handles_missing_pvs = 1;
|
|
|
191583 |
- if (!vg_write(correct_vg)) {
|
|
|
191583 |
- log_error("Automatic metadata correction failed");
|
|
|
191583 |
+ if (!_repair_inconsistent_vg(correct_vg)) {
|
|
|
191583 |
_free_pv_list(&all_pvs);
|
|
|
191583 |
release_vg(correct_vg);
|
|
|
191583 |
- cmd->handles_missing_pvs = saved_handles_missing_pvs;
|
|
|
191583 |
- return NULL;
|
|
|
191583 |
- }
|
|
|
191583 |
- cmd->handles_missing_pvs = saved_handles_missing_pvs;
|
|
|
191583 |
-
|
|
|
191583 |
- if (!vg_commit(correct_vg)) {
|
|
|
191583 |
- log_error("Automatic metadata correction commit "
|
|
|
191583 |
- "failed");
|
|
|
191583 |
- release_vg(correct_vg);
|
|
|
191583 |
return NULL;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
|
|
|
191583 |
index 2408c23..21ac204 100644
|
|
|
191583 |
--- a/lib/metadata/metadata.h
|
|
|
191583 |
+++ b/lib/metadata/metadata.h
|
|
|
191583 |
@@ -486,7 +486,4 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
|
|
|
191583 |
uint64_t find_min_mda_size(struct dm_list *mdas);
|
|
|
191583 |
char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags);
|
|
|
191583 |
|
|
|
191583 |
-void check_reappeared_pv(struct volume_group *correct_vg,
|
|
|
191583 |
- struct physical_volume *pv);
|
|
|
191583 |
-
|
|
|
191583 |
#endif
|
|
|
191583 |
diff --git a/libdaemon/client/daemon-io.c b/libdaemon/client/daemon-io.c
|
|
|
191583 |
index 906f375..e2c5180 100644
|
|
|
191583 |
--- a/libdaemon/client/daemon-io.c
|
|
|
191583 |
+++ b/libdaemon/client/daemon-io.c
|
|
|
191583 |
@@ -38,7 +38,7 @@ int buffer_read(int fd, struct buffer *buffer) {
|
|
|
191583 |
result = read(fd, buffer->mem + buffer->used, buffer->allocated - buffer->used);
|
|
|
191583 |
if (result > 0) {
|
|
|
191583 |
buffer->used += result;
|
|
|
191583 |
- if (!strncmp((buffer->mem) + buffer->used - 4, "\n##\n", 4)) {
|
|
|
191583 |
+ if (buffer->used >= 4 && !strncmp((buffer->mem) + buffer->used - 4, "\n##\n", 4)) {
|
|
|
191583 |
buffer->used -= 4;
|
|
|
191583 |
buffer->mem[buffer->used] = 0;
|
|
|
191583 |
break; /* success, we have the full message now */
|
|
|
191583 |
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
|
|
|
191583 |
index df2c852..b114b9f 100644
|
|
|
191583 |
--- a/libdaemon/server/daemon-server.c
|
|
|
191583 |
+++ b/libdaemon/server/daemon-server.c
|
|
|
191583 |
@@ -381,6 +381,7 @@ static void *client_thread(void *baton)
|
|
|
191583 |
request req;
|
|
|
191583 |
response res;
|
|
|
191583 |
|
|
|
191583 |
+ b->client.thread_id = pthread_self();
|
|
|
191583 |
buffer_init(&req.buffer);
|
|
|
191583 |
|
|
|
191583 |
while (1) {
|
|
|
191583 |
@@ -431,6 +432,7 @@ static int handle_connect(daemon_state s)
|
|
|
191583 |
struct sockaddr_un sockaddr;
|
|
|
191583 |
client_handle client = { .thread_id = 0 };
|
|
|
191583 |
socklen_t sl = sizeof(sockaddr);
|
|
|
191583 |
+ pthread_t tid;
|
|
|
191583 |
|
|
|
191583 |
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
|
|
|
191583 |
if (client.socket_fd < 0)
|
|
|
191583 |
@@ -446,10 +448,10 @@ static int handle_connect(daemon_state s)
|
|
|
191583 |
baton->s = s;
|
|
|
191583 |
baton->client = client;
|
|
|
191583 |
|
|
|
191583 |
- if (pthread_create(&baton->client.thread_id, NULL, client_thread, baton))
|
|
|
191583 |
+ if (pthread_create(&tid, NULL, client_thread, baton))
|
|
|
191583 |
return 0;
|
|
|
191583 |
|
|
|
191583 |
- pthread_detach(baton->client.thread_id);
|
|
|
191583 |
+ pthread_detach(tid);
|
|
|
191583 |
|
|
|
191583 |
return 1;
|
|
|
191583 |
}
|
|
|
191583 |
diff --git a/libdm/Makefile.in b/libdm/Makefile.in
|
|
|
191583 |
index bddb0a0..2aa70d4 100644
|
|
|
191583 |
--- a/libdm/Makefile.in
|
|
|
191583 |
+++ b/libdm/Makefile.in
|
|
|
191583 |
@@ -57,7 +57,7 @@ include $(top_builddir)/make.tmpl
|
|
|
191583 |
DEFS += -DDM_DEVICE_UID=@DM_DEVICE_UID@ -DDM_DEVICE_GID=@DM_DEVICE_GID@ \
|
|
|
191583 |
-DDM_DEVICE_MODE=@DM_DEVICE_MODE@
|
|
|
191583 |
|
|
|
191583 |
-LIBS += $(SELINUX_LIBS) $(UDEV_LIBS)
|
|
|
191583 |
+LIBS += $(SELINUX_LIBS) $(UDEV_LIBS) $(PTHREAD_LIBS)
|
|
|
191583 |
|
|
|
191583 |
device-mapper: all
|
|
|
191583 |
|
|
|
191583 |
diff --git a/libdm/mm/pool-fast.c b/libdm/mm/pool-fast.c
|
|
|
191583 |
index 2b494d6..edb31a0 100644
|
|
|
191583 |
--- a/libdm/mm/pool-fast.c
|
|
|
191583 |
+++ b/libdm/mm/pool-fast.c
|
|
|
191583 |
@@ -62,7 +62,9 @@ struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint)
|
|
|
191583 |
while (new_size < p->chunk_size)
|
|
|
191583 |
new_size <<= 1;
|
|
|
191583 |
p->chunk_size = new_size;
|
|
|
191583 |
+ pthread_mutex_lock(&_dm_pools_mutex);
|
|
|
191583 |
dm_list_add(&_dm_pools, &p->list);
|
|
|
191583 |
+ pthread_mutex_unlock(&_dm_pools_mutex);
|
|
|
191583 |
return p;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
@@ -77,7 +79,9 @@ void dm_pool_destroy(struct dm_pool *p)
|
|
|
191583 |
c = pr;
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
+ pthread_mutex_lock(&_dm_pools_mutex);
|
|
|
191583 |
dm_list_del(&p->list);
|
|
|
191583 |
+ pthread_mutex_unlock(&_dm_pools_mutex);
|
|
|
191583 |
dm_free(p);
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
diff --git a/libdm/mm/pool.c b/libdm/mm/pool.c
|
|
|
191583 |
index fd08307..ef006a4 100644
|
|
|
191583 |
--- a/libdm/mm/pool.c
|
|
|
191583 |
+++ b/libdm/mm/pool.c
|
|
|
191583 |
@@ -15,9 +15,10 @@
|
|
|
191583 |
|
|
|
191583 |
#include "dmlib.h"
|
|
|
191583 |
#include <sys/mman.h>
|
|
|
191583 |
+#include <pthread.h>
|
|
|
191583 |
|
|
|
191583 |
-/* FIXME: thread unsafe */
|
|
|
191583 |
static DM_LIST_INIT(_dm_pools);
|
|
|
191583 |
+static pthread_mutex_t _dm_pools_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
191583 |
void dm_pools_check_leaks(void);
|
|
|
191583 |
|
|
|
191583 |
#ifdef DEBUG_ENFORCE_POOL_LOCKING
|
|
|
191583 |
@@ -81,8 +82,11 @@ void dm_pools_check_leaks(void)
|
|
|
191583 |
{
|
|
|
191583 |
struct dm_pool *p;
|
|
|
191583 |
|
|
|
191583 |
- if (dm_list_empty(&_dm_pools))
|
|
|
191583 |
+ pthread_mutex_lock(&_dm_pools_mutex);
|
|
|
191583 |
+ if (dm_list_empty(&_dm_pools)) {
|
|
|
191583 |
+ pthread_mutex_unlock(&_dm_pools_mutex);
|
|
|
191583 |
return;
|
|
|
191583 |
+ }
|
|
|
191583 |
|
|
|
191583 |
log_error("You have a memory leak (not released memory pool):");
|
|
|
191583 |
dm_list_iterate_items(p, &_dm_pools) {
|
|
|
191583 |
@@ -94,6 +98,7 @@ void dm_pools_check_leaks(void)
|
|
|
191583 |
log_error(" [%p] %s", p, p->name);
|
|
|
191583 |
#endif
|
|
|
191583 |
}
|
|
|
191583 |
+ pthread_mutex_unlock(&_dm_pools_mutex);
|
|
|
191583 |
log_error(INTERNAL_ERROR "Unreleased memory pool(s) found.");
|
|
|
191583 |
}
|
|
|
191583 |
|
|
|
191583 |
diff --git a/test/Makefile.in b/test/Makefile.in
|
|
|
191583 |
index 1b9789f..5685544 100644
|
|
|
191583 |
--- a/test/Makefile.in
|
|
|
191583 |
+++ b/test/Makefile.in
|
|
|
191583 |
@@ -34,7 +34,8 @@ T ?= .
|
|
|
191583 |
S ?= @ # never match anything by default
|
|
|
191583 |
VERBOSE ?= 0
|
|
|
191583 |
ALL = $(shell find $(srcdir) \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) | sort)
|
|
|
191583 |
-RUN = $(shell find $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(T)).*" -and -not -regex "$(srcdir)/.*($(S)).*" | sort)
|
|
|
191583 |
+comma = ,
|
|
|
191583 |
+RUN = $(shell find $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(subst $(comma),|,$(T))).*" -and -not -regex "$(srcdir)/.*($(subst $(comma),|,$(S))).*" | sort)
|
|
|
191583 |
RUN_BASE = $(subst $(srcdir)/,,$(RUN))
|
|
|
191583 |
|
|
|
191583 |
# Shell quote;
|
|
|
191583 |
diff --git a/test/shell/lvmcache-exercise.sh b/test/shell/lvmcache-exercise.sh
|
|
|
191583 |
index b1e2b92..6e8efda 100644
|
|
|
191583 |
--- a/test/shell/lvmcache-exercise.sh
|
|
|
191583 |
+++ b/test/shell/lvmcache-exercise.sh
|
|
|
191583 |
@@ -1,5 +1,5 @@
|
|
|
191583 |
#!/bin/sh
|
|
|
191583 |
-# Copyright (C) 2008 Red Hat, Inc. All rights reserved.
|
|
|
191583 |
+# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
|
|
|
191583 |
#
|
|
|
191583 |
# This copyrighted material is made available to anyone wishing to use,
|
|
|
191583 |
# modify, copy, or redistribute it subject to the terms and conditions
|
|
|
191583 |
@@ -14,10 +14,23 @@
|
|
|
191583 |
aux prepare_pvs 5
|
|
|
191583 |
|
|
|
191583 |
vgcreate $vg1 "$dev1"
|
|
|
191583 |
-vgcreate $vg2 "$dev3"
|
|
|
191583 |
+vgcreate $vg2 "$dev3" "$dev4" "$dev5"
|
|
|
191583 |
|
|
|
191583 |
aux disable_dev "$dev1"
|
|
|
191583 |
pvscan
|
|
|
191583 |
vgcreate $vg1 "$dev2"
|
|
|
191583 |
aux enable_dev "$dev1"
|
|
|
191583 |
pvs
|
|
|
191583 |
+
|
|
|
191583 |
+# reappearing device (rhbz 995440)
|
|
|
191583 |
+lvcreate -aey -m2 --type mirror -l4 --alloc anywhere --corelog -n $lv1 $vg2
|
|
|
191583 |
+
|
|
|
191583 |
+aux disable_dev "$dev3"
|
|
|
191583 |
+lvconvert --yes --repair $vg2/$lv1
|
|
|
191583 |
+aux enable_dev "$dev3"
|
|
|
191583 |
+
|
|
|
191583 |
+# here it should fix any reappeared devices
|
|
|
191583 |
+lvs
|
|
|
191583 |
+
|
|
|
191583 |
+lvs -a $vg2 -o+devices 2>&1 | tee out
|
|
|
191583 |
+not grep reappeared out
|
|
|
191583 |
diff --git a/test/shell/vgrename-usage.sh b/test/shell/vgrename-usage.sh
|
|
|
191583 |
index 2b8ac5a..59576ac 100644
|
|
|
191583 |
--- a/test/shell/vgrename-usage.sh
|
|
|
191583 |
+++ b/test/shell/vgrename-usage.sh
|
|
|
191583 |
@@ -38,3 +38,18 @@ vgcreate $vg1 "$dev1"
|
|
|
191583 |
vgcreate $vg2 "$dev2"
|
|
|
191583 |
not vgrename $vg1 $vg2
|
|
|
191583 |
vgremove $vg1 $vg2
|
|
|
191583 |
+
|
|
|
191583 |
+# vgrename duplicate name
|
|
|
191583 |
+vgcreate $vg1 "$dev1"
|
|
|
191583 |
+aux disable_dev "$dev1"
|
|
|
191583 |
+vgcreate $vg1 "$dev2"
|
|
|
191583 |
+UUID=$(vgs --noheading -o vg_uuid $vg1)
|
|
|
191583 |
+aux enable_dev "$dev1"
|
|
|
191583 |
+
|
|
|
191583 |
+not vgrename $vg1 $vg2
|
|
|
191583 |
+vgrename $UUID $vg2
|
|
|
191583 |
+not vgrename $UUID $vg1
|
|
|
191583 |
+
|
|
|
191583 |
+vgs
|
|
|
191583 |
+
|
|
|
191583 |
+vgremove $vg1 $vg2
|
|
|
191583 |
diff --git a/tools/vgrename.c b/tools/vgrename.c
|
|
|
191583 |
index 154a6f3..b5e778f 100644
|
|
|
191583 |
--- a/tools/vgrename.c
|
|
|
191583 |
+++ b/tools/vgrename.c
|
|
|
191583 |
@@ -83,6 +83,8 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
|
|
|
191583 |
if (!lvmetad_vg_list_to_lvmcache(cmd))
|
|
|
191583 |
stack;
|
|
|
191583 |
|
|
|
191583 |
+ lvmcache_label_scan(cmd, 2);
|
|
|
191583 |
+
|
|
|
191583 |
/* Avoid duplicates */
|
|
|
191583 |
if (!(vgids = get_vgids(cmd, 0)) || dm_list_empty(vgids)) {
|
|
|
191583 |
log_error("No complete volume groups found");
|