summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2014-12-04 16:11:10 -0600
committerDavid Teigland <teigland@redhat.com>2015-03-11 13:31:15 -0500
commit9226ed0dfc30152ce42ba39f78cefda217f82894 (patch)
treeb478d94b77066cee4b5bcef520984ed540f857ad
parent41347e42e48f75ee522ec04750d556696e7b9456 (diff)
downloadlvm2-9226ed0dfc30152ce42ba39f78cefda217f82894.tar.gz
vgchange: lock-start options for auto and wait
Adds options to use with --lock-start, --lock-opt wait|auto|autowait wait: wait for the start to finish auto: use when the system is running the command autowait: both auto and wait The auto option enables the use of lvm.conf activation_lock_start_list which defines VG's that should be automatically started by the system. This is similar to the auto_activation_volume_list used when the system automatically activates LV's.
-rw-r--r--lib/config/config_settings.h2
-rw-r--r--lib/locking/lvmlockd.c34
-rw-r--r--lib/locking/lvmlockd.h2
-rw-r--r--tools/args.h1
-rw-r--r--tools/vgchange.c74
5 files changed, 111 insertions, 2 deletions
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 99bb1724d..0990bc335 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -231,6 +231,8 @@ cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE
cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_INTERVAL, vsn(2, 2, 63), NULL)
cfg(activation_auto_set_activation_skip_CFG, "auto_set_activation_skip", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_AUTO_SET_ACTIVATION_SKIP, vsn(2,2,99), NULL)
cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL)
+cfg_array(activation_lock_start_list_CFG, "lock_start_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY|CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL)
+cfg_array(activation_auto_lock_start_list_CFG, "auto_lock_start_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY|CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 112), NULL)
cfg(metadata_vgcreate_cy_lock_type_CFG, "vgcreate_cy_lock_type", metadata_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CY_LOCK_TYPE, vsn(2, 2, 113), NULL)
cfg(metadata_vgcreate_default_lock_type_CFG, "vgcreate_default_lock_type", metadata_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_LOCK_TYPE, vsn(2, 2, 113), NULL)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index faebdcea7..114e14ca7 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -887,6 +887,40 @@ out:
return ret;
}
+int lockd_start_wait(struct cmd_context *cmd)
+{
+ daemon_reply reply;
+ int result;
+ int ret;
+
+ if (!_lvmlockd_active)
+ return 1;
+ if (!lvmlockd_connected())
+ return 0;
+
+ reply = _lockd_send("start_wait",
+ "pid = %d", getpid(),
+ NULL);
+
+ if (!_lockd_result(reply, &result, NULL)) {
+ ret = 0;
+ } else {
+ ret = (result < 0) ? 0 : 1;
+ }
+
+ if (!ret)
+ log_error("Locking start failed");
+
+ /*
+ * Get a list of vgs that started so we can
+ * better report what worked and what didn't?
+ */
+
+ daemon_reply_destroy(reply);
+
+ return ret;
+}
+
static int _mode_num(const char *mode)
{
if (!strcmp(mode, "na"))
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index 63ecae566..3a656753c 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -103,6 +103,7 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
+int lockd_start_wait(struct cmd_context *cmd);
/* locking */
@@ -144,6 +145,7 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg,
#define lockd_start_vg(cmd, vg) (1)
#define lockd_stop_vg(cmd, vg) (1)
+#define lockd_start_wait(cmd) (1)
#define lockd_gl_create(cmd, def_mode, vg_lock_type) (1)
#define lockd_gl(cmd, def_mode, flags) (1)
diff --git a/tools/args.h b/tools/args.h
index 7a9c4b31f..e31223c20 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -51,6 +51,7 @@ arg(labelsector_ARG, '\0', "labelsector", int_arg, 0)
arg(lockgl_ARG, '\0', "lock-gl", string_arg, 0)
arg(lockvg_ARG, '\0', "lock-vg", string_arg, 0)
arg(locklv_ARG, '\0', "lock-lv", string_arg, 0)
+arg(lockopt_ARG, '\0', "lock-opt", string_arg, 0)
arg(lockstart_ARG, '\0', "lock-start", string_arg, 0)
arg(lockstop_ARG, '\0', "lock-stop", string_arg, 0)
arg(locktype_ARG, '\0', "lock-type", string_arg, 0)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index e26da83fd..be20d7cb0 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -789,8 +789,66 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg)
return 1;
}
+static int _passes_lock_start_filter(struct cmd_context *cmd,
+ struct volume_group *vg,
+ const int cfg_id)
+{
+ const struct dm_config_node *cn;
+ const struct dm_config_value *cv;
+ const char *str;
+
+ /* undefined list means no restrictions, all vg names pass */
+
+ cn = find_config_tree_node(cmd, cfg_id, NULL);
+ if (!cn)
+ return 1;
+
+ /* with a defined list, the vg name must be included to pass */
+
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (cv->type == DM_CFG_EMPTY_ARRAY)
+ break;
+ if (cv->type != DM_CFG_STRING) {
+ log_error("Ignoring invalid string in lock_start list");
+ continue;
+ }
+ str = cv->v.str;
+ if (!*str) {
+ log_error("Ignoring empty string in config file");
+ continue;
+ }
+
+ /* ignoring tags for now */
+
+ if (!strcmp(str, vg->name))
+ return 1;
+ }
+
+ return 0;
+}
+
static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg)
{
+ const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
+ int auto_opt = 0;
+
+ if (!start_opt || arg_is_set(cmd, force_ARG))
+ goto do_start;
+
+ if (!strcmp(start_opt, "auto") || !strcmp(start_opt, "autowait"))
+ auto_opt = 1;
+
+ if (!_passes_lock_start_filter(cmd, vg, activation_lock_start_list_CFG)) {
+ log_verbose("Not starting %s since it does not pass lock_start_list", vg->name);
+ return 1;
+ }
+
+ if (auto_opt && !_passes_lock_start_filter(cmd, vg, activation_auto_lock_start_list_CFG)) {
+ log_verbose("Not starting %s since it does not pass auto_lock_start_list", vg->name);
+ return 1;
+ }
+
+do_start:
return lockd_start_vg(cmd, vg);
}
@@ -996,6 +1054,8 @@ static int lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
+ int ret;
+
int noupdate =
arg_count(cmd, activate_ARG) ||
arg_count(cmd, lockstart_ARG) ||
@@ -1122,6 +1182,16 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (!lockd_vgchange(cmd, argc, argv))
return_ECMD_FAILED;
- return process_each_vg(cmd, argc, argv, update ? READ_FOR_UPDATE : 0,
- NULL, &vgchange_single);
+ ret = process_each_vg(cmd, argc, argv, update ? READ_FOR_UPDATE : 0,
+ NULL, &vgchange_single);
+
+ /* Wait for lock-start ops that were initiated in vgchange_lockstart. */
+
+ if (arg_is_set(cmd, lockstart_ARG) && arg_is_set(cmd, lockopt_ARG)) {
+ const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
+ if (!strcmp(start_opt, "wait") || !strcmp(start_opt, "autowait"))
+ lockd_start_wait(cmd);
+ }
+
+ return ret;
}