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