diff options
author | David Teigland <teigland@redhat.com> | 2014-12-04 16:11:10 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2014-12-05 16:09:56 -0600 |
commit | 615f3b20bd0c2d4c3a76cedb5843304da9a35417 (patch) | |
tree | bbdf786df9cbb8a723e3eec759106ef05c38c442 | |
parent | b02f49d43372695d81454b4c67f3d32631ab7c3b (diff) | |
download | lvm2-615f3b20bd0c2d4c3a76cedb5843304da9a35417.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/commands.h | 2 | ||||
-rw-r--r-- | tools/vgchange.c | 74 |
6 files changed, 112 insertions, 3 deletions
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h index 17748a855..37c908733 100644 --- a/lib/config/config_settings.h +++ b/lib/config/config_settings.h @@ -227,6 +227,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 911349ff6..769acfa5b 100644 --- a/lib/locking/lvmlockd.c +++ b/lib/locking/lvmlockd.c @@ -882,6 +882,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 7440d5866..0972cf3ac 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 fa750bc88..de69b1628 100644 --- a/tools/args.h +++ b/tools/args.h @@ -50,6 +50,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/commands.h b/tools/commands.h index 4e363976d..c0f79d20f 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -962,7 +962,7 @@ xx(vgchange, metadataprofile_ARG, monitor_ARG, noudevsync_ARG, metadatacopies_ARG, vgmetadatacopies_ARG, partial_ARG, physicalextentsize_ARG, poll_ARG, refresh_ARG, resizeable_ARG, resizable_ARG, sysinit_ARG, test_ARG, uuid_ARG, - systemid_ARG, systemidsource_ARG, lockstart_ARG, lockstop_ARG, locktype_ARG) + systemid_ARG, systemidsource_ARG, lockstart_ARG, lockopt_ARG, lockstop_ARG, locktype_ARG) xx(vgck, "Check the consistency of volume group(s)", diff --git a/tools/vgchange.c b/tools/vgchange.c index 87ef2e463..cfab8bdb0 100644 --- a/tools/vgchange.c +++ b/tools/vgchange.c @@ -730,8 +730,66 @@ change: 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); } @@ -938,6 +996,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) || @@ -1062,6 +1122,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; } |