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