mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmlockd: replace lock adopt info source
The lock adopt feature was disabled since it had used lvmetad as a source of info. This replaces the lvmetad info with a local file and enables the adopt feature again (enabled with lvmlockd --adopt 1).
This commit is contained in:
parent
d945b53ff7
commit
5263551a2d
@ -14,6 +14,7 @@
|
|||||||
#include "libdaemon/client/daemon-client.h"
|
#include "libdaemon/client/daemon-client.h"
|
||||||
|
|
||||||
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
|
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
|
||||||
|
#define LVMLOCKD_ADOPT_FILE DEFAULT_RUN_DIR "/lvmlockd.adopt"
|
||||||
|
|
||||||
/* Wrappers to open/close connection */
|
/* Wrappers to open/close connection */
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#define EXTERN
|
#define EXTERN
|
||||||
#include "lvmlockd-internal.h"
|
#include "lvmlockd-internal.h"
|
||||||
|
|
||||||
|
static int str_to_mode(const char *str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic operation of lvmlockd
|
* Basic operation of lvmlockd
|
||||||
*
|
*
|
||||||
@ -142,6 +144,8 @@ static const char *lvmlockd_protocol = "lvmlockd";
|
|||||||
static const int lvmlockd_protocol_version = 1;
|
static const int lvmlockd_protocol_version = 1;
|
||||||
static int daemon_quit;
|
static int daemon_quit;
|
||||||
static int adopt_opt;
|
static int adopt_opt;
|
||||||
|
static uint32_t adopt_update_count;
|
||||||
|
static const char *adopt_file;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use a separate socket for dumping daemon info.
|
* We use a separate socket for dumping daemon info.
|
||||||
@ -811,6 +815,144 @@ int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsi
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write new info when a command exits if that command has acquired a new LV
|
||||||
|
* lock. If the command has released an LV lock we don't bother updating the
|
||||||
|
* info. When adopting, we eliminate any LV lock adoptions if there is no dm
|
||||||
|
* device for that LV. If lvmlockd is terminated after acquiring but before
|
||||||
|
* writing this file, those LV locks would not be adopted on restart.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ADOPT_VERSION_MAJOR 1
|
||||||
|
#define ADOPT_VERSION_MINOR 0
|
||||||
|
|
||||||
|
static void write_adopt_file(void)
|
||||||
|
{
|
||||||
|
struct lockspace *ls;
|
||||||
|
struct resource *r;
|
||||||
|
struct lock *lk;
|
||||||
|
time_t t;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (!(fp = fopen(adopt_file, "w")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
adopt_update_count++;
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
fprintf(fp, "lvmlockd adopt_version %u.%u pid %d updates %u %s",
|
||||||
|
ADOPT_VERSION_MAJOR, ADOPT_VERSION_MINOR, getpid(), adopt_update_count, ctime(&t));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lockspaces_mutex);
|
||||||
|
list_for_each_entry(ls, &lockspaces, list) {
|
||||||
|
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||||
|
continue;
|
||||||
|
fprintf(fp, "VG: %38s %s %s %s\n",
|
||||||
|
ls->vg_uuid, ls->vg_name, lm_str(ls->lm_type), ls->vg_args);
|
||||||
|
list_for_each_entry(r, &ls->resources, list) {
|
||||||
|
if (r->type != LD_RT_LV)
|
||||||
|
continue;
|
||||||
|
if ((r->mode != LD_LK_EX) && (r->mode != LD_LK_SH))
|
||||||
|
continue;
|
||||||
|
list_for_each_entry(lk, &r->locks, list) {
|
||||||
|
fprintf(fp, "LV: %38s %s %s %s %u\n",
|
||||||
|
ls->vg_uuid, r->name, r->lv_args, mode_str(r->mode), r->version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||||||
|
|
||||||
|
fflush(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_adopt_file(struct list_head *vg_lockd)
|
||||||
|
{
|
||||||
|
char adopt_line[512];
|
||||||
|
char vg_uuid[72];
|
||||||
|
char lm_type_str[16];
|
||||||
|
char mode[8];
|
||||||
|
struct lockspace *ls, *ls2;
|
||||||
|
struct resource *r;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (MAX_ARGS != 64 || MAX_NAME != 64)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(fp = fopen(adopt_file, "r")))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (fgets(adopt_line, sizeof(adopt_line), fp)) {
|
||||||
|
if (adopt_line[0] == '#')
|
||||||
|
continue;
|
||||||
|
else if (!strncmp(adopt_line, "lvmlockd", 8)) {
|
||||||
|
unsigned int v_major = 0, v_minor = 0;
|
||||||
|
sscanf(adopt_line, "lvmlockd adopt_version %u.%u", &v_major, &v_minor);
|
||||||
|
if (v_major != ADOPT_VERSION_MAJOR)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
} else if (!strncmp(adopt_line, "VG:", 3)) {
|
||||||
|
if (!(ls = alloc_lockspace()))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
memset(vg_uuid, 0, sizeof(vg_uuid));
|
||||||
|
|
||||||
|
if (sscanf(adopt_line, "VG: %63s %64s %16s %64s",
|
||||||
|
vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ls->vg_uuid, vg_uuid, 64);
|
||||||
|
|
||||||
|
if ((ls->lm_type = str_to_lm(lm_type_str)) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
list_add(&ls->list, vg_lockd);
|
||||||
|
|
||||||
|
} else if (!strncmp(adopt_line, "LV:", 3)) {
|
||||||
|
if (!(r = alloc_resource()))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
r->type = LD_RT_LV;
|
||||||
|
|
||||||
|
memset(vg_uuid, 0, sizeof(vg_uuid));
|
||||||
|
|
||||||
|
if (sscanf(adopt_line, "LV: %64s %64s %s %8s %u",
|
||||||
|
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((r->adopt_mode = str_to_mode(mode)) == LD_LK_IV)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (ls && !memcmp(ls->vg_uuid, vg_uuid, 64)) {
|
||||||
|
list_add(&r->list, &ls->resources);
|
||||||
|
r = NULL;
|
||||||
|
} else {
|
||||||
|
list_for_each_entry(ls2, vg_lockd, list) {
|
||||||
|
if (memcmp(ls2->vg_uuid, vg_uuid, 64))
|
||||||
|
continue;
|
||||||
|
list_add(&r->list, &ls2->resources);
|
||||||
|
r = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
log_error("No lockspace found for resource %s vg_uuid %s", r->name, vg_uuid);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are few enough that arrays of function pointers can
|
* These are few enough that arrays of function pointers can
|
||||||
* be avoided.
|
* be avoided.
|
||||||
@ -4689,6 +4831,7 @@ static void *client_thread_main(void *arg_in)
|
|||||||
struct client *cl;
|
struct client *cl;
|
||||||
struct action *act;
|
struct action *act;
|
||||||
struct action *act_un;
|
struct action *act_un;
|
||||||
|
uint32_t lock_acquire_count = 0, lock_acquire_written = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -4720,6 +4863,9 @@ static void *client_thread_main(void *arg_in)
|
|||||||
rv = -1;
|
rv = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (act->flags & LD_AF_LV_LOCK)
|
||||||
|
lock_acquire_count++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The client failed after we acquired an LV lock for
|
* The client failed after we acquired an LV lock for
|
||||||
* it, but before getting this reply saying it's done.
|
* it, but before getting this reply saying it's done.
|
||||||
@ -4741,6 +4887,11 @@ static void *client_thread_main(void *arg_in)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (adopt_opt && (lock_acquire_count > lock_acquire_written)) {
|
||||||
|
lock_acquire_written = lock_acquire_count;
|
||||||
|
write_adopt_file();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Queue incoming actions for lockspace threads
|
* Queue incoming actions for lockspace threads
|
||||||
*/
|
*/
|
||||||
@ -4814,6 +4965,8 @@ static void *client_thread_main(void *arg_in)
|
|||||||
pthread_mutex_unlock(&client_mutex);
|
pthread_mutex_unlock(&client_mutex);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
if (adopt_opt && lock_acquire_written)
|
||||||
|
unlink(adopt_file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4846,180 +4999,6 @@ static void close_client_thread(void)
|
|||||||
log_error("pthread_join client_thread error %d", perrno);
|
log_error("pthread_join client_thread error %d", perrno);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a list of all VGs with a lockd type (sanlock|dlm).
|
|
||||||
* We'll match this list against a list of existing lockspaces that are
|
|
||||||
* found in the lock manager.
|
|
||||||
*
|
|
||||||
* For each of these VGs, also create a struct resource on ls->resources to
|
|
||||||
* represent each LV in the VG that uses a lock. For each of these LVs
|
|
||||||
* that are active, we'll attempt to adopt a lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int get_lockd_vgs(struct list_head *vg_lockd)
|
|
||||||
{
|
|
||||||
/* FIXME: get VGs some other way */
|
|
||||||
return -1;
|
|
||||||
#if 0
|
|
||||||
struct list_head update_vgs;
|
|
||||||
daemon_reply reply;
|
|
||||||
struct dm_config_node *cn;
|
|
||||||
struct dm_config_node *metadata;
|
|
||||||
struct dm_config_node *md_cn;
|
|
||||||
struct dm_config_node *lv_cn;
|
|
||||||
struct lockspace *ls, *safe;
|
|
||||||
struct resource *r;
|
|
||||||
const char *vg_name;
|
|
||||||
const char *vg_uuid;
|
|
||||||
const char *lv_uuid;
|
|
||||||
const char *lock_type;
|
|
||||||
const char *lock_args;
|
|
||||||
char find_str_path[PATH_MAX];
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&update_vgs);
|
|
||||||
|
|
||||||
reply = send_lvmetad("vg_list", "token = %s", "skip", NULL);
|
|
||||||
|
|
||||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
|
||||||
log_error("vg_list from lvmetad failed %d", reply.error);
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(cn = dm_config_find_node(reply.cft->root, "volume_groups"))) {
|
|
||||||
log_error("get_lockd_vgs no vgs");
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create an update_vgs list of all vg uuids */
|
|
||||||
|
|
||||||
for (cn = cn->child; cn; cn = cn->sib) {
|
|
||||||
vg_uuid = cn->key;
|
|
||||||
|
|
||||||
if (!(ls = alloc_lockspace())) {
|
|
||||||
rv = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(ls->vg_uuid, vg_uuid, 64);
|
|
||||||
list_add_tail(&ls->list, &update_vgs);
|
|
||||||
log_debug("get_lockd_vgs %s", vg_uuid);
|
|
||||||
}
|
|
||||||
destroy:
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
|
|
||||||
if (rv < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* get vg_name and lock_type for each vg uuid entry in update_vgs */
|
|
||||||
|
|
||||||
list_for_each_entry(ls, &update_vgs, list) {
|
|
||||||
reply = send_lvmetad("vg_lookup",
|
|
||||||
"token = %s", "skip",
|
|
||||||
"uuid = %s", ls->vg_uuid,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
|
||||||
log_error("vg_lookup from lvmetad failed %d", reply.error);
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
vg_name = daemon_reply_str(reply, "name", NULL);
|
|
||||||
if (!vg_name) {
|
|
||||||
log_error("get_lockd_vgs %s no name", ls->vg_uuid);
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(ls->vg_name, vg_name, MAX_NAME);
|
|
||||||
|
|
||||||
metadata = dm_config_find_node(reply.cft->root, "metadata");
|
|
||||||
if (!metadata) {
|
|
||||||
log_error("get_lockd_vgs %s name %s no metadata",
|
|
||||||
ls->vg_uuid, ls->vg_name);
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL);
|
|
||||||
ls->lm_type = str_to_lm(lock_type);
|
|
||||||
|
|
||||||
if ((ls->lm_type != LD_LM_SANLOCK) && (ls->lm_type != LD_LM_DLM)) {
|
|
||||||
log_debug("get_lockd_vgs %s not lockd type", ls->vg_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_args = dm_config_find_str(metadata, "metadata/lock_args", NULL);
|
|
||||||
if (lock_args)
|
|
||||||
strncpy(ls->vg_args, lock_args, MAX_ARGS);
|
|
||||||
|
|
||||||
log_debug("get_lockd_vgs %s lock_type %s lock_args %s",
|
|
||||||
ls->vg_name, lock_type, lock_args ?: "none");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make a record (struct resource) of each lv that uses a lock.
|
|
||||||
* For any lv that uses a lock, we'll check if the lv is active
|
|
||||||
* and if so try to adopt a lock for it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (md_cn = metadata->child; md_cn; md_cn = md_cn->sib) {
|
|
||||||
if (strcmp(md_cn->key, "logical_volumes"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (lv_cn = md_cn->child; lv_cn; lv_cn = lv_cn->sib) {
|
|
||||||
snprintf(find_str_path, PATH_MAX, "%s/lock_args", lv_cn->key);
|
|
||||||
lock_args = dm_config_find_str(lv_cn, find_str_path, NULL);
|
|
||||||
if (!lock_args)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(find_str_path, PATH_MAX, "%s/id", lv_cn->key);
|
|
||||||
lv_uuid = dm_config_find_str(lv_cn, find_str_path, NULL);
|
|
||||||
|
|
||||||
if (!lv_uuid) {
|
|
||||||
log_error("get_lock_vgs no lv id for name %s", lv_cn->key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(r = alloc_resource())) {
|
|
||||||
rv = -ENOMEM;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->use_vb = 0;
|
|
||||||
r->type = LD_RT_LV;
|
|
||||||
strncpy(r->name, lv_uuid, MAX_NAME);
|
|
||||||
if (lock_args)
|
|
||||||
strncpy(r->lv_args, lock_args, MAX_ARGS);
|
|
||||||
list_add_tail(&r->list, &ls->resources);
|
|
||||||
log_debug("get_lockd_vgs %s lv %s %s (name %s)",
|
|
||||||
ls->vg_name, r->name, lock_args ? lock_args : "", lv_cn->key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
daemon_reply_destroy(reply);
|
|
||||||
|
|
||||||
if (rv < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
/* Return lockd VG's on the vg_lockd list. */
|
|
||||||
|
|
||||||
list_for_each_entry_safe(ls, safe, &update_vgs, list) {
|
|
||||||
list_del(&ls->list);
|
|
||||||
|
|
||||||
if ((ls->lm_type == LD_LM_SANLOCK) || (ls->lm_type == LD_LM_DLM))
|
|
||||||
list_add_tail(&ls->list, vg_lockd);
|
|
||||||
else
|
|
||||||
free(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static char _dm_uuid[DM_UUID_LEN];
|
static char _dm_uuid[DM_UUID_LEN];
|
||||||
|
|
||||||
static char *get_dm_uuid(char *dm_name)
|
static char *get_dm_uuid(char *dm_name)
|
||||||
@ -5236,9 +5215,9 @@ static void adopt_locks(void)
|
|||||||
INIT_LIST_HEAD(&to_unlock);
|
INIT_LIST_HEAD(&to_unlock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get list of lockspaces from lock managers.
|
* Get list of lockspaces from currently running lock managers.
|
||||||
* Get list of VGs from lvmetad with a lockd type.
|
* Get list of shared VGs from file written by prior lvmlockd.
|
||||||
* Get list of active lockd type LVs from /dev.
|
* Get list of active LVs (in the shared VGs) from the file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (lm_support_dlm() && lm_is_running_dlm()) {
|
if (lm_support_dlm() && lm_is_running_dlm()) {
|
||||||
@ -5262,12 +5241,17 @@ static void adopt_locks(void)
|
|||||||
* Adds a struct lockspace to vg_lockd for each lockd VG.
|
* Adds a struct lockspace to vg_lockd for each lockd VG.
|
||||||
* Adds a struct resource to ls->resources for each LV.
|
* Adds a struct resource to ls->resources for each LV.
|
||||||
*/
|
*/
|
||||||
rv = get_lockd_vgs(&vg_lockd);
|
rv = read_adopt_file(&vg_lockd);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("adopt_locks get_lockd_vgs failed");
|
log_error("adopt_locks read_adopt_file failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (list_empty(&vg_lockd)) {
|
||||||
|
log_debug("No lockspaces in adopt file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each resource on each lockspace, check if the
|
* For each resource on each lockspace, check if the
|
||||||
* corresponding LV is active. If so, leave the
|
* corresponding LV is active. If so, leave the
|
||||||
@ -5506,7 +5490,7 @@ static void adopt_locks(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
act->op = LD_OP_LOCK;
|
act->op = LD_OP_LOCK;
|
||||||
act->rt = LD_RT_LV;
|
act->rt = LD_RT_LV;
|
||||||
act->mode = LD_LK_EX;
|
act->mode = r->adopt_mode;
|
||||||
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
|
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
|
||||||
act->client_id = INTERNAL_CLIENT_ID;
|
act->client_id = INTERNAL_CLIENT_ID;
|
||||||
act->lm_type = ls->lm_type;
|
act->lm_type = ls->lm_type;
|
||||||
@ -5604,8 +5588,9 @@ static void adopt_locks(void)
|
|||||||
* Adopt failed because the orphan has a different mode
|
* Adopt failed because the orphan has a different mode
|
||||||
* than initially requested. Repeat the lock-adopt operation
|
* than initially requested. Repeat the lock-adopt operation
|
||||||
* with the other mode. N.B. this logic depends on first
|
* with the other mode. N.B. this logic depends on first
|
||||||
* trying sh then ex for GL/VG locks, and ex then sh for
|
* trying sh then ex for GL/VG locks; for LV locks the mode
|
||||||
* LV locks.
|
* from the adopt file is tried first, the alternate
|
||||||
|
* (if the mode in adopt file was wrong somehow.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((act->rt != LD_RT_LV) && (act->mode == LD_LK_SH)) {
|
if ((act->rt != LD_RT_LV) && (act->mode == LD_LK_SH)) {
|
||||||
@ -5613,9 +5598,12 @@ static void adopt_locks(void)
|
|||||||
act->mode = LD_LK_EX;
|
act->mode = LD_LK_EX;
|
||||||
rv = add_lock_action(act);
|
rv = add_lock_action(act);
|
||||||
|
|
||||||
} else if ((act->rt == LD_RT_LV) && (act->mode == LD_LK_EX)) {
|
} else if (act->rt == LD_RT_LV) {
|
||||||
/* LV locks: attempt to adopt sh after ex failed. */
|
/* LV locks: attempt to adopt the other mode. */
|
||||||
act->mode = LD_LK_SH;
|
if (act->mode == LD_LK_EX)
|
||||||
|
act->mode = LD_LK_SH;
|
||||||
|
else if (act->mode == LD_LK_SH)
|
||||||
|
act->mode = LD_LK_EX;
|
||||||
rv = add_lock_action(act);
|
rv = add_lock_action(act);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -5750,10 +5738,13 @@ static void adopt_locks(void)
|
|||||||
if (count_start_fail || count_adopt_fail)
|
if (count_start_fail || count_adopt_fail)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
unlink(adopt_file);
|
||||||
|
write_adopt_file();
|
||||||
log_debug("adopt_locks done");
|
log_debug("adopt_locks done");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
unlink(adopt_file);
|
||||||
log_error("adopt_locks failed, reset host");
|
log_error("adopt_locks failed, reset host");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6028,6 +6019,8 @@ static void usage(char *prog, FILE *file)
|
|||||||
fprintf(file, " Set path to the pid file. [%s]\n", LVMLOCKD_PIDFILE);
|
fprintf(file, " Set path to the pid file. [%s]\n", LVMLOCKD_PIDFILE);
|
||||||
fprintf(file, " --socket-path | -s <path>\n");
|
fprintf(file, " --socket-path | -s <path>\n");
|
||||||
fprintf(file, " Set path to the socket to listen on. [%s]\n", LVMLOCKD_SOCKET);
|
fprintf(file, " Set path to the socket to listen on. [%s]\n", LVMLOCKD_SOCKET);
|
||||||
|
fprintf(file, " --adopt-file <path>\n");
|
||||||
|
fprintf(file, " Set path to the adopt file. [%s]\n", LVMLOCKD_ADOPT_FILE);
|
||||||
fprintf(file, " --syslog-priority | -S err|warning|debug\n");
|
fprintf(file, " --syslog-priority | -S err|warning|debug\n");
|
||||||
fprintf(file, " Write log messages from this level up to syslog. [%s]\n", _syslog_num_to_name(LOG_SYSLOG_PRIO));
|
fprintf(file, " Write log messages from this level up to syslog. [%s]\n", _syslog_num_to_name(LOG_SYSLOG_PRIO));
|
||||||
fprintf(file, " --gl-type | -g <str>\n");
|
fprintf(file, " --gl-type | -g <str>\n");
|
||||||
@ -6063,6 +6056,7 @@ int main(int argc, char *argv[])
|
|||||||
{"daemon-debug", no_argument, 0, 'D' },
|
{"daemon-debug", no_argument, 0, 'D' },
|
||||||
{"pid-file", required_argument, 0, 'p' },
|
{"pid-file", required_argument, 0, 'p' },
|
||||||
{"socket-path", required_argument, 0, 's' },
|
{"socket-path", required_argument, 0, 's' },
|
||||||
|
{"adopt-file", required_argument, 0, 128 },
|
||||||
{"gl-type", required_argument, 0, 'g' },
|
{"gl-type", required_argument, 0, 'g' },
|
||||||
{"host-id", required_argument, 0, 'i' },
|
{"host-id", required_argument, 0, 'i' },
|
||||||
{"host-id-file", required_argument, 0, 'F' },
|
{"host-id-file", required_argument, 0, 'F' },
|
||||||
@ -6085,6 +6079,9 @@ int main(int argc, char *argv[])
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '0':
|
case '0':
|
||||||
break;
|
break;
|
||||||
|
case 128:
|
||||||
|
adopt_file = strdup(optarg);
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(argv[0], stdout);
|
usage(argv[0], stdout);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
@ -6146,6 +6143,9 @@ int main(int argc, char *argv[])
|
|||||||
if (!ds.socket_path)
|
if (!ds.socket_path)
|
||||||
ds.socket_path = LVMLOCKD_SOCKET;
|
ds.socket_path = LVMLOCKD_SOCKET;
|
||||||
|
|
||||||
|
if (!adopt_file)
|
||||||
|
adopt_file = LVMLOCKD_ADOPT_FILE;
|
||||||
|
|
||||||
/* runs daemon_main/main_loop */
|
/* runs daemon_main/main_loop */
|
||||||
daemon_start(ds);
|
daemon_start(ds);
|
||||||
|
|
||||||
|
@ -398,12 +398,18 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
|||||||
(void *)1, (void *)1, (void *)1,
|
(void *)1, (void *)1, (void *)1,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
if (rv == -1 && errno == -EAGAIN) {
|
if (rv == -1 && (errno == EAGAIN)) {
|
||||||
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
|
||||||
ls->name, r->name, ld_mode);
|
ls->name, r->name, ld_mode);
|
||||||
rv = -EUCLEAN;
|
rv = -EUCLEAN;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (rv == -1 && (errno == ENOENT)) {
|
||||||
|
log_debug("S %s R %s adopt_dlm adopt mode %d no lock",
|
||||||
|
ls->name, r->name, ld_mode);
|
||||||
|
rv = -ENOENT;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
|
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
|
||||||
ls->name, r->name, mode, flags, rv, errno);
|
ls->name, r->name, mode, flags, rv, errno);
|
||||||
|
@ -145,6 +145,7 @@ struct resource {
|
|||||||
char name[MAX_NAME+1]; /* vg name or lv name */
|
char name[MAX_NAME+1]; /* vg name or lv name */
|
||||||
int8_t type; /* resource type LD_RT_ */
|
int8_t type; /* resource type LD_RT_ */
|
||||||
int8_t mode;
|
int8_t mode;
|
||||||
|
int8_t adopt_mode;
|
||||||
unsigned int sh_count; /* number of sh locks on locks list */
|
unsigned int sh_count; /* number of sh locks on locks list */
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t last_client_id; /* last client_id to lock or unlock resource */
|
uint32_t last_client_id; /* last client_id to lock or unlock resource */
|
||||||
|
@ -58,6 +58,10 @@ For default settings, see lvmlockd -h.
|
|||||||
.I path
|
.I path
|
||||||
Set path to the socket to listen on.
|
Set path to the socket to listen on.
|
||||||
|
|
||||||
|
.B --adopt-file
|
||||||
|
.I path
|
||||||
|
Set path to the adopt file.
|
||||||
|
|
||||||
.B --syslog-priority | -S err|warning|debug
|
.B --syslog-priority | -S err|warning|debug
|
||||||
Write log messages from this level up to syslog.
|
Write log messages from this level up to syslog.
|
||||||
|
|
||||||
@ -76,6 +80,8 @@ For default settings, see lvmlockd -h.
|
|||||||
.I seconds
|
.I seconds
|
||||||
Override the default sanlock I/O timeout.
|
Override the default sanlock I/O timeout.
|
||||||
|
|
||||||
|
.B --adopt | -A 0|1
|
||||||
|
Enable (1) or disable (0) lock adoption.
|
||||||
|
|
||||||
.SH USAGE
|
.SH USAGE
|
||||||
|
|
||||||
@ -548,7 +554,13 @@ necessary locks.
|
|||||||
.B lvmlockd failure
|
.B lvmlockd failure
|
||||||
|
|
||||||
If lvmlockd fails or is killed while holding locks, the locks are orphaned
|
If lvmlockd fails or is killed while holding locks, the locks are orphaned
|
||||||
in the lock manager.
|
in the lock manager. Orphaned locks must be cleared or adopted before the
|
||||||
|
associated resources can be accessed normally. If lock adoption is
|
||||||
|
enabled, lvmlockd keeps a record of locks in the adopt-file. A subsequent
|
||||||
|
instance of lvmlockd will then adopt locks orphaned by the previous
|
||||||
|
instance. Adoption must be enabled in both instances (--adopt|-A 1).
|
||||||
|
Without adoption, the lock manager or host would require a reset to clear
|
||||||
|
orphaned lock state.
|
||||||
|
|
||||||
.B dlm/corosync failure
|
.B dlm/corosync failure
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user