1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lvmlockd: parse lockopt string into flags

This commit is contained in:
David Teigland 2024-06-18 11:24:02 -05:00
parent 9ea5ff3db5
commit 943e979079
9 changed files with 94 additions and 32 deletions

View File

@ -286,6 +286,7 @@ struct cmd_context {
struct dm_list pending_delete; /* list of LVs for removal */
struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */
struct vdo_convert_params *lvcreate_vcp;/* params for LV to VDO conversion */
uint32_t lockopt; /* LOCKOPT_* from --lockopt string */
};
/*

View File

@ -1223,11 +1223,11 @@ static int _lockd_all_lvs(struct cmd_context *cmd, struct volume_group *vg)
/* vgremove before the vg is removed */
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
int changing, const char *lockopt, int yes)
int changing, int yes)
{
int lock_type_num = get_lock_type_from_string(vg->lock_type);
if (lockopt && strstr(lockopt, "force")) {
if (cmd->lockopt & LOCKOPT_FORCE) {
if (!yes && yes_no_prompt("Force unprotected removal of shared VG? [y/n]: ") == 'n') {
log_error("VG not removed.");
return 0;
@ -2782,8 +2782,8 @@ int lockd_lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
{
char lv_uuid[64] __attribute__((aligned(8)));
char path[PATH_MAX];
int shupdate = (lp->lockopt && strstr(lp->lockopt, "shupdate"));
int norefresh = (lp->lockopt && strstr(lp->lockopt, "norefresh"));
int shupdate = cmd->lockopt & LOCKOPT_SHUPDATE;
int norefresh = cmd->lockopt & LOCKOPT_NOREFRESH;
int rv;
if (!vg_is_shared(lv->vg))
@ -3453,3 +3453,60 @@ int lockd_lv_refresh(struct cmd_context *cmd, struct lvresize_params *lp)
return 1;
}
static void _split_line(char *buf, int *argc, char **argv, int max_args, char sep)
{
char *p = buf;
int i;
argv[0] = p;
for (i = 1; i < max_args; i++) {
p = strchr(p, sep);
if (!p)
break;
*p++ = '\0';
argv[i] = p;
}
*argc = i;
}
#define MAX_LOCKOPT 16
void lockd_lockopt_get_flags(const char *str, uint32_t *flags)
{
char buf[PATH_MAX];
char *argv[MAX_LOCKOPT];
int argc;
int i;
if (!str)
return;
dm_strncpy(buf, str, sizeof(buf));
_split_line(buf, &argc, argv, MAX_LOCKOPT, ',');
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "force"))
*flags |= LOCKOPT_FORCE;
else if (!strcmp(argv[i], "shupdate"))
*flags |= LOCKOPT_SHUPDATE;
else if (!strcmp(argv[i], "norefresh"))
*flags |= LOCKOPT_NOREFRESH;
else if (!strcmp(argv[i], "skipgl"))
*flags |= LOCKOPT_SKIPGL;
else if (!strcmp(argv[i], "skipvg"))
*flags |= LOCKOPT_SKIPVG;
else if (!strcmp(argv[i], "skiplv"))
*flags |= LOCKOPT_SKIPLV;
else if (!strcmp(argv[i], "auto"))
*flags |= LOCKOPT_AUTO;
else if (!strcmp(argv[i], "nowait"))
*flags |= LOCKOPT_NOWAIT;
else if (!strcmp(argv[i], "autonowait"))
*flags |= LOCKOPT_AUTONOWAIT;
else
log_warn("Ignoring unknown lockopt value: %s", argv[i]);
}
}

View File

@ -39,6 +39,19 @@
#define LDST_FAIL_OTHER 0x00000020
#define LDST_FAIL (LDST_FAIL_REQUEST | LDST_FAIL_NOLS | LDST_FAIL_STARTING | LDST_FAIL_OTHER)
/* --lockopt flags */
#define LOCKOPT_FORCE 0x00000001
#define LOCKOPT_SHUPDATE 0x00000002
#define LOCKOPT_NOREFRESH 0x00000004
#define LOCKOPT_SKIPGL 0x00000008
#define LOCKOPT_SKIPVG 0x00000010
#define LOCKOPT_SKIPLV 0x00000020
#define LOCKOPT_AUTO 0x00000040
#define LOCKOPT_NOWAIT 0x00000080
#define LOCKOPT_AUTONOWAIT 0x00000100
void lockd_lockopt_get_flags(const char *str, uint32_t *flags);
#ifdef LVMLOCKD_SUPPORT
struct lvresize_params;
@ -53,10 +66,11 @@ void lvmlockd_init(struct cmd_context *cmd);
void lvmlockd_connect(void);
void lvmlockd_disconnect(void);
/* vgcreate/vgremove use init/free */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing, const char *lockopt, int yes);
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing, int yes);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
/* vgrename */

View File

