summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2011-09-24 20:48:34 +0000
committerZdenek Kabelac <zkabelac@redhat.com>2011-09-24 20:48:34 +0000
commita039e204e7263ba409218d4cc3fa407b12a111c1 (patch)
treee2b94b7e51e243e37d859f4ec9e8355b744e05ba
parente8ee29e9c183557e0f3df4691ee11167d1a8162f (diff)
downloadlvm2-a039e204e7263ba409218d4cc3fa407b12a111c1.tar.gz
lvm2-a039e204e7263ba409218d4cc3fa407b12a111c1.tar.xz
lvm2-a039e204e7263ba409218d4cc3fa407b12a111c1.zip
CLVMD bugfix support for args -S -E
Bugfix: Add (most probably unfinished) support for -E arg with list of exclusive locks. (During clvmd restart all exclusive locks would have been lost and in fact, if there would have been an exclusive lock, usage text would be printed and clvmd exits.) Instead of parsing list options multiple times every time some lock UUID is checked - put them straight into the hash table - make the code easier to understand as well. Remove was_ex_lock() function (replaced with dm_hash_lookup()). Swap return value for get_initial_state() (1 means success). Update man pages and usage info for -E option.
-rw-r--r--WHATS_NEW1
-rw-r--r--daemons/clvmd/clvmd.c19
-rw-r--r--daemons/clvmd/lvm-functions.c42
-rw-r--r--daemons/clvmd/lvm-functions.h2
-rw-r--r--man/clvmd.8.in4
5 files changed, 31 insertions, 37 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index e97c5d0c..e346c320 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
+ Fix restart of clvmd (preserve exlusive locks). (2.02.64)
Add 'Volume Type' lv_attr characters for RAID and RAID_IMAGE.
Add activation/retry_deactivation to lvm.conf to retry deactivation of an LV.
Replace open_count check with holders/mounted_fs check on lvremove path.
diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index 3fef68c8..baee198d 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -78,7 +78,7 @@ struct lvm_thread_cmd {
};
struct lvm_startup_params {
- char **argv;
+ struct dm_hash_table *excl_uuid;
};
static debug_t debug = DEBUG_OFF;
@@ -149,6 +149,7 @@ static void usage(const char *prog, FILE *file)
" -h Show this help information\n"
" -d[n] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
" -f Don't fork, run in the foreground\n"
+ " -E<lockuuid> Take this lock uuid as exclusively locked resource (for restart)\n"
" -R Tell all running clvmds in the cluster to reload their device cache\n"
" -S Restart clvmd, preserving exclusive locks\n"
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
@@ -348,6 +349,11 @@ int main(int argc, char *argv[])
{ NULL, 0, 0, 0 }
};
+ if (!(lvm_params.excl_uuid = dm_hash_create(128))) {
+ fprintf(stderr, "Failed to allocate hash table\n");
+ return 1;
+ }
+
/* Deal with command-line arguments */
opterr = 0;
optind = 0;
@@ -391,6 +397,12 @@ int main(int argc, char *argv[])
case 'I':
cluster_iface = parse_cluster_interface(optarg);
break;
+ case 'E':
+ if (!dm_hash_insert(lvm_params.excl_uuid, optarg, optarg)) {
+ fprintf(stderr, "Failed to allocate hash entry\n");
+ return 1;
+ }
+ break;
case 'T':
start_timeout = atoi(optarg);
if (start_timeout <= 0) {
@@ -565,7 +577,6 @@ int main(int argc, char *argv[])
/* Don't let anyone else to do work until we are started */
pthread_mutex_lock(&lvm_start_mutex);
- lvm_params.argv = argv;
pthread_create(&lvm_thread, NULL, lvm_thread_fn, &lvm_params);
/* Tell the rest of the cluster our version number */
@@ -603,6 +614,8 @@ int main(int argc, char *argv[])
free(delfd);
}
+ dm_hash_destroy(lvm_params.excl_uuid);
+
return 0;
}
@@ -1978,7 +1991,7 @@ static void *lvm_thread_fn(void *arg)
pthread_sigmask(SIG_BLOCK, &ss, NULL);
/* Initialise the interface to liblvm */
- init_clvm(lvm_params->argv);
+ init_clvm(lvm_params->excl_uuid);
/* Allow others to get moving */
pthread_mutex_unlock(&lvm_start_mutex);
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index b988b155..ba786bb0 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -694,34 +694,11 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
}
/*
- * Compare the uuid with the list of exclusive locks that clvmd
- * held before it was restarted, so we can get the right kind
- * of lock now we are restarting.
- */
-static int was_ex_lock(char *uuid, char **argv)
-{
- int optnum = 0;
- char *opt = argv[optnum];
-
- while (opt) {
- if (strcmp(opt, "-E") == 0) {
- opt = argv[++optnum];
- if (opt && (strcmp(opt, uuid) == 0)) {
- DEBUGLOG("Lock %s is exclusive\n", uuid);
- return 1;
- }
- }
- opt = argv[++optnum];
- }
- return 0;
-}
-
-/*
* Ideally, clvmd should be started before any LVs are active
* but this may not be the case...
* I suppose this also comes in handy if clvmd crashes, not that it would!
*/
-static int get_initial_state(char **argv)
+static int get_initial_state(struct dm_hash_table *excl_uuid)
{
int lock_mode;
char lv[64], vg[64], flags[25], vg_flags[25];
@@ -733,7 +710,7 @@ static int get_initial_state(char **argv)
"r");
if (!lvs)
- return 1;
+ return 0;
while (fgets(line, sizeof(line), lvs)) {
if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) {
@@ -759,12 +736,10 @@ static int get_initial_state(char **argv)
memcpy(&uuid[58], &lv[32], 6);
uuid[64] = '\0';
- lock_mode = LCK_READ;
-
/* Look for this lock in the list of EX locks
we were passed on the command-line */
- if (was_ex_lock(uuid, argv))
- lock_mode = LCK_EXCL;
+ lock_mode = (dm_hash_lookup(excl_uuid, uuid)) ?
+ LCK_EXCL : LCK_READ;
DEBUGLOG("getting initial lock for %s\n", uuid);
hold_lock(uuid, lock_mode, LCKF_NOQUEUE);
@@ -773,7 +748,8 @@ static int get_initial_state(char **argv)
}
if (fclose(lvs))
DEBUGLOG("lvs fclose failed: %s\n", strerror(errno));
- return 0;
+
+ return 1;
}
static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
@@ -880,14 +856,14 @@ void lvm_do_fs_unlock(void)
}
/* Called to initialise the LVM context of the daemon */
-int init_clvm(char **argv)
+int init_clvm(struct dm_hash_table *excl_uuid)
{
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
init_syslog(LOG_DAEMON);
openlog("clvmd", LOG_PID, LOG_DAEMON);
/* Initialise already held locks */
- if (get_initial_state(argv))
+ if (!get_initial_state(excl_uuid))
log_error("Cannot load initial lock states.");
if (!(cmd = create_toolcontext(1, NULL, 0))) {
diff --git a/daemons/clvmd/lvm-functions.h b/daemons/clvmd/lvm-functions.h
index f9c43b7c..565f878d 100644
--- a/daemons/clvmd/lvm-functions.h
+++ b/daemons/clvmd/lvm-functions.h
@@ -27,7 +27,7 @@ extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(const char *vgname);
extern int do_refresh_cache(void);
-extern int init_clvm(char **argv);
+extern int init_clvm(struct dm_hash_table *excl_uuid);
extern void destroy_lvm(void);
extern void init_lvhash(void);
extern void destroy_lvhash(void);
diff --git a/man/clvmd.8.in b/man/clvmd.8.in
index a4b9cc9c..22d94b27 100644
--- a/man/clvmd.8.in
+++ b/man/clvmd.8.in
@@ -4,6 +4,7 @@ clvmd \- cluster LVM daemon
.SH SYNOPSIS
.B clvmd
[\-d[<value>]] [\-C] [\-h]
+[\-E <lock uuid>]
[\-R]
[\-S]
[\-t <timeout>]
@@ -69,6 +70,9 @@ sensible.
.br
This timeout will be ignored if you start clvmd with the -d switch.
.TP
+.I \-E <lock uuid>
+Pass lock uuid to be reacquired exclusively when clvmd is restarted.
+.TP
.I \-R
Tells all the running clvmds in the cluster to reload their device cache and
re-read the lvm configuration file. This command should be run whenever the