mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-30 17:18:21 +03:00
lvmlockd: adopt options
Lock adoption is not part of standard command behavior, but can be used for manual recovery or cleanup from unexpected failure cases. Like other lockopt values, they are hidden options for --lockopt. Different lock managers will behave differently. Adopting locks with lvmlockd -A1 is more accurate and automatic. --lockopt adoptls . for vgchange --lockstart . adopt existing ls, or fail if no existing lockspace is found --lockopt adoptgl | adoptvg | adoptlv . for commands using lvmlockd locks . adopt orphan gl/vg/lv lock, or fail the lock request if no orphan lock is found . will fail if orphan lock exists with a different lock mode . command may still continue with a failed shared lock request --lockopt adopt . for lockstart or any command using lvmlockd locks . adopt existing lockspace, or start lockspace if none exists . adopt orphan gl/vg/lv lock, or acquire new lock if no orphan found . will fail if orphan lock exists with a different lock mode . command may still continue with a failed shared lock request . with dlm this option only works for ls
This commit is contained in:
parent
943e979079
commit
f32fd1fcb9
@ -54,5 +54,8 @@ static inline void lvmlockd_close(daemon_handle h)
|
||||
#define EREMOVED 219
|
||||
#define EDEVOPEN 220 /* sanlock failed to open lvmlock LV */
|
||||
#define ELMERR 221
|
||||
#define EORPHAN 222
|
||||
#define EADOPT_NONE 223
|
||||
#define EADOPT_RETRY 224
|
||||
|
||||
#endif /* _LVM_LVMLOCKD_CLIENT_H */
|
||||
|
@ -1062,16 +1062,16 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt)
|
||||
static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt_only, int adopt_ok)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (ls->lm_type == LD_LM_DLM)
|
||||
rv = lm_add_lockspace_dlm(ls, adopt);
|
||||
rv = lm_add_lockspace_dlm(ls, adopt_only, adopt_ok);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_add_lockspace_sanlock(ls, adopt);
|
||||
rv = lm_add_lockspace_sanlock(ls, adopt_only, adopt_ok);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_add_lockspace_idm(ls, adopt);
|
||||
rv = lm_add_lockspace_idm(ls, adopt_only, adopt_ok);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@ -1099,17 +1099,17 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
|
||||
}
|
||||
|
||||
static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct action *act,
|
||||
struct val_blk *vb_out, int *retry, int adopt)
|
||||
struct val_blk *vb_out, int *retry, int adopt_only, int adopt_ok)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (ls->lm_type == LD_LM_DLM)
|
||||
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
|
||||
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt_only, adopt_ok);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
|
||||
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt_only, adopt_ok);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
|
||||
&act->pvs, adopt);
|
||||
&act->pvs, adopt_only, adopt_ok);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@ -1190,10 +1190,13 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *s
|
||||
|
||||
/*
|
||||
* While adopting locks, actions originate from the adopt_locks()
|
||||
* function, not from a client. So, these actions (flagged ADOPT),
|
||||
* function, not from a client. So, these actions (flagged ADOPT_ONLY),
|
||||
* should be passed back to the adopt_locks() function through the
|
||||
* adopt_results list, and not be sent back to a client via the
|
||||
* client_list/client_thread.
|
||||
* client_list/client_thread. INTERNAL_CLIENT_ID indicates the
|
||||
* act was generated internally and not from a client, and
|
||||
* distinguishes internal adopt request from those received from
|
||||
* a client.
|
||||
*/
|
||||
|
||||
static void add_client_result(struct action *act)
|
||||
@ -1206,7 +1209,7 @@ static void add_client_result(struct action *act)
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&client_mutex);
|
||||
if (act->flags & LD_AF_ADOPT)
|
||||
if ((act->flags & LD_AF_ADOPT_ONLY) && (act->client_id == INTERNAL_CLIENT_ID))
|
||||
list_add_tail(&act->list, &adopt_results);
|
||||
else
|
||||
list_add_tail(&act->list, &client_results);
|
||||
@ -1283,7 +1286,9 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
|
||||
if (r->type == LD_RT_LV && act->lv_args[0])
|
||||
memcpy(r->lv_args, act->lv_args, MAX_ARGS);
|
||||
|
||||
rv = lm_lock(ls, r, act->mode, act, &vb, retry, act->flags & LD_AF_ADOPT);
|
||||
rv = lm_lock(ls, r, act->mode, act, &vb, retry,
|
||||
act->flags & LD_AF_ADOPT_ONLY ? 1 : 0,
|
||||
act->flags & LD_AF_ADOPT ? 1 : 0);
|
||||
|
||||
if (rv && r->use_vb)
|
||||
log_debug("%s:%s res_lock rv %d read vb %x %x %u",
|
||||
@ -2486,7 +2491,8 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
int free_vg = 0;
|
||||
int drop_vg = 0;
|
||||
int error = 0;
|
||||
int adopt_flag = 0;
|
||||
int adopt_only = 0;
|
||||
int adopt_ok = 0;
|
||||
int wait_flag = 0;
|
||||
int retry;
|
||||
int rv;
|
||||
@ -2505,14 +2511,16 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
|
||||
if (add_act->flags & LD_AF_WAIT)
|
||||
wait_flag = 1;
|
||||
if (add_act->flags & LD_AF_ADOPT_ONLY)
|
||||
adopt_only = 1;
|
||||
if (add_act->flags & LD_AF_ADOPT)
|
||||
adopt_flag = 1;
|
||||
adopt_ok = 1;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ls->mutex);
|
||||
|
||||
log_debug("S %s lm_add_lockspace %s wait %d adopt %d",
|
||||
ls->name, lm_str(ls->lm_type), wait_flag, adopt_flag);
|
||||
log_debug("S %s lm_add_lockspace %s wait %d adopt_only %d adopt_ok %d",
|
||||
ls->name, lm_str(ls->lm_type), wait_flag, adopt_only, adopt_ok);
|
||||
|
||||
/*
|
||||
* The prepare step does not wait for anything and is quick;
|
||||
@ -2531,7 +2539,7 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
* The actual lockspace join can take a while.
|
||||
*/
|
||||
if (!error) {
|
||||
error = lm_add_lockspace(ls, add_act, adopt_flag);
|
||||
error = lm_add_lockspace(ls, add_act, adopt_only, adopt_ok);
|
||||
|
||||
log_debug("S %s lm_add_lockspace done %d", ls->name, error);
|
||||
|
||||
@ -4505,6 +4513,12 @@ static uint32_t str_to_opts(const char *str)
|
||||
flags |= LD_AF_ENABLE;
|
||||
if (strstr(str, "disable"))
|
||||
flags |= LD_AF_DISABLE;
|
||||
|
||||
/* FIXME: parse the flag values properly */
|
||||
if (strstr(str, "adopt_only"))
|
||||
flags |= LD_AF_ADOPT_ONLY;
|
||||
else if (strstr(str, "adopt"))
|
||||
flags |= LD_AF_ADOPT;
|
||||
out:
|
||||
return flags;
|
||||
}
|
||||
@ -5755,7 +5769,7 @@ static void adopt_locks(void)
|
||||
act->op = LD_OP_LOCK;
|
||||
act->rt = LD_RT_LV;
|
||||
act->mode = r->adopt_mode;
|
||||
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
|
||||
act->flags = (LD_AF_ADOPT_ONLY | LD_AF_PERSISTENT);
|
||||
act->client_id = INTERNAL_CLIENT_ID;
|
||||
act->lm_type = ls->lm_type;
|
||||
dm_strncpy(act->vg_name, ls->vg_name, sizeof(act->vg_name));
|
||||
@ -5783,7 +5797,7 @@ static void adopt_locks(void)
|
||||
act->op = LD_OP_LOCK;
|
||||
act->rt = LD_RT_VG;
|
||||
act->mode = LD_LK_SH;
|
||||
act->flags = LD_AF_ADOPT;
|
||||
act->flags = LD_AF_ADOPT_ONLY;
|
||||
act->client_id = INTERNAL_CLIENT_ID;
|
||||
act->lm_type = ls->lm_type;
|
||||
dm_strncpy(act->vg_name, ls->vg_name, sizeof(act->vg_name));
|
||||
@ -5809,7 +5823,7 @@ static void adopt_locks(void)
|
||||
act->op = LD_OP_LOCK;
|
||||
act->rt = LD_RT_GL;
|
||||
act->mode = LD_LK_SH;
|
||||
act->flags = LD_AF_ADOPT;
|
||||
act->flags = LD_AF_ADOPT_ONLY;
|
||||
act->client_id = INTERNAL_CLIENT_ID;
|
||||
act->lm_type = (gl_use_sanlock ? LD_LM_SANLOCK : LD_LM_DLM);
|
||||
|
||||
@ -5848,7 +5862,7 @@ static void adopt_locks(void)
|
||||
* lock adopt results
|
||||
*/
|
||||
|
||||
if (act->result == -EUCLEAN) {
|
||||
if (act->result == -EADOPT_RETRY) {
|
||||
/*
|
||||
* Adopt failed because the orphan has a different mode
|
||||
* than initially requested. Repeat the lock-adopt operation
|
||||
@ -5887,7 +5901,7 @@ static void adopt_locks(void)
|
||||
free_action(act);
|
||||
}
|
||||
|
||||
} else if (act->result == -ENOENT) {
|
||||
} else if (act->result == -EADOPT_NONE) {
|
||||
/*
|
||||
* No orphan lock exists. This is common for GL/VG locks
|
||||
* because they may not have been held when lvmlockd exited.
|
||||
|
@ -305,20 +305,27 @@ fail:
|
||||
return rv;
|
||||
}
|
||||
|
||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
|
||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
if (adopt)
|
||||
if (adopt_only || adopt_ok) {
|
||||
lmd->dh = dlm_open_lockspace(ls->name);
|
||||
else
|
||||
if (!lmd->dh && adopt_ok)
|
||||
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
|
||||
if (!lmd->dh)
|
||||
log_error("add_lockspace_dlm adopt_only %d adopt_ok %d %s error",
|
||||
adopt_only, adopt_ok, ls->name);
|
||||
} else {
|
||||
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
|
||||
if (!lmd->dh)
|
||||
log_error("add_lockspace_dlm %s error", ls->name);
|
||||
}
|
||||
|
||||
if (!lmd->dh) {
|
||||
log_error("add_lockspace_dlm %s adopt %d error", ls->name, adopt);
|
||||
free(lmd);
|
||||
ls->lm_data = NULL;
|
||||
return -1;
|
||||
@ -486,13 +493,13 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
if (rv == -1 && (errno == EAGAIN)) {
|
||||
log_debug("%s:%s adopt_dlm adopt mode %d try other mode",
|
||||
ls->name, r->name, ld_mode);
|
||||
rv = -EUCLEAN;
|
||||
rv = -EADOPT_RETRY;
|
||||
goto fail;
|
||||
}
|
||||
if (rv == -1 && (errno == ENOENT)) {
|
||||
log_debug("%s:%s adopt_dlm adopt mode %d no lock",
|
||||
ls->name, r->name, ld_mode);
|
||||
rv = -ENOENT;
|
||||
rv = -EADOPT_NONE;
|
||||
goto fail;
|
||||
}
|
||||
if (rv < 0) {
|
||||
@ -526,7 +533,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
*/
|
||||
|
||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int adopt)
|
||||
struct val_blk *vb_out, int adopt_only, int adopt_ok)
|
||||
{
|
||||
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
|
||||
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
|
||||
@ -536,7 +543,13 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
int mode;
|
||||
int rv;
|
||||
|
||||
if (adopt) {
|
||||
if (adopt_ok) {
|
||||
log_debug("%s:%s lock_dlm adopt_ok not supported", ls->name, r->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adopt_only) {
|
||||
log_debug("%s:%s lock_dlm adopt_only", ls->name, r->name);
|
||||
/* When adopting, we don't follow the normal method
|
||||
of acquiring a NL lock then converting it to the
|
||||
desired mode. */
|
||||
|
@ -391,7 +391,7 @@ int lm_prepare_lockspace_idm(struct lockspace *ls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
char killpath[IDM_FAILURE_PATH_LEN];
|
||||
char killargs[IDM_FAILURE_ARGS_LEN];
|
||||
@ -530,7 +530,7 @@ static int to_idm_mode(int ld_mode)
|
||||
|
||||
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt)
|
||||
int adopt_only, int adopt_ok)
|
||||
{
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
|
@ -107,11 +107,12 @@ struct client {
|
||||
#define LD_AF_SEARCH_LS 0x00000200
|
||||
#define LD_AF_WAIT_STARTING 0x00001000
|
||||
#define LD_AF_DUP_GL_LS 0x00002000
|
||||
#define LD_AF_ADOPT 0x00010000
|
||||
#define LD_AF_ADOPT 0x00010000 /* adopt ok but not required */
|
||||
#define LD_AF_WARN_GL_REMOVED 0x00020000
|
||||
#define LD_AF_LV_LOCK 0x00040000
|
||||
#define LD_AF_LV_UNLOCK 0x00080000
|
||||
#define LD_AF_SH_EXISTS 0x00100000
|
||||
#define LD_AF_ADOPT_ONLY 0x00200000 /* adopt orphan or fail */
|
||||
|
||||
/*
|
||||
* Number of times to repeat a lock request after
|
||||
@ -393,11 +394,11 @@ static inline const char *mode_str(int x)
|
||||
|
||||
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
||||
int lm_prepare_lockspace_dlm(struct lockspace *ls);
|
||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
|
||||
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok);
|
||||
int lm_purge_locks_dlm(struct lockspace *ls);
|
||||
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
|
||||
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int adopt);
|
||||
struct val_blk *vb_out, int adopt_only, int adopt_ok);
|
||||
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version);
|
||||
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
||||
@ -427,7 +428,7 @@ static inline int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
|
||||
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -443,7 +444,7 @@ static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
|
||||
}
|
||||
|
||||
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int adopt)
|
||||
struct val_blk *vb_out, int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -509,10 +510,11 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_arg
|
||||
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
|
||||
int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
||||
int lm_prepare_lockspace_sanlock(struct lockspace *ls);
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok);
|
||||
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
|
||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, int adopt);
|
||||
struct val_blk *vb_out, int *retry,
|
||||
int adopt_only, int adopt_ok);
|
||||
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version);
|
||||
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||
@ -559,7 +561,7 @@ static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
||||
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -570,7 +572,8 @@ static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
||||
}
|
||||
|
||||
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, int adopt)
|
||||
struct val_blk *vb_out, int *retry,
|
||||
int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -644,11 +647,11 @@ static inline int lm_support_sanlock(void)
|
||||
int lm_data_size_idm(void);
|
||||
int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
||||
int lm_prepare_lockspace_idm(struct lockspace *ls);
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt);
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok);
|
||||
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg);
|
||||
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt);
|
||||
int adopt_only, int adopt_ok);
|
||||
int lm_convert_idm(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version);
|
||||
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
|
||||
@ -681,7 +684,7 @@ static inline int lm_prepare_lockspace_idm(struct lockspace *ls)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
|
||||
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -693,7 +696,7 @@ static inline int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
|
||||
|
||||
static inline int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt)
|
||||
int adopt_only, int adopt_ok)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -1501,7 +1501,7 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok)
|
||||
{
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
int rv;
|
||||
@ -1512,11 +1512,15 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
||||
}
|
||||
|
||||
rv = sanlock_add_lockspace_timeout(&lms->ss, 0, sanlock_io_timeout);
|
||||
if (rv == -EEXIST && adopt) {
|
||||
if (rv == -EEXIST && (adopt_ok || adopt_only)) {
|
||||
/* We could alternatively just skip the sanlock call for adopt. */
|
||||
log_debug("S %s add_lockspace_san adopt found ls", ls->name);
|
||||
goto out;
|
||||
}
|
||||
if ((rv != -EEXIST) && adopt_only) {
|
||||
log_error("S %s add_lockspace_san add_lockspace adopt_only not found", ls->name);
|
||||
goto fail;
|
||||
}
|
||||
if (rv < 0) {
|
||||
/* retry for some errors? */
|
||||
log_error("S %s add_lockspace_san add_lockspace error %d", ls->name, rv);
|
||||
@ -1638,7 +1642,7 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
|
||||
}
|
||||
|
||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, int adopt)
|
||||
struct val_blk *vb_out, int *retry, int adopt_only, int adopt_ok)
|
||||
{
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
||||
@ -1732,8 +1736,10 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
|
||||
if (rds->vb)
|
||||
flags |= SANLK_ACQUIRE_LVB;
|
||||
if (adopt)
|
||||
if (adopt_only)
|
||||
flags |= SANLK_ACQUIRE_ORPHAN_ONLY;
|
||||
if (adopt_ok)
|
||||
flags |= SANLK_ACQUIRE_ORPHAN;
|
||||
|
||||
/*
|
||||
* Don't block waiting for a failed lease to expire since it causes
|
||||
@ -1779,7 +1785,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
if (adopt && (rv == -EUCLEAN)) {
|
||||
if ((adopt_only || adopt_ok) && (rv == -EUCLEAN)) {
|
||||
/*
|
||||
* The orphan lock exists but in a different mode than we asked
|
||||
* for, so the caller should try again with the other mode.
|
||||
@ -1787,17 +1793,17 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
log_debug("%s:%s lock_san adopt mode %d try other mode",
|
||||
ls->name, r->name, ld_mode);
|
||||
*retry = 0;
|
||||
return -EUCLEAN;
|
||||
return -EADOPT_RETRY;
|
||||
}
|
||||
|
||||
if (adopt && (rv == -ENOENT)) {
|
||||
if (adopt_only && (rv == -ENOENT)) {
|
||||
/*
|
||||
* No orphan lock exists.
|
||||
*/
|
||||
log_debug("%s:%s lock_san adopt mode %d no orphan found",
|
||||
log_debug("%s:%s lock_san adopt_only mode %d no orphan found",
|
||||
ls->name, r->name, ld_mode);
|
||||
*retry = 0;
|
||||
return -ENOENT;
|
||||
return -EADOPT_NONE;
|
||||
}
|
||||
|
||||
if (rv == SANLK_ACQUIRE_IDLIVE || rv == SANLK_ACQUIRE_OWNED || rv == SANLK_ACQUIRE_OTHER) {
|
||||
@ -1880,7 +1886,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
|
||||
/* sanlock gets i/o errors trying to read/write the leases. */
|
||||
if (rv == -EIO)
|
||||
rv = -ELOCKIO;
|
||||
return -ELOCKIO;
|
||||
|
||||
/*
|
||||
* The sanlock lockspace can disappear if the lease storage fails,
|
||||
@ -1889,7 +1895,11 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
* stop and free the lockspace.
|
||||
*/
|
||||
if (rv == -ENOSPC)
|
||||
rv = -ELOCKIO;
|
||||
return -ELOCKIO;
|
||||
|
||||
/* The request conflicted with an orphan lock. */
|
||||
if (rv == -EUCLEAN)
|
||||
return -EORPHAN;
|
||||
|
||||
/*
|
||||
* generic error number for sanlock errors that we are not
|
||||
|
@ -1315,6 +1315,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 *exists)
|
||||
{
|
||||
char uuid[64] __attribute__((aligned(8)));
|
||||
const char *opts = NULL;
|
||||
daemon_reply reply;
|
||||
uint32_t lockd_flags = 0;
|
||||
int host_id = 0;
|
||||
@ -1336,6 +1337,11 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd->lockopt & LOCKOPT_ADOPTLS)
|
||||
opts = "adopt_only";
|
||||
else if (cmd->lockopt & LOCKOPT_ADOPT)
|
||||
opts = "adopt";
|
||||
|
||||
log_debug("lockd start VG %s lock_type %s",
|
||||
vg->name, vg->lock_type ? vg->lock_type : "empty");
|
||||
|
||||
@ -1372,7 +1378,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
|
||||
"vg_uuid = %s", uuid[0] ? uuid : "none",
|
||||
"version = " FMTd64, (int64_t) vg->seqno,
|
||||
"host_id = " FMTd64, (int64_t) host_id,
|
||||
"opts = %s", "none",
|
||||
"opts = %s", opts ?: "none",
|
||||
NULL);
|
||||
_lockd_free_pv_list(&lock_pvs);
|
||||
} else {
|
||||
@ -1385,7 +1391,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
|
||||
"vg_uuid = %s", uuid[0] ? uuid : "none",
|
||||
"version = " FMTd64, (int64_t) vg->seqno,
|
||||
"host_id = " FMTd64, (int64_t) host_id,
|
||||
"opts = %s", "none",
|
||||
"opts = %s", opts ?: "none",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -1840,6 +1846,11 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmd->lockopt & LOCKOPT_ADOPTGL)
|
||||
opts = "adopt_only";
|
||||
else if (cmd->lockopt & LOCKOPT_ADOPT)
|
||||
opts = "adopt";
|
||||
|
||||
if (!strcmp(mode, "sh") && cmd->lockd_global_ex)
|
||||
return 1;
|
||||
|
||||
@ -1912,7 +1923,10 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
if (result == -ENOLS ||
|
||||
result == -ESTARTING ||
|
||||
result == -EVGKILLED ||
|
||||
result == -ELOCKIO) {
|
||||
result == -ELOCKIO ||
|
||||
result == -EORPHAN ||
|
||||
result == -EADOPT_RETRY ||
|
||||
result == -EADOPT_NONE) {
|
||||
/*
|
||||
* If an ex global lock fails, then the command fails.
|
||||
*/
|
||||
@ -1925,6 +1939,12 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
log_error("Global lock failed: storage errors for sanlock leases");
|
||||
else if (result == -EVGKILLED)
|
||||
log_error("Global lock failed: storage failed for sanlock leases");
|
||||
else if (result == -EORPHAN)
|
||||
log_error("Global lock failed: orphan lock needs to be adopted");
|
||||
else if (result == -EADOPT_NONE)
|
||||
log_error("Global lock failed: adopt found no orphan");
|
||||
else if (result == -EADOPT_RETRY)
|
||||
log_error("Global lock failed: adopt found other mode");
|
||||
else
|
||||
log_error("Global lock failed: error %d", result);
|
||||
|
||||
@ -1953,6 +1973,21 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
goto allow;
|
||||
}
|
||||
|
||||
if (result == -EORPHAN) {
|
||||
log_warn("Skipping global lock: orphan lock needs to be adopted");
|
||||
goto allow;
|
||||
}
|
||||
|
||||
if (result == -EADOPT_NONE) {
|
||||
log_warn("Skipping global lock: adopt found no orphan");
|
||||
goto allow;
|
||||
}
|
||||
|
||||
if (result == -EADOPT_RETRY) {
|
||||
log_warn("Skipping global lock: adopt found other mode");
|
||||
goto allow;
|
||||
}
|
||||
|
||||
if ((lockd_flags & LD_RF_NO_GL_LS) || (lockd_flags & LD_RF_NO_LOCKSPACES)) {
|
||||
log_debug("Skipping global lock: lockspace not found or started");
|
||||
goto allow;
|
||||
@ -2037,6 +2072,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
uint32_t flags, uint32_t *lockd_state)
|
||||
{
|
||||
const char *mode = NULL;
|
||||
const char *opts = NULL;
|
||||
uint32_t lockd_flags;
|
||||
uint32_t prev_state = *lockd_state;
|
||||
int retries = 0;
|
||||
@ -2103,6 +2139,11 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
if (!mode)
|
||||
mode = cmd->lockd_vg_default_sh ? "sh" : "ex";
|
||||
|
||||
if (cmd->lockopt & LOCKOPT_ADOPTVG)
|
||||
opts = "adopt_only";
|
||||
else if (cmd->lockopt & LOCKOPT_ADOPT)
|
||||
opts = "adopt";
|
||||
|
||||
if (!strcmp(mode, "ex"))
|
||||
*lockd_state |= LDST_EX;
|
||||
|
||||
@ -2124,7 +2165,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
log_debug("lockd VG %s mode %s", vg_name, mode);
|
||||
|
||||
if (!_lockd_request(cmd, "lock_vg",
|
||||
vg_name, NULL, NULL, NULL, NULL, NULL, mode, NULL,
|
||||
vg_name, NULL, NULL, NULL, NULL, NULL, mode, opts,
|
||||
NULL, &result, &lockd_flags)) {
|
||||
/*
|
||||
* No result from lvmlockd, it is probably not running.
|
||||
@ -2237,6 +2278,43 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -EORPHAN) {
|
||||
if (!strcmp(mode, "sh")) {
|
||||
log_warn("VG %s lock skipped: orphan lock needs to be adopted.", vg_name);
|
||||
ret = 1;
|
||||
goto out;
|
||||
} else {
|
||||
log_error("VG %s lock failed: orphan lock needs to be adopted.", vg_name);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -EADOPT_NONE) {
|
||||
if (!strcmp(mode, "sh")) {
|
||||
log_warn("VG %s lock skipped: adopt found no orphan.", vg_name);
|
||||
ret = 1;
|
||||
goto out;
|
||||
} else {
|
||||
log_error("VG %s lock failed: adopt found no orphan.", vg_name);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == -EADOPT_RETRY) {
|
||||
if (!strcmp(mode, "sh")) {
|
||||
log_warn("VG %s lock skipped: adopt found other mode.", vg_name);
|
||||
ret = 1;
|
||||
goto out;
|
||||
} else {
|
||||
log_error("VG %s lock failed: adopt found other mode.", vg_name);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No lockspace for the VG was found. It may be a local
|
||||
* VG that lvmlockd doesn't keep track of, or it may be
|
||||
@ -2420,8 +2498,9 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
const char *lock_args, const char *def_mode, uint32_t flags)
|
||||
{
|
||||
char lv_uuid[64] __attribute__((aligned(8)));
|
||||
const char *mode = NULL;
|
||||
char opt_buf[64] = {};
|
||||
const char *opts = NULL;
|
||||
const char *mode = NULL;
|
||||
uint32_t lockd_flags;
|
||||
int refreshed = 0;
|
||||
int result;
|
||||
@ -2485,8 +2564,15 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
if (!mode)
|
||||
mode = "ex";
|
||||
|
||||
if (flags & LDLV_PERSISTENT)
|
||||
opts = "persistent";
|
||||
if ((flags & LDLV_PERSISTENT) ||
|
||||
(cmd->lockopt & LOCKOPT_ADOPTLV) ||
|
||||
(cmd->lockopt & LOCKOPT_ADOPT)) {
|
||||
dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s",
|
||||
(flags & LDLV_PERSISTENT) ? "persistent," : "",
|
||||
(cmd->lockopt & LOCKOPT_ADOPTLV) ? "adopt_only" : "",
|
||||
(cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "");
|
||||
opts = opt_buf;
|
||||
}
|
||||
|
||||
retry:
|
||||
log_debug("lockd LV %s/%s mode %s uuid %s", vg->name, lv_name, mode, lv_uuid);
|
||||
@ -2527,6 +2613,21 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result == -EORPHAN) {
|
||||
log_error("LV %s/%s lock failed: orphan lock needs to be adopted.", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result == -EADOPT_NONE) {
|
||||
log_error("LV %s/%s lock failed: adopt found no orphan.", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result == -EADOPT_RETRY) {
|
||||
log_error("LV %s/%s lock failed: adopt found other mode.", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result == -EEXIST) {
|
||||
/*
|
||||
* This happens if a command like lvchange tries to modify the
|
||||
@ -3506,6 +3607,16 @@ void lockd_lockopt_get_flags(const char *str, uint32_t *flags)
|
||||
*flags |= LOCKOPT_NOWAIT;
|
||||
else if (!strcmp(argv[i], "autonowait"))
|
||||
*flags |= LOCKOPT_AUTONOWAIT;
|
||||
else if (!strcmp(argv[i], "adoptls"))
|
||||
*flags |= LOCKOPT_ADOPTLS;
|
||||
else if (!strcmp(argv[i], "adoptgl"))
|
||||
*flags |= LOCKOPT_ADOPTGL;
|
||||
else if (!strcmp(argv[i], "adoptvg"))
|
||||
*flags |= LOCKOPT_ADOPTVG;
|
||||
else if (!strcmp(argv[i], "adoptlv"))
|
||||
*flags |= LOCKOPT_ADOPTLV;
|
||||
else if (!strcmp(argv[i], "adopt"))
|
||||
*flags |= LOCKOPT_ADOPT;
|
||||
else
|
||||
log_warn("Ignoring unknown lockopt value: %s", argv[i]);
|
||||
}
|
||||
|
@ -49,6 +49,11 @@
|
||||
#define LOCKOPT_AUTO 0x00000040
|
||||
#define LOCKOPT_NOWAIT 0x00000080
|
||||
#define LOCKOPT_AUTONOWAIT 0x00000100
|
||||
#define LOCKOPT_ADOPTLS 0x00000200
|
||||
#define LOCKOPT_ADOPTGL 0x00000400
|
||||
#define LOCKOPT_ADOPTVG 0x00000800
|
||||
#define LOCKOPT_ADOPTLV 0x00001000
|
||||
#define LOCKOPT_ADOPT 0x00002000
|
||||
|
||||
void lockd_lockopt_get_flags(const char *str, uint32_t *flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user