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