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:
parent
9ea5ff3db5
commit
943e979079
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")) {
|
||||
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user