@ -699,7 +699,6 @@ struct lvresize_params {
int extend_fs_error; /* FS extend error after LV extend success */
int vg_changed_error; /* VG metadata was modified during fs resize */
const char *lockopt;
char *lockd_lv_refresh_path; /* set during resize to use for refresh at the end */
char *lockd_lv_refresh_uuid; /* set during resize to use for refresh at the end */

View File

@ -2943,16 +2943,17 @@ static int _init_lvmlockd(struct cmd_context *cmd)
}
if (use_lvmlockd && arg_is_set(cmd, lockopt_ARG)) {
const char *opts = arg_str_value(cmd, lockopt_ARG, "");
if (strstr(opts, "skiplv")) {
lockd_lockopt_get_flags(arg_str_value(cmd, lockopt_ARG, ""), &cmd->lockopt);
if (cmd->lockopt & LOCKOPT_SKIPLV) {
log_warn("WARNING: skipping LV lock in lvmlockd.");
cmd->lockd_lv_disable = 1;
}
if (strstr(opts, "skipvg")) {
if (cmd->lockopt & LOCKOPT_SKIPVG) {
log_warn("WARNING: skipping VG lock in lvmlockd.");
cmd->lockd_vg_disable = 1;
}
if (strstr(opts, "skipgl")) {
if (cmd->lockopt & LOCKOPT_SKIPGL) {
log_warn("WARNING: skipping global lock in lvmlockd.");
cmd->lockd_gl_disable = 1;
}

View File

@ -195,7 +195,6 @@ static int _lvresize_params(struct cmd_context *cmd, struct lvresize_params *lp)
lp->yes = arg_is_set(cmd, yes_ARG);
lp->force = arg_is_set(cmd, force_ARG),
lp->nosync = arg_is_set(cmd, nosync_ARG);
lp->lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
if (type_str) {
if (!strcmp(type_str, "linear")) {

View File

@ -647,7 +647,6 @@ static int _passes_lock_start_filter(struct cmd_context *cmd,
static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg,
struct vgchange_params *vp)
{
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
int auto_opt = 0;
int exists = 0;
int r;
@ -659,10 +658,9 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
goto do_start;
/*
* Recognize both "auto" and "autonowait" options.
* Any waiting is done at the end of vgchange.
*/
if (start_opt && !strncmp(start_opt, "auto", 4))
if ((cmd->lockopt & LOCKOPT_AUTO) || (cmd->lockopt & LOCKOPT_AUTONOWAIT))
auto_opt = 1;
if (!_passes_lock_start_filter(cmd, vg, activation_lock_start_list_CFG)) {
@ -1144,13 +1142,12 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg, int *no_change)
{
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
struct lv_list *lvl;
struct logical_volume *lv;
int lv_lock_count = 0;
/* Special recovery case. */
if (lock_type && lockopt && !strcmp(lock_type, "none") && !strcmp(lockopt, "force")) {
if (lock_type && !strcmp(lock_type, "none") && (cmd->lockopt & LOCKOPT_FORCE)) {
vg->status &= ~CLUSTERED;
vg->lock_type = "none";
vg->lock_args = NULL;
@ -1215,7 +1212,7 @@ static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg,
* lockd type to ..., first undo lockd type
*/
if (is_lockd_type(vg->lock_type)) {
if (!lockd_free_vg_before(cmd, vg, 1, NULL, 0))
if (!lockd_free_vg_before(cmd, vg, 1, 0))
return 0;
lockd_free_vg_final(cmd, vg);
@ -1347,9 +1344,9 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv)
{
struct processing_handle *handle;
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
int ret;
/*
* vgchange --locktype none --lockopt force VG
*
@ -1372,7 +1369,7 @@ int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv)
* disable locking. lockd_gl(), lockd_vg() and lockd_lv() will
* just return success when they see the disable flag set.
*/
if (lockopt && !strcmp(lockopt, "force")) {
if (cmd->lockopt & LOCKOPT_FORCE) {
if (!arg_is_set(cmd, yes_ARG) &&
yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') {
log_error("VG lock type not changed.");
@ -1480,19 +1477,17 @@ int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv)
/* Wait for lock-start ops that were initiated in vgchange_lockstart. */
if (arg_is_set(cmd, lockstart_ARG) && vp.lock_start_count) {
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
if (!lockd_global(cmd, "un"))
stack;
if (!start_opt || !strcmp(start_opt, "auto")) {
if ((cmd->lockopt & LOCKOPT_NOWAIT) || (cmd->lockopt & LOCKOPT_AUTONOWAIT)) {
log_print_unless_silent("Starting locking. VG can only be read until locks are ready.");
} else {
if (vp.lock_start_sanlock)
log_print_unless_silent("Starting locking. Waiting for sanlock may take a few seconds to 3 min...");
else
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
lockd_start_wait(cmd);
} else if (!strcmp(start_opt, "nowait") || !strcmp(start_opt, "autonowait")) {
log_print_unless_silent("Starting locking. VG can only be read until locks are ready.");
}
}

View File

@ -181,8 +181,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* read without locks until the lockspace is done starting.)
*/
if (vg_is_shared(vg)) {
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
if (!lockd_start_vg(cmd, vg, NULL)) {
log_error("Failed to start locking");
goto out;
@ -190,15 +188,13 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
lock_global(cmd, "un");
if (!start_opt || !strcmp(start_opt, "wait")) {
if (cmd->lockopt & LOCKOPT_NOWAIT) {
log_print_unless_silent("Starting locking. VG is read-only until locks are ready.");
} else {
/* It is OK if the user does Ctrl-C to cancel the wait. */
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
lockd_start_wait(cmd);
} else if (!strcmp(start_opt, "nowait")) {
log_print_unless_silent("Starting locking. VG is read-only until locks are ready.");
}
}
out:
release_vg(vg);

View File

@ -70,7 +70,7 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
!lvremove_single(cmd, vg->pool_metadata_spare_lv, &void_handle))
return_ECMD_FAILED;
if (!lockd_free_vg_before(cmd, vg, 0, arg_str_value(cmd, lockopt_ARG, NULL), arg_is_set(cmd, yes_ARG)))
if (!lockd_free_vg_before(cmd, vg, 0, arg_is_set(cmd, yes_ARG)))
return_ECMD_FAILED;
if (!force && !vg_remove_check(vg))