master - lvmlockd: use DM_UUID_LEN for buffer size
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c995e40b6333fb83fc1...
Commit: c995e40b6333fb83fc1eda7be0cc4ef43f1eb88e
Parent: bffae6c9855033a22893b28a79d5e7952504b95e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 7 14:58:35 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jul 7 15:00:15 2017 -0500
lvmlockd: use DM_UUID_LEN for buffer size
---
daemons/lvmlockd/lvmlockd-core.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index b6f3df9..867e3ca 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -19,6 +19,7 @@
#include "lvm-version.h"
#include "lvmetad-client.h"
#include "lvmlockd-client.h"
+#include "dm-ioctl.h" /* for DM_UUID_LEN */
/* #include <assert.h> */
#include <errno.h>
@@ -4956,7 +4957,7 @@ out:
return rv;
}
-static char _dm_uuid[72];
+static char _dm_uuid[DM_UUID_LEN];
static char *get_dm_uuid(char *dm_name)
{
6 years, 9 months
master - lvmlockd: miss adopt orphaned resources
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=bffae6c9855033a2289...
Commit: bffae6c9855033a22893b28a79d5e7952504b95e
Parent: 3797f47ecf23c41d4476e2cce0f210b48b32923d
Author: Huan Zhang <zhanghuan(a)chinac.com>
AuthorDate: Fri Jul 7 14:53:16 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jul 7 14:58:14 2017 -0500
lvmlockd: miss adopt orphaned resources
1. dm_uuid is 68 byte length, but buf is 64 which
will cause miss match uuid from lv lock manager
2. no lv lock_type path in dm config, use lock_args instead
Signed-off-by: Zhang Huan <zhanghuan(a)chinac.com>
---
daemons/lvmlockd/lvmlockd-core.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 4d96e67..b6f3df9 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -4907,14 +4907,10 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
continue;
for (lv_cn = md_cn->child; lv_cn; lv_cn = lv_cn->sib) {
- snprintf(find_str_path, PATH_MAX, "%s/lock_type", lv_cn->key);
- lock_type = dm_config_find_str(lv_cn, find_str_path, NULL);
-
- if (!lock_type)
- continue;
-
snprintf(find_str_path, PATH_MAX, "%s/lock_args", lv_cn->key);
lock_args = dm_config_find_str(lv_cn, find_str_path, NULL);
+ if (!lock_args)
+ continue;
snprintf(find_str_path, PATH_MAX, "%s/id", lv_cn->key);
lv_uuid = dm_config_find_str(lv_cn, find_str_path, NULL);
@@ -4960,7 +4956,7 @@ out:
return rv;
}
-static char _dm_uuid[64];
+static char _dm_uuid[72];
static char *get_dm_uuid(char *dm_name)
{
6 years, 9 months
master - lvmlockd: fix revert in lvcreate
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3797f47ecf23c41d447...
Commit: 3797f47ecf23c41d4476e2cce0f210b48b32923d
Parent: a0f6135e5c53af8bb361932ebe8fec55a1804cc9
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 7 14:42:25 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jul 7 14:42:25 2017 -0500
lvmlockd: fix revert in lvcreate
If the activation step in lvcreate fails (e.g. the specified
minor number is already used), then the lvcreate is reverted,
but the LV lock in lvmlockd was not being unlocked or properly
freed.
---
lib/metadata/lv_manip.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index f75cf51..fbe0aed 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7983,7 +7983,8 @@ deactivate_and_revert_new_lv:
}
revert_new_lv:
- lockd_free_lv(vg->cmd, vg, lp->lv_name, &lv->lvid.id[1], lp->lock_args);
+ lockd_lv(cmd, lv, "un", LDLV_PERSISTENT);
+ lockd_free_lv(vg->cmd, vg, lp->lv_name, &lv->lvid.id[1], lv->lock_args);
/* FIXME Better to revert to backup of metadata? */
if (!lv_remove(lv) || !vg_write(vg) || !vg_commit(vg))
6 years, 9 months
master - lvmlockd: use lock on thin pool when command names tdata
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a0f6135e5c53af8bb36...
Commit: a0f6135e5c53af8bb361932ebe8fec55a1804cc9
Parent: fdd00ecdd1fd51605be1b616d712a2220ced8875
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 7 12:06:53 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jul 7 12:06:53 2017 -0500
lvmlockd: use lock on thin pool when command names tdata
Some lvconvert commands can be used directly on the data sublv:
lvconvert ... vg/pool_tdata
The correct LV lock to use in lvmlockd is the one on the pool LV.
---
lib/locking/lvmlockd.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 92a970a..34b3882 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -2077,6 +2077,10 @@ static int _lockd_lv_thin(struct cmd_context *cmd, struct logical_volume *lv,
} else if (lv_is_thin_pool(lv)) {
pool_lv = lv;
+ } else if (lv_is_thin_pool_data(lv)) {
+ /* FIXME: there should be a function to get pool lv from data lv. */
+ pool_lv = lv_parent(lv);
+
} else {
/* This should not happen AFAIK. */
log_error("Lock on incorrect thin lv type %s/%s",
6 years, 9 months
master - lvmetad: Suppress accept error on clean shutdown
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fdd00ecdd1fd51605be...
Commit: fdd00ecdd1fd51605be1b616d712a2220ced8875
Parent: 70c340dbc25523de18195a7916f27aa37b051e43
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Jul 6 14:53:10 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Jul 6 14:53:10 2017 +0100
lvmetad: Suppress accept error on clean shutdown
Also fix error message after pthread_create() error in handle_connect().
---
WHATS_NEW | 1 +
libdaemon/server/daemon-server.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3e72d83..062a440 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.173 -
=================================
+ Suppress error message from accept() on clean lvmetad shutdown.
Tidy clvmd client list processing and fix segfaults.
Protect clvmd debug log messages with mutex and add client id.
Fix shellcheck reported issues for script files.
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 10cc8f7..6fdf195 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -491,7 +491,8 @@ static int handle_connect(daemon_state s)
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
if (client.socket_fd < 0) {
- ERROR(&s, "Failed to accept connection errno %d.", errno);
+ if (errno != EAGAIN || !_shutdown_requested)
+ ERROR(&s, "Failed to accept connection: %s.", strerror(errno));
return 0;
}
@@ -512,8 +513,8 @@ static int handle_connect(daemon_state s)
ts->s = s;
ts->client = client;
- if (pthread_create(&ts->client.thread_id, NULL, _client_thread, ts)) {
- ERROR(&s, "Failed to create client thread errno %d.", errno);
+ if ((errno = pthread_create(&ts->client.thread_id, NULL, _client_thread, ts))) {
+ ERROR(&s, "Failed to create client thread: %s.", strerror(errno));
return 0;
}
6 years, 9 months
master - test: return 0 if ignoring 'a' device health chars is requested
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=70c340dbc25523de181...
Commit: 70c340dbc25523de18195a7916f27aa37b051e43
Parent: f2eda36cfa9baf3f7e132dbc3a3f34c908cb36d4
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Jul 4 19:34:10 2017 +0200
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Jul 4 19:34:10 2017 +0200
test: return 0 if ignoring 'a' device health chars is requested
This allows lvconvert-raid-reshape-striped_to_linear.sh to succeed when
it reduces raid5 to two stripes before converting to raid1 and linear.
---
test/lib/check.sh | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/test/lib/check.sh b/test/lib/check.sh
index c8efcca..a1abda8 100644
--- a/test/lib/check.sh
+++ b/test/lib/check.sh
@@ -234,6 +234,7 @@ in_sync() {
[ $ignore_a -eq 0 ] && \
die "$lvm_name ($type$snap) in-sync, but 'a' characters in health status"
echo "$lvm_name ($type$snap) is not in-sync"
+ [ $ignore_a -eq 1 ] && return 0
return 1
fi
6 years, 9 months
master - clvmd: Fix client list corruption
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f2eda36cfa9baf3f7e1...
Commit: f2eda36cfa9baf3f7e132dbc3a3f34c908cb36d4
Parent: af789fd6d0cba45cc4897772bae3ca73a3f15b38
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jul 1 01:34:38 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jul 1 01:34:38 2017 +0100
clvmd: Fix client list corruption
Centralise editing of the client list into _add_client() and
_del_client(). Introduce _local_client_count to track the size of the
list for debugging purposes. Simplify and standardise the various ways
the list gets walked.
While processing one element of the list in main_loop(),
cleanup_zombie() may be called and remove a different element, so make
sure main_loop() refreshes its list state on return. Prior to this
patch, the list edits for clients disappearing could race against the
list edits for new clients connecting and corrupt the list and cause a
variety of segfaults.
An easy way to trigger such failures was by repeatedly running shell
commands such as:
lvs &; lvs &; lvs &;...;killall -9 lvs; lvs &; lvs &;...
Situations that occasionally lead to the failures can be spotted by
looking for 'EOF' with 'inprogress=1' in the clvmd debug logs.
---
WHATS_NEW | 1 +
daemons/clvmd/clvmd.c | 90 ++++++++++++++++++++++++++++++-------------------
2 files changed, 56 insertions(+), 35 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 29f07b8..3e72d83 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.173 -
=================================
+ Tidy clvmd client list processing and fix segfaults.
Protect clvmd debug log messages with mutex and add client id.
Fix shellcheck reported issues for script files.
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index a8a121c..881a931 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -58,6 +58,7 @@
/* Head of the fd list. Also contains
the cluster_socket details */
static struct local_client local_client_head;
+static int _local_client_count = 0;
static unsigned short global_xid = 0; /* Last transaction ID issued */
@@ -68,6 +69,37 @@ static unsigned max_csid_len;
static unsigned max_cluster_message;
static unsigned max_cluster_member_name_len;
+static void _add_client(struct local_client *new_client, struct local_client *existing_client)
+{
+ _local_client_count++;
+ DEBUGLOG("(%p) Adding listener for fd %d. (Now %d monitored fds.)\n", new_client, new_client->fd, _local_client_count);
+ new_client->next = existing_client->next;
+ existing_client->next = new_client;
+}
+
+int add_client(struct local_client *new_client)
+{
+ _add_client(new_client, &local_client_head);
+
+ return 0;
+}
+
+/* Returns 0 if delfd is found and removed from list */
+static int _del_client(struct local_client *delfd)
+{
+ struct local_client *lastfd, *thisfd;
+
+ for (lastfd = &local_client_head; (thisfd = lastfd->next); lastfd = thisfd)
+ if (thisfd == delfd) {
+ DEBUGLOG("(%p) Removing listener for fd %d\n", thisfd, thisfd->fd);
+ lastfd->next = delfd->next;
+ _local_client_count--;
+ return 0;
+ }
+
+ return 1;
+}
+
/* Structure of items on the LVM thread list */
struct lvm_thread_cmd {
struct dm_list list;
@@ -590,6 +622,7 @@ int main(int argc, char *argv[])
local_client_head.fd = clops->get_main_cluster_fd();
local_client_head.type = CLUSTER_MAIN_SOCK;
local_client_head.callback = clops->cluster_fd_callback;
+ _local_client_count++;
/* Add the local socket to the list */
if (!(newfd = dm_zalloc(sizeof(struct local_client)))) {
@@ -600,8 +633,8 @@ int main(int argc, char *argv[])
newfd->fd = local_sock;
newfd->type = LOCAL_RENDEZVOUS;
newfd->callback = local_rendezvous_callback;
- newfd->next = local_client_head.next;
- local_client_head.next = newfd;
+
+ (void) add_client(newfd);
/* This needs to be started after cluster initialisation
as it may need to take out locks */
@@ -643,6 +676,7 @@ int main(int argc, char *argv[])
while ((delfd = local_client_head.next)) {
local_client_head.next = delfd->next;
+ _local_client_count--;
/* Failing cleanup_zombie leaks... */
if (delfd->type == LOCAL_SOCK && !cleanup_zombie(delfd))
cmd_client_cleanup(delfd); /* calls sync_unlock */
@@ -859,13 +893,11 @@ static void main_loop(int cmd_timeout)
while (!quit) {
fd_set in;
int select_status;
- struct local_client *thisfd;
+ struct local_client *thisfd, *nextfd;
struct timeval tv = { cmd_timeout, 0 };
int quorate = clops->is_quorate();
int client_count = 0;
int max_fd = 0;
- struct local_client *lastfd = &local_client_head;
- struct local_client *nextfd = local_client_head.next;
/* Wait on the cluster FD and all local sockets/pipes */
local_client_head.fd = clops->get_main_cluster_fd();
@@ -881,20 +913,20 @@ static void main_loop(int cmd_timeout)
fprintf(stderr, "WARNING: Your cluster may freeze up if the number of clvmd file descriptors (%d) exceeds %d.\n", max_fd + 1, FD_SETSIZE);
}
- for (thisfd = &local_client_head; thisfd; thisfd = nextfd, nextfd = thisfd ? thisfd->next : NULL) {
+ for (thisfd = &local_client_head; thisfd; thisfd = nextfd) {
+ nextfd = thisfd->next;
if (thisfd->removeme && !cleanup_zombie(thisfd)) {
- struct local_client *free_fd = thisfd;
- lastfd->next = nextfd;
- DEBUGLOG("(%p) removeme set with %d monitored fds remaining\n", thisfd, client_count - 1);
+ /* cleanup_zombie might have removed the next list element */
+ nextfd = thisfd->next;
- /* Queue cleanup, this also frees the client struct */
- add_to_lvmqueue(free_fd, NULL, 0, NULL);
+ (void) _del_client(thisfd);
- continue;
- }
+ DEBUGLOG("(%p) removeme set with %d monitored fds remaining\n", thisfd, _local_client_count);
- lastfd = thisfd;
+ /* Queue cleanup, this also frees the client struct */
+ add_to_lvmqueue(thisfd, NULL, 0, NULL);
+ }
if (thisfd->removeme)
continue;
@@ -953,8 +985,7 @@ static void main_loop(int cmd_timeout)
/* New client...simply add it to the list */
if (newfd) {
- newfd->next = thisfd->next;
- thisfd->next = newfd;
+ _add_client(newfd, thisfd);
thisfd = newfd;
}
}
@@ -1225,20 +1256,16 @@ static int cleanup_zombie(struct local_client *thisfd)
/* Remove the pipe client */
if (thisfd->bits.localsock.pipe_client) {
- struct local_client *delfd;
- struct local_client *lastfd;
+ struct local_client *delfd = thisfd->bits.localsock.pipe_client;
- (void) close(thisfd->bits.localsock.pipe_client->fd); /* Close pipe */
+ (void) close(delfd->fd); /* Close pipe */
(void) close(thisfd->bits.localsock.pipe);
/* Remove pipe client */
- for (lastfd = &local_client_head; (delfd = lastfd->next); lastfd = delfd)
- if (thisfd->bits.localsock.pipe_client == delfd) {
- thisfd->bits.localsock.pipe_client = NULL;
- lastfd->next = delfd->next;
- dm_free(delfd);
- break;
- }
+ if (!_del_client(delfd)) {
+ dm_free(delfd);
+ thisfd->bits.localsock.pipe_client = NULL;
+ }
}
}
@@ -1436,8 +1463,8 @@ static int read_from_local_sock(struct local_client *thisfd)
newfd->type = THREAD_PIPE;
newfd->callback = local_pipe_callback;
newfd->bits.pipe.client = thisfd;
- newfd->next = thisfd->next;
- thisfd->next = newfd;
+
+ _add_client(newfd, thisfd);
/* Store a cross link to the pipe */
thisfd->bits.localsock.pipe_client = newfd;
@@ -1461,13 +1488,6 @@ static int read_from_local_sock(struct local_client *thisfd)
/* Add a file descriptor from the cluster or comms interface to
our list of FDs for select
*/
-int add_client(struct local_client *new_client)
-{
- new_client->next = local_client_head.next;
- local_client_head.next = new_client;
-
- return 0;
-}
/* Called when the pre-command has completed successfully - we
now execute the real command on all the requested nodes */
6 years, 9 months
master - clvmd: add client id to debug log messages
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=af789fd6d0cba45cc48...
Commit: af789fd6d0cba45cc4897772bae3ca73a3f15b38
Parent: 17ed25409136162d091809d412596a45e0a30fd4
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jul 1 01:17:40 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jul 1 01:17:40 2017 +0100
clvmd: add client id to debug log messages
Use standard format to make it easier to find the client to which each
debug log message refers.
---
WHATS_NEW | 2 +-
daemons/clvmd/clvmd-command.c | 6 +-
daemons/clvmd/clvmd.c | 120 +++++++++++++++++++++--------------------
3 files changed, 65 insertions(+), 63 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3f496fe..29f07b8 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,6 +1,6 @@
Version 2.02.173 -
=================================
- Protect clvmd debug log messages with mutex.
+ Protect clvmd debug log messages with mutex and add client id.
Fix shellcheck reported issues for script files.
Version 2.02.172 - 28th June 2017
diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c
index 0593f6f..cf19dc2 100644
--- a/daemons/clvmd/clvmd-command.c
+++ b/daemons/clvmd/clvmd-command.c
@@ -206,7 +206,7 @@ static int lock_vg(struct local_client *client)
lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
/* lock_flags = args[1]; */
lockname = &args[2];
- DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
+ DEBUGLOG("(%p) doing PRE command LOCK_VG '%s' at %x\n", client, lockname, lock_cmd);
if (lock_mode == LCK_UNLOCK) {
if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
@@ -323,7 +323,7 @@ void cmd_client_cleanup(struct local_client *client)
int lkid;
char *lockname;
- DEBUGLOG("Client thread cleanup (%p)\n", client);
+ DEBUGLOG("(%p) Client thread cleanup\n", client);
if (!client->bits.localsock.private)
return;
@@ -332,7 +332,7 @@ void cmd_client_cleanup(struct local_client *client)
dm_hash_iterate(v, lock_hash) {
lkid = (int)(long)dm_hash_get_data(lock_hash, v);
lockname = dm_hash_get_key(lock_hash, v);
- DEBUGLOG("Cleanup (%p): Unlocking lock %s %x\n", client, lockname, lkid);
+ DEBUGLOG("(%p) Cleanup: Unlocking lock %s %x\n", client, lockname, lkid);
(void) sync_unlock(lockname, lkid);
}
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index 0f96356..a8a121c 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -606,8 +606,8 @@ int main(int argc, char *argv[])
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("Starting LVM thread\n");
- DEBUGLOG("Main cluster socket fd %d (%p) with local socket %d (%p)\n",
- local_client_head.fd, &local_client_head, newfd->fd, newfd);
+ DEBUGLOG("(%p) Main cluster socket fd %d with local socket %d (%p)\n",
+ &local_client_head, local_client_head.fd, newfd->fd, newfd);
/* Don't let anyone else to do work until we are started */
if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
@@ -704,13 +704,13 @@ static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
pthread_mutex_init(&newfd->bits.localsock.mutex, NULL);
if (fcntl(client_fd, F_SETFD, 1))
- DEBUGLOG("Setting CLOEXEC on client fd failed: %s\n", strerror(errno));
+ DEBUGLOG("(%p) Setting CLOEXEC on client fd %d failed: %s\n", thisfd, client_fd, strerror(errno));
newfd->fd = client_fd;
newfd->type = LOCAL_SOCK;
newfd->callback = local_sock_callback;
newfd->bits.localsock.all_success = 1;
- DEBUGLOG("Got new connection on fd %d (%p)\n", newfd->fd, newfd);
+ DEBUGLOG("(%p) Got new connection on fd %d\n", newfd, newfd->fd);
*new_client = newfd;
}
return 1;
@@ -732,8 +732,8 @@ static int local_pipe_callback(struct local_client *thisfd, char *buf,
if (len == sizeof(int))
memcpy(&status, buffer, sizeof(int));
- DEBUGLOG("Read on pipe %d, %d bytes, status %d\n",
- thisfd->fd, len, status);
+ DEBUGLOG("(%p) Read on pipe %d, %d bytes, status %d\n",
+ thisfd, thisfd->fd, len, status);
/* EOF on pipe or an error, close it */
if (len <= 0) {
@@ -756,11 +756,11 @@ static int local_pipe_callback(struct local_client *thisfd, char *buf,
}
return -1;
} else {
- DEBUGLOG("Background routine status was %d, sock_client (%p)\n",
- status, sock_client);
+ DEBUGLOG("(%p) Background routine status was %d, sock_client %p\n",
+ thisfd, status, sock_client);
/* But has the client gone away ?? */
if (!sock_client) {
- DEBUGLOG("Got pipe response for dead client, ignoring it\n");
+ DEBUGLOG("(%p) Got pipe response for dead client, ignoring it\n", thisfd);
} else {
/* If error then just return that code */
if (status)
@@ -800,7 +800,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
return;
clops->name_from_csid(csid, nodename);
- DEBUGLOG("Checking for a reply from %s\n", nodename);
+ DEBUGLOG("(%p) Checking for a reply from %s\n", client, nodename);
pthread_mutex_lock(&client->bits.localsock.mutex);
reply = client->bits.localsock.replies;
@@ -810,7 +810,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
pthread_mutex_unlock(&client->bits.localsock.mutex);
if (!reply) {
- DEBUGLOG("Node %s timed-out\n", nodename);
+ DEBUGLOG("(%p) Node %s timed-out\n", client, nodename);
add_reply_to_list(client, ETIMEDOUT, csid,
"Command timed out", 18);
}
@@ -825,7 +825,7 @@ static void timedout_callback(struct local_client *client, const char *csid,
*/
static void request_timed_out(struct local_client *client)
{
- DEBUGLOG("Request timed-out. padding\n");
+ DEBUGLOG("(%p) Request timed-out. padding\n", client);
clops->cluster_do_node_callback(client, timedout_callback);
if (!client->bits.localsock.threadid)
@@ -886,7 +886,7 @@ static void main_loop(int cmd_timeout)
if (thisfd->removeme && !cleanup_zombie(thisfd)) {
struct local_client *free_fd = thisfd;
lastfd->next = nextfd;
- DEBUGLOG("removeme set for %p with %d monitored fds remaining\n", free_fd, client_count - 1);
+ DEBUGLOG("(%p) removeme set with %d monitored fds remaining\n", thisfd, client_count - 1);
/* Queue cleanup, this also frees the client struct */
add_to_lvmqueue(free_fd, NULL, 0, NULL);
@@ -945,8 +945,8 @@ static void main_loop(int cmd_timeout)
type == CLUSTER_INTERNAL)
goto closedown;
- DEBUGLOG("ret == %d, errno = %d. removing client\n",
- ret, errno);
+ DEBUGLOG("(%p) ret == %d, errno = %d. removing client\n",
+ thisfd, ret, errno);
thisfd->removeme = 1;
continue;
}
@@ -972,8 +972,8 @@ static void main_loop(int cmd_timeout)
thisfd->bits.localsock.expected_replies !=
thisfd->bits.localsock.num_replies) {
/* Send timed out message + replies we already have */
- DEBUGLOG("Request timed-out (send: %ld, now: %ld)\n",
- thisfd->bits.localsock.sent_time, the_time);
+ DEBUGLOG("Request to client %p timed-out (send: %ld, now: %ld)\n",
+ thisfd, thisfd->bits.localsock.sent_time, the_time);
thisfd->bits.localsock.all_success = 0;
@@ -1185,8 +1185,8 @@ static int cleanup_zombie(struct local_client *thisfd)
if (!thisfd->bits.localsock.cleanup_needed)
return 0;
- DEBUGLOG("EOF on local socket: inprogress=%d\n",
- thisfd->bits.localsock.in_progress);
+ DEBUGLOG("(%p) EOF on local socket %d: inprogress=%d\n",
+ thisfd, thisfd->fd, thisfd->bits.localsock.in_progress);
if ((pipe_client = thisfd->bits.localsock.pipe_client))
pipe_client = pipe_client->bits.pipe.client;
@@ -1208,7 +1208,7 @@ static int cleanup_zombie(struct local_client *thisfd)
/* Kill the subthread & free resources */
if (thisfd->bits.localsock.threadid) {
- DEBUGLOG("Waiting for pre&post thread (%p)\n", pipe_client);
+ DEBUGLOG("(%p) Waiting for pre&post thread\n", pipe_client);
pthread_mutex_lock(&thisfd->bits.localsock.mutex);
thisfd->bits.localsock.state = PRE_COMMAND;
thisfd->bits.localsock.finished = 1;
@@ -1219,7 +1219,7 @@ static int cleanup_zombie(struct local_client *thisfd)
(void **) &status)))
log_sys_error("pthread_join", "");
- DEBUGLOG("Joined pre&post thread\n");
+ DEBUGLOG("(%p) Joined pre&post thread\n", pipe_client);
thisfd->bits.localsock.threadid = 0;
@@ -1269,7 +1269,7 @@ static int read_from_local_sock(struct local_client *thisfd)
if (len == -1 && errno == EINTR)
return 1;
- DEBUGLOG("Read on local socket %d, len = %d\n", thisfd->fd, len);
+ DEBUGLOG("(%p) Read on local socket %d, len = %d\n", thisfd, thisfd->fd, len);
if (len && verify_message(buffer, len) < 0) {
log_error("read_from_local_sock from %d len %d bad verify.",
@@ -1343,15 +1343,15 @@ static int read_from_local_sock(struct local_client *thisfd)
char *argptr = inheader->node + strlen(inheader->node) + 1;
while (missing_len > 0) {
- DEBUGLOG("got %d bytes, need another %d (total %d)\n",
- argslen, missing_len, inheader->arglen);
+ DEBUGLOG("(%p) got %d bytes, need another %d (total %d)\n",
+ thisfd, argslen, missing_len, inheader->arglen);
len = read(thisfd->fd, argptr + argslen, missing_len);
if (len == -1 && errno == EINTR)
continue;
if (len <= 0) {
/* EOF or error on socket */
- DEBUGLOG("EOF on local socket\n");
+ DEBUGLOG("(%p) EOF on local socket\n", thisfd);
dm_free(thisfd->bits.localsock.cmd);
thisfd->bits.localsock.cmd = NULL;
return 0;
@@ -1379,7 +1379,7 @@ static int read_from_local_sock(struct local_client *thisfd)
.status = ENOENT
};
- DEBUGLOG("Unknown node: '%s'\n", inheader->node);
+ DEBUGLOG("(%p) Unknown node: '%s'\n", thisfd, inheader->node);
send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
"Error sending ENOENT reply to local user");
thisfd->bits.localsock.expected_replies = 0;
@@ -1405,7 +1405,7 @@ static int read_from_local_sock(struct local_client *thisfd)
.status = EBUSY
};
- DEBUGLOG("Creating pipe failed: %s\n", strerror(errno));
+ DEBUGLOG("(%p) Creating pipe failed: %s\n", thisfd, strerror(errno));
send_message(&reply, sizeof(reply), our_csid, thisfd->fd,
"Error sending EBUSY reply to local user");
return len;
@@ -1425,7 +1425,7 @@ static int read_from_local_sock(struct local_client *thisfd)
return len;
}
- DEBUGLOG("Creating pipe, [%d, %d]\n", comms_pipe[0], comms_pipe[1]);
+ DEBUGLOG("(%p) Creating pipe, [%d, %d]\n", thisfd, comms_pipe[0], comms_pipe[1]);
if (fcntl(comms_pipe[0], F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on pipe[0] failed: %s\n", strerror(errno));
@@ -1450,10 +1450,10 @@ static int read_from_local_sock(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
thisfd->bits.localsock.state = PRE_COMMAND;
thisfd->bits.localsock.cleanup_needed = 1;
- DEBUGLOG("Creating pre&post thread for pipe fd %d (%p)\n", newfd->fd, newfd);
+ DEBUGLOG("(%p) Creating pre&post thread for pipe fd %d\n", newfd, newfd->fd);
status = pthread_create(&thisfd->bits.localsock.threadid,
&stack_attr, pre_and_post_thread, thisfd);
- DEBUGLOG("Created pre&post thread, state = %d\n", status);
+ DEBUGLOG("(%p) Created pre&post thread, state = %d\n", newfd, status);
return len;
}
@@ -1478,8 +1478,8 @@ static int distribute_command(struct local_client *thisfd)
int len = thisfd->bits.localsock.cmd_len;
thisfd->xid = global_xid++;
- DEBUGLOG("distribute command: XID = %d, flags=0x%x (%s%s)\n",
- thisfd->xid, inheader->flags,
+ DEBUGLOG("(%p) distribute command: XID = %d, flags=0x%x (%s%s)\n",
+ thisfd, thisfd->xid, inheader->flags,
(inheader->flags & CLVMD_FLAG_LOCAL) ? "LOCAL" : "",
(inheader->flags & CLVMD_FLAG_REMOTE) ? "REMOTE" : "");
@@ -1501,7 +1501,7 @@ static int distribute_command(struct local_client *thisfd)
*/
add_to_lvmqueue(thisfd, inheader, len, NULL);
- DEBUGLOG("Sending message to all cluster nodes\n");
+ DEBUGLOG("(%p) Sending message to all cluster nodes\n", thisfd);
inheader->xid = thisfd->xid;
send_message(inheader, len, NULL, -1,
"Error forwarding message to cluster");
@@ -1520,11 +1520,11 @@ static int distribute_command(struct local_client *thisfd)
/* Are we the requested node ?? */
if (memcmp(csid, our_csid, max_csid_len) == 0) {
- DEBUGLOG("Doing command on local node only\n");
+ DEBUGLOG("(%p) Doing command on local node only\n", thisfd);
add_to_lvmqueue(thisfd, inheader, len, NULL);
} else {
- DEBUGLOG("Sending message to single node: %s\n",
- inheader->node);
+ DEBUGLOG("(%p) Sending message to single node: %s\n",
+ thisfd, inheader->node);
inheader->xid = thisfd->xid;
send_message(inheader, len, csid, -1,
"Error forwarding message to cluster node");
@@ -1535,7 +1535,7 @@ static int distribute_command(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
thisfd->bits.localsock.expected_replies = 1;
thisfd->bits.localsock.num_replies = 0;
- DEBUGLOG("Doing command explicitly on local node only\n");
+ DEBUGLOG("(%p) Doing command explicitly on local node only\n", thisfd);
add_to_lvmqueue(thisfd, inheader, len, NULL);
}
@@ -1661,7 +1661,7 @@ static void add_reply_to_list(struct local_client *client, int status,
reply->status = status;
clops->name_from_csid(csid, reply->node);
- DEBUGLOG("Reply from node %s: %d bytes\n", reply->node, len);
+ DEBUGLOG("(%p) Reply from node %s: %d bytes\n", client, reply->node, len);
if (len > 0) {
if (!(reply->replymsg = dm_malloc(len)))
@@ -1688,8 +1688,8 @@ static void add_reply_to_list(struct local_client *client, int status,
client->bits.localsock.state = POST_COMMAND;
pthread_cond_signal(&client->bits.localsock.cond);
}
- DEBUGLOG("Got %d replies, expecting: %d\n",
- client->bits.localsock.num_replies,
+ DEBUGLOG("(%p) Got %d replies, expecting: %d\n",
+ client, client->bits.localsock.num_replies,
client->bits.localsock.expected_replies);
}
pthread_mutex_unlock(&client->bits.localsock.mutex);
@@ -1704,7 +1704,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
sigset_t ss;
int pipe_fd = client->bits.localsock.pipe;
- DEBUGLOG("Pre&post thread (%p), pipe fd %d\n", client, pipe_fd);
+ DEBUGLOG("(%p) Pre&post thread pipe fd %d\n", client, pipe_fd);
pthread_mutex_lock(&client->bits.localsock.mutex);
/* Ignore SIGUSR1 (handled by master process) but enable
@@ -1724,7 +1724,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
if ((status = do_pre_command(client)))
client->bits.localsock.all_success = 0;
- DEBUGLOG("Pre&post thread (%p) writes status %d down to pipe fd %d\n",
+ DEBUGLOG("(%p) Pre&post thread writes status %d down to pipe fd %d\n",
client, status, pipe_fd);
/* Tell the parent process we have finished this bit */
@@ -1742,13 +1742,13 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
/* We may need to wait for the condition variable before running the post command */
if (client->bits.localsock.state != POST_COMMAND &&
!client->bits.localsock.finished) {
- DEBUGLOG("Pre&post thread (%p) waiting to do post command, state = %d\n",
+ DEBUGLOG("(%p) Pre&post thread waiting to do post command, state = %d\n",
client, client->bits.localsock.state);
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
- DEBUGLOG("Pre&post thread (%p) got post command condition...\n", client);
+ DEBUGLOG("(%p) Pre&post thread got post command condition...\n", client);
/* POST function must always run, even if the client aborts */
status = 0;
@@ -1762,15 +1762,15 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
next_pre:
if (client->bits.localsock.state != PRE_COMMAND &&
!client->bits.localsock.finished) {
- DEBUGLOG("Pre&post thread (%p) waiting for next pre command\n", client);
+ DEBUGLOG("(%p) Pre&post thread waiting for next pre command\n", client);
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
- DEBUGLOG("Pre&post thread (%p) got pre command condition...\n", client);
+ DEBUGLOG("(%p) Pre&post thread got pre command condition...\n", client);
}
pthread_mutex_unlock(&client->bits.localsock.mutex);
- DEBUGLOG("Pre&post thread (%p) finished\n", client);
+ DEBUGLOG("(%p) Pre&post thread finished\n", client);
pthread_exit(NULL);
}
@@ -1788,8 +1788,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
if (!(replybuf = dm_malloc(max_cluster_message)))
return -1;
- DEBUGLOG("process_local_command: %s msg=%p, msglen =%d, client=%p\n",
- decode_cmd(msg->cmd), msg, msglen, client);
+ DEBUGLOG("(%p) process_local_command: %s msg=%p, msglen =%d\n",
+ client, decode_cmd(msg->cmd), msg, msglen);
/* If remote flag is set, just set a successful status code. */
if (msg->flags & CLVMD_FLAG_REMOTE)
@@ -1804,8 +1804,8 @@ static int process_local_command(struct clvm_header *msg, int msglen,
if (xid == client->xid)
add_reply_to_list(client, status, our_csid, replybuf, replylen);
else
- DEBUGLOG("Local command took too long, discarding xid %d, current is %d\n",
- xid, client->xid);
+ DEBUGLOG("(%p) Local command took too long, discarding xid %d, current is %d\n",
+ client, xid, client->xid);
dm_free(replybuf);
@@ -1847,7 +1847,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
char *ptr;
int message_len = 0;
- DEBUGLOG("Send local reply\n");
+ DEBUGLOG("(%p) Send local reply\n", client);
/* Work out the total size of the reply */
while (thisreply) {
@@ -1864,7 +1864,7 @@ static void send_local_reply(struct local_client *client, int status, int fd)
/* Add in the size of our header */
message_len = message_len + sizeof(struct clvm_header);
if (!(replybuf = dm_malloc(message_len))) {
- DEBUGLOG("Memory allocation fails\n");
+ DEBUGLOG("(%p) Memory allocation fails\n", client);
return;
}
@@ -1993,6 +1993,7 @@ static int send_message(void *buf, int msglen, const char *csid, int fd,
(void) nanosleep (&delay, &remtime);
continue;
}
+ DEBUGLOG("%s", errtext);
log_error("%s", errtext);
break;
}
@@ -2006,7 +2007,7 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
{
/* If msg is NULL then this is a cleanup request */
if (cmd->msg == NULL) {
- DEBUGLOG("process_work_item: free %p\n", cmd->client);
+ DEBUGLOG("(%p) process_work_item: free\n", cmd->client);
cmd_client_cleanup(cmd->client);
pthread_mutex_destroy(&cmd->client->bits.localsock.mutex);
pthread_cond_destroy(&cmd->client->bits.localsock.cond);
@@ -2015,11 +2016,11 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
}
if (!cmd->remote) {
- DEBUGLOG("process_work_item: local\n");
+ DEBUGLOG("(%p) process_work_item: local\n", cmd->client);
process_local_command(cmd->msg, cmd->msglen, cmd->client,
cmd->xid);
} else {
- DEBUGLOG("process_work_item: remote\n");
+ DEBUGLOG("(%p) process_work_item: remote\n", cmd->client);
process_remote_command(cmd->msg, cmd->msglen, cmd->client->fd,
cmd->csid);
}
@@ -2113,8 +2114,8 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
} else
cmd->remote = 0;
- DEBUGLOG("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
- cmd, client, msg, msglen, csid, cmd->xid);
+ DEBUGLOG("(%p) add_to_lvmqueue: cmd=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
+ client, cmd, msg, msglen, csid, cmd->xid);
pthread_mutex_lock(&lvm_thread_mutex);
if (lvm_thread_exit) {
pthread_mutex_unlock(&lvm_thread_mutex);
@@ -2250,7 +2251,8 @@ static void check_all_callback(struct local_client *client, const char *csid,
If not, returns -1 and prints out a list of errant nodes */
static int check_all_clvmds_running(struct local_client *client)
{
- DEBUGLOG("check_all_clvmds_running\n");
+ DEBUGLOG("(%p) check_all_clvmds_running\n", client);
+
return clops->cluster_do_node_callback(client, check_all_callback);
}
6 years, 9 months
master - clvmd: add debuglog mutex
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=17ed25409136162d091...
Commit: 17ed25409136162d091809d412596a45e0a30fd4
Parent: 006a9eaada2744ca39b05aed7b7bf152524580be
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jul 1 00:58:39 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jul 1 00:58:39 2017 +0100
clvmd: add debuglog mutex
Log messages issued by different threads occasionally got intertwined.
---
WHATS_NEW | 1 +
daemons/clvmd/clvmd.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 2c98f5e..3f496fe 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.173 -
=================================
+ Protect clvmd debug log messages with mutex.
Fix shellcheck reported issues for script files.
Version 2.02.172 - 28th June 2017
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index dcc986b..0f96356 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -92,6 +92,7 @@ static const size_t STACK_SIZE = 128 * 1024;
static pthread_attr_t stack_attr;
static int lvm_thread_exit = 0;
static pthread_mutex_t lvm_thread_mutex;
+static pthread_mutex_t _debuglog_mutex;
static pthread_cond_t lvm_thread_cond;
static pthread_barrier_t lvm_start_barrier;
static struct dm_list lvm_cmd_head;
@@ -218,14 +219,17 @@ void debuglog(const char *fmt, ...)
switch (clvmd_get_debug()) {
case DEBUG_STDERR:
+ pthread_mutex_lock(&_debuglog_mutex);
va_start(ap,fmt);
time(&P);
fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime_r(&P, buf_ctime) + 4);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
+ pthread_mutex_unlock(&_debuglog_mutex);
break;
case DEBUG_SYSLOG:
+ pthread_mutex_lock(&_debuglog_mutex);
if (!syslog_init) {
openlog("clvmd", LOG_PID, LOG_DAEMON);
syslog_init = 1;
@@ -234,6 +238,7 @@ void debuglog(const char *fmt, ...)
va_start(ap,fmt);
vsyslog(LOG_DEBUG, fmt, ap);
va_end(ap);
+ pthread_mutex_unlock(&_debuglog_mutex);
break;
case DEBUG_OFF:
break;
@@ -522,6 +527,7 @@ int main(int argc, char *argv[])
exit(1);
}
pthread_mutex_init(&lvm_thread_mutex, NULL);
+ pthread_mutex_init(&_debuglog_mutex, NULL);
pthread_cond_init(&lvm_thread_cond, NULL);
pthread_barrier_init(&lvm_start_barrier, NULL, 2);
init_lvhash();
6 years, 9 months