summaryrefslogtreecommitdiffstats
path: root/daemons/clvmd/clvmd-command.c
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2010-06-04 12:59:30 +0000
committerMilan Broz <mbroz@redhat.com>2010-06-04 12:59:30 +0000
commit8d6e0c95621d9650e27c0821d63ce46d78cdb42a (patch)
tree3c529c7d0aab91869035c3fc40634591771bcee8 /daemons/clvmd/clvmd-command.c
parent850fa8233fb919e860e69fb84394307101a76bd4 (diff)
downloadlvm2-8d6e0c95621d9650e27c0821d63ce46d78cdb42a.tar.gz
lvm2-8d6e0c95621d9650e27c0821d63ce46d78cdb42a.tar.xz
lvm2-8d6e0c95621d9650e27c0821d63ce46d78cdb42a.zip
Fix restart of clvmd using -S switch
- allocate environment dynamically (still missing some limit?) - try to recover, if destroy failed (do not destroy lvm here) and free memory - check strdup() return codes - report failure to log - do not print NULL in exclusive lock loop
Diffstat (limited to 'daemons/clvmd/clvmd-command.c')
-rw-r--r--daemons/clvmd/clvmd-command.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c
index 180f8091..83d03ef7 100644
--- a/daemons/clvmd/clvmd-command.c
+++ b/daemons/clvmd/clvmd-command.c
@@ -361,33 +361,51 @@ void cmd_client_cleanup(struct local_client *client)
static int restart_clvmd(void)
{
- char *argv[1024];
- int argc = 1;
+ char **argv = NULL;
+ char *debug_arg = NULL, *lv_name;
+ int i, argc = 0, max_locks = 0;
struct dm_hash_node *hn = NULL;
- char *lv_name;
DEBUGLOG("clvmd restart requested\n");
+ /* Count exclusively-open LVs */
+ hn = NULL;
+ do {
+ hn = get_next_excl_lock(hn, &lv_name);
+ if (lv_name)
+ max_locks++;
+ } while (hn && *lv_name);
+
+ /* clvmd + locks (-E uuid) + debug (-d X) + NULL */
+ argv = malloc((max_locks * 2 + 4) * sizeof(*argv));
+ if (!argv)
+ goto_out;
+
/*
* Build the command-line
*/
- /* FIXME missing strdup error checks */
- argv[0] = strdup("clvmd");
+ argv[argc++] = strdup("clvmd");
+ if (!argv[0])
+ goto_out;
/* Propogate debug options */
if (debug) {
- char debug_level[16];
-
- sprintf(debug_level, "-d%d", debug);
- argv[argc++] = strdup(debug_level);
+ if (!(debug_arg = malloc(16)) ||
+ snprintf(debug_arg, 16, "-d%d", (int)debug) < 0)
+ goto_out;
+ argv[argc++] = debug_arg;
}
/* Now add the exclusively-open LVs */
do {
hn = get_next_excl_lock(hn, &lv_name);
if (lv_name) {
- argv[argc++] = strdup("-E");
- argv[argc++] = strdup(lv_name);
+ argv[argc] = strdup("-E");
+ if (!argv[argc++])
+ goto_out;
+ argv[argc] = strdup(lv_name);
+ if (!argv[argc++])
+ goto_out;
DEBUGLOG("excl lock: %s\n", lv_name);
hn = get_next_excl_lock(hn, &lv_name);
@@ -395,13 +413,16 @@ static int restart_clvmd(void)
} while (hn && *lv_name);
argv[argc++] = NULL;
- /* Tidy up */
- destroy_lvm();
-
/* Exec new clvmd */
/* NOTE: This will fail when downgrading! */
execve(CLVMD_PATH, argv, NULL);
-
+out:
/* We failed */
+ DEBUGLOG("Restart of clvmd failed.\n");
+
+ for (i = 0; i < argc && argv[i]; i++)
+ free(argv[i]);
+ free(argv);
+
return 0;
}