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_list pending_delete; /* list of LVs for removal */
|
||||||
struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */
|
struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */
|
||||||
struct vdo_convert_params *lvcreate_vcp;/* params for LV to VDO conversion */
|
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 */
|
/* vgremove before the vg is removed */
|
||||||
|
|
||||||
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
|
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);
|
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') {
|
if (!yes && yes_no_prompt("Force unprotected removal of shared VG? [y/n]: ") == 'n') {
|
||||||
log_error("VG not removed.");
|
log_error("VG not removed.");
|
||||||
return 0;
|
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 lv_uuid[64] __attribute__((aligned(8)));
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
int shupdate = (lp->lockopt && strstr(lp->lockopt, "shupdate"));
|
int shupdate = cmd->lockopt & LOCKOPT_SHUPDATE;
|
||||||
int norefresh = (lp->lockopt && strstr(lp->lockopt, "norefresh"));
|
int norefresh = cmd->lockopt & LOCKOPT_NOREFRESH;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (!vg_is_shared(lv->vg))
|
if (!vg_is_shared(lv->vg))
|
||||||
@ -3453,3 +3453,60 @@ int lockd_lv_refresh(struct cmd_context *cmd, struct lvresize_params *lp)
|
|||||||
return 1;
|
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_OTHER 0x00000020
|
||||||
#define LDST_FAIL (LDST_FAIL_REQUEST | LDST_FAIL_NOLS | LDST_FAIL_STARTING | LDST_FAIL_OTHER)
|
#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
|
#ifdef LVMLOCKD_SUPPORT
|
||||||
|
|
||||||
struct lvresize_params;
|
struct lvresize_params;
|
||||||
@ -53,10 +66,11 @@ void lvmlockd_init(struct cmd_context *cmd);
|
|||||||
void lvmlockd_connect(void);
|
void lvmlockd_connect(void);
|
||||||
void lvmlockd_disconnect(void);
|
void lvmlockd_disconnect(void);
|
||||||
|
|
||||||
|
|
||||||
/* vgcreate/vgremove use init/free */
|
/* 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_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);
|
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
|
||||||
|
|
||||||
/* vgrename */
|
/* vgrename */
|
||||||
|
@ -699,7 +699,6 @@ struct lvresize_params {
|
|||||||
int extend_fs_error; /* FS extend error after LV extend success */
|
int extend_fs_error; /* FS extend error after LV extend success */
|
||||||
int vg_changed_error; /* VG metadata was modified during fs resize */
|
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_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 */
|
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)) {
|
if (use_lvmlockd && arg_is_set(cmd, lockopt_ARG)) {
|
||||||
const char *opts = arg_str_value(cmd, lockopt_ARG, "");
|
lockd_lockopt_get_flags(arg_str_value(cmd, lockopt_ARG, ""), &cmd->lockopt);
|
||||||
if (strstr(opts, "skiplv")) {
|
|
||||||
|
if (cmd->lockopt & LOCKOPT_SKIPLV) {
|
||||||
log_warn("WARNING: skipping LV lock in lvmlockd.");
|
log_warn("WARNING: skipping LV lock in lvmlockd.");
|
||||||
cmd->lockd_lv_disable = 1;
|
cmd->lockd_lv_disable = 1;
|
||||||
}
|
}
|
||||||
if (strstr(opts, "skipvg")) {
|
if (cmd->lockopt & LOCKOPT_SKIPVG) {
|
||||||
log_warn("WARNING: skipping VG lock in lvmlockd.");
|
log_warn("WARNING: skipping VG lock in lvmlockd.");
|
||||||
cmd->lockd_vg_disable = 1;
|
cmd->lockd_vg_disable = 1;
|
||||||
}
|
}
|
||||||
if (strstr(opts, "skipgl")) {
|
if (cmd->lockopt & LOCKOPT_SKIPGL) {
|
||||||
log_warn("WARNING: skipping global lock in lvmlockd.");
|
log_warn("WARNING: skipping global lock in lvmlockd.");
|
||||||
cmd->lockd_gl_disable = 1;
|
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->yes = arg_is_set(cmd, yes_ARG);
|
||||||
lp->force = arg_is_set(cmd, force_ARG),
|
lp->force = arg_is_set(cmd, force_ARG),
|
||||||
lp->nosync = arg_is_set(cmd, nosync_ARG);
|
lp->nosync = arg_is_set(cmd, nosync_ARG);
|
||||||
lp->lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
|
|
||||||
if (type_str) {
|
if (type_str) {
|
||||||
if (!strcmp(type_str, "linear")) {
|
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,
|
static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
struct vgchange_params *vp)
|
struct vgchange_params *vp)
|
||||||
{
|
{
|
||||||
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
int auto_opt = 0;
|
int auto_opt = 0;
|
||||||
int exists = 0;
|
int exists = 0;
|
||||||
int r;
|
int r;
|
||||||
@ -659,10 +658,9 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
|
|||||||
goto do_start;
|
goto do_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recognize both "auto" and "autonowait" options.
|
|
||||||
* Any waiting is done at the end of vgchange.
|
* 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;
|
auto_opt = 1;
|
||||||
|
|
||||||
if (!_passes_lock_start_filter(cmd, vg, activation_lock_start_list_CFG)) {
|
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)
|
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 *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
|
||||||
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
struct lv_list *lvl;
|
struct lv_list *lvl;
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int lv_lock_count = 0;
|
int lv_lock_count = 0;
|
||||||
|
|
||||||
/* Special recovery case. */
|
/* 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->status &= ~CLUSTERED;
|
||||||
vg->lock_type = "none";
|
vg->lock_type = "none";
|
||||||
vg->lock_args = NULL;
|
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
|
* lockd type to ..., first undo lockd type
|
||||||
*/
|
*/
|
||||||
if (is_lockd_type(vg->lock_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;
|
return 0;
|
||||||
|
|
||||||
lockd_free_vg_final(cmd, vg);
|
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;
|
struct processing_handle *handle;
|
||||||
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
|
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
|
||||||
const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vgchange --locktype none --lockopt force VG
|
* 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
|
* disable locking. lockd_gl(), lockd_vg() and lockd_lv() will
|
||||||
* just return success when they see the disable flag set.
|
* 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) &&
|
if (!arg_is_set(cmd, yes_ARG) &&
|
||||||
yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') {
|
yes_no_prompt("Forcibly change VG lock type to %s? [y/n]: ", lock_type) == 'n') {
|
||||||
log_error("VG lock type not changed.");
|
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. */
|
/* Wait for lock-start ops that were initiated in vgchange_lockstart. */
|
||||||
|
|
||||||
if (arg_is_set(cmd, lockstart_ARG) && vp.lock_start_count) {
|
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"))
|
if (!lockd_global(cmd, "un"))
|
||||||
stack;
|
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)
|
if (vp.lock_start_sanlock)
|
||||||
log_print_unless_silent("Starting locking. Waiting for sanlock may take a few seconds to 3 min...");
|
log_print_unless_silent("Starting locking. Waiting for sanlock may take a few seconds to 3 min...");
|
||||||
else
|
else
|
||||||
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
|
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
|
||||||
lockd_start_wait(cmd);
|
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.)
|
* read without locks until the lockspace is done starting.)
|
||||||
*/
|
*/
|
||||||
if (vg_is_shared(vg)) {
|
if (vg_is_shared(vg)) {
|
||||||
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
|
|
||||||
|
|
||||||
if (!lockd_start_vg(cmd, vg, NULL)) {
|
if (!lockd_start_vg(cmd, vg, NULL)) {
|
||||||
log_error("Failed to start locking");
|
log_error("Failed to start locking");
|
||||||
goto out;
|
goto out;
|
||||||
@ -190,15 +188,13 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
|
|
||||||
lock_global(cmd, "un");
|
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. */
|
/* It is OK if the user does Ctrl-C to cancel the wait. */
|
||||||
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
|
log_print_unless_silent("Starting locking. Waiting until locks are ready...");
|
||||||
lockd_start_wait(cmd);
|
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:
|
out:
|
||||||
release_vg(vg);
|
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))
|
!lvremove_single(cmd, vg->pool_metadata_spare_lv, &void_handle))
|
||||||
return_ECMD_FAILED;
|
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;
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
if (!force && !vg_remove_check(vg))
|
if (!force && !vg_remove_check(vg))
|
||||||
|
Loading…
Reference in New Issue
Block a user