mirror of https://github.com/torvalds/linux.git
dlm: add new configfs entry release_recover for lockspace members
A new configfs entry is added for a lockspace member: /config/dlm/<cluster>/spaces/<space>/nodes/<node>/release_recover release_recover can be set to 1 by userspace (dlm_controld process) prior to removing the lockspace member (rmdir of the <node>). This tells the kernel to handle the removed member as if it had failed, i.e. recovery steps for a failed node should be perfomed, as opposed to the recovery steps for a node doing a controlled leave. Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
This commit is contained in:
parent
5665374c72
commit
de7b4869b4
|
|
@ -26,6 +26,7 @@
|
||||||
/*
|
/*
|
||||||
* /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid (refers to <node>)
|
* /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid (refers to <node>)
|
||||||
* /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
|
* /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
|
||||||
|
* /config/dlm/<cluster>/spaces/<space>/nodes/<node>/release_recover
|
||||||
* /config/dlm/<cluster>/comms/<comm>/nodeid (refers to <comm>)
|
* /config/dlm/<cluster>/comms/<comm>/nodeid (refers to <comm>)
|
||||||
* /config/dlm/<cluster>/comms/<comm>/local
|
* /config/dlm/<cluster>/comms/<comm>/local
|
||||||
* /config/dlm/<cluster>/comms/<comm>/addr (write only)
|
* /config/dlm/<cluster>/comms/<comm>/addr (write only)
|
||||||
|
|
@ -267,6 +268,7 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
NODE_ATTR_NODEID = 0,
|
NODE_ATTR_NODEID = 0,
|
||||||
NODE_ATTR_WEIGHT,
|
NODE_ATTR_WEIGHT,
|
||||||
|
NODE_ATTR_RELEASE_RECOVER,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dlm_clusters {
|
struct dlm_clusters {
|
||||||
|
|
@ -280,6 +282,8 @@ struct dlm_spaces {
|
||||||
struct dlm_space {
|
struct dlm_space {
|
||||||
struct config_group group;
|
struct config_group group;
|
||||||
struct list_head members;
|
struct list_head members;
|
||||||
|
struct list_head members_gone;
|
||||||
|
int members_gone_count;
|
||||||
struct mutex members_lock;
|
struct mutex members_lock;
|
||||||
int members_count;
|
int members_count;
|
||||||
struct dlm_nodes *nds;
|
struct dlm_nodes *nds;
|
||||||
|
|
@ -310,6 +314,14 @@ struct dlm_node {
|
||||||
int weight;
|
int weight;
|
||||||
int new;
|
int new;
|
||||||
int comm_seq; /* copy of cm->seq when nd->nodeid is set */
|
int comm_seq; /* copy of cm->seq when nd->nodeid is set */
|
||||||
|
unsigned int release_recover;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dlm_member_gone {
|
||||||
|
int nodeid;
|
||||||
|
unsigned int release_recover;
|
||||||
|
|
||||||
|
struct list_head list; /* space->members_gone */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct configfs_group_operations clusters_ops = {
|
static struct configfs_group_operations clusters_ops = {
|
||||||
|
|
@ -480,6 +492,7 @@ static struct config_group *make_space(struct config_group *g, const char *name)
|
||||||
configfs_add_default_group(&nds->ns_group, &sp->group);
|
configfs_add_default_group(&nds->ns_group, &sp->group);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sp->members);
|
INIT_LIST_HEAD(&sp->members);
|
||||||
|
INIT_LIST_HEAD(&sp->members_gone);
|
||||||
mutex_init(&sp->members_lock);
|
mutex_init(&sp->members_lock);
|
||||||
sp->members_count = 0;
|
sp->members_count = 0;
|
||||||
sp->nds = nds;
|
sp->nds = nds;
|
||||||
|
|
@ -587,10 +600,20 @@ static void drop_node(struct config_group *g, struct config_item *i)
|
||||||
{
|
{
|
||||||
struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
|
struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
|
||||||
struct dlm_node *nd = config_item_to_node(i);
|
struct dlm_node *nd = config_item_to_node(i);
|
||||||
|
struct dlm_member_gone *mb_gone;
|
||||||
|
|
||||||
|
mb_gone = kzalloc(sizeof(*mb_gone), GFP_KERNEL);
|
||||||
|
if (!mb_gone)
|
||||||
|
return;
|
||||||
|
|
||||||
mutex_lock(&sp->members_lock);
|
mutex_lock(&sp->members_lock);
|
||||||
list_del(&nd->list);
|
list_del(&nd->list);
|
||||||
sp->members_count--;
|
sp->members_count--;
|
||||||
|
|
||||||
|
mb_gone->nodeid = nd->nodeid;
|
||||||
|
mb_gone->release_recover = nd->release_recover;
|
||||||
|
list_add(&mb_gone->list, &sp->members_gone);
|
||||||
|
sp->members_gone_count++;
|
||||||
mutex_unlock(&sp->members_lock);
|
mutex_unlock(&sp->members_lock);
|
||||||
|
|
||||||
config_item_put(i);
|
config_item_put(i);
|
||||||
|
|
@ -815,12 +838,34 @@ static ssize_t node_weight_store(struct config_item *item, const char *buf,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t node_release_recover_show(struct config_item *item, char *buf)
|
||||||
|
{
|
||||||
|
struct dlm_node *n = config_item_to_node(item);
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", n->release_recover);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t node_release_recover_store(struct config_item *item,
|
||||||
|
const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct dlm_node *n = config_item_to_node(item);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = kstrtouint(buf, 0, &n->release_recover);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
CONFIGFS_ATTR(node_, nodeid);
|
CONFIGFS_ATTR(node_, nodeid);
|
||||||
CONFIGFS_ATTR(node_, weight);
|
CONFIGFS_ATTR(node_, weight);
|
||||||
|
CONFIGFS_ATTR(node_, release_recover);
|
||||||
|
|
||||||
static struct configfs_attribute *node_attrs[] = {
|
static struct configfs_attribute *node_attrs[] = {
|
||||||
[NODE_ATTR_NODEID] = &node_attr_nodeid,
|
[NODE_ATTR_NODEID] = &node_attr_nodeid,
|
||||||
[NODE_ATTR_WEIGHT] = &node_attr_weight,
|
[NODE_ATTR_WEIGHT] = &node_attr_weight,
|
||||||
|
[NODE_ATTR_RELEASE_RECOVER] = &node_attr_release_recover,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -882,9 +927,10 @@ static void put_comm(struct dlm_comm *cm)
|
||||||
int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
|
int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
|
||||||
int *count_out)
|
int *count_out)
|
||||||
{
|
{
|
||||||
|
struct dlm_member_gone *mb_gone, *mb_safe;
|
||||||
|
struct dlm_config_node *nodes, *node;
|
||||||
struct dlm_space *sp;
|
struct dlm_space *sp;
|
||||||
struct dlm_node *nd;
|
struct dlm_node *nd;
|
||||||
struct dlm_config_node *nodes, *node;
|
|
||||||
int rv, count;
|
int rv, count;
|
||||||
|
|
||||||
sp = get_space(lsname);
|
sp = get_space(lsname);
|
||||||
|
|
@ -898,7 +944,7 @@ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = sp->members_count;
|
count = sp->members_count + sp->members_gone_count;
|
||||||
|
|
||||||
nodes = kcalloc(count, sizeof(struct dlm_config_node), GFP_NOFS);
|
nodes = kcalloc(count, sizeof(struct dlm_config_node), GFP_NOFS);
|
||||||
if (!nodes) {
|
if (!nodes) {
|
||||||
|
|
@ -917,6 +963,20 @@ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
|
||||||
nd->new = 0;
|
nd->new = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we delay the remove on nodes until here as configfs does
|
||||||
|
* not support addtional attributes for rmdir().
|
||||||
|
*/
|
||||||
|
list_for_each_entry_safe(mb_gone, mb_safe, &sp->members_gone, list) {
|
||||||
|
node->nodeid = mb_gone->nodeid;
|
||||||
|
node->release_recover = mb_gone->release_recover;
|
||||||
|
node->gone = true;
|
||||||
|
node++;
|
||||||
|
|
||||||
|
list_del(&mb_gone->list);
|
||||||
|
sp->members_gone_count--;
|
||||||
|
kfree(mb_gone);
|
||||||
|
}
|
||||||
|
|
||||||
*count_out = count;
|
*count_out = count;
|
||||||
*nodes_out = nodes;
|
*nodes_out = nodes;
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@
|
||||||
struct dlm_config_node {
|
struct dlm_config_node {
|
||||||
int nodeid;
|
int nodeid;
|
||||||
int weight;
|
int weight;
|
||||||
|
bool gone;
|
||||||
int new;
|
int new;
|
||||||
uint32_t comm_seq;
|
uint32_t comm_seq;
|
||||||
|
unsigned int release_recover;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct rhashtable_params dlm_rhash_rsb_params;
|
extern const struct rhashtable_params dlm_rhash_rsb_params;
|
||||||
|
|
|
||||||
|
|
@ -569,10 +569,10 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
|
||||||
|
|
||||||
list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) {
|
list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) {
|
||||||
node = find_config_node(rv, memb->nodeid);
|
node = find_config_node(rv, memb->nodeid);
|
||||||
if (node && !node->new)
|
if (node && !node->new && !node->gone)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!node) {
|
if (node->gone) {
|
||||||
log_rinfo(ls, "remove member %d", memb->nodeid);
|
log_rinfo(ls, "remove member %d", memb->nodeid);
|
||||||
} else {
|
} else {
|
||||||
/* removed and re-added */
|
/* removed and re-added */
|
||||||
|
|
@ -591,6 +591,9 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
|
||||||
|
|
||||||
for (i = 0; i < rv->nodes_count; i++) {
|
for (i = 0; i < rv->nodes_count; i++) {
|
||||||
node = &rv->nodes[i];
|
node = &rv->nodes[i];
|
||||||
|
if (node->gone)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (dlm_is_member(ls, node->nodeid))
|
if (dlm_is_member(ls, node->nodeid))
|
||||||
continue;
|
continue;
|
||||||
error = dlm_add_member(ls, node);
|
error = dlm_add_member(ls, node);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue