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