Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/dlm/config.c
15109 views
1
/******************************************************************************
2
*******************************************************************************
3
**
4
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5
** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
6
**
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.
10
**
11
*******************************************************************************
12
******************************************************************************/
13
14
#include <linux/kernel.h>
15
#include <linux/module.h>
16
#include <linux/configfs.h>
17
#include <linux/slab.h>
18
#include <linux/in.h>
19
#include <linux/in6.h>
20
#include <net/ipv6.h>
21
#include <net/sock.h>
22
23
#include "config.h"
24
#include "lowcomms.h"
25
26
/*
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.
33
*/
34
35
static struct config_group *space_list;
36
static struct config_group *comm_list;
37
static struct dlm_comm *local_comm;
38
39
struct dlm_clusters;
40
struct dlm_cluster;
41
struct dlm_spaces;
42
struct dlm_space;
43
struct dlm_comms;
44
struct dlm_comm;
45
struct dlm_nodes;
46
struct dlm_node;
47
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 *);
60
61
static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
62
char *buf);
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,
67
char *buf);
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,
71
char *buf);
72
static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
73
const char *buf, size_t len);
74
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,
77
size_t len);
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,
80
size_t len);
81
static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf,
82
size_t len);
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,
85
size_t len);
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,
88
size_t len);
89
90
struct dlm_cluster {
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;
104
};
105
106
enum {
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,
119
};
120
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);
125
};
126
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)
130
{
131
unsigned int x;
132
133
if (!capable(CAP_SYS_ADMIN))
134
return -EACCES;
135
136
x = simple_strtoul(buf, NULL, 0);
137
138
if (check_zero && !x)
139
return -EINVAL;
140
141
*cl_field = x;
142
*info_field = x;
143
144
return len;
145
}
146
147
#define CLUSTER_ATTR(name, check_zero) \
148
static ssize_t name##_write(struct dlm_cluster *cl, const char *buf, size_t len) \
149
{ \
150
return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name, \
151
check_zero, buf, len); \
152
} \
153
static ssize_t name##_read(struct dlm_cluster *cl, char *buf) \
154
{ \
155
return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name); \
156
} \
157
static struct cluster_attribute cluster_attr_##name = \
158
__CONFIGFS_ATTR(name, 0644, name##_read, name##_write)
159
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);
172
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,
186
NULL,
187
};
188
189
enum {
190
COMM_ATTR_NODEID = 0,
191
COMM_ATTR_LOCAL,
192
COMM_ATTR_ADDR,
193
};
194
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);
199
};
200
201
static struct comm_attribute comm_attr_nodeid = {
202
.attr = { .ca_owner = THIS_MODULE,
203
.ca_name = "nodeid",
204
.ca_mode = S_IRUGO | S_IWUSR },
205
.show = comm_nodeid_read,
206
.store = comm_nodeid_write,
207
};
208
209
static struct comm_attribute comm_attr_local = {
210
.attr = { .ca_owner = THIS_MODULE,
211
.ca_name = "local",
212
.ca_mode = S_IRUGO | S_IWUSR },
213
.show = comm_local_read,
214
.store = comm_local_write,
215
};
216
217
static struct comm_attribute comm_attr_addr = {
218
.attr = { .ca_owner = THIS_MODULE,
219
.ca_name = "addr",
220
.ca_mode = S_IRUGO | S_IWUSR },
221
.store = comm_addr_write,
222
};
223
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,
228
NULL,
229
};
230
231
enum {
232
NODE_ATTR_NODEID = 0,
233
NODE_ATTR_WEIGHT,
234
};
235
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);
240
};
241
242
static struct node_attribute node_attr_nodeid = {
243
.attr = { .ca_owner = THIS_MODULE,
244
.ca_name = "nodeid",
245
.ca_mode = S_IRUGO | S_IWUSR },
246
.show = node_nodeid_read,
247
.store = node_nodeid_write,
248
};
249
250
static struct node_attribute node_attr_weight = {
251
.attr = { .ca_owner = THIS_MODULE,
252
.ca_name = "weight",
253
.ca_mode = S_IRUGO | S_IWUSR },
254
.show = node_weight_read,
255
.store = node_weight_write,
256
};
257
258
static struct configfs_attribute *node_attrs[] = {
259
[NODE_ATTR_NODEID] = &node_attr_nodeid.attr,
260
[NODE_ATTR_WEIGHT] = &node_attr_weight.attr,
261
NULL,
262
};
263
264
struct dlm_clusters {
265
struct configfs_subsystem subsys;
266
};
267
268
struct dlm_spaces {
269
struct config_group ss_group;
270
};
271
272
struct dlm_space {
273
struct config_group group;
274
struct list_head members;
275
struct mutex members_lock;
276
int members_count;
277
};
278
279
struct dlm_comms {
280
struct config_group cs_group;
281
};
282
283
struct dlm_comm {
284
struct config_item item;
285
int nodeid;
286
int local;
287
int addr_count;
288
struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT];
289
};
290
291
struct dlm_nodes {
292
struct config_group ns_group;
293
};
294
295
struct dlm_node {
296
struct config_item item;
297
struct list_head list; /* space->members */
298
int nodeid;
299
int weight;
300
int new;
301
};
302
303
static struct configfs_group_operations clusters_ops = {
304
.make_group = make_cluster,
305
.drop_item = drop_cluster,
306
};
307
308
static struct configfs_item_operations cluster_ops = {
309
.release = release_cluster,
310
.show_attribute = show_cluster,
311
.store_attribute = store_cluster,
312
};
313
314
static struct configfs_group_operations spaces_ops = {
315
.make_group = make_space,
316
.drop_item = drop_space,
317
};
318
319
static struct configfs_item_operations space_ops = {
320
.release = release_space,
321
};
322
323
static struct configfs_group_operations comms_ops = {
324
.make_item = make_comm,
325
.drop_item = drop_comm,
326
};
327
328
static struct configfs_item_operations comm_ops = {
329
.release = release_comm,
330
.show_attribute = show_comm,
331
.store_attribute = store_comm,
332
};
333
334
static struct configfs_group_operations nodes_ops = {
335
.make_item = make_node,
336
.drop_item = drop_node,
337
};
338
339
static struct configfs_item_operations node_ops = {
340
.release = release_node,
341
.show_attribute = show_node,
342
.store_attribute = store_node,
343
};
344
345
static struct config_item_type clusters_type = {
346
.ct_group_ops = &clusters_ops,
347
.ct_owner = THIS_MODULE,
348
};
349
350
static struct config_item_type cluster_type = {
351
.ct_item_ops = &cluster_ops,
352
.ct_attrs = cluster_attrs,
353
.ct_owner = THIS_MODULE,
354
};
355
356
static struct config_item_type spaces_type = {
357
.ct_group_ops = &spaces_ops,
358
.ct_owner = THIS_MODULE,
359
};
360
361
static struct config_item_type space_type = {
362
.ct_item_ops = &space_ops,
363
.ct_owner = THIS_MODULE,
364
};
365
366
static struct config_item_type comms_type = {
367
.ct_group_ops = &comms_ops,
368
.ct_owner = THIS_MODULE,
369
};
370
371
static struct config_item_type comm_type = {
372
.ct_item_ops = &comm_ops,
373
.ct_attrs = comm_attrs,
374
.ct_owner = THIS_MODULE,
375
};
376
377
static struct config_item_type nodes_type = {
378
.ct_group_ops = &nodes_ops,
379
.ct_owner = THIS_MODULE,
380
};
381
382
static struct config_item_type node_type = {
383
.ct_item_ops = &node_ops,
384
.ct_attrs = node_attrs,
385
.ct_owner = THIS_MODULE,
386
};
387
388
static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
389
{
390
return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
391
NULL;
392
}
393
394
static struct dlm_space *config_item_to_space(struct config_item *i)
395
{
396
return i ? container_of(to_config_group(i), struct dlm_space, group) :
397
NULL;
398
}
399
400
static struct dlm_comm *config_item_to_comm(struct config_item *i)
401
{
402
return i ? container_of(i, struct dlm_comm, item) : NULL;
403
}
404
405
static struct dlm_node *config_item_to_node(struct config_item *i)
406
{
407
return i ? container_of(i, struct dlm_node, item) : NULL;
408
}
409
410
static struct config_group *make_cluster(struct config_group *g,
411
const char *name)
412
{
413
struct dlm_cluster *cl = NULL;
414
struct dlm_spaces *sps = NULL;
415
struct dlm_comms *cms = NULL;
416
void *gps = NULL;
417
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);
422
423
if (!cl || !gps || !sps || !cms)
424
goto fail;
425
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);
429
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;
434
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;
447
448
space_list = &sps->ss_group;
449
comm_list = &cms->cs_group;
450
return &cl->group;
451
452
fail:
453
kfree(cl);
454
kfree(gps);
455
kfree(sps);
456
kfree(cms);
457
return ERR_PTR(-ENOMEM);
458
}
459
460
static void drop_cluster(struct config_group *g, struct config_item *i)
461
{
462
struct dlm_cluster *cl = config_item_to_cluster(i);
463
struct config_item *tmp;
464
int j;
465
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);
470
}
471
472
space_list = NULL;
473
comm_list = NULL;
474
475
config_item_put(i);
476
}
477
478
static void release_cluster(struct config_item *i)
479
{
480
struct dlm_cluster *cl = config_item_to_cluster(i);
481
kfree(cl->group.default_groups);
482
kfree(cl);
483
}
484
485
static struct config_group *make_space(struct config_group *g, const char *name)
486
{
487
struct dlm_space *sp = NULL;
488
struct dlm_nodes *nds = NULL;
489
void *gps = NULL;
490
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);
494
495
if (!sp || !gps || !nds)
496
goto fail;
497
498
config_group_init_type_name(&sp->group, name, &space_type);
499
config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type);
500
501
sp->group.default_groups = gps;
502
sp->group.default_groups[0] = &nds->ns_group;
503
sp->group.default_groups[1] = NULL;
504
505
INIT_LIST_HEAD(&sp->members);
506
mutex_init(&sp->members_lock);
507
sp->members_count = 0;
508
return &sp->group;
509
510
fail:
511
kfree(sp);
512
kfree(gps);
513
kfree(nds);
514
return ERR_PTR(-ENOMEM);
515
}
516
517
static void drop_space(struct config_group *g, struct config_item *i)
518
{
519
struct dlm_space *sp = config_item_to_space(i);
520
struct config_item *tmp;
521
int j;
522
523
/* assert list_empty(&sp->members) */
524
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);
529
}
530
531
config_item_put(i);
532
}
533
534
static void release_space(struct config_item *i)
535
{
536
struct dlm_space *sp = config_item_to_space(i);
537
kfree(sp->group.default_groups);
538
kfree(sp);
539
}
540
541
static struct config_item *make_comm(struct config_group *g, const char *name)
542
{
543
struct dlm_comm *cm;
544
545
cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS);
546
if (!cm)
547
return ERR_PTR(-ENOMEM);
548
549
config_item_init_type_name(&cm->item, name, &comm_type);
550
cm->nodeid = -1;
551
cm->local = 0;
552
cm->addr_count = 0;
553
return &cm->item;
554
}
555
556
static void drop_comm(struct config_group *g, struct config_item *i)
557
{
558
struct dlm_comm *cm = config_item_to_comm(i);
559
if (local_comm == cm)
560
local_comm = NULL;
561
dlm_lowcomms_close(cm->nodeid);
562
while (cm->addr_count--)
563
kfree(cm->addr[cm->addr_count]);
564
config_item_put(i);
565
}
566
567
static void release_comm(struct config_item *i)
568
{
569
struct dlm_comm *cm = config_item_to_comm(i);
570
kfree(cm);
571
}
572
573
static struct config_item *make_node(struct config_group *g, const char *name)
574
{
575
struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
576
struct dlm_node *nd;
577
578
nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS);
579
if (!nd)
580
return ERR_PTR(-ENOMEM);
581
582
config_item_init_type_name(&nd->item, name, &node_type);
583
nd->nodeid = -1;
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() */
586
587
mutex_lock(&sp->members_lock);
588
list_add(&nd->list, &sp->members);
589
sp->members_count++;
590
mutex_unlock(&sp->members_lock);
591
592
return &nd->item;
593
}
594
595
static void drop_node(struct config_group *g, struct config_item *i)
596
{
597
struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
598
struct dlm_node *nd = config_item_to_node(i);
599
600
mutex_lock(&sp->members_lock);
601
list_del(&nd->list);
602
sp->members_count--;
603
mutex_unlock(&sp->members_lock);
604
605
config_item_put(i);
606
}
607
608
static void release_node(struct config_item *i)
609
{
610
struct dlm_node *nd = config_item_to_node(i);
611
kfree(nd);
612
}
613
614
static struct dlm_clusters clusters_root = {
615
.subsys = {
616
.su_group = {
617
.cg_item = {
618
.ci_namebuf = "dlm",
619
.ci_type = &clusters_type,
620
},
621
},
622
},
623
};
624
625
int __init dlm_config_init(void)
626
{
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);
630
}
631
632
void dlm_config_exit(void)
633
{
634
configfs_unregister_subsystem(&clusters_root.subsys);
635
}
636
637
/*
638
* Functions for user space to read/write attributes
639
*/
640
641
static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a,
642
char *buf)
643
{
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;
648
}
649
650
static ssize_t store_cluster(struct config_item *i,
651
struct configfs_attribute *a,
652
const char *buf, size_t len)
653
{
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;
658
}
659
660
static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a,
661
char *buf)
662
{
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;
667
}
668
669
static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a,
670
const char *buf, size_t len)
671
{
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;
676
}
677
678
static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf)
679
{
680
return sprintf(buf, "%d\n", cm->nodeid);
681
}
682
683
static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
684
size_t len)
685
{
686
cm->nodeid = simple_strtol(buf, NULL, 0);
687
return len;
688
}
689
690
static ssize_t comm_local_read(struct dlm_comm *cm, char *buf)
691
{
692
return sprintf(buf, "%d\n", cm->local);
693
}
694
695
static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
696
size_t len)
697
{
698
cm->local= simple_strtol(buf, NULL, 0);
699
if (cm->local && !local_comm)
700
local_comm = cm;
701
return len;
702
}
703
704
static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
705
{
706
struct sockaddr_storage *addr;
707
708
if (len != sizeof(struct sockaddr_storage))
709
return -EINVAL;
710
711
if (cm->addr_count >= DLM_MAX_ADDR_COUNT)
712
return -ENOSPC;
713
714
addr = kzalloc(sizeof(*addr), GFP_NOFS);
715
if (!addr)
716
return -ENOMEM;
717
718
memcpy(addr, buf, len);
719
cm->addr[cm->addr_count++] = addr;
720
return len;
721
}
722
723
static ssize_t show_node(struct config_item *i, struct configfs_attribute *a,
724
char *buf)
725
{
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;
730
}
731
732
static ssize_t store_node(struct config_item *i, struct configfs_attribute *a,
733
const char *buf, size_t len)
734
{
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;
739
}
740
741
static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf)
742
{
743
return sprintf(buf, "%d\n", nd->nodeid);
744
}
745
746
static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
747
size_t len)
748
{
749
nd->nodeid = simple_strtol(buf, NULL, 0);
750
return len;
751
}
752
753
static ssize_t node_weight_read(struct dlm_node *nd, char *buf)
754
{
755
return sprintf(buf, "%d\n", nd->weight);
756
}
757
758
static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
759
size_t len)
760
{
761
nd->weight = simple_strtol(buf, NULL, 0);
762
return len;
763
}
764
765
/*
766
* Functions for the dlm to get the info that's been configured
767
*/
768
769
static struct dlm_space *get_space(char *name)
770
{
771
struct config_item *i;
772
773
if (!space_list)
774
return NULL;
775
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);
779
780
return config_item_to_space(i);
781
}
782
783
static void put_space(struct dlm_space *sp)
784
{
785
config_item_put(&sp->group.cg_item);
786
}
787
788
static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y)
789
{
790
switch (x->ss_family) {
791
case AF_INET: {
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)
795
return 0;
796
if (sinx->sin_port != siny->sin_port)
797
return 0;
798
break;
799
}
800
case AF_INET6: {
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))
804
return 0;
805
if (sinx->sin6_port != siny->sin6_port)
806
return 0;
807
break;
808
}
809
default:
810
return 0;
811
}
812
return 1;
813
}
814
815
static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr)
816
{
817
struct config_item *i;
818
struct dlm_comm *cm = NULL;
819
int found = 0;
820
821
if (!comm_list)
822
return NULL;
823
824
mutex_lock(&clusters_root.subsys.su_mutex);
825
826
list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
827
cm = config_item_to_comm(i);
828
829
if (nodeid) {
830
if (cm->nodeid != nodeid)
831
continue;
832
found = 1;
833
config_item_get(i);
834
break;
835
} else {
836
if (!cm->addr_count || !addr_compare(cm->addr[0], addr))
837
continue;
838
found = 1;
839
config_item_get(i);
840
break;
841
}
842
}
843
mutex_unlock(&clusters_root.subsys.su_mutex);
844
845
if (!found)
846
cm = NULL;
847
return cm;
848
}
849
850
static void put_comm(struct dlm_comm *cm)
851
{
852
config_item_put(&cm->item);
853
}
854
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)
858
{
859
struct dlm_space *sp;
860
struct dlm_node *nd;
861
int i = 0, rv = 0, ids_count = 0, new_count = 0;
862
int *ids, *new;
863
864
sp = get_space(lsname);
865
if (!sp)
866
return -EEXIST;
867
868
mutex_lock(&sp->members_lock);
869
if (!sp->members_count) {
870
rv = -EINVAL;
871
printk(KERN_ERR "dlm: zero members_count\n");
872
goto out;
873
}
874
875
ids_count = sp->members_count;
876
877
ids = kcalloc(ids_count, sizeof(int), GFP_NOFS);
878
if (!ids) {
879
rv = -ENOMEM;
880
goto out;
881
}
882
883
list_for_each_entry(nd, &sp->members, list) {
884
ids[i++] = nd->nodeid;
885
if (nd->new)
886
new_count++;
887
}
888
889
if (ids_count != i)
890
printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
891
892
if (!new_count)
893
goto out_ids;
894
895
new = kcalloc(new_count, sizeof(int), GFP_NOFS);
896
if (!new) {
897
kfree(ids);
898
rv = -ENOMEM;
899
goto out;
900
}
901
902
i = 0;
903
list_for_each_entry(nd, &sp->members, list) {
904
if (nd->new) {
905
new[i++] = nd->nodeid;
906
nd->new = 0;
907
}
908
}
909
*new_count_out = new_count;
910
*new_out = new;
911
912
out_ids:
913
*ids_count_out = ids_count;
914
*ids_out = ids;
915
out:
916
mutex_unlock(&sp->members_lock);
917
put_space(sp);
918
return rv;
919
}
920
921
int dlm_node_weight(char *lsname, int nodeid)
922
{
923
struct dlm_space *sp;
924
struct dlm_node *nd;
925
int w = -EEXIST;
926
927
sp = get_space(lsname);
928
if (!sp)
929
goto out;
930
931
mutex_lock(&sp->members_lock);
932
list_for_each_entry(nd, &sp->members, list) {
933
if (nd->nodeid != nodeid)
934
continue;
935
w = nd->weight;
936
break;
937
}
938
mutex_unlock(&sp->members_lock);
939
put_space(sp);
940
out:
941
return w;
942
}
943
944
int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr)
945
{
946
struct dlm_comm *cm = get_comm(nodeid, NULL);
947
if (!cm)
948
return -EEXIST;
949
if (!cm->addr_count)
950
return -ENOENT;
951
memcpy(addr, cm->addr[0], sizeof(*addr));
952
put_comm(cm);
953
return 0;
954
}
955
956
int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid)
957
{
958
struct dlm_comm *cm = get_comm(0, addr);
959
if (!cm)
960
return -EEXIST;
961
*nodeid = cm->nodeid;
962
put_comm(cm);
963
return 0;
964
}
965
966
int dlm_our_nodeid(void)
967
{
968
return local_comm ? local_comm->nodeid : 0;
969
}
970
971
/* num 0 is first addr, num 1 is second addr */
972
int dlm_our_addr(struct sockaddr_storage *addr, int num)
973
{
974
if (!local_comm)
975
return -1;
976
if (num + 1 > local_comm->addr_count)
977
return -1;
978
memcpy(addr, local_comm->addr[num], sizeof(*addr));
979
return 0;
980
}
981
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
995
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
1009
};
1010
1011
1012