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