1 /******************************************************************************
2 *******************************************************************************
4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5 ** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
7 ** This copyrighted material is made available to anyone wishing to use,
8 ** modify, copy, or redistribute it subject to the terms and conditions
9 ** of the GNU General Public License v.2.
11 *******************************************************************************
12 ******************************************************************************/
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/configfs.h>
17 #include <linux/slab.h>
19 #include <linux/in6.h>
27 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid
28 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
29 * /config/dlm/<cluster>/comms/<comm>/nodeid
30 * /config/dlm/<cluster>/comms/<comm>/local
31 * /config/dlm/<cluster>/comms/<comm>/addr
32 * The <cluster> level is useless, but I haven't figured out how to avoid it.
35 static struct config_group
*space_list
;
36 static struct config_group
*comm_list
;
37 static struct dlm_comm
*local_comm
;
48 static struct config_group
*make_cluster(struct config_group
*, const char *);
49 static void drop_cluster(struct config_group
*, struct config_item
*);
50 static void release_cluster(struct config_item
*);
51 static struct config_group
*make_space(struct config_group
*, const char *);
52 static void drop_space(struct config_group
*, struct config_item
*);
53 static void release_space(struct config_item
*);
54 static struct config_item
*make_comm(struct config_group
*, const char *);
55 static void drop_comm(struct config_group
*, struct config_item
*);
56 static void release_comm(struct config_item
*);
57 static struct config_item
*make_node(struct config_group
*, const char *);
58 static void drop_node(struct config_group
*, struct config_item
*);
59 static void release_node(struct config_item
*);
61 static ssize_t
show_cluster(struct config_item
*i
, struct configfs_attribute
*a
,
63 static ssize_t
store_cluster(struct config_item
*i
,
64 struct configfs_attribute
*a
,
65 const char *buf
, size_t len
);
66 static ssize_t
show_comm(struct config_item
*i
, struct configfs_attribute
*a
,
68 static ssize_t
store_comm(struct config_item
*i
, struct configfs_attribute
*a
,
69 const char *buf
, size_t len
);
70 static ssize_t
show_node(struct config_item
*i
, struct configfs_attribute
*a
,
72 static ssize_t
store_node(struct config_item
*i
, struct configfs_attribute
*a
,
73 const char *buf
, size_t len
);
75 static ssize_t
comm_nodeid_read(struct dlm_comm
*cm
, char *buf
);
76 static ssize_t
comm_nodeid_write(struct dlm_comm
*cm
, const char *buf
,
78 static ssize_t
comm_local_read(struct dlm_comm
*cm
, char *buf
);
79 static ssize_t
comm_local_write(struct dlm_comm
*cm
, const char *buf
,
81 static ssize_t
comm_addr_write(struct dlm_comm
*cm
, const char *buf
,
83 static ssize_t
node_nodeid_read(struct dlm_node
*nd
, char *buf
);
84 static ssize_t
node_nodeid_write(struct dlm_node
*nd
, const char *buf
,
86 static ssize_t
node_weight_read(struct dlm_node
*nd
, char *buf
);
87 static ssize_t
node_weight_write(struct dlm_node
*nd
, const char *buf
,
91 struct config_group group
;
92 unsigned int cl_tcp_port
;
93 unsigned int cl_buffer_size
;
94 unsigned int cl_rsbtbl_size
;
95 unsigned int cl_lkbtbl_size
;
96 unsigned int cl_dirtbl_size
;
97 unsigned int cl_recover_timer
;
98 unsigned int cl_toss_secs
;
99 unsigned int cl_scan_secs
;
100 unsigned int cl_log_debug
;
101 unsigned int cl_protocol
;
102 unsigned int cl_timewarn_cs
;
103 unsigned int cl_waitwarn_us
;
107 CLUSTER_ATTR_TCP_PORT
= 0,
108 CLUSTER_ATTR_BUFFER_SIZE
,
109 CLUSTER_ATTR_RSBTBL_SIZE
,
110 CLUSTER_ATTR_LKBTBL_SIZE
,
111 CLUSTER_ATTR_DIRTBL_SIZE
,
112 CLUSTER_ATTR_RECOVER_TIMER
,
113 CLUSTER_ATTR_TOSS_SECS
,
114 CLUSTER_ATTR_SCAN_SECS
,
115 CLUSTER_ATTR_LOG_DEBUG
,
116 CLUSTER_ATTR_PROTOCOL
,
117 CLUSTER_ATTR_TIMEWARN_CS
,
118 CLUSTER_ATTR_WAITWARN_US
,
121 struct cluster_attribute
{
122 struct configfs_attribute attr
;
123 ssize_t (*show
)(struct dlm_cluster
*, char *);
124 ssize_t (*store
)(struct dlm_cluster
*, const char *, size_t);
127 static ssize_t
cluster_set(struct dlm_cluster
*cl
, unsigned int *cl_field
,
128 int *info_field
, int check_zero
,
129 const char *buf
, size_t len
)
133 if (!capable(CAP_SYS_ADMIN
))
136 x
= simple_strtoul(buf
, NULL
, 0);
138 if (check_zero
&& !x
)
147 #define CLUSTER_ATTR(name, check_zero) \
148 static ssize_t name##_write(struct dlm_cluster *cl, const char *buf, size_t len) \
150 return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name, \
151 check_zero, buf, len); \
153 static ssize_t name##_read(struct dlm_cluster *cl, char *buf) \
155 return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name); \
157 static struct cluster_attribute cluster_attr_##name = \
158 __CONFIGFS_ATTR(name, 0644, name##_read, name##_write)
160 CLUSTER_ATTR(tcp_port
, 1);
161 CLUSTER_ATTR(buffer_size
, 1);
162 CLUSTER_ATTR(rsbtbl_size
, 1);
163 CLUSTER_ATTR(lkbtbl_size
, 1);
164 CLUSTER_ATTR(dirtbl_size
, 1);
165 CLUSTER_ATTR(recover_timer
, 1);
166 CLUSTER_ATTR(toss_secs
, 1);
167 CLUSTER_ATTR(scan_secs
, 1);
168 CLUSTER_ATTR(log_debug
, 0);
169 CLUSTER_ATTR(protocol
, 0);
170 CLUSTER_ATTR(timewarn_cs
, 1);
171 CLUSTER_ATTR(waitwarn_us
, 0);
173 static struct configfs_attribute
*cluster_attrs
[] = {
174 [CLUSTER_ATTR_TCP_PORT
] = &cluster_attr_tcp_port
.attr
,
175 [CLUSTER_ATTR_BUFFER_SIZE
] = &cluster_attr_buffer_size
.attr
,
176 [CLUSTER_ATTR_RSBTBL_SIZE
] = &cluster_attr_rsbtbl_size
.attr
,
177 [CLUSTER_ATTR_LKBTBL_SIZE
] = &cluster_attr_lkbtbl_size
.attr
,
178 [CLUSTER_ATTR_DIRTBL_SIZE
] = &cluster_attr_dirtbl_size
.attr
,
179 [CLUSTER_ATTR_RECOVER_TIMER
] = &cluster_attr_recover_timer
.attr
,
180 [CLUSTER_ATTR_TOSS_SECS
] = &cluster_attr_toss_secs
.attr
,
181 [CLUSTER_ATTR_SCAN_SECS
] = &cluster_attr_scan_secs
.attr
,
182 [CLUSTER_ATTR_LOG_DEBUG
] = &cluster_attr_log_debug
.attr
,
183 [CLUSTER_ATTR_PROTOCOL
] = &cluster_attr_protocol
.attr
,
184 [CLUSTER_ATTR_TIMEWARN_CS
] = &cluster_attr_timewarn_cs
.attr
,
185 [CLUSTER_ATTR_WAITWARN_US
] = &cluster_attr_waitwarn_us
.attr
,
190 COMM_ATTR_NODEID
= 0,
195 struct comm_attribute
{
196 struct configfs_attribute attr
;
197 ssize_t (*show
)(struct dlm_comm
*, char *);
198 ssize_t (*store
)(struct dlm_comm
*, const char *, size_t);
201 static struct comm_attribute comm_attr_nodeid
= {
202 .attr
= { .ca_owner
= THIS_MODULE
,
204 .ca_mode
= S_IRUGO
| S_IWUSR
},
205 .show
= comm_nodeid_read
,
206 .store
= comm_nodeid_write
,
209 static struct comm_attribute comm_attr_local
= {
210 .attr
= { .ca_owner
= THIS_MODULE
,
212 .ca_mode
= S_IRUGO
| S_IWUSR
},
213 .show
= comm_local_read
,
214 .store
= comm_local_write
,
217 static struct comm_attribute comm_attr_addr
= {
218 .attr
= { .ca_owner
= THIS_MODULE
,
220 .ca_mode
= S_IRUGO
| S_IWUSR
},
221 .store
= comm_addr_write
,
224 static struct configfs_attribute
*comm_attrs
[] = {
225 [COMM_ATTR_NODEID
] = &comm_attr_nodeid
.attr
,
226 [COMM_ATTR_LOCAL
] = &comm_attr_local
.attr
,
227 [COMM_ATTR_ADDR
] = &comm_attr_addr
.attr
,
232 NODE_ATTR_NODEID
= 0,
236 struct node_attribute
{
237 struct configfs_attribute attr
;
238 ssize_t (*show
)(struct dlm_node
*, char *);
239 ssize_t (*store
)(struct dlm_node
*, const char *, size_t);
242 static struct node_attribute node_attr_nodeid
= {
243 .attr
= { .ca_owner
= THIS_MODULE
,
245 .ca_mode
= S_IRUGO
| S_IWUSR
},
246 .show
= node_nodeid_read
,
247 .store
= node_nodeid_write
,
250 static struct node_attribute node_attr_weight
= {
251 .attr
= { .ca_owner
= THIS_MODULE
,
253 .ca_mode
= S_IRUGO
| S_IWUSR
},
254 .show
= node_weight_read
,
255 .store
= node_weight_write
,
258 static struct configfs_attribute
*node_attrs
[] = {
259 [NODE_ATTR_NODEID
] = &node_attr_nodeid
.attr
,
260 [NODE_ATTR_WEIGHT
] = &node_attr_weight
.attr
,
264 struct dlm_clusters
{
265 struct configfs_subsystem subsys
;
269 struct config_group ss_group
;
273 struct config_group group
;
274 struct list_head members
;
275 struct mutex members_lock
;
280 struct config_group cs_group
;
284 struct config_item item
;
288 struct sockaddr_storage
*addr
[DLM_MAX_ADDR_COUNT
];
292 struct config_group ns_group
;
296 struct config_item item
;
297 struct list_head list
; /* space->members */
303 static struct configfs_group_operations clusters_ops
= {
304 .make_group
= make_cluster
,
305 .drop_item
= drop_cluster
,
308 static struct configfs_item_operations cluster_ops
= {
309 .release
= release_cluster
,
310 .show_attribute
= show_cluster
,
311 .store_attribute
= store_cluster
,
314 static struct configfs_group_operations spaces_ops
= {
315 .make_group
= make_space
,
316 .drop_item
= drop_space
,
319 static struct configfs_item_operations space_ops
= {
320 .release
= release_space
,
323 static struct configfs_group_operations comms_ops
= {
324 .make_item
= make_comm
,
325 .drop_item
= drop_comm
,
328 static struct configfs_item_operations comm_ops
= {
329 .release
= release_comm
,
330 .show_attribute
= show_comm
,
331 .store_attribute
= store_comm
,
334 static struct configfs_group_operations nodes_ops
= {
335 .make_item
= make_node
,
336 .drop_item
= drop_node
,
339 static struct configfs_item_operations node_ops
= {
340 .release
= release_node
,
341 .show_attribute
= show_node
,
342 .store_attribute
= store_node
,
345 static struct config_item_type clusters_type
= {
346 .ct_group_ops
= &clusters_ops
,
347 .ct_owner
= THIS_MODULE
,
350 static struct config_item_type cluster_type
= {
351 .ct_item_ops
= &cluster_ops
,
352 .ct_attrs
= cluster_attrs
,
353 .ct_owner
= THIS_MODULE
,
356 static struct config_item_type spaces_type
= {
357 .ct_group_ops
= &spaces_ops
,
358 .ct_owner
= THIS_MODULE
,
361 static struct config_item_type space_type
= {
362 .ct_item_ops
= &space_ops
,
363 .ct_owner
= THIS_MODULE
,
366 static struct config_item_type comms_type
= {
367 .ct_group_ops
= &comms_ops
,
368 .ct_owner
= THIS_MODULE
,
371 static struct config_item_type comm_type
= {
372 .ct_item_ops
= &comm_ops
,
373 .ct_attrs
= comm_attrs
,
374 .ct_owner
= THIS_MODULE
,
377 static struct config_item_type nodes_type
= {
378 .ct_group_ops
= &nodes_ops
,
379 .ct_owner
= THIS_MODULE
,
382 static struct config_item_type node_type
= {
383 .ct_item_ops
= &node_ops
,
384 .ct_attrs
= node_attrs
,
385 .ct_owner
= THIS_MODULE
,
388 static struct dlm_cluster
*config_item_to_cluster(struct config_item
*i
)
390 return i
? container_of(to_config_group(i
), struct dlm_cluster
, group
) :
394 static struct dlm_space
*config_item_to_space(struct config_item
*i
)
396 return i
? container_of(to_config_group(i
), struct dlm_space
, group
) :
400 static struct dlm_comm
*config_item_to_comm(struct config_item
*i
)
402 return i
? container_of(i
, struct dlm_comm
, item
) : NULL
;
405 static struct dlm_node
*config_item_to_node(struct config_item
*i
)
407 return i
? container_of(i
, struct dlm_node
, item
) : NULL
;
410 static struct config_group
*make_cluster(struct config_group
*g
,
413 struct dlm_cluster
*cl
= NULL
;
414 struct dlm_spaces
*sps
= NULL
;
415 struct dlm_comms
*cms
= NULL
;
418 cl
= kzalloc(sizeof(struct dlm_cluster
), GFP_NOFS
);
419 gps
= kcalloc(3, sizeof(struct config_group
*), GFP_NOFS
);
420 sps
= kzalloc(sizeof(struct dlm_spaces
), GFP_NOFS
);
421 cms
= kzalloc(sizeof(struct dlm_comms
), GFP_NOFS
);
423 if (!cl
|| !gps
|| !sps
|| !cms
)
426 config_group_init_type_name(&cl
->group
, name
, &cluster_type
);
427 config_group_init_type_name(&sps
->ss_group
, "spaces", &spaces_type
);
428 config_group_init_type_name(&cms
->cs_group
, "comms", &comms_type
);
430 cl
->group
.default_groups
= gps
;
431 cl
->group
.default_groups
[0] = &sps
->ss_group
;
432 cl
->group
.default_groups
[1] = &cms
->cs_group
;
433 cl
->group
.default_groups
[2] = NULL
;
435 cl
->cl_tcp_port
= dlm_config
.ci_tcp_port
;
436 cl
->cl_buffer_size
= dlm_config
.ci_buffer_size
;
437 cl
->cl_rsbtbl_size
= dlm_config
.ci_rsbtbl_size
;
438 cl
->cl_lkbtbl_size
= dlm_config
.ci_lkbtbl_size
;
439 cl
->cl_dirtbl_size
= dlm_config
.ci_dirtbl_size
;
440 cl
->cl_recover_timer
= dlm_config
.ci_recover_timer
;
441 cl
->cl_toss_secs
= dlm_config
.ci_toss_secs
;
442 cl
->cl_scan_secs
= dlm_config
.ci_scan_secs
;
443 cl
->cl_log_debug
= dlm_config
.ci_log_debug
;
444 cl
->cl_protocol
= dlm_config
.ci_protocol
;
445 cl
->cl_timewarn_cs
= dlm_config
.ci_timewarn_cs
;
446 cl
->cl_waitwarn_us
= dlm_config
.ci_waitwarn_us
;
448 space_list
= &sps
->ss_group
;
449 comm_list
= &cms
->cs_group
;
457 return ERR_PTR(-ENOMEM
);
460 static void drop_cluster(struct config_group
*g
, struct config_item
*i
)
462 struct dlm_cluster
*cl
= config_item_to_cluster(i
);
463 struct config_item
*tmp
;
466 for (j
= 0; cl
->group
.default_groups
[j
]; j
++) {
467 tmp
= &cl
->group
.default_groups
[j
]->cg_item
;
468 cl
->group
.default_groups
[j
] = NULL
;
469 config_item_put(tmp
);
478 static void release_cluster(struct config_item
*i
)
480 struct dlm_cluster
*cl
= config_item_to_cluster(i
);
481 kfree(cl
->group
.default_groups
);
485 static struct config_group
*make_space(struct config_group
*g
, const char *name
)
487 struct dlm_space
*sp
= NULL
;
488 struct dlm_nodes
*nds
= NULL
;
491 sp
= kzalloc(sizeof(struct dlm_space
), GFP_NOFS
);
492 gps
= kcalloc(2, sizeof(struct config_group
*), GFP_NOFS
);
493 nds
= kzalloc(sizeof(struct dlm_nodes
), GFP_NOFS
);
495 if (!sp
|| !gps
|| !nds
)
498 config_group_init_type_name(&sp
->group
, name
, &space_type
);
499 config_group_init_type_name(&nds
->ns_group
, "nodes", &nodes_type
);
501 sp
->group
.default_groups
= gps
;
502 sp
->group
.default_groups
[0] = &nds
->ns_group
;
503 sp
->group
.default_groups
[1] = NULL
;
505 INIT_LIST_HEAD(&sp
->members
);
506 mutex_init(&sp
->members_lock
);
507 sp
->members_count
= 0;
514 return ERR_PTR(-ENOMEM
);
517 static void drop_space(struct config_group
*g
, struct config_item
*i
)
519 struct dlm_space
*sp
= config_item_to_space(i
);
520 struct config_item
*tmp
;
523 /* assert list_empty(&sp->members) */
525 for (j
= 0; sp
->group
.default_groups
[j
]; j
++) {
526 tmp
= &sp
->group
.default_groups
[j
]->cg_item
;
527 sp
->group
.default_groups
[j
] = NULL
;
528 config_item_put(tmp
);
534 static void release_space(struct config_item
*i
)
536 struct dlm_space
*sp
= config_item_to_space(i
);
537 kfree(sp
->group
.default_groups
);
541 static struct config_item
*make_comm(struct config_group
*g
, const char *name
)
545 cm
= kzalloc(sizeof(struct dlm_comm
), GFP_NOFS
);
547 return ERR_PTR(-ENOMEM
);
549 config_item_init_type_name(&cm
->item
, name
, &comm_type
);
556 static void drop_comm(struct config_group
*g
, struct config_item
*i
)
558 struct dlm_comm
*cm
= config_item_to_comm(i
);
559 if (local_comm
== cm
)
561 dlm_lowcomms_close(cm
->nodeid
);
562 while (cm
->addr_count
--)
563 kfree(cm
->addr
[cm
->addr_count
]);
567 static void release_comm(struct config_item
*i
)
569 struct dlm_comm
*cm
= config_item_to_comm(i
);
573 static struct config_item
*make_node(struct config_group
*g
, const char *name
)
575 struct dlm_space
*sp
= config_item_to_space(g
->cg_item
.ci_parent
);
578 nd
= kzalloc(sizeof(struct dlm_node
), GFP_NOFS
);
580 return ERR_PTR(-ENOMEM
);
582 config_item_init_type_name(&nd
->item
, name
, &node_type
);
584 nd
->weight
= 1; /* default weight of 1 if none is set */
585 nd
->new = 1; /* set to 0 once it's been read by dlm_nodeid_list() */
587 mutex_lock(&sp
->members_lock
);
588 list_add(&nd
->list
, &sp
->members
);
590 mutex_unlock(&sp
->members_lock
);
595 static void drop_node(struct config_group
*g
, struct config_item
*i
)
597 struct dlm_space
*sp
= config_item_to_space(g
->cg_item
.ci_parent
);
598 struct dlm_node
*nd
= config_item_to_node(i
);
600 mutex_lock(&sp
->members_lock
);
603 mutex_unlock(&sp
->members_lock
);
608 static void release_node(struct config_item
*i
)
610 struct dlm_node
*nd
= config_item_to_node(i
);
614 static struct dlm_clusters clusters_root
= {
619 .ci_type
= &clusters_type
,
625 int __init
dlm_config_init(void)
627 config_group_init(&clusters_root
.subsys
.su_group
);
628 mutex_init(&clusters_root
.subsys
.su_mutex
);
629 return configfs_register_subsystem(&clusters_root
.subsys
);
632 void dlm_config_exit(void)
634 configfs_unregister_subsystem(&clusters_root
.subsys
);
638 * Functions for user space to read/write attributes
641 static ssize_t
show_cluster(struct config_item
*i
, struct configfs_attribute
*a
,
644 struct dlm_cluster
*cl
= config_item_to_cluster(i
);
645 struct cluster_attribute
*cla
=
646 container_of(a
, struct cluster_attribute
, attr
);
647 return cla
->show
? cla
->show(cl
, buf
) : 0;
650 static ssize_t
store_cluster(struct config_item
*i
,
651 struct configfs_attribute
*a
,
652 const char *buf
, size_t len
)
654 struct dlm_cluster
*cl
= config_item_to_cluster(i
);
655 struct cluster_attribute
*cla
=
656 container_of(a
, struct cluster_attribute
, attr
);
657 return cla
->store
? cla
->store(cl
, buf
, len
) : -EINVAL
;
660 static ssize_t
show_comm(struct config_item
*i
, struct configfs_attribute
*a
,
663 struct dlm_comm
*cm
= config_item_to_comm(i
);
664 struct comm_attribute
*cma
=
665 container_of(a
, struct comm_attribute
, attr
);
666 return cma
->show
? cma
->show(cm
, buf
) : 0;
669 static ssize_t
store_comm(struct config_item
*i
, struct configfs_attribute
*a
,
670 const char *buf
, size_t len
)
672 struct dlm_comm
*cm
= config_item_to_comm(i
);
673 struct comm_attribute
*cma
=
674 container_of(a
, struct comm_attribute
, attr
);
675 return cma
->store
? cma
->store(cm
, buf
, len
) : -EINVAL
;
678 static ssize_t
comm_nodeid_read(struct dlm_comm
*cm
, char *buf
)
680 return sprintf(buf
, "%d\n", cm
->nodeid
);
683 static ssize_t
comm_nodeid_write(struct dlm_comm
*cm
, const char *buf
,
686 cm
->nodeid
= simple_strtol(buf
, NULL
, 0);
690 static ssize_t
comm_local_read(struct dlm_comm
*cm
, char *buf
)
692 return sprintf(buf
, "%d\n", cm
->local
);
695 static ssize_t
comm_local_write(struct dlm_comm
*cm
, const char *buf
,
698 cm
->local
= simple_strtol(buf
, NULL
, 0);
699 if (cm
->local
&& !local_comm
)
704 static ssize_t
comm_addr_write(struct dlm_comm
*cm
, const char *buf
, size_t len
)
706 struct sockaddr_storage
*addr
;
708 if (len
!= sizeof(struct sockaddr_storage
))
711 if (cm
->addr_count
>= DLM_MAX_ADDR_COUNT
)
714 addr
= kzalloc(sizeof(*addr
), GFP_NOFS
);
718 memcpy(addr
, buf
, len
);
719 cm
->addr
[cm
->addr_count
++] = addr
;
723 static ssize_t
show_node(struct config_item
*i
, struct configfs_attribute
*a
,
726 struct dlm_node
*nd
= config_item_to_node(i
);
727 struct node_attribute
*nda
=
728 container_of(a
, struct node_attribute
, attr
);
729 return nda
->show
? nda
->show(nd
, buf
) : 0;
732 static ssize_t
store_node(struct config_item
*i
, struct configfs_attribute
*a
,
733 const char *buf
, size_t len
)
735 struct dlm_node
*nd
= config_item_to_node(i
);
736 struct node_attribute
*nda
=
737 container_of(a
, struct node_attribute
, attr
);
738 return nda
->store
? nda
->store(nd
, buf
, len
) : -EINVAL
;
741 static ssize_t
node_nodeid_read(struct dlm_node
*nd
, char *buf
)
743 return sprintf(buf
, "%d\n", nd
->nodeid
);
746 static ssize_t
node_nodeid_write(struct dlm_node
*nd
, const char *buf
,
749 nd
->nodeid
= simple_strtol(buf
, NULL
, 0);
753 static ssize_t
node_weight_read(struct dlm_node
*nd
, char *buf
)
755 return sprintf(buf
, "%d\n", nd
->weight
);
758 static ssize_t
node_weight_write(struct dlm_node
*nd
, const char *buf
,
761 nd
->weight
= simple_strtol(buf
, NULL
, 0);
766 * Functions for the dlm to get the info that's been configured
769 static struct dlm_space
*get_space(char *name
)
771 struct config_item
*i
;
776 mutex_lock(&space_list
->cg_subsys
->su_mutex
);
777 i
= config_group_find_item(space_list
, name
);
778 mutex_unlock(&space_list
->cg_subsys
->su_mutex
);
780 return config_item_to_space(i
);
783 static void put_space(struct dlm_space
*sp
)
785 config_item_put(&sp
->group
.cg_item
);
788 static int addr_compare(struct sockaddr_storage
*x
, struct sockaddr_storage
*y
)
790 switch (x
->ss_family
) {
792 struct sockaddr_in
*sinx
= (struct sockaddr_in
*)x
;
793 struct sockaddr_in
*siny
= (struct sockaddr_in
*)y
;
794 if (sinx
->sin_addr
.s_addr
!= siny
->sin_addr
.s_addr
)
796 if (sinx
->sin_port
!= siny
->sin_port
)
801 struct sockaddr_in6
*sinx
= (struct sockaddr_in6
*)x
;
802 struct sockaddr_in6
*siny
= (struct sockaddr_in6
*)y
;
803 if (!ipv6_addr_equal(&sinx
->sin6_addr
, &siny
->sin6_addr
))
805 if (sinx
->sin6_port
!= siny
->sin6_port
)
815 static struct dlm_comm
*get_comm(int nodeid
, struct sockaddr_storage
*addr
)
817 struct config_item
*i
;
818 struct dlm_comm
*cm
= NULL
;
824 mutex_lock(&clusters_root
.subsys
.su_mutex
);
826 list_for_each_entry(i
, &comm_list
->cg_children
, ci_entry
) {
827 cm
= config_item_to_comm(i
);
830 if (cm
->nodeid
!= nodeid
)
836 if (!cm
->addr_count
|| !addr_compare(cm
->addr
[0], addr
))
843 mutex_unlock(&clusters_root
.subsys
.su_mutex
);
850 static void put_comm(struct dlm_comm
*cm
)
852 config_item_put(&cm
->item
);
855 /* caller must free mem */
856 int dlm_nodeid_list(char *lsname
, int **ids_out
, int *ids_count_out
,
857 int **new_out
, int *new_count_out
)
859 struct dlm_space
*sp
;
861 int i
= 0, rv
= 0, ids_count
= 0, new_count
= 0;
864 sp
= get_space(lsname
);
868 mutex_lock(&sp
->members_lock
);
869 if (!sp
->members_count
) {
871 printk(KERN_ERR
"dlm: zero members_count\n");
875 ids_count
= sp
->members_count
;
877 ids
= kcalloc(ids_count
, sizeof(int), GFP_NOFS
);
883 list_for_each_entry(nd
, &sp
->members
, list
) {
884 ids
[i
++] = nd
->nodeid
;
890 printk(KERN_ERR
"dlm: bad nodeid count %d %d\n", ids_count
, i
);
895 new = kcalloc(new_count
, sizeof(int), GFP_NOFS
);
903 list_for_each_entry(nd
, &sp
->members
, list
) {
905 new[i
++] = nd
->nodeid
;
909 *new_count_out
= new_count
;
913 *ids_count_out
= ids_count
;
916 mutex_unlock(&sp
->members_lock
);
921 int dlm_node_weight(char *lsname
, int nodeid
)
923 struct dlm_space
*sp
;
927 sp
= get_space(lsname
);
931 mutex_lock(&sp
->members_lock
);
932 list_for_each_entry(nd
, &sp
->members
, list
) {
933 if (nd
->nodeid
!= nodeid
)
938 mutex_unlock(&sp
->members_lock
);
944 int dlm_nodeid_to_addr(int nodeid
, struct sockaddr_storage
*addr
)
946 struct dlm_comm
*cm
= get_comm(nodeid
, NULL
);
951 memcpy(addr
, cm
->addr
[0], sizeof(*addr
));
956 int dlm_addr_to_nodeid(struct sockaddr_storage
*addr
, int *nodeid
)
958 struct dlm_comm
*cm
= get_comm(0, addr
);
961 *nodeid
= cm
->nodeid
;
966 int dlm_our_nodeid(void)
968 return local_comm
? local_comm
->nodeid
: 0;
971 /* num 0 is first addr, num 1 is second addr */
972 int dlm_our_addr(struct sockaddr_storage
*addr
, int num
)
976 if (num
+ 1 > local_comm
->addr_count
)
978 memcpy(addr
, local_comm
->addr
[num
], sizeof(*addr
));
982 /* Config file defaults */
983 #define DEFAULT_TCP_PORT 21064
984 #define DEFAULT_BUFFER_SIZE 4096
985 #define DEFAULT_RSBTBL_SIZE 1024
986 #define DEFAULT_LKBTBL_SIZE 1024
987 #define DEFAULT_DIRTBL_SIZE 1024
988 #define DEFAULT_RECOVER_TIMER 5
989 #define DEFAULT_TOSS_SECS 10
990 #define DEFAULT_SCAN_SECS 5
991 #define DEFAULT_LOG_DEBUG 0
992 #define DEFAULT_PROTOCOL 0
993 #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */
994 #define DEFAULT_WAITWARN_US 0
996 struct dlm_config_info dlm_config
= {
997 .ci_tcp_port
= DEFAULT_TCP_PORT
,
998 .ci_buffer_size
= DEFAULT_BUFFER_SIZE
,
999 .ci_rsbtbl_size
= DEFAULT_RSBTBL_SIZE
,
1000 .ci_lkbtbl_size
= DEFAULT_LKBTBL_SIZE
,
1001 .ci_dirtbl_size
= DEFAULT_DIRTBL_SIZE
,
1002 .ci_recover_timer
= DEFAULT_RECOVER_TIMER
,
1003 .ci_toss_secs
= DEFAULT_TOSS_SECS
,
1004 .ci_scan_secs
= DEFAULT_SCAN_SECS
,
1005 .ci_log_debug
= DEFAULT_LOG_DEBUG
,
1006 .ci_protocol
= DEFAULT_PROTOCOL
,
1007 .ci_timewarn_cs
= DEFAULT_TIMEWARN_CS
,
1008 .ci_waitwarn_us
= DEFAULT_WAITWARN_US