diff options
author | David Teigland <teigland@redhat.com> | 2014-12-04 16:11:10 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-03-11 13:31:15 -0500 |
commit | 9226ed0dfc30152ce42ba39f78cefda217f82894 (patch) | |
tree | b478d94b77066cee4b5bcef520984ed540f857ad | |
parent | 41347e42e48f75ee522ec04750d556696e7b9456 (diff) | |
download | lvm2-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.h | 2 | ||||
-rw-r--r-- | lib/locking/lvmlockd.c | 34 | ||||
-rw-r--r-- | lib/locking/lvmlockd.h | 2 | ||||
-rw-r--r-- | tools/args.h | 1 | ||||
-rw-r--r-- | tools/vgchange.c | 74 |
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; } |