1 /******************************************************************************
2 *******************************************************************************
4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5 ** Copyright (C) 2004-2005 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>
23 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid
24 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
25 * /config/dlm/<cluster>/comms/<comm>/nodeid
26 * /config/dlm/<cluster>/comms/<comm>/local
27 * /config/dlm/<cluster>/comms/<comm>/addr
28 * The <cluster> level is useless, but I haven't figured out how to avoid it.
31 static struct config_group
*space_list
;
32 static struct config_group
*comm_list
;
33 static struct comm
*local_comm
;
44 static struct config_group
*make_cluster(struct config_group
*, const char *);
45 static void drop_cluster(struct config_group
*, struct config_item
*);
46 static void release_cluster(struct config_item
*);
47 static struct config_group
*make_space(struct config_group
*, const char *);
48 static void drop_space(struct config_group
*, struct config_item
*);
49 static void release_space(struct config_item
*);
50 static struct config_item
*make_comm(struct config_group
*, const char *);
51 static void drop_comm(struct config_group
*, struct config_item
*);
52 static void release_comm(struct config_item
*);
53 static struct config_item
*make_node(struct config_group
*, const char *);
54 static void drop_node(struct config_group
*, struct config_item
*);
55 static void release_node(struct config_item
*);
57 static ssize_t
show_comm(struct config_item
*i
, struct configfs_attribute
*a
,
59 static ssize_t
store_comm(struct config_item
*i
, struct configfs_attribute
*a
,
60 const char *buf
, size_t len
);
61 static ssize_t
show_node(struct config_item
*i
, struct configfs_attribute
*a
,
63 static ssize_t
store_node(struct config_item
*i
, struct configfs_attribute
*a
,
64 const char *buf
, size_t len
);
66 static ssize_t
comm_nodeid_read(struct comm
*cm
, char *buf
);
67 static ssize_t
comm_nodeid_write(struct comm
*cm
, const char *buf
, size_t len
);
68 static ssize_t
comm_local_read(struct comm
*cm
, char *buf
);
69 static ssize_t
comm_local_write(struct comm
*cm
, const char *buf
, size_t len
);
70 static ssize_t
comm_addr_write(struct comm
*cm
, const char *buf
, size_t len
);
71 static ssize_t
node_nodeid_read(struct node
*nd
, char *buf
);
72 static ssize_t
node_nodeid_write(struct node
*nd
, const char *buf
, size_t len
);
73 static ssize_t
node_weight_read(struct node
*nd
, char *buf
);
74 static ssize_t
node_weight_write(struct node
*nd
, const char *buf
, size_t len
);
82 struct comm_attribute
{
83 struct configfs_attribute attr
;
84 ssize_t (*show
)(struct comm
*, char *);
85 ssize_t (*store
)(struct comm
*, const char *, size_t);
88 static struct comm_attribute comm_attr_nodeid
= {
89 .attr
= { .ca_owner
= THIS_MODULE
,
91 .ca_mode
= S_IRUGO
| S_IWUSR
},
92 .show
= comm_nodeid_read
,
93 .store
= comm_nodeid_write
,
96 static struct comm_attribute comm_attr_local
= {
97 .attr
= { .ca_owner
= THIS_MODULE
,
99 .ca_mode
= S_IRUGO
| S_IWUSR
},
100 .show
= comm_local_read
,
101 .store
= comm_local_write
,
104 static struct comm_attribute comm_attr_addr
= {
105 .attr
= { .ca_owner
= THIS_MODULE
,
107 .ca_mode
= S_IRUGO
| S_IWUSR
},
108 .store
= comm_addr_write
,
111 static struct configfs_attribute
*comm_attrs
[] = {
112 [COMM_ATTR_NODEID
] = &comm_attr_nodeid
.attr
,
113 [COMM_ATTR_LOCAL
] = &comm_attr_local
.attr
,
114 [COMM_ATTR_ADDR
] = &comm_attr_addr
.attr
,
119 NODE_ATTR_NODEID
= 0,
123 struct node_attribute
{
124 struct configfs_attribute attr
;
125 ssize_t (*show
)(struct node
*, char *);
126 ssize_t (*store
)(struct node
*, const char *, size_t);
129 static struct node_attribute node_attr_nodeid
= {
130 .attr
= { .ca_owner
= THIS_MODULE
,
132 .ca_mode
= S_IRUGO
| S_IWUSR
},
133 .show
= node_nodeid_read
,
134 .store
= node_nodeid_write
,
137 static struct node_attribute node_attr_weight
= {
138 .attr
= { .ca_owner
= THIS_MODULE
,
140 .ca_mode
= S_IRUGO
| S_IWUSR
},
141 .show
= node_weight_read
,
142 .store
= node_weight_write
,
145 static struct configfs_attribute
*node_attrs
[] = {
146 [NODE_ATTR_NODEID
] = &node_attr_nodeid
.attr
,
147 [NODE_ATTR_WEIGHT
] = &node_attr_weight
.attr
,
152 struct configfs_subsystem subsys
;
156 struct config_group group
;
160 struct config_group ss_group
;
164 struct config_group group
;
165 struct list_head members
;
166 struct mutex members_lock
;
171 struct config_group cs_group
;
175 struct config_item item
;
179 struct sockaddr_storage
*addr
[DLM_MAX_ADDR_COUNT
];
183 struct config_group ns_group
;
187 struct config_item item
;
188 struct list_head list
; /* space->members */
193 static struct configfs_group_operations clusters_ops
= {
194 .make_group
= make_cluster
,
195 .drop_item
= drop_cluster
,
198 static struct configfs_item_operations cluster_ops
= {
199 .release
= release_cluster
,
202 static struct configfs_group_operations spaces_ops
= {
203 .make_group
= make_space
,
204 .drop_item
= drop_space
,
207 static struct configfs_item_operations space_ops
= {
208 .release
= release_space
,
211 static struct configfs_group_operations comms_ops
= {
212 .make_item
= make_comm
,
213 .drop_item
= drop_comm
,
216 static struct configfs_item_operations comm_ops
= {
217 .release
= release_comm
,
218 .show_attribute
= show_comm
,
219 .store_attribute
= store_comm
,
222 static struct configfs_group_operations nodes_ops
= {
223 .make_item
= make_node
,
224 .drop_item
= drop_node
,
227 static struct configfs_item_operations node_ops
= {
228 .release
= release_node
,
229 .show_attribute
= show_node
,
230 .store_attribute
= store_node
,
233 static struct config_item_type clusters_type
= {
234 .ct_group_ops
= &clusters_ops
,
235 .ct_owner
= THIS_MODULE
,
238 static struct config_item_type cluster_type
= {
239 .ct_item_ops
= &cluster_ops
,
240 .ct_owner
= THIS_MODULE
,
243 static struct config_item_type spaces_type
= {
244 .ct_group_ops
= &spaces_ops
,
245 .ct_owner
= THIS_MODULE
,
248 static struct config_item_type space_type
= {
249 .ct_item_ops
= &space_ops
,
250 .ct_owner
= THIS_MODULE
,
253 static struct config_item_type comms_type
= {
254 .ct_group_ops
= &comms_ops
,
255 .ct_owner
= THIS_MODULE
,
258 static struct config_item_type comm_type
= {
259 .ct_item_ops
= &comm_ops
,
260 .ct_attrs
= comm_attrs
,
261 .ct_owner
= THIS_MODULE
,
264 static struct config_item_type nodes_type
= {
265 .ct_group_ops
= &nodes_ops
,
266 .ct_owner
= THIS_MODULE
,
269 static struct config_item_type node_type
= {
270 .ct_item_ops
= &node_ops
,
271 .ct_attrs
= node_attrs
,
272 .ct_owner
= THIS_MODULE
,
275 static struct cluster
*to_cluster(struct config_item
*i
)
277 return i
? container_of(to_config_group(i
), struct cluster
, group
):NULL
;
280 static struct space
*to_space(struct config_item
*i
)
282 return i
? container_of(to_config_group(i
), struct space
, group
) : NULL
;
285 static struct comm
*to_comm(struct config_item
*i
)
287 return i
? container_of(i
, struct comm
, item
) : NULL
;
290 static struct node
*to_node(struct config_item
*i
)
292 return i
? container_of(i
, struct node
, item
) : NULL
;
295 static struct config_group
*make_cluster(struct config_group
*g
,
298 struct cluster
*cl
= NULL
;
299 struct spaces
*sps
= NULL
;
300 struct comms
*cms
= NULL
;
303 cl
= kzalloc(sizeof(struct cluster
), GFP_KERNEL
);
304 gps
= kcalloc(3, sizeof(struct config_group
*), GFP_KERNEL
);
305 sps
= kzalloc(sizeof(struct spaces
), GFP_KERNEL
);
306 cms
= kzalloc(sizeof(struct comms
), GFP_KERNEL
);
308 if (!cl
|| !gps
|| !sps
|| !cms
)
311 config_group_init_type_name(&cl
->group
, name
, &cluster_type
);
312 config_group_init_type_name(&sps
->ss_group
, "spaces", &spaces_type
);
313 config_group_init_type_name(&cms
->cs_group
, "comms", &comms_type
);
315 cl
->group
.default_groups
= gps
;
316 cl
->group
.default_groups
[0] = &sps
->ss_group
;
317 cl
->group
.default_groups
[1] = &cms
->cs_group
;
318 cl
->group
.default_groups
[2] = NULL
;
320 space_list
= &sps
->ss_group
;
321 comm_list
= &cms
->cs_group
;
332 static void drop_cluster(struct config_group
*g
, struct config_item
*i
)
334 struct cluster
*cl
= to_cluster(i
);
335 struct config_item
*tmp
;
338 for (j
= 0; cl
->group
.default_groups
[j
]; j
++) {
339 tmp
= &cl
->group
.default_groups
[j
]->cg_item
;
340 cl
->group
.default_groups
[j
] = NULL
;
341 config_item_put(tmp
);
350 static void release_cluster(struct config_item
*i
)
352 struct cluster
*cl
= to_cluster(i
);
353 kfree(cl
->group
.default_groups
);
357 static struct config_group
*make_space(struct config_group
*g
, const char *name
)
359 struct space
*sp
= NULL
;
360 struct nodes
*nds
= NULL
;
363 sp
= kzalloc(sizeof(struct space
), GFP_KERNEL
);
364 gps
= kcalloc(2, sizeof(struct config_group
*), GFP_KERNEL
);
365 nds
= kzalloc(sizeof(struct nodes
), GFP_KERNEL
);
367 if (!sp
|| !gps
|| !nds
)
370 config_group_init_type_name(&sp
->group
, name
, &space_type
);
371 config_group_init_type_name(&nds
->ns_group
, "nodes", &nodes_type
);
373 sp
->group
.default_groups
= gps
;
374 sp
->group
.default_groups
[0] = &nds
->ns_group
;
375 sp
->group
.default_groups
[1] = NULL
;
377 INIT_LIST_HEAD(&sp
->members
);
378 mutex_init(&sp
->members_lock
);
379 sp
->members_count
= 0;
389 static void drop_space(struct config_group
*g
, struct config_item
*i
)
391 struct space
*sp
= to_space(i
);
392 struct config_item
*tmp
;
395 /* assert list_empty(&sp->members) */
397 for (j
= 0; sp
->group
.default_groups
[j
]; j
++) {
398 tmp
= &sp
->group
.default_groups
[j
]->cg_item
;
399 sp
->group
.default_groups
[j
] = NULL
;
400 config_item_put(tmp
);
406 static void release_space(struct config_item
*i
)
408 struct space
*sp
= to_space(i
);
409 kfree(sp
->group
.default_groups
);
413 static struct config_item
*make_comm(struct config_group
*g
, const char *name
)
417 cm
= kzalloc(sizeof(struct comm
), GFP_KERNEL
);
421 config_item_init_type_name(&cm
->item
, name
, &comm_type
);
428 static void drop_comm(struct config_group
*g
, struct config_item
*i
)
430 struct comm
*cm
= to_comm(i
);
431 if (local_comm
== cm
)
433 dlm_lowcomms_close(cm
->nodeid
);
434 while (cm
->addr_count
--)
435 kfree(cm
->addr
[cm
->addr_count
]);
439 static void release_comm(struct config_item
*i
)
441 struct comm
*cm
= to_comm(i
);
445 static struct config_item
*make_node(struct config_group
*g
, const char *name
)
447 struct space
*sp
= to_space(g
->cg_item
.ci_parent
);
450 nd
= kzalloc(sizeof(struct node
), GFP_KERNEL
);
454 config_item_init_type_name(&nd
->item
, name
, &node_type
);
456 nd
->weight
= 1; /* default weight of 1 if none is set */
458 mutex_lock(&sp
->members_lock
);
459 list_add(&nd
->list
, &sp
->members
);
461 mutex_unlock(&sp
->members_lock
);
466 static void drop_node(struct config_group
*g
, struct config_item
*i
)
468 struct space
*sp
= to_space(g
->cg_item
.ci_parent
);
469 struct node
*nd
= to_node(i
);
471 mutex_lock(&sp
->members_lock
);
474 mutex_unlock(&sp
->members_lock
);
479 static void release_node(struct config_item
*i
)
481 struct node
*nd
= to_node(i
);
485 static struct clusters clusters_root
= {
490 .ci_type
= &clusters_type
,
496 int dlm_config_init(void)
498 config_group_init(&clusters_root
.subsys
.su_group
);
499 init_MUTEX(&clusters_root
.subsys
.su_sem
);
500 return configfs_register_subsystem(&clusters_root
.subsys
);
503 void dlm_config_exit(void)
505 configfs_unregister_subsystem(&clusters_root
.subsys
);
509 * Functions for user space to read/write attributes
512 static ssize_t
show_comm(struct config_item
*i
, struct configfs_attribute
*a
,
515 struct comm
*cm
= to_comm(i
);
516 struct comm_attribute
*cma
=
517 container_of(a
, struct comm_attribute
, attr
);
518 return cma
->show
? cma
->show(cm
, buf
) : 0;
521 static ssize_t
store_comm(struct config_item
*i
, struct configfs_attribute
*a
,
522 const char *buf
, size_t len
)
524 struct comm
*cm
= to_comm(i
);
525 struct comm_attribute
*cma
=
526 container_of(a
, struct comm_attribute
, attr
);
527 return cma
->store
? cma
->store(cm
, buf
, len
) : -EINVAL
;
530 static ssize_t
comm_nodeid_read(struct comm
*cm
, char *buf
)
532 return sprintf(buf
, "%d\n", cm
->nodeid
);
535 static ssize_t
comm_nodeid_write(struct comm
*cm
, const char *buf
, size_t len
)
537 cm
->nodeid
= simple_strtol(buf
, NULL
, 0);
541 static ssize_t
comm_local_read(struct comm
*cm
, char *buf
)
543 return sprintf(buf
, "%d\n", cm
->local
);
546 static ssize_t
comm_local_write(struct comm
*cm
, const char *buf
, size_t len
)
548 cm
->local
= simple_strtol(buf
, NULL
, 0);
549 if (cm
->local
&& !local_comm
)
554 static ssize_t
comm_addr_write(struct comm
*cm
, const char *buf
, size_t len
)
556 struct sockaddr_storage
*addr
;
558 if (len
!= sizeof(struct sockaddr_storage
))
561 if (cm
->addr_count
>= DLM_MAX_ADDR_COUNT
)
564 addr
= kzalloc(sizeof(*addr
), GFP_KERNEL
);
568 memcpy(addr
, buf
, len
);
569 cm
->addr
[cm
->addr_count
++] = addr
;
573 static ssize_t
show_node(struct config_item
*i
, struct configfs_attribute
*a
,
576 struct node
*nd
= to_node(i
);
577 struct node_attribute
*nda
=
578 container_of(a
, struct node_attribute
, attr
);
579 return nda
->show
? nda
->show(nd
, buf
) : 0;
582 static ssize_t
store_node(struct config_item
*i
, struct configfs_attribute
*a
,
583 const char *buf
, size_t len
)
585 struct node
*nd
= to_node(i
);
586 struct node_attribute
*nda
=
587 container_of(a
, struct node_attribute
, attr
);
588 return nda
->store
? nda
->store(nd
, buf
, len
) : -EINVAL
;
591 static ssize_t
node_nodeid_read(struct node
*nd
, char *buf
)
593 return sprintf(buf
, "%d\n", nd
->nodeid
);
596 static ssize_t
node_nodeid_write(struct node
*nd
, const char *buf
, size_t len
)
598 nd
->nodeid
= simple_strtol(buf
, NULL
, 0);
602 static ssize_t
node_weight_read(struct node
*nd
, char *buf
)
604 return sprintf(buf
, "%d\n", nd
->weight
);
607 static ssize_t
node_weight_write(struct node
*nd
, const char *buf
, size_t len
)
609 nd
->weight
= simple_strtol(buf
, NULL
, 0);
614 * Functions for the dlm to get the info that's been configured
617 static struct space
*get_space(char *name
)
621 return to_space(config_group_find_obj(space_list
, name
));
624 static void put_space(struct space
*sp
)
626 config_item_put(&sp
->group
.cg_item
);
629 static struct comm
*get_comm(int nodeid
, struct sockaddr_storage
*addr
)
631 struct config_item
*i
;
632 struct comm
*cm
= NULL
;
638 down(&clusters_root
.subsys
.su_sem
);
640 list_for_each_entry(i
, &comm_list
->cg_children
, ci_entry
) {
644 if (cm
->nodeid
!= nodeid
)
649 if (!cm
->addr_count
||
650 memcmp(cm
->addr
[0], addr
, sizeof(*addr
)))
656 up(&clusters_root
.subsys
.su_sem
);
665 static void put_comm(struct comm
*cm
)
667 config_item_put(&cm
->item
);
670 /* caller must free mem */
671 int dlm_nodeid_list(char *lsname
, int **ids_out
)
678 sp
= get_space(lsname
);
682 mutex_lock(&sp
->members_lock
);
683 if (!sp
->members_count
) {
688 ids
= kcalloc(sp
->members_count
, sizeof(int), GFP_KERNEL
);
694 rv
= sp
->members_count
;
695 list_for_each_entry(nd
, &sp
->members
, list
)
696 ids
[i
++] = nd
->nodeid
;
699 printk("bad nodeid count %d %d\n", rv
, i
);
703 mutex_unlock(&sp
->members_lock
);
708 int dlm_node_weight(char *lsname
, int nodeid
)
714 sp
= get_space(lsname
);
718 mutex_lock(&sp
->members_lock
);
719 list_for_each_entry(nd
, &sp
->members
, list
) {
720 if (nd
->nodeid
!= nodeid
)
725 mutex_unlock(&sp
->members_lock
);
731 int dlm_nodeid_to_addr(int nodeid
, struct sockaddr_storage
*addr
)
733 struct comm
*cm
= get_comm(nodeid
, NULL
);
738 memcpy(addr
, cm
->addr
[0], sizeof(*addr
));
743 int dlm_addr_to_nodeid(struct sockaddr_storage
*addr
, int *nodeid
)
745 struct comm
*cm
= get_comm(0, addr
);
748 *nodeid
= cm
->nodeid
;
753 int dlm_our_nodeid(void)
755 return local_comm
? local_comm
->nodeid
: 0;
758 /* num 0 is first addr, num 1 is second addr */
759 int dlm_our_addr(struct sockaddr_storage
*addr
, int num
)
763 if (num
+ 1 > local_comm
->addr_count
)
765 memcpy(addr
, local_comm
->addr
[num
], sizeof(*addr
));
769 /* Config file defaults */
770 #define DEFAULT_TCP_PORT 21064
771 #define DEFAULT_BUFFER_SIZE 4096
772 #define DEFAULT_RSBTBL_SIZE 256
773 #define DEFAULT_LKBTBL_SIZE 1024
774 #define DEFAULT_DIRTBL_SIZE 512
775 #define DEFAULT_RECOVER_TIMER 5
776 #define DEFAULT_TOSS_SECS 10
777 #define DEFAULT_SCAN_SECS 5
779 struct dlm_config_info dlm_config
= {
780 .tcp_port
= DEFAULT_TCP_PORT
,
781 .buffer_size
= DEFAULT_BUFFER_SIZE
,
782 .rsbtbl_size
= DEFAULT_RSBTBL_SIZE
,
783 .lkbtbl_size
= DEFAULT_LKBTBL_SIZE
,
784 .dirtbl_size
= DEFAULT_DIRTBL_SIZE
,
785 .recover_timer
= DEFAULT_RECOVER_TIMER
,
786 .toss_secs
= DEFAULT_TOSS_SECS
,
787 .scan_secs
= DEFAULT_SCAN_SECS