mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmlockd: optimize new lv lease search
When converting a VG to locktype sanlock, a new lease is allocated for each existing lv. Finding a new lease location involved searching the lvmlock LV from the start for an unused location, which would be very slow with many LVs. Improve this by starting each search from the last used location.
This commit is contained in:
parent
4eb66fd20c
commit
88a085c485
@ -3649,7 +3649,7 @@ static int work_init_lv(struct action *act)
|
||||
if (lm_type == LD_LM_SANLOCK) {
|
||||
/* ls is NULL if the lockspace is not started, which happens
|
||||
for vgchange --locktype sanlock. */
|
||||
rv = lm_init_lv_sanlock(ls, ls_name, act->vg_name, act->lv_uuid, vg_args, lv_args);
|
||||
rv = lm_init_lv_sanlock(ls, ls_name, act->vg_name, act->lv_uuid, vg_args, lv_args, act->prev_lv_args);
|
||||
memcpy(act->lv_args, lv_args, MAX_ARGS);
|
||||
return rv;
|
||||
|
||||
@ -5019,6 +5019,10 @@ static void client_recv_action(struct client *cl)
|
||||
if (str && strcmp(str, "none"))
|
||||
strncpy(act->lv_args, str, MAX_ARGS);
|
||||
|
||||
str = daemon_request_str(req, "prev_lv_args", NULL);
|
||||
if (str && strcmp(str, "none"))
|
||||
strncpy(act->prev_lv_args, str, MAX_ARGS);
|
||||
|
||||
/* start_vg will include lvmlocal.conf local/host_id here */
|
||||
val = daemon_request_int(req, "host_id", 0);
|
||||
if (val)
|
||||
|
@ -150,6 +150,7 @@ struct action {
|
||||
char lv_uuid[MAX_NAME+1];
|
||||
char vg_args[MAX_ARGS+1];
|
||||
char lv_args[MAX_ARGS+1];
|
||||
char prev_lv_args[MAX_ARGS+1];
|
||||
char vg_sysid[MAX_NAME+1];
|
||||
struct pvs pvs; /* PV list for idm */
|
||||
};
|
||||
@ -507,7 +508,7 @@ static inline int lm_refresh_lv_check_dlm(struct action *act)
|
||||
#ifdef LOCKDSANLOCK_SUPPORT
|
||||
|
||||
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args, int opt_align_mb);
|
||||
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args);
|
||||
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args);
|
||||
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);
|
||||
@ -542,7 +543,7 @@ static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flag
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args)
|
||||
static inline int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -773,7 +773,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
* can be saved in the lv's lock_args in the vg metadata.
|
||||
*/
|
||||
|
||||
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args)
|
||||
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args)
|
||||
{
|
||||
char disk_path[SANLK_PATH_LEN];
|
||||
struct lm_sanlock *lms;
|
||||
@ -781,11 +781,13 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
|
||||
char lock_lv_name[MAX_ARGS+1];
|
||||
char lock_args_version[MAX_VERSION+1];
|
||||
uint64_t offset;
|
||||
uint64_t prev_offset = 0;
|
||||
int sector_size;
|
||||
int align_size;
|
||||
int align_mb;
|
||||
uint32_t ss_flags;
|
||||
uint32_t rs_flags;
|
||||
uint32_t tries = 1;
|
||||
int rv;
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
@ -825,10 +827,7 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
|
||||
offset = ls->free_lock_offset;
|
||||
} else {
|
||||
/* FIXME: optimize repeated init_lv for vgchange --locktype sanlock,
|
||||
to avoid finding align_size/rs_flags/free_lock_offset each time.
|
||||
Since the lockspace is not started, there's no ls struct to save
|
||||
all these in between calls. We could have the command send back
|
||||
the last offset it used, what about the other two? */
|
||||
to avoid finding align_size/rs_flags each time. */
|
||||
|
||||
rv = get_sizes_lockspace(disk_path, §or_size, &align_size, &align_mb, &ss_flags, &rs_flags);
|
||||
if (rv < 0) {
|
||||
@ -837,8 +836,14 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Starts searching from the start for every init_lv. */
|
||||
offset = align_size * LV_LOCK_BEGIN;
|
||||
/*
|
||||
* With a prev offset, start search after that.
|
||||
* Without a prev offset, start search from the beginning.
|
||||
*/
|
||||
if (prev_args && !lock_lv_offset_from_args(prev_args, &prev_offset))
|
||||
offset = prev_offset + align_size;
|
||||
else
|
||||
offset = align_size * LV_LOCK_BEGIN;
|
||||
}
|
||||
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
@ -878,8 +883,8 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
|
||||
* indicating an uninitialized paxos structure on disk.
|
||||
*/
|
||||
if ((rv == SANLK_LEADER_MAGIC) || !strcmp(rd.rs.name, "#unused")) {
|
||||
log_debug("S %s init_lv_san %s found unused area at %llu",
|
||||
ls_name, lv_name, (unsigned long long)offset);
|
||||
log_debug("S %s init_lv_san %s found unused area at %llu try %u",
|
||||
ls_name, lv_name, (unsigned long long)offset, tries);
|
||||
|
||||
strcpy_name_len(rd.rs.name, lv_name, SANLK_NAME_LEN);
|
||||
rd.rs.flags = rs_flags;
|
||||
@ -896,6 +901,7 @@ int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char
|
||||
}
|
||||
|
||||
offset += align_size;
|
||||
tries++;
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -1293,6 +1299,7 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
|
||||
struct sanlk_resourced rd;
|
||||
uint64_t offset;
|
||||
uint64_t start_offset;
|
||||
uint32_t tries = 0;
|
||||
int rv;
|
||||
int round = 0;
|
||||
|
||||
@ -1371,8 +1378,8 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
|
||||
* an invalid paxos structure on disk.
|
||||
*/
|
||||
if (rv == SANLK_LEADER_MAGIC) {
|
||||
log_debug("S %s find_free_lock_san found empty area at %llu",
|
||||
ls->name, (unsigned long long)offset);
|
||||
log_debug("S %s find_free_lock_san found empty area at %llu try %u",
|
||||
ls->name, (unsigned long long)offset, tries);
|
||||
ls->free_lock_offset = offset;
|
||||
return 0;
|
||||
}
|
||||
@ -1384,12 +1391,13 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
|
||||
}
|
||||
|
||||
if (!strcmp(rd.rs.name, "#unused")) {
|
||||
log_debug("S %s find_free_lock_san found unused area at %llu",
|
||||
ls->name, (unsigned long long)offset);
|
||||
log_debug("S %s find_free_lock_san found unused area at %llu try %u",
|
||||
ls->name, (unsigned long long)offset, tries);
|
||||
ls->free_lock_offset = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tries++;
|
||||
offset += lms->align_size;
|
||||
}
|
||||
|
||||
|
@ -3073,6 +3073,7 @@ int lockd_lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
|
||||
static int _init_lv_sanlock(struct cmd_context *cmd, struct volume_group *vg,
|
||||
const char *lv_name, struct id *lv_id,
|
||||
const char *last_args,
|
||||
const char **lock_args_ret)
|
||||
{
|
||||
char lv_uuid[64] __attribute__((aligned(8)));
|
||||
@ -3095,6 +3096,7 @@ static int _init_lv_sanlock(struct cmd_context *cmd, struct volume_group *vg,
|
||||
"vg_name = %s", vg->name,
|
||||
"lv_name = %s", lv_name,
|
||||
"lv_uuid = %s", lv_uuid,
|
||||
"prev_lv_args = %s", last_args ? last_args : "none",
|
||||
"vg_lock_type = %s", "sanlock",
|
||||
"vg_lock_args = %s", vg->lock_args,
|
||||
NULL);
|
||||
@ -3181,7 +3183,9 @@ static int _free_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct logical_volume *lv,
|
||||
const char *lock_type, const char **lock_args)
|
||||
const char *lock_type,
|
||||
const char *last_args,
|
||||
const char **lock_args)
|
||||
{
|
||||
if (!lock_type)
|
||||
return 1;
|
||||
@ -3190,7 +3194,7 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg,
|
||||
else if (!strcmp(lock_type, "idm"))
|
||||
*lock_args = "idm";
|
||||
else if (!strcmp(lock_type, "sanlock"))
|
||||
return _init_lv_sanlock(cmd, vg, lv->name, &lv->lvid.id[1], lock_args);
|
||||
return _init_lv_sanlock(cmd, vg, lv->name, &lv->lvid.id[1], last_args, lock_args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ int lockd_lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logical_volume *lv,
|
||||
struct lvcreate_params *lp);
|
||||
int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct logical_volume *lv, const char *lock_type, const char **lock_args);
|
||||
struct logical_volume *lv, const char *lock_type, const char *last_args, const char **lock_args);
|
||||
int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
const char *lv_name, struct id *lv_id, const char *lock_args);
|
||||
int lockd_free_lv_after_update(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
@ -2944,12 +2944,14 @@ int vg_write(struct volume_group *vg)
|
||||
log_debug("Writing metadata for VG %s.", vg->name);
|
||||
|
||||
if (vg_is_shared(vg)) {
|
||||
const char *last_args = NULL;
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->lock_args && !strcmp(lvl->lv->lock_args, "pending")) {
|
||||
if (!lockd_init_lv_args(vg->cmd, vg, lvl->lv, vg->lock_type, &lvl->lv->lock_args)) {
|
||||
if (!lockd_init_lv_args(vg->cmd, vg, lvl->lv, vg->lock_type, last_args, &lvl->lv->lock_args)) {
|
||||
log_error("Cannot allocate lock for new LV.");
|
||||
return 0;
|
||||
}
|
||||
last_args = lvl->lv->lock_args;
|
||||
lvl->lv->new_lock_args = 1;
|
||||
}
|
||||
}
|
||||
|
@ -3512,7 +3512,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
|
||||
metadata_lv->lock_args = NULL;
|
||||
|
||||
if (to_thin) {
|
||||
if (!lockd_init_lv_args(cmd, vg, pool_lv, vg->lock_type, &pool_lv->lock_args)) {
|
||||
if (!lockd_init_lv_args(cmd, vg, pool_lv, vg->lock_type, NULL, &pool_lv->lock_args)) {
|
||||
log_error("Cannot allocate lock for new pool LV.");
|
||||
goto bad;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user