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