1 /****************************************************************************** 2 ******************************************************************************* 3 ** 4 ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 5 ** Copyright (C) 2004-2011 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 <linux/dlmconstants.h> 21 #include <net/ipv6.h> 22 #include <net/sock.h> 23 24 #include "config.h" 25 #include "lowcomms.h" 26 27 /* 28 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid 29 * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight 30 * /config/dlm/<cluster>/comms/<comm>/nodeid 31 * /config/dlm/<cluster>/comms/<comm>/local 32 * /config/dlm/<cluster>/comms/<comm>/addr (write only) 33 * /config/dlm/<cluster>/comms/<comm>/addr_list (read only) 34 * The <cluster> level is useless, but I haven't figured out how to avoid it. 35 */ 36 37 static struct config_group *space_list; 38 static struct config_group *comm_list; 39 static struct dlm_comm *local_comm; 40 static uint32_t dlm_comm_count; 41 42 struct dlm_clusters; 43 struct dlm_cluster; 44 struct dlm_spaces; 45 struct dlm_space; 46 struct dlm_comms; 47 struct dlm_comm; 48 struct dlm_nodes; 49 struct dlm_node; 50 51 static struct config_group *make_cluster(struct config_group *, const char *); 52 static void drop_cluster(struct config_group *, struct config_item *); 53 static void release_cluster(struct config_item *); 54 static struct config_group *make_space(struct config_group *, const char *); 55 static void drop_space(struct config_group *, struct config_item *); 56 static void release_space(struct config_item *); 57 static struct config_item *make_comm(struct config_group *, const char *); 58 static void drop_comm(struct config_group *, struct config_item *); 59 static void release_comm(struct config_item *); 60 static struct config_item *make_node(struct config_group *, const char *); 61 static void drop_node(struct config_group *, struct config_item *); 62 static void release_node(struct config_item *); 63 64 static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a, 65 char *buf); 66 static ssize_t store_cluster(struct config_item *i, 67 struct configfs_attribute *a, 68 const char *buf, size_t len); 69 static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a, 70 char *buf); 71 static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a, 72 const char *buf, size_t len); 73 static ssize_t show_node(struct config_item *i, struct configfs_attribute *a, 74 char *buf); 75 static ssize_t store_node(struct config_item *i, struct configfs_attribute *a, 76 const char *buf, size_t len); 77 78 static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf); 79 static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf, 80 size_t len); 81 static ssize_t comm_local_read(struct dlm_comm *cm, char *buf); 82 static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf, 83 size_t len); 84 static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, 85 size_t len); 86 static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf); 87 static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf); 88 static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf, 89 size_t len); 90 static ssize_t node_weight_read(struct dlm_node *nd, char *buf); 91 static ssize_t node_weight_write(struct dlm_node *nd, const char *buf, 92 size_t len); 93 94 struct dlm_cluster { 95 struct config_group group; 96 unsigned int cl_tcp_port; 97 unsigned int cl_buffer_size; 98 unsigned int cl_rsbtbl_size; 99 unsigned int cl_recover_timer; 100 unsigned int cl_toss_secs; 101 unsigned int cl_scan_secs; 102 unsigned int cl_log_debug; 103 unsigned int cl_protocol; 104 unsigned int cl_timewarn_cs; 105 unsigned int cl_waitwarn_us; 106 unsigned int cl_new_rsb_count; 107 unsigned int cl_recover_callbacks; 108 char cl_cluster_name[DLM_LOCKSPACE_LEN]; 109 }; 110 111 enum { 112 CLUSTER_ATTR_TCP_PORT = 0, 113 CLUSTER_ATTR_BUFFER_SIZE, 114 CLUSTER_ATTR_RSBTBL_SIZE, 115 CLUSTER_ATTR_RECOVER_TIMER, 116 CLUSTER_ATTR_TOSS_SECS, 117 CLUSTER_ATTR_SCAN_SECS, 118 CLUSTER_ATTR_LOG_DEBUG, 119 CLUSTER_ATTR_PROTOCOL, 120 CLUSTER_ATTR_TIMEWARN_CS, 121 CLUSTER_ATTR_WAITWARN_US, 122 CLUSTER_ATTR_NEW_RSB_COUNT, 123 CLUSTER_ATTR_RECOVER_CALLBACKS, 124 CLUSTER_ATTR_CLUSTER_NAME, 125 }; 126 127 struct cluster_attribute { 128 struct configfs_attribute attr; 129 ssize_t (*show)(struct dlm_cluster *, char *); 130 ssize_t (*store)(struct dlm_cluster *, const char *, size_t); 131 }; 132 133 static ssize_t cluster_cluster_name_read(struct dlm_cluster *cl, char *buf) 134 { 135 return sprintf(buf, "%s\n", cl->cl_cluster_name); 136 } 137 138 static ssize_t cluster_cluster_name_write(struct dlm_cluster *cl, 139 const char *buf, size_t len) 140 { 141 strlcpy(dlm_config.ci_cluster_name, buf, 142 sizeof(dlm_config.ci_cluster_name)); 143 strlcpy(cl->cl_cluster_name, buf, sizeof(cl->cl_cluster_name)); 144 return len; 145 } 146 147 static struct cluster_attribute cluster_attr_cluster_name = { 148 .attr = { .ca_owner = THIS_MODULE, 149 .ca_name = "cluster_name", 150 .ca_mode = S_IRUGO | S_IWUSR }, 151 .show = cluster_cluster_name_read, 152 .store = cluster_cluster_name_write, 153 }; 154 155 static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field, 156 int *info_field, int check_zero, 157 const char *buf, size_t len) 158 { 159 unsigned int x; 160 161 if (!capable(CAP_SYS_ADMIN)) 162 return -EPERM; 163 164 x = simple_strtoul(buf, NULL, 0); 165 166 if (check_zero && !x) 167 return -EINVAL; 168 169 *cl_field = x; 170 *info_field = x; 171 172 return len; 173 } 174 175 #define CLUSTER_ATTR(name, check_zero) \ 176 static ssize_t name##_write(struct dlm_cluster *cl, const char *buf, size_t len) \ 177 { \ 178 return cluster_set(cl, &cl->cl_##name, &dlm_config.ci_##name, \ 179 check_zero, buf, len); \ 180 } \ 181 static ssize_t name##_read(struct dlm_cluster *cl, char *buf) \ 182 { \ 183 return snprintf(buf, PAGE_SIZE, "%u\n", cl->cl_##name); \ 184 } \ 185 static struct cluster_attribute cluster_attr_##name = \ 186 __CONFIGFS_ATTR(name, 0644, name##_read, name##_write) 187 188 CLUSTER_ATTR(tcp_port, 1); 189 CLUSTER_ATTR(buffer_size, 1); 190 CLUSTER_ATTR(rsbtbl_size, 1); 191 CLUSTER_ATTR(recover_timer, 1); 192 CLUSTER_ATTR(toss_secs, 1); 193 CLUSTER_ATTR(scan_secs, 1); 194 CLUSTER_ATTR(log_debug, 0); 195 CLUSTER_ATTR(protocol, 0); 196 CLUSTER_ATTR(timewarn_cs, 1); 197 CLUSTER_ATTR(waitwarn_us, 0); 198 CLUSTER_ATTR(new_rsb_count, 0); 199 CLUSTER_ATTR(recover_callbacks, 0); 200 201 static struct configfs_attribute *cluster_attrs[] = { 202 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, 203 [CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size.attr, 204 [CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size.attr, 205 [CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer.attr, 206 [CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr, 207 [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr, 208 [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, 209 [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, 210 [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, 211 [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr, 212 [CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count.attr, 213 [CLUSTER_ATTR_RECOVER_CALLBACKS] = &cluster_attr_recover_callbacks.attr, 214 [CLUSTER_ATTR_CLUSTER_NAME] = &cluster_attr_cluster_name.attr, 215 NULL, 216 }; 217 218 enum { 219 COMM_ATTR_NODEID = 0, 220 COMM_ATTR_LOCAL, 221 COMM_ATTR_ADDR, 222 COMM_ATTR_ADDR_LIST, 223 }; 224 225 struct comm_attribute { 226 struct configfs_attribute attr; 227 ssize_t (*show)(struct dlm_comm *, char *); 228 ssize_t (*store)(struct dlm_comm *, const char *, size_t); 229 }; 230 231 static struct comm_attribute comm_attr_nodeid = { 232 .attr = { .ca_owner = THIS_MODULE, 233 .ca_name = "nodeid", 234 .ca_mode = S_IRUGO | S_IWUSR }, 235 .show = comm_nodeid_read, 236 .store = comm_nodeid_write, 237 }; 238 239 static struct comm_attribute comm_attr_local = { 240 .attr = { .ca_owner = THIS_MODULE, 241 .ca_name = "local", 242 .ca_mode = S_IRUGO | S_IWUSR }, 243 .show = comm_local_read, 244 .store = comm_local_write, 245 }; 246 247 static struct comm_attribute comm_attr_addr = { 248 .attr = { .ca_owner = THIS_MODULE, 249 .ca_name = "addr", 250 .ca_mode = S_IWUSR }, 251 .store = comm_addr_write, 252 }; 253 254 static struct comm_attribute comm_attr_addr_list = { 255 .attr = { .ca_owner = THIS_MODULE, 256 .ca_name = "addr_list", 257 .ca_mode = S_IRUGO }, 258 .show = comm_addr_list_read, 259 }; 260 261 static struct configfs_attribute *comm_attrs[] = { 262 [COMM_ATTR_NODEID] = &comm_attr_nodeid.attr, 263 [COMM_ATTR_LOCAL] = &comm_attr_local.attr, 264 [COMM_ATTR_ADDR] = &comm_attr_addr.attr, 265 [COMM_ATTR_ADDR_LIST] = &comm_attr_addr_list.attr, 266 NULL, 267 }; 268 269 enum { 270 NODE_ATTR_NODEID = 0, 271 NODE_ATTR_WEIGHT, 272 }; 273 274 struct node_attribute { 275 struct configfs_attribute attr; 276 ssize_t (*show)(struct dlm_node *, char *); 277 ssize_t (*store)(struct dlm_node *, const char *, size_t); 278 }; 279 280 static struct node_attribute node_attr_nodeid = { 281 .attr = { .ca_owner = THIS_MODULE, 282 .ca_name = "nodeid", 283 .ca_mode = S_IRUGO | S_IWUSR }, 284 .show = node_nodeid_read, 285 .store = node_nodeid_write, 286 }; 287 288 static struct node_attribute node_attr_weight = { 289 .attr = { .ca_owner = THIS_MODULE, 290 .ca_name = "weight", 291 .ca_mode = S_IRUGO | S_IWUSR }, 292 .show = node_weight_read, 293 .store = node_weight_write, 294 }; 295 296 static struct configfs_attribute *node_attrs[] = { 297 [NODE_ATTR_NODEID] = &node_attr_nodeid.attr, 298 [NODE_ATTR_WEIGHT] = &node_attr_weight.attr, 299 NULL, 300 }; 301 302 struct dlm_clusters { 303 struct configfs_subsystem subsys; 304 }; 305 306 struct dlm_spaces { 307 struct config_group ss_group; 308 }; 309 310 struct dlm_space { 311 struct config_group group; 312 struct list_head members; 313 struct mutex members_lock; 314 int members_count; 315 }; 316 317 struct dlm_comms { 318 struct config_group cs_group; 319 }; 320 321 struct dlm_comm { 322 struct config_item item; 323 int seq; 324 int nodeid; 325 int local; 326 int addr_count; 327 struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT]; 328 }; 329 330 struct dlm_nodes { 331 struct config_group ns_group; 332 }; 333 334 struct dlm_node { 335 struct config_item item; 336 struct list_head list; /* space->members */ 337 int nodeid; 338 int weight; 339 int new; 340 int comm_seq; /* copy of cm->seq when nd->nodeid is set */ 341 }; 342 343 static struct configfs_group_operations clusters_ops = { 344 .make_group = make_cluster, 345 .drop_item = drop_cluster, 346 }; 347 348 static struct configfs_item_operations cluster_ops = { 349 .release = release_cluster, 350 .show_attribute = show_cluster, 351 .store_attribute = store_cluster, 352 }; 353 354 static struct configfs_group_operations spaces_ops = { 355 .make_group = make_space, 356 .drop_item = drop_space, 357 }; 358 359 static struct configfs_item_operations space_ops = { 360 .release = release_space, 361 }; 362 363 static struct configfs_group_operations comms_ops = { 364 .make_item = make_comm, 365 .drop_item = drop_comm, 366 }; 367 368 static struct configfs_item_operations comm_ops = { 369 .release = release_comm, 370 .show_attribute = show_comm, 371 .store_attribute = store_comm, 372 }; 373 374 static struct configfs_group_operations nodes_ops = { 375 .make_item = make_node, 376 .drop_item = drop_node, 377 }; 378 379 static struct configfs_item_operations node_ops = { 380 .release = release_node, 381 .show_attribute = show_node, 382 .store_attribute = store_node, 383 }; 384 385 static struct config_item_type clusters_type = { 386 .ct_group_ops = &clusters_ops, 387 .ct_owner = THIS_MODULE, 388 }; 389 390 static struct config_item_type cluster_type = { 391 .ct_item_ops = &cluster_ops, 392 .ct_attrs = cluster_attrs, 393 .ct_owner = THIS_MODULE, 394 }; 395 396 static struct config_item_type spaces_type = { 397 .ct_group_ops = &spaces_ops, 398 .ct_owner = THIS_MODULE, 399 }; 400 401 static struct config_item_type space_type = { 402 .ct_item_ops = &space_ops, 403 .ct_owner = THIS_MODULE, 404 }; 405 406 static struct config_item_type comms_type = { 407 .ct_group_ops = &comms_ops, 408 .ct_owner = THIS_MODULE, 409 }; 410 411 static struct config_item_type comm_type = { 412 .ct_item_ops = &comm_ops, 413 .ct_attrs = comm_attrs, 414 .ct_owner = THIS_MODULE, 415 }; 416 417 static struct config_item_type nodes_type = { 418 .ct_group_ops = &nodes_ops, 419 .ct_owner = THIS_MODULE, 420 }; 421 422 static struct config_item_type node_type = { 423 .ct_item_ops = &node_ops, 424 .ct_attrs = node_attrs, 425 .ct_owner = THIS_MODULE, 426 }; 427 428 static struct dlm_cluster *config_item_to_cluster(struct config_item *i) 429 { 430 return i ? container_of(to_config_group(i), struct dlm_cluster, group) : 431 NULL; 432 } 433 434 static struct dlm_space *config_item_to_space(struct config_item *i) 435 { 436 return i ? container_of(to_config_group(i), struct dlm_space, group) : 437 NULL; 438 } 439 440 static struct dlm_comm *config_item_to_comm(struct config_item *i) 441 { 442 return i ? container_of(i, struct dlm_comm, item) : NULL; 443 } 444 445 static struct dlm_node *config_item_to_node(struct config_item *i) 446 { 447 return i ? container_of(i, struct dlm_node, item) : NULL; 448 } 449 450 static struct config_group *make_cluster(struct config_group *g, 451 const char *name) 452 { 453 struct dlm_cluster *cl = NULL; 454 struct dlm_spaces *sps = NULL; 455 struct dlm_comms *cms = NULL; 456 void *gps = NULL; 457 458 cl = kzalloc(sizeof(struct dlm_cluster), GFP_NOFS); 459 gps = kcalloc(3, sizeof(struct config_group *), GFP_NOFS); 460 sps = kzalloc(sizeof(struct dlm_spaces), GFP_NOFS); 461 cms = kzalloc(sizeof(struct dlm_comms), GFP_NOFS); 462 463 if (!cl || !gps || !sps || !cms) 464 goto fail; 465 466 config_group_init_type_name(&cl->group, name, &cluster_type); 467 config_group_init_type_name(&sps->ss_group, "spaces", &spaces_type); 468 config_group_init_type_name(&cms->cs_group, "comms", &comms_type); 469 470 cl->group.default_groups = gps; 471 cl->group.default_groups[0] = &sps->ss_group; 472 cl->group.default_groups[1] = &cms->cs_group; 473 cl->group.default_groups[2] = NULL; 474 475 cl->cl_tcp_port = dlm_config.ci_tcp_port; 476 cl->cl_buffer_size = dlm_config.ci_buffer_size; 477 cl->cl_rsbtbl_size = dlm_config.ci_rsbtbl_size; 478 cl->cl_recover_timer = dlm_config.ci_recover_timer; 479 cl->cl_toss_secs = dlm_config.ci_toss_secs; 480 cl->cl_scan_secs = dlm_config.ci_scan_secs; 481 cl->cl_log_debug = dlm_config.ci_log_debug; 482 cl->cl_protocol = dlm_config.ci_protocol; 483 cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; 484 cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us; 485 cl->cl_new_rsb_count = dlm_config.ci_new_rsb_count; 486 cl->cl_recover_callbacks = dlm_config.ci_recover_callbacks; 487 memcpy(cl->cl_cluster_name, dlm_config.ci_cluster_name, 488 DLM_LOCKSPACE_LEN); 489 490 space_list = &sps->ss_group; 491 comm_list = &cms->cs_group; 492 return &cl->group; 493 494 fail: 495 kfree(cl); 496 kfree(gps); 497 kfree(sps); 498 kfree(cms); 499 return ERR_PTR(-ENOMEM); 500 } 501 502 static void drop_cluster(struct config_group *g, struct config_item *i) 503 { 504 struct dlm_cluster *cl = config_item_to_cluster(i); 505 struct config_item *tmp; 506 int j; 507 508 for (j = 0; cl->group.default_groups[j]; j++) { 509 tmp = &cl->group.default_groups[j]->cg_item; 510 cl->group.default_groups[j] = NULL; 511 config_item_put(tmp); 512 } 513 514 space_list = NULL; 515 comm_list = NULL; 516 517 config_item_put(i); 518 } 519 520 static void release_cluster(struct config_item *i) 521 { 522 struct dlm_cluster *cl = config_item_to_cluster(i); 523 kfree(cl->group.default_groups); 524 kfree(cl); 525 } 526 527 static struct config_group *make_space(struct config_group *g, const char *name) 528 { 529 struct dlm_space *sp = NULL; 530 struct dlm_nodes *nds = NULL; 531 void *gps = NULL; 532 533 sp = kzalloc(sizeof(struct dlm_space), GFP_NOFS); 534 gps = kcalloc(2, sizeof(struct config_group *), GFP_NOFS); 535 nds = kzalloc(sizeof(struct dlm_nodes), GFP_NOFS); 536 537 if (!sp || !gps || !nds) 538 goto fail; 539 540 config_group_init_type_name(&sp->group, name, &space_type); 541 config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type); 542 543 sp->group.default_groups = gps; 544 sp->group.default_groups[0] = &nds->ns_group; 545 sp->group.default_groups[1] = NULL; 546 547 INIT_LIST_HEAD(&sp->members); 548 mutex_init(&sp->members_lock); 549 sp->members_count = 0; 550 return &sp->group; 551 552 fail: 553 kfree(sp); 554 kfree(gps); 555 kfree(nds); 556 return ERR_PTR(-ENOMEM); 557 } 558 559 static void drop_space(struct config_group *g, struct config_item *i) 560 { 561 struct dlm_space *sp = config_item_to_space(i); 562 struct config_item *tmp; 563 int j; 564 565 /* assert list_empty(&sp->members) */ 566 567 for (j = 0; sp->group.default_groups[j]; j++) { 568 tmp = &sp->group.default_groups[j]->cg_item; 569 sp->group.default_groups[j] = NULL; 570 config_item_put(tmp); 571 } 572 573 config_item_put(i); 574 } 575 576 static void release_space(struct config_item *i) 577 { 578 struct dlm_space *sp = config_item_to_space(i); 579 kfree(sp->group.default_groups); 580 kfree(sp); 581 } 582 583 static struct config_item *make_comm(struct config_group *g, const char *name) 584 { 585 struct dlm_comm *cm; 586 587 cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS); 588 if (!cm) 589 return ERR_PTR(-ENOMEM); 590 591 config_item_init_type_name(&cm->item, name, &comm_type); 592 593 cm->seq = dlm_comm_count++; 594 if (!cm->seq) 595 cm->seq = dlm_comm_count++; 596 597 cm->nodeid = -1; 598 cm->local = 0; 599 cm->addr_count = 0; 600 return &cm->item; 601 } 602 603 static void drop_comm(struct config_group *g, struct config_item *i) 604 { 605 struct dlm_comm *cm = config_item_to_comm(i); 606 if (local_comm == cm) 607 local_comm = NULL; 608 dlm_lowcomms_close(cm->nodeid); 609 while (cm->addr_count--) 610 kfree(cm->addr[cm->addr_count]); 611 config_item_put(i); 612 } 613 614 static void release_comm(struct config_item *i) 615 { 616 struct dlm_comm *cm = config_item_to_comm(i); 617 kfree(cm); 618 } 619 620 static struct config_item *make_node(struct config_group *g, const char *name) 621 { 622 struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent); 623 struct dlm_node *nd; 624 625 nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS); 626 if (!nd) 627 return ERR_PTR(-ENOMEM); 628 629 config_item_init_type_name(&nd->item, name, &node_type); 630 nd->nodeid = -1; 631 nd->weight = 1; /* default weight of 1 if none is set */ 632 nd->new = 1; /* set to 0 once it's been read by dlm_nodeid_list() */ 633 634 mutex_lock(&sp->members_lock); 635 list_add(&nd->list, &sp->members); 636 sp->members_count++; 637 mutex_unlock(&sp->members_lock); 638 639 return &nd->item; 640 } 641 642 static void drop_node(struct config_group *g, struct config_item *i) 643 { 644 struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent); 645 struct dlm_node *nd = config_item_to_node(i); 646 647 mutex_lock(&sp->members_lock); 648 list_del(&nd->list); 649 sp->members_count--; 650 mutex_unlock(&sp->members_lock); 651 652 config_item_put(i); 653 } 654 655 static void release_node(struct config_item *i) 656 { 657 struct dlm_node *nd = config_item_to_node(i); 658 kfree(nd); 659 } 660 661 static struct dlm_clusters clusters_root = { 662 .subsys = { 663 .su_group = { 664 .cg_item = { 665 .ci_namebuf = "dlm", 666 .ci_type = &clusters_type, 667 }, 668 }, 669 }, 670 }; 671 672 int __init dlm_config_init(void) 673 { 674 config_group_init(&clusters_root.subsys.su_group); 675 mutex_init(&clusters_root.subsys.su_mutex); 676 return configfs_register_subsystem(&clusters_root.subsys); 677 } 678 679 void dlm_config_exit(void) 680 { 681 configfs_unregister_subsystem(&clusters_root.subsys); 682 } 683 684 /* 685 * Functions for user space to read/write attributes 686 */ 687 688 static ssize_t show_cluster(struct config_item *i, struct configfs_attribute *a, 689 char *buf) 690 { 691 struct dlm_cluster *cl = config_item_to_cluster(i); 692 struct cluster_attribute *cla = 693 container_of(a, struct cluster_attribute, attr); 694 return cla->show ? cla->show(cl, buf) : 0; 695 } 696 697 static ssize_t store_cluster(struct config_item *i, 698 struct configfs_attribute *a, 699 const char *buf, size_t len) 700 { 701 struct dlm_cluster *cl = config_item_to_cluster(i); 702 struct cluster_attribute *cla = 703 container_of(a, struct cluster_attribute, attr); 704 return cla->store ? cla->store(cl, buf, len) : -EINVAL; 705 } 706 707 static ssize_t show_comm(struct config_item *i, struct configfs_attribute *a, 708 char *buf) 709 { 710 struct dlm_comm *cm = config_item_to_comm(i); 711 struct comm_attribute *cma = 712 container_of(a, struct comm_attribute, attr); 713 return cma->show ? cma->show(cm, buf) : 0; 714 } 715 716 static ssize_t store_comm(struct config_item *i, struct configfs_attribute *a, 717 const char *buf, size_t len) 718 { 719 struct dlm_comm *cm = config_item_to_comm(i); 720 struct comm_attribute *cma = 721 container_of(a, struct comm_attribute, attr); 722 return cma->store ? cma->store(cm, buf, len) : -EINVAL; 723 } 724 725 static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf) 726 { 727 return sprintf(buf, "%d\n", cm->nodeid); 728 } 729 730 static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf, 731 size_t len) 732 { 733 cm->nodeid = simple_strtol(buf, NULL, 0); 734 return len; 735 } 736 737 static ssize_t comm_local_read(struct dlm_comm *cm, char *buf) 738 { 739 return sprintf(buf, "%d\n", cm->local); 740 } 741 742 static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf, 743 size_t len) 744 { 745 cm->local= simple_strtol(buf, NULL, 0); 746 if (cm->local && !local_comm) 747 local_comm = cm; 748 return len; 749 } 750 751 static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len) 752 { 753 struct sockaddr_storage *addr; 754 int rv; 755 756 if (len != sizeof(struct sockaddr_storage)) 757 return -EINVAL; 758 759 if (cm->addr_count >= DLM_MAX_ADDR_COUNT) 760 return -ENOSPC; 761 762 addr = kzalloc(sizeof(*addr), GFP_NOFS); 763 if (!addr) 764 return -ENOMEM; 765 766 memcpy(addr, buf, len); 767 768 rv = dlm_lowcomms_addr(cm->nodeid, addr, len); 769 if (rv) { 770 kfree(addr); 771 return rv; 772 } 773 774 cm->addr[cm->addr_count++] = addr; 775 return len; 776 } 777 778 static ssize_t comm_addr_list_read(struct dlm_comm *cm, char *buf) 779 { 780 ssize_t s; 781 ssize_t allowance; 782 int i; 783 struct sockaddr_storage *addr; 784 struct sockaddr_in *addr_in; 785 struct sockaddr_in6 *addr_in6; 786 787 /* Taken from ip6_addr_string() defined in lib/vsprintf.c */ 788 char buf0[sizeof("AF_INET6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255\n")]; 789 790 791 /* Derived from SIMPLE_ATTR_SIZE of fs/configfs/file.c */ 792 allowance = 4096; 793 buf[0] = '\0'; 794 795 for (i = 0; i < cm->addr_count; i++) { 796 addr = cm->addr[i]; 797 798 switch(addr->ss_family) { 799 case AF_INET: 800 addr_in = (struct sockaddr_in *)addr; 801 s = sprintf(buf0, "AF_INET %pI4\n", &addr_in->sin_addr.s_addr); 802 break; 803 case AF_INET6: 804 addr_in6 = (struct sockaddr_in6 *)addr; 805 s = sprintf(buf0, "AF_INET6 %pI6\n", &addr_in6->sin6_addr); 806 break; 807 default: 808 s = sprintf(buf0, "%s\n", "<UNKNOWN>"); 809 break; 810 } 811 allowance -= s; 812 if (allowance >= 0) 813 strcat(buf, buf0); 814 else { 815 allowance += s; 816 break; 817 } 818 } 819 return 4096 - allowance; 820 } 821 822 static ssize_t show_node(struct config_item *i, struct configfs_attribute *a, 823 char *buf) 824 { 825 struct dlm_node *nd = config_item_to_node(i); 826 struct node_attribute *nda = 827 container_of(a, struct node_attribute, attr); 828 return nda->show ? nda->show(nd, buf) : 0; 829 } 830 831 static ssize_t store_node(struct config_item *i, struct configfs_attribute *a, 832 const char *buf, size_t len) 833 { 834 struct dlm_node *nd = config_item_to_node(i); 835 struct node_attribute *nda = 836 container_of(a, struct node_attribute, attr); 837 return nda->store ? nda->store(nd, buf, len) : -EINVAL; 838 } 839 840 static ssize_t node_nodeid_read(struct dlm_node *nd, char *buf) 841 { 842 return sprintf(buf, "%d\n", nd->nodeid); 843 } 844 845 static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf, 846 size_t len) 847 { 848 uint32_t seq = 0; 849 nd->nodeid = simple_strtol(buf, NULL, 0); 850 dlm_comm_seq(nd->nodeid, &seq); 851 nd->comm_seq = seq; 852 return len; 853 } 854 855 static ssize_t node_weight_read(struct dlm_node *nd, char *buf) 856 { 857 return sprintf(buf, "%d\n", nd->weight); 858 } 859 860 static ssize_t node_weight_write(struct dlm_node *nd, const char *buf, 861 size_t len) 862 { 863 nd->weight = simple_strtol(buf, NULL, 0); 864 return len; 865 } 866 867 /* 868 * Functions for the dlm to get the info that's been configured 869 */ 870 871 static struct dlm_space *get_space(char *name) 872 { 873 struct config_item *i; 874 875 if (!space_list) 876 return NULL; 877 878 mutex_lock(&space_list->cg_subsys->su_mutex); 879 i = config_group_find_item(space_list, name); 880 mutex_unlock(&space_list->cg_subsys->su_mutex); 881 882 return config_item_to_space(i); 883 } 884 885 static void put_space(struct dlm_space *sp) 886 { 887 config_item_put(&sp->group.cg_item); 888 } 889 890 static struct dlm_comm *get_comm(int nodeid) 891 { 892 struct config_item *i; 893 struct dlm_comm *cm = NULL; 894 int found = 0; 895 896 if (!comm_list) 897 return NULL; 898 899 mutex_lock(&clusters_root.subsys.su_mutex); 900 901 list_for_each_entry(i, &comm_list->cg_children, ci_entry) { 902 cm = config_item_to_comm(i); 903 904 if (cm->nodeid != nodeid) 905 continue; 906 found = 1; 907 config_item_get(i); 908 break; 909 } 910 mutex_unlock(&clusters_root.subsys.su_mutex); 911 912 if (!found) 913 cm = NULL; 914 return cm; 915 } 916 917 static void put_comm(struct dlm_comm *cm) 918 { 919 config_item_put(&cm->item); 920 } 921 922 /* caller must free mem */ 923 int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, 924 int *count_out) 925 { 926 struct dlm_space *sp; 927 struct dlm_node *nd; 928 struct dlm_config_node *nodes, *node; 929 int rv, count; 930 931 sp = get_space(lsname); 932 if (!sp) 933 return -EEXIST; 934 935 mutex_lock(&sp->members_lock); 936 if (!sp->members_count) { 937 rv = -EINVAL; 938 printk(KERN_ERR "dlm: zero members_count\n"); 939 goto out; 940 } 941 942 count = sp->members_count; 943 944 nodes = kcalloc(count, sizeof(struct dlm_config_node), GFP_NOFS); 945 if (!nodes) { 946 rv = -ENOMEM; 947 goto out; 948 } 949 950 node = nodes; 951 list_for_each_entry(nd, &sp->members, list) { 952 node->nodeid = nd->nodeid; 953 node->weight = nd->weight; 954 node->new = nd->new; 955 node->comm_seq = nd->comm_seq; 956 node++; 957 958 nd->new = 0; 959 } 960 961 *count_out = count; 962 *nodes_out = nodes; 963 rv = 0; 964 out: 965 mutex_unlock(&sp->members_lock); 966 put_space(sp); 967 return rv; 968 } 969 970 int dlm_comm_seq(int nodeid, uint32_t *seq) 971 { 972 struct dlm_comm *cm = get_comm(nodeid); 973 if (!cm) 974 return -EEXIST; 975 *seq = cm->seq; 976 put_comm(cm); 977 return 0; 978 } 979 980 int dlm_our_nodeid(void) 981 { 982 return local_comm ? local_comm->nodeid : 0; 983 } 984 985 /* num 0 is first addr, num 1 is second addr */ 986 int dlm_our_addr(struct sockaddr_storage *addr, int num) 987 { 988 if (!local_comm) 989 return -1; 990 if (num + 1 > local_comm->addr_count) 991 return -1; 992 memcpy(addr, local_comm->addr[num], sizeof(*addr)); 993 return 0; 994 } 995 996 /* Config file defaults */ 997 #define DEFAULT_TCP_PORT 21064 998 #define DEFAULT_BUFFER_SIZE 4096 999 #define DEFAULT_RSBTBL_SIZE 1024 1000 #define DEFAULT_RECOVER_TIMER 5 1001 #define DEFAULT_TOSS_SECS 10 1002 #define DEFAULT_SCAN_SECS 5 1003 #define DEFAULT_LOG_DEBUG 0 1004 #define DEFAULT_PROTOCOL 0 1005 #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ 1006 #define DEFAULT_WAITWARN_US 0 1007 #define DEFAULT_NEW_RSB_COUNT 128 1008 #define DEFAULT_RECOVER_CALLBACKS 0 1009 #define DEFAULT_CLUSTER_NAME "" 1010 1011 struct dlm_config_info dlm_config = { 1012 .ci_tcp_port = DEFAULT_TCP_PORT, 1013 .ci_buffer_size = DEFAULT_BUFFER_SIZE, 1014 .ci_rsbtbl_size = DEFAULT_RSBTBL_SIZE, 1015 .ci_recover_timer = DEFAULT_RECOVER_TIMER, 1016 .ci_toss_secs = DEFAULT_TOSS_SECS, 1017 .ci_scan_secs = DEFAULT_SCAN_SECS, 1018 .ci_log_debug = DEFAULT_LOG_DEBUG, 1019 .ci_protocol = DEFAULT_PROTOCOL, 1020 .ci_timewarn_cs = DEFAULT_TIMEWARN_CS, 1021 .ci_waitwarn_us = DEFAULT_WAITWARN_US, 1022 .ci_new_rsb_count = DEFAULT_NEW_RSB_COUNT, 1023 .ci_recover_callbacks = DEFAULT_RECOVER_CALLBACKS, 1024 .ci_cluster_name = DEFAULT_CLUSTER_NAME 1025 }; 1026 1027