aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/config.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2011-11-02 15:30:58 -0400
committerDavid Teigland <teigland@redhat.com>2012-01-04 09:56:31 -0500
commit60f98d1839376d30e13f3e452dce2433fad3060e (patch)
treeb8b43859ad26519bd75a40920f6d1ca46f2d44a5 /fs/dlm/config.c
parent757a42719635495779462514458bbfbf12a37dac (diff)
dlm: add recovery callbacks
These new callbacks notify the dlm user about lock recovery. GFS2, and possibly others, need to be aware of when the dlm will be doing lock recovery for a failed lockspace member. In the past, this coordination has been done between dlm and file system daemons in userspace, which then direct their kernel counterparts. These callbacks allow the same coordination directly, and more simply. Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/config.c')
-rw-r--r--fs/dlm/config.c130
1 files changed, 73 insertions, 57 deletions
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index 6cf72fcc0d0c..e7e327d43fa5 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -17,6 +17,7 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/in.h> 18#include <linux/in.h>
19#include <linux/in6.h> 19#include <linux/in6.h>
20#include <linux/dlmconstants.h>
20#include <net/ipv6.h> 21#include <net/ipv6.h>
21#include <net/sock.h> 22#include <net/sock.h>
22 23
@@ -36,6 +37,7 @@
36static struct config_group *space_list; 37static struct config_group *space_list;
37static struct config_group *comm_list; 38static struct config_group *comm_list;
38static struct dlm_comm *local_comm; 39static struct dlm_comm *local_comm;
40static uint32_t dlm_comm_count;
39 41
40struct dlm_clusters; 42struct dlm_clusters;
41struct dlm_cluster; 43struct dlm_cluster;
@@ -103,6 +105,8 @@ struct dlm_cluster {
103 unsigned int cl_timewarn_cs; 105 unsigned int cl_timewarn_cs;
104 unsigned int cl_waitwarn_us; 106 unsigned int cl_waitwarn_us;
105 unsigned int cl_new_rsb_count; 107 unsigned int cl_new_rsb_count;
108 unsigned int cl_recover_callbacks;
109 char cl_cluster_name[DLM_LOCKSPACE_LEN];
106}; 110};
107 111
108enum { 112enum {
@@ -118,6 +122,8 @@ enum {
118 CLUSTER_ATTR_TIMEWARN_CS, 122 CLUSTER_ATTR_TIMEWARN_CS,
119 CLUSTER_ATTR_WAITWARN_US, 123 CLUSTER_ATTR_WAITWARN_US,
120 CLUSTER_ATTR_NEW_RSB_COUNT, 124 CLUSTER_ATTR_NEW_RSB_COUNT,
125 CLUSTER_ATTR_RECOVER_CALLBACKS,
126 CLUSTER_ATTR_CLUSTER_NAME,
121}; 127};
122 128
123struct cluster_attribute { 129struct cluster_attribute {
@@ -126,6 +132,27 @@ struct cluster_attribute {
126 ssize_t (*store)(struct dlm_cluster *, const char *, size_t); 132 ssize_t (*store)(struct dlm_cluster *, const char *, size_t);
127}; 133};
128 134
135static ssize_t cluster_cluster_name_read(struct dlm_cluster *cl, char *buf)
136{
137 return sprintf(buf, "%s\n", cl->cl_cluster_name);
138}
139
140static ssize_t cluster_cluster_name_write(struct dlm_cluster *cl,
141 const char *buf, size_t len)
142{
143 strncpy(dlm_config.ci_cluster_name, buf, DLM_LOCKSPACE_LEN);
144 strncpy(cl->cl_cluster_name, buf, DLM_LOCKSPACE_LEN);
145 return len;
146}
147
148static struct cluster_attribute cluster_attr_cluster_name = {
149 .attr = { .ca_owner = THIS_MODULE,
150 .ca_name = "cluster_name",
151 .ca_mode = S_IRUGO | S_IWUSR },
152 .show = cluster_cluster_name_read,
153 .store = cluster_cluster_name_write,
154};
155
129static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field, 156static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
130 int *info_field, int check_zero, 157 int *info_field, int check_zero,
131 const char *buf, size_t len) 158 const char *buf, size_t len)
@@ -171,6 +198,7 @@ CLUSTER_ATTR(protocol, 0);
171CLUSTER_ATTR(timewarn_cs, 1); 198CLUSTER_ATTR(timewarn_cs, 1);
172CLUSTER_ATTR(waitwarn_us, 0); 199CLUSTER_ATTR(waitwarn_us, 0);
173CLUSTER_ATTR(new_rsb_count, 0); 200CLUSTER_ATTR(new_rsb_count, 0);
201CLUSTER_ATTR(recover_callbacks, 0);
174 202
175static struct configfs_attribute *cluster_attrs[] = { 203static struct configfs_attribute *cluster_attrs[] = {
176 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, 204 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
@@ -185,6 +213,8 @@ static struct configfs_attribute *cluster_attrs[] = {
185 [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, 213 [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
186 [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr, 214 [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr,
187 [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count.attr, 215 [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count.attr,
216 [CLUSTER_ATTR_RECOVER_CALLBACKS] = &cluster_attr_recover_callbacks.attr,
217 [CLUSTER_ATTR_CLUSTER_NAME] = &cluster_attr_cluster_name.attr,
188 NULL, 218 NULL,
189}; 219};
190 220
@@ -293,6 +323,7 @@ struct dlm_comms {
293 323
294struct dlm_comm { 324struct dlm_comm {
295 struct config_item item; 325 struct config_item item;
326 int seq;
296 int nodeid; 327 int nodeid;
297 int local; 328 int local;
298 int addr_count; 329 int addr_count;
@@ -309,6 +340,7 @@ struct dlm_node {
309 int nodeid; 340 int nodeid;
310 int weight; 341 int weight;
311 int new; 342 int new;
343 int comm_seq; /* copy of cm->seq when nd->nodeid is set */
312}; 344};
313 345
314static struct configfs_group_operations clusters_ops = { 346static struct configfs_group_operations clusters_ops = {
@@ -455,6 +487,9 @@ static struct config_group *make_cluster(struct config_group *g,
455 cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; 487 cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs;
456 cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us; 488 cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us;
457 cl->cl_new_rsb_count = dlm_config.ci_new_rsb_count; 489 cl->cl_new_rsb_count = dlm_config.ci_new_rsb_count;
490 cl->cl_recover_callbacks = dlm_config.ci_recover_callbacks;
491 memcpy(cl->cl_cluster_name, dlm_config.ci_cluster_name,
492 DLM_LOCKSPACE_LEN);
458 493
459 space_list = &sps->ss_group; 494 space_list = &sps->ss_group;
460 comm_list = &cms->cs_group; 495 comm_list = &cms->cs_group;
@@ -558,6 +593,11 @@ static struct config_item *make_comm(struct config_group *g, const char *name)
558 return ERR_PTR(-ENOMEM); 593 return ERR_PTR(-ENOMEM);
559 594
560 config_item_init_type_name(&cm->item, name, &comm_type); 595 config_item_init_type_name(&cm->item, name, &comm_type);
596
597 cm->seq = dlm_comm_count++;
598 if (!cm->seq)
599 cm->seq = dlm_comm_count++;
600
561 cm->nodeid = -1; 601 cm->nodeid = -1;
562 cm->local = 0; 602 cm->local = 0;
563 cm->addr_count = 0; 603 cm->addr_count = 0;
@@ -801,7 +841,10 @@ static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf)
801static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf, 841static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
802 size_t len) 842 size_t len)
803{ 843{
844 uint32_t seq = 0;
804 nd->nodeid = simple_strtol(buf, NULL, 0); 845 nd->nodeid = simple_strtol(buf, NULL, 0);
846 dlm_comm_seq(nd->nodeid, &seq);
847 nd->comm_seq = seq;
805 return len; 848 return len;
806} 849}
807 850
@@ -908,13 +951,13 @@ static void put_comm(struct dlm_comm *cm)
908} 951}
909 952
910/* caller must free mem */ 953/* caller must free mem */
911int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out, 954int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
912 int **new_out, int *new_count_out) 955 int *count_out)
913{ 956{
914 struct dlm_space *sp; 957 struct dlm_space *sp;
915 struct dlm_node *nd; 958 struct dlm_node *nd;
916 int i = 0, rv = 0, ids_count = 0, new_count = 0; 959 struct dlm_config_node *nodes, *node;
917 int *ids, *new; 960 int rv, count;
918 961
919 sp = get_space(lsname); 962 sp = get_space(lsname);
920 if (!sp) 963 if (!sp)
@@ -927,73 +970,42 @@ int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
927 goto out; 970 goto out;
928 } 971 }
929 972
930 ids_count = sp->members_count; 973 count = sp->members_count;
931 974
932 ids = kcalloc(ids_count, sizeof(int), GFP_NOFS); 975 nodes = kcalloc(count, sizeof(struct dlm_config_node), GFP_NOFS);
933 if (!ids) { 976 if (!nodes) {
934 rv = -ENOMEM; 977 rv = -ENOMEM;
935 goto out; 978 goto out;
936 } 979 }
937 980
981 node = nodes;
938 list_for_each_entry(nd, &sp->members, list) { 982 list_for_each_entry(nd, &sp->members, list) {
939 ids[i++] = nd->nodeid; 983 node->nodeid = nd->nodeid;
940 if (nd->new) 984 node->weight = nd->weight;
941 new_count++; 985 node->new = nd->new;
942 } 986 node->comm_seq = nd->comm_seq;
943 987 node++;
944 if (ids_count != i)
945 printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
946
947 if (!new_count)
948 goto out_ids;
949 988
950 new = kcalloc(new_count, sizeof(int), GFP_NOFS); 989 nd->new = 0;
951 if (!new) {
952 kfree(ids);
953 rv = -ENOMEM;
954 goto out;
955 } 990 }
956 991
957 i = 0; 992 *count_out = count;
958 list_for_each_entry(nd, &sp->members, list) { 993 *nodes_out = nodes;
959 if (nd->new) { 994 rv = 0;
960 new[i++] = nd->nodeid;
961 nd->new = 0;
962 }
963 }
964 *new_count_out = new_count;
965 *new_out = new;
966
967 out_ids:
968 *ids_count_out = ids_count;
969 *ids_out = ids;
970 out: 995 out:
971 mutex_unlock(&sp->members_lock); 996 mutex_unlock(&sp->members_lock);
972 put_space(sp); 997 put_space(sp);
973 return rv; 998 return rv;
974} 999}
975 1000
976int dlm_node_weight(char *lsname, int nodeid) 1001int dlm_comm_seq(int nodeid, uint32_t *seq)
977{ 1002{
978 struct dlm_space *sp; 1003 struct dlm_comm *cm = get_comm(nodeid, NULL);
979 struct dlm_node *nd; 1004 if (!cm)
980 int w = -EEXIST; 1005 return -EEXIST;
981 1006 *seq = cm->seq;
982 sp = get_space(lsname); 1007 put_comm(cm);
983 if (!sp) 1008 return 0;
984 goto out;
985
986 mutex_lock(&sp->members_lock);
987 list_for_each_entry(nd, &sp->members, list) {
988 if (nd->nodeid != nodeid)
989 continue;
990 w = nd->weight;
991 break;
992 }
993 mutex_unlock(&sp->members_lock);
994 put_space(sp);
995 out:
996 return w;
997} 1009}
998 1010
999int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr) 1011int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr)
@@ -1047,6 +1059,8 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
1047#define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ 1059#define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */
1048#define DEFAULT_WAITWARN_US 0 1060#define DEFAULT_WAITWARN_US 0
1049#define DEFAULT_NEW_RSB_COUNT 128 1061#define DEFAULT_NEW_RSB_COUNT 128
1062#define DEFAULT_RECOVER_CALLBACKS 0
1063#define DEFAULT_CLUSTER_NAME ""
1050 1064
1051struct dlm_config_info dlm_config = { 1065struct dlm_config_info dlm_config = {
1052 .ci_tcp_port = DEFAULT_TCP_PORT, 1066 .ci_tcp_port = DEFAULT_TCP_PORT,
@@ -1060,6 +1074,8 @@ struct dlm_config_info dlm_config = {
1060 .ci_protocol = DEFAULT_PROTOCOL, 1074 .ci_protocol = DEFAULT_PROTOCOL,
1061 .ci_timewarn_cs = DEFAULT_TIMEWARN_CS, 1075 .ci_timewarn_cs = DEFAULT_TIMEWARN_CS,
1062 .ci_waitwarn_us = DEFAULT_WAITWARN_US, 1076 .ci_waitwarn_us = DEFAULT_WAITWARN_US,
1063 .ci_new_rsb_count = DEFAULT_NEW_RSB_COUNT 1077 .ci_new_rsb_count = DEFAULT_NEW_RSB_COUNT,
1078 .ci_recover_callbacks = DEFAULT_RECOVER_CALLBACKS,
1079 .ci_cluster_name = DEFAULT_CLUSTER_NAME
1064}; 1080};
1065 1081