linux/drivers/staging/lustre/lustre/obdclass/obd_config.c
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  19 *
  20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  21 * CA 95054 USA or visit www.sun.com if you need additional information or
  22 * have any questions.
  23 *
  24 * GPL HEADER END
  25 */
  26/*
  27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  28 * Use is subject to license terms.
  29 *
  30 * Copyright (c) 2011, 2012, Intel Corporation.
  31 */
  32/*
  33 * This file is part of Lustre, http://www.lustre.org/
  34 * Lustre is a trademark of Sun Microsystems, Inc.
  35 *
  36 * lustre/obdclass/obd_config.c
  37 *
  38 * Config API
  39 */
  40
  41#define DEBUG_SUBSYSTEM S_CLASS
  42#include "../include/obd_class.h"
  43#include <linux/string.h>
  44#include "../include/lustre_log.h"
  45#include "../include/lprocfs_status.h"
  46#include "../include/lustre_param.h"
  47
  48#include "llog_internal.h"
  49
  50static cfs_hash_ops_t uuid_hash_ops;
  51static cfs_hash_ops_t nid_hash_ops;
  52
  53/*********** string parsing utils *********/
  54
  55/* returns 0 if we find this key in the buffer, else 1 */
  56int class_find_param(char *buf, char *key, char **valp)
  57{
  58        char *ptr;
  59
  60        if (!buf)
  61                return 1;
  62
  63        ptr = strstr(buf, key);
  64        if (ptr == NULL)
  65                return 1;
  66
  67        if (valp)
  68                *valp = ptr + strlen(key);
  69
  70        return 0;
  71}
  72EXPORT_SYMBOL(class_find_param);
  73
  74/**
  75 * Check whether the proc parameter \a param is an old parameter or not from
  76 * the array \a ptr which contains the mapping from old parameters to new ones.
  77 * If it's an old one, then return the pointer to the cfg_interop_param struc-
  78 * ture which contains both the old and new parameters.
  79 *
  80 * \param param                 proc parameter
  81 * \param ptr                   an array which contains the mapping from
  82 *                              old parameters to new ones
  83 *
  84 * \retval valid-pointer        pointer to the cfg_interop_param structure
  85 *                              which contains the old and new parameters
  86 * \retval NULL                 \a param or \a ptr is NULL,
  87 *                              or \a param is not an old parameter
  88 */
  89struct cfg_interop_param *class_find_old_param(const char *param,
  90                                               struct cfg_interop_param *ptr)
  91{
  92        char *value = NULL;
  93        int   name_len = 0;
  94
  95        if (param == NULL || ptr == NULL)
  96                return NULL;
  97
  98        value = strchr(param, '=');
  99        if (value == NULL)
 100                name_len = strlen(param);
 101        else
 102                name_len = value - param;
 103
 104        while (ptr->old_param != NULL) {
 105                if (strncmp(param, ptr->old_param, name_len) == 0 &&
 106                    name_len == strlen(ptr->old_param))
 107                        return ptr;
 108                ptr++;
 109        }
 110
 111        return NULL;
 112}
 113EXPORT_SYMBOL(class_find_old_param);
 114
 115/**
 116 * Finds a parameter in \a params and copies it to \a copy.
 117 *
 118 * Leading spaces are skipped. Next space or end of string is the
 119 * parameter terminator with the exception that spaces inside single or double
 120 * quotes get included into a parameter. The parameter is copied into \a copy
 121 * which has to be allocated big enough by a caller, quotes are stripped in
 122 * the copy and the copy is terminated by 0.
 123 *
 124 * On return \a params is set to next parameter or to NULL if last
 125 * parameter is returned.
 126 *
 127 * \retval 0 if parameter is returned in \a copy
 128 * \retval 1 otherwise
 129 * \retval -EINVAL if unbalanced quota is found
 130 */
 131int class_get_next_param(char **params, char *copy)
 132{
 133        char *q1, *q2, *str;
 134        int len;
 135
 136        str = *params;
 137        while (*str == ' ')
 138                str++;
 139
 140        if (*str == '\0') {
 141                *params = NULL;
 142                return 1;
 143        }
 144
 145        while (1) {
 146                q1 = strpbrk(str, " '\"");
 147                if (q1 == NULL) {
 148                        len = strlen(str);
 149                        memcpy(copy, str, len);
 150                        copy[len] = '\0';
 151                        *params = NULL;
 152                        return 0;
 153                }
 154                len = q1 - str;
 155                if (*q1 == ' ') {
 156                        memcpy(copy, str, len);
 157                        copy[len] = '\0';
 158                        *params = str + len;
 159                        return 0;
 160                }
 161
 162                memcpy(copy, str, len);
 163                copy += len;
 164
 165                /* search for the matching closing quote */
 166                str = q1 + 1;
 167                q2 = strchr(str, *q1);
 168                if (q2 == NULL) {
 169                        CERROR("Unbalanced quota in parameters: \"%s\"\n",
 170                               *params);
 171                        return -EINVAL;
 172                }
 173                len = q2 - str;
 174                memcpy(copy, str, len);
 175                copy += len;
 176                str = q2 + 1;
 177        }
 178        return 1;
 179}
 180EXPORT_SYMBOL(class_get_next_param);
 181
 182/* returns 0 if this is the first key in the buffer, else 1.
 183   valp points to first char after key. */
 184int class_match_param(char *buf, char *key, char **valp)
 185{
 186        if (!buf)
 187                return 1;
 188
 189        if (memcmp(buf, key, strlen(key)) != 0)
 190                return 1;
 191
 192        if (valp)
 193                *valp = buf + strlen(key);
 194
 195        return 0;
 196}
 197EXPORT_SYMBOL(class_match_param);
 198
 199static int parse_nid(char *buf, void *value, int quiet)
 200{
 201        lnet_nid_t *nid = (lnet_nid_t *)value;
 202
 203        *nid = libcfs_str2nid(buf);
 204        if (*nid != LNET_NID_ANY)
 205                return 0;
 206
 207        if (!quiet)
 208                LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
 209        return -EINVAL;
 210}
 211
 212static int parse_net(char *buf, void *value)
 213{
 214        __u32 *net = (__u32 *)value;
 215
 216        *net = libcfs_str2net(buf);
 217        CDEBUG(D_INFO, "Net %s\n", libcfs_net2str(*net));
 218        return 0;
 219}
 220
 221enum {
 222        CLASS_PARSE_NID = 1,
 223        CLASS_PARSE_NET,
 224};
 225
 226/* 0 is good nid,
 227   1 not found
 228   < 0 error
 229   endh is set to next separator */
 230static int class_parse_value(char *buf, int opc, void *value, char **endh,
 231                             int quiet)
 232{
 233        char *endp;
 234        char  tmp;
 235        int   rc = 0;
 236
 237        if (!buf)
 238                return 1;
 239        while (*buf == ',' || *buf == ':')
 240                buf++;
 241        if (*buf == ' ' || *buf == '/' || *buf == '\0')
 242                return 1;
 243
 244        /* nid separators or end of nids */
 245        endp = strpbrk(buf, ",: /");
 246        if (endp == NULL)
 247                endp = buf + strlen(buf);
 248
 249        tmp = *endp;
 250        *endp = '\0';
 251        switch (opc) {
 252        default:
 253                LBUG();
 254        case CLASS_PARSE_NID:
 255                rc = parse_nid(buf, value, quiet);
 256                break;
 257        case CLASS_PARSE_NET:
 258                rc = parse_net(buf, value);
 259                break;
 260        }
 261        *endp = tmp;
 262        if (rc != 0)
 263                return rc;
 264        if (endh)
 265                *endh = endp;
 266        return 0;
 267}
 268
 269int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
 270{
 271        return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
 272}
 273EXPORT_SYMBOL(class_parse_nid);
 274
 275int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
 276{
 277        return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
 278}
 279EXPORT_SYMBOL(class_parse_nid_quiet);
 280
 281int class_parse_net(char *buf, __u32 *net, char **endh)
 282{
 283        return class_parse_value(buf, CLASS_PARSE_NET, (void *)net, endh, 0);
 284}
 285EXPORT_SYMBOL(class_parse_net);
 286
 287/* 1 param contains key and match
 288 * 0 param contains key and not match
 289 * -1 param does not contain key
 290 */
 291int class_match_nid(char *buf, char *key, lnet_nid_t nid)
 292{
 293        lnet_nid_t tmp;
 294        int   rc = -1;
 295
 296        while (class_find_param(buf, key, &buf) == 0) {
 297                /* please restrict to the nids pertaining to
 298                 * the specified nids */
 299                while (class_parse_nid(buf, &tmp, &buf) == 0) {
 300                        if (tmp == nid)
 301                                return 1;
 302                }
 303                rc = 0;
 304        }
 305        return rc;
 306}
 307EXPORT_SYMBOL(class_match_nid);
 308
 309int class_match_net(char *buf, char *key, __u32 net)
 310{
 311        __u32 tmp;
 312        int   rc = -1;
 313
 314        while (class_find_param(buf, key, &buf) == 0) {
 315                /* please restrict to the nids pertaining to
 316                 * the specified networks */
 317                while (class_parse_net(buf, &tmp, &buf) == 0) {
 318                        if (tmp == net)
 319                                return 1;
 320                }
 321                rc = 0;
 322        }
 323        return rc;
 324}
 325EXPORT_SYMBOL(class_match_net);
 326
 327/********************** class fns **********************/
 328
 329/**
 330 * Create a new obd device and set the type, name and uuid.  If successful,
 331 * the new device can be accessed by either name or uuid.
 332 */
 333int class_attach(struct lustre_cfg *lcfg)
 334{
 335        struct obd_device *obd = NULL;
 336        char *typename, *name, *uuid;
 337        int rc, len;
 338
 339        if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
 340                CERROR("No type passed!\n");
 341                return -EINVAL;
 342        }
 343        typename = lustre_cfg_string(lcfg, 1);
 344
 345        if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
 346                CERROR("No name passed!\n");
 347                return -EINVAL;
 348        }
 349        name = lustre_cfg_string(lcfg, 0);
 350
 351        if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
 352                CERROR("No UUID passed!\n");
 353                return -EINVAL;
 354        }
 355        uuid = lustre_cfg_string(lcfg, 2);
 356
 357        CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
 358               MKSTR(typename), MKSTR(name), MKSTR(uuid));
 359
 360        obd = class_newdev(typename, name);
 361        if (IS_ERR(obd)) {
 362                /* Already exists or out of obds */
 363                rc = PTR_ERR(obd);
 364                obd = NULL;
 365                CERROR("Cannot create device %s of type %s : %d\n",
 366                       name, typename, rc);
 367                goto out;
 368        }
 369        LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
 370                 name, typename);
 371        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
 372                 "obd %p obd_magic %08X != %08X\n",
 373                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
 374        LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
 375                 "%p obd_name %s != %s\n", obd, obd->obd_name, name);
 376
 377        rwlock_init(&obd->obd_pool_lock);
 378        obd->obd_pool_limit = 0;
 379        obd->obd_pool_slv = 0;
 380
 381        INIT_LIST_HEAD(&obd->obd_exports);
 382        INIT_LIST_HEAD(&obd->obd_unlinked_exports);
 383        INIT_LIST_HEAD(&obd->obd_delayed_exports);
 384        INIT_LIST_HEAD(&obd->obd_exports_timed);
 385        spin_lock_init(&obd->obd_nid_lock);
 386        spin_lock_init(&obd->obd_dev_lock);
 387        mutex_init(&obd->obd_dev_mutex);
 388        spin_lock_init(&obd->obd_osfs_lock);
 389        /* obd->obd_osfs_age must be set to a value in the distant
 390         * past to guarantee a fresh statfs is fetched on mount. */
 391        obd->obd_osfs_age = cfs_time_shift_64(-1000);
 392
 393        /* XXX belongs in setup not attach  */
 394        init_rwsem(&obd->obd_observer_link_sem);
 395        /* recovery data */
 396        cfs_init_timer(&obd->obd_recovery_timer);
 397        spin_lock_init(&obd->obd_recovery_task_lock);
 398        init_waitqueue_head(&obd->obd_next_transno_waitq);
 399        init_waitqueue_head(&obd->obd_evict_inprogress_waitq);
 400        INIT_LIST_HEAD(&obd->obd_req_replay_queue);
 401        INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
 402        INIT_LIST_HEAD(&obd->obd_final_req_queue);
 403        INIT_LIST_HEAD(&obd->obd_evict_list);
 404
 405        llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);
 406
 407        obd->obd_conn_inprogress = 0;
 408
 409        len = strlen(uuid);
 410        if (len >= sizeof(obd->obd_uuid)) {
 411                CERROR("uuid must be < %d bytes long\n",
 412                       (int)sizeof(obd->obd_uuid));
 413                rc = -EINVAL;
 414                goto out;
 415        }
 416        memcpy(obd->obd_uuid.uuid, uuid, len);
 417
 418        /* do the attach */
 419        if (OBP(obd, attach)) {
 420                rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
 421                if (rc) {
 422                        rc = -EINVAL;
 423                        goto out;
 424                }
 425        }
 426
 427        /* Detach drops this */
 428        spin_lock(&obd->obd_dev_lock);
 429        atomic_set(&obd->obd_refcount, 1);
 430        spin_unlock(&obd->obd_dev_lock);
 431        lu_ref_init(&obd->obd_reference);
 432        lu_ref_add(&obd->obd_reference, "attach", obd);
 433
 434        obd->obd_attached = 1;
 435        CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
 436               obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
 437        return 0;
 438 out:
 439        if (obd != NULL) {
 440                class_release_dev(obd);
 441        }
 442        return rc;
 443}
 444EXPORT_SYMBOL(class_attach);
 445
 446/** Create hashes, self-export, and call type-specific setup.
 447 * Setup is effectively the "start this obd" call.
 448 */
 449int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 450{
 451        int err = 0;
 452        struct obd_export *exp;
 453
 454        LASSERT(obd != NULL);
 455        LASSERTF(obd == class_num2obd(obd->obd_minor),
 456                 "obd %p != obd_devs[%d] %p\n",
 457                 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
 458        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
 459                 "obd %p obd_magic %08x != %08x\n",
 460                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
 461
 462        /* have we attached a type to this device? */
 463        if (!obd->obd_attached) {
 464                CERROR("Device %d not attached\n", obd->obd_minor);
 465                return -ENODEV;
 466        }
 467
 468        if (obd->obd_set_up) {
 469                CERROR("Device %d already setup (type %s)\n",
 470                       obd->obd_minor, obd->obd_type->typ_name);
 471                return -EEXIST;
 472        }
 473
 474        /* is someone else setting us up right now? (attach inits spinlock) */
 475        spin_lock(&obd->obd_dev_lock);
 476        if (obd->obd_starting) {
 477                spin_unlock(&obd->obd_dev_lock);
 478                CERROR("Device %d setup in progress (type %s)\n",
 479                       obd->obd_minor, obd->obd_type->typ_name);
 480                return -EEXIST;
 481        }
 482        /* just leave this on forever.  I can't use obd_set_up here because
 483           other fns check that status, and we're not actually set up yet. */
 484        obd->obd_starting = 1;
 485        obd->obd_uuid_hash = NULL;
 486        obd->obd_nid_hash = NULL;
 487        spin_unlock(&obd->obd_dev_lock);
 488
 489        /* create an uuid-export lustre hash */
 490        obd->obd_uuid_hash = cfs_hash_create("UUID_HASH",
 491                                             HASH_UUID_CUR_BITS,
 492                                             HASH_UUID_MAX_BITS,
 493                                             HASH_UUID_BKT_BITS, 0,
 494                                             CFS_HASH_MIN_THETA,
 495                                             CFS_HASH_MAX_THETA,
 496                                             &uuid_hash_ops, CFS_HASH_DEFAULT);
 497        if (!obd->obd_uuid_hash) {
 498                err = -ENOMEM;
 499                goto err_hash;
 500        }
 501
 502        /* create a nid-export lustre hash */
 503        obd->obd_nid_hash = cfs_hash_create("NID_HASH",
 504                                            HASH_NID_CUR_BITS,
 505                                            HASH_NID_MAX_BITS,
 506                                            HASH_NID_BKT_BITS, 0,
 507                                            CFS_HASH_MIN_THETA,
 508                                            CFS_HASH_MAX_THETA,
 509                                            &nid_hash_ops, CFS_HASH_DEFAULT);
 510        if (!obd->obd_nid_hash) {
 511                err = -ENOMEM;
 512                goto err_hash;
 513        }
 514
 515        exp = class_new_export(obd, &obd->obd_uuid);
 516        if (IS_ERR(exp)) {
 517                err = PTR_ERR(exp);
 518                goto err_hash;
 519        }
 520
 521        obd->obd_self_export = exp;
 522        list_del_init(&exp->exp_obd_chain_timed);
 523        class_export_put(exp);
 524
 525        err = obd_setup(obd, lcfg);
 526        if (err)
 527                goto err_exp;
 528
 529        obd->obd_set_up = 1;
 530
 531        spin_lock(&obd->obd_dev_lock);
 532        /* cleanup drops this */
 533        class_incref(obd, "setup", obd);
 534        spin_unlock(&obd->obd_dev_lock);
 535
 536        CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
 537               obd->obd_name, obd->obd_uuid.uuid);
 538
 539        return 0;
 540err_exp:
 541        if (obd->obd_self_export) {
 542                class_unlink_export(obd->obd_self_export);
 543                obd->obd_self_export = NULL;
 544        }
 545err_hash:
 546        if (obd->obd_uuid_hash) {
 547                cfs_hash_putref(obd->obd_uuid_hash);
 548                obd->obd_uuid_hash = NULL;
 549        }
 550        if (obd->obd_nid_hash) {
 551                cfs_hash_putref(obd->obd_nid_hash);
 552                obd->obd_nid_hash = NULL;
 553        }
 554        obd->obd_starting = 0;
 555        CERROR("setup %s failed (%d)\n", obd->obd_name, err);
 556        return err;
 557}
 558EXPORT_SYMBOL(class_setup);
 559
 560/** We have finished using this obd and are ready to destroy it.
 561 * There can be no more references to this obd.
 562 */
 563int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
 564{
 565        if (obd->obd_set_up) {
 566                CERROR("OBD device %d still set up\n", obd->obd_minor);
 567                return -EBUSY;
 568        }
 569
 570        spin_lock(&obd->obd_dev_lock);
 571        if (!obd->obd_attached) {
 572                spin_unlock(&obd->obd_dev_lock);
 573                CERROR("OBD device %d not attached\n", obd->obd_minor);
 574                return -ENODEV;
 575        }
 576        obd->obd_attached = 0;
 577        spin_unlock(&obd->obd_dev_lock);
 578
 579        CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
 580               obd->obd_name, obd->obd_uuid.uuid);
 581
 582        class_decref(obd, "attach", obd);
 583        return 0;
 584}
 585EXPORT_SYMBOL(class_detach);
 586
 587/** Start shutting down the obd.  There may be in-progress ops when
 588 * this is called.  We tell them to start shutting down with a call
 589 * to class_disconnect_exports().
 590 */
 591int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
 592{
 593        int err = 0;
 594        char *flag;
 595
 596        OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
 597
 598        if (!obd->obd_set_up) {
 599                CERROR("Device %d not setup\n", obd->obd_minor);
 600                return -ENODEV;
 601        }
 602
 603        spin_lock(&obd->obd_dev_lock);
 604        if (obd->obd_stopping) {
 605                spin_unlock(&obd->obd_dev_lock);
 606                CERROR("OBD %d already stopping\n", obd->obd_minor);
 607                return -ENODEV;
 608        }
 609        /* Leave this on forever */
 610        obd->obd_stopping = 1;
 611
 612        /* wait for already-arrived-connections to finish. */
 613        while (obd->obd_conn_inprogress > 0) {
 614                spin_unlock(&obd->obd_dev_lock);
 615
 616                cond_resched();
 617
 618                spin_lock(&obd->obd_dev_lock);
 619        }
 620        spin_unlock(&obd->obd_dev_lock);
 621
 622        if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
 623                for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
 624                        switch (*flag) {
 625                        case 'F':
 626                                obd->obd_force = 1;
 627                                break;
 628                        case 'A':
 629                                LCONSOLE_WARN("Failing over %s\n",
 630                                              obd->obd_name);
 631                                obd->obd_fail = 1;
 632                                obd->obd_no_transno = 1;
 633                                obd->obd_no_recov = 1;
 634                                if (OBP(obd, iocontrol)) {
 635                                        obd_iocontrol(OBD_IOC_SYNC,
 636                                                      obd->obd_self_export,
 637                                                      0, NULL, NULL);
 638                                }
 639                                break;
 640                        default:
 641                                CERROR("Unrecognised flag '%c'\n", *flag);
 642                        }
 643        }
 644
 645        LASSERT(obd->obd_self_export);
 646
 647        /* The three references that should be remaining are the
 648         * obd_self_export and the attach and setup references. */
 649        if (atomic_read(&obd->obd_refcount) > 3) {
 650                /* refcount - 3 might be the number of real exports
 651                   (excluding self export). But class_incref is called
 652                   by other things as well, so don't count on it. */
 653                CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
 654                       obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
 655                dump_exports(obd, 0);
 656                class_disconnect_exports(obd);
 657        }
 658
 659        /* Precleanup, we must make sure all exports get destroyed. */
 660        err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
 661        if (err)
 662                CERROR("Precleanup %s returned %d\n",
 663                       obd->obd_name, err);
 664
 665        /* destroy an uuid-export hash body */
 666        if (obd->obd_uuid_hash) {
 667                cfs_hash_putref(obd->obd_uuid_hash);
 668                obd->obd_uuid_hash = NULL;
 669        }
 670
 671        /* destroy a nid-export hash body */
 672        if (obd->obd_nid_hash) {
 673                cfs_hash_putref(obd->obd_nid_hash);
 674                obd->obd_nid_hash = NULL;
 675        }
 676
 677        class_decref(obd, "setup", obd);
 678        obd->obd_set_up = 0;
 679
 680        return 0;
 681}
 682EXPORT_SYMBOL(class_cleanup);
 683
 684struct obd_device *class_incref(struct obd_device *obd,
 685                                const char *scope, const void *source)
 686{
 687        lu_ref_add_atomic(&obd->obd_reference, scope, source);
 688        atomic_inc(&obd->obd_refcount);
 689        CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
 690               atomic_read(&obd->obd_refcount));
 691
 692        return obd;
 693}
 694EXPORT_SYMBOL(class_incref);
 695
 696void class_decref(struct obd_device *obd, const char *scope, const void *source)
 697{
 698        int err;
 699        int refs;
 700
 701        spin_lock(&obd->obd_dev_lock);
 702        atomic_dec(&obd->obd_refcount);
 703        refs = atomic_read(&obd->obd_refcount);
 704        spin_unlock(&obd->obd_dev_lock);
 705        lu_ref_del(&obd->obd_reference, scope, source);
 706
 707        CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
 708
 709        if ((refs == 1) && obd->obd_stopping) {
 710                /* All exports have been destroyed; there should
 711                   be no more in-progress ops by this point.*/
 712
 713                spin_lock(&obd->obd_self_export->exp_lock);
 714                obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
 715                spin_unlock(&obd->obd_self_export->exp_lock);
 716
 717                /* note that we'll recurse into class_decref again */
 718                class_unlink_export(obd->obd_self_export);
 719                return;
 720        }
 721
 722        if (refs == 0) {
 723                CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
 724                       obd->obd_name, obd->obd_uuid.uuid);
 725                LASSERT(!obd->obd_attached);
 726                if (obd->obd_stopping) {
 727                        /* If we're not stopping, we were never set up */
 728                        err = obd_cleanup(obd);
 729                        if (err)
 730                                CERROR("Cleanup %s returned %d\n",
 731                                       obd->obd_name, err);
 732                }
 733                if (OBP(obd, detach)) {
 734                        err = OBP(obd, detach)(obd);
 735                        if (err)
 736                                CERROR("Detach returned %d\n", err);
 737                }
 738                class_release_dev(obd);
 739        }
 740}
 741EXPORT_SYMBOL(class_decref);
 742
 743/** Add a failover nid location.
 744 * Client obd types contact server obd types using this nid list.
 745 */
 746int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
 747{
 748        struct obd_import *imp;
 749        struct obd_uuid uuid;
 750        int rc;
 751
 752        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
 753            LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
 754                CERROR("invalid conn_uuid\n");
 755                return -EINVAL;
 756        }
 757        if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
 758            strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
 759            strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) &&
 760            strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) &&
 761            strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
 762                CERROR("can't add connection on non-client dev\n");
 763                return -EINVAL;
 764        }
 765
 766        imp = obd->u.cli.cl_import;
 767        if (!imp) {
 768                CERROR("try to add conn on immature client dev\n");
 769                return -EINVAL;
 770        }
 771
 772        obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
 773        rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
 774
 775        return rc;
 776}
 777EXPORT_SYMBOL(class_add_conn);
 778
 779/** Remove a failover nid location.
 780 */
 781int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
 782{
 783        struct obd_import *imp;
 784        struct obd_uuid uuid;
 785        int rc;
 786
 787        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
 788            LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
 789                CERROR("invalid conn_uuid\n");
 790                return -EINVAL;
 791        }
 792        if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
 793            strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
 794                CERROR("can't del connection on non-client dev\n");
 795                return -EINVAL;
 796        }
 797
 798        imp = obd->u.cli.cl_import;
 799        if (!imp) {
 800                CERROR("try to del conn on immature client dev\n");
 801                return -EINVAL;
 802        }
 803
 804        obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
 805        rc = obd_del_conn(imp, &uuid);
 806
 807        return rc;
 808}
 809
 810LIST_HEAD(lustre_profile_list);
 811
 812struct lustre_profile *class_get_profile(const char *prof)
 813{
 814        struct lustre_profile *lprof;
 815
 816        list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
 817                if (!strcmp(lprof->lp_profile, prof)) {
 818                        return lprof;
 819                }
 820        }
 821        return NULL;
 822}
 823EXPORT_SYMBOL(class_get_profile);
 824
 825/** Create a named "profile".
 826 * This defines the mdc and osc names to use for a client.
 827 * This also is used to define the lov to be used by a mdt.
 828 */
 829int class_add_profile(int proflen, char *prof, int osclen, char *osc,
 830                      int mdclen, char *mdc)
 831{
 832        struct lustre_profile *lprof;
 833        int err = 0;
 834
 835        CDEBUG(D_CONFIG, "Add profile %s\n", prof);
 836
 837        lprof = kzalloc(sizeof(*lprof), GFP_NOFS);
 838        if (lprof == NULL)
 839                return -ENOMEM;
 840        INIT_LIST_HEAD(&lprof->lp_list);
 841
 842        LASSERT(proflen == (strlen(prof) + 1));
 843        lprof->lp_profile = kmemdup(prof, proflen, GFP_NOFS);
 844        if (lprof->lp_profile == NULL) {
 845                err = -ENOMEM;
 846                goto free_lprof;
 847        }
 848
 849        LASSERT(osclen == (strlen(osc) + 1));
 850        lprof->lp_dt = kmemdup(osc, osclen, GFP_NOFS);
 851        if (lprof->lp_dt == NULL) {
 852                err = -ENOMEM;
 853                goto free_lp_profile;
 854        }
 855
 856        if (mdclen > 0) {
 857                LASSERT(mdclen == (strlen(mdc) + 1));
 858                lprof->lp_md = kmemdup(mdc, mdclen, GFP_NOFS);
 859                if (lprof->lp_md == NULL) {
 860                        err = -ENOMEM;
 861                        goto free_lp_dt;
 862                }
 863        }
 864
 865        list_add(&lprof->lp_list, &lustre_profile_list);
 866        return err;
 867
 868free_lp_dt:
 869        kfree(lprof->lp_dt);
 870free_lp_profile:
 871        kfree(lprof->lp_profile);
 872free_lprof:
 873        kfree(lprof);
 874        return err;
 875}
 876
 877void class_del_profile(const char *prof)
 878{
 879        struct lustre_profile *lprof;
 880
 881        CDEBUG(D_CONFIG, "Del profile %s\n", prof);
 882
 883        lprof = class_get_profile(prof);
 884        if (lprof) {
 885                list_del(&lprof->lp_list);
 886                kfree(lprof->lp_profile);
 887                kfree(lprof->lp_dt);
 888                kfree(lprof->lp_md);
 889                kfree(lprof);
 890        }
 891}
 892EXPORT_SYMBOL(class_del_profile);
 893
 894/* COMPAT_146 */
 895void class_del_profiles(void)
 896{
 897        struct lustre_profile *lprof, *n;
 898
 899        list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
 900                list_del(&lprof->lp_list);
 901                kfree(lprof->lp_profile);
 902                kfree(lprof->lp_dt);
 903                kfree(lprof->lp_md);
 904                kfree(lprof);
 905        }
 906}
 907EXPORT_SYMBOL(class_del_profiles);
 908
 909static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
 910{
 911        if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
 912                at_min = val;
 913        else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
 914                at_max = val;
 915        else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
 916                at_extra = val;
 917        else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
 918                at_early_margin = val;
 919        else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
 920                at_history = val;
 921        else if (class_match_param(ptr, PARAM_JOBID_VAR, NULL) == 0)
 922                strlcpy(obd_jobid_var, lustre_cfg_string(lcfg, 2),
 923                        JOBSTATS_JOBID_VAR_MAX_LEN + 1);
 924        else
 925                return -EINVAL;
 926
 927        CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
 928        return 0;
 929}
 930
 931
 932/* We can't call ll_process_config or lquota_process_config directly because
 933 * it lives in a module that must be loaded after this one. */
 934static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
 935static int (*quota_process_config)(struct lustre_cfg *lcfg) = NULL;
 936
 937void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
 938{
 939        client_process_config = cpc;
 940}
 941EXPORT_SYMBOL(lustre_register_client_process_config);
 942
 943/**
 944 * Rename the proc parameter in \a cfg with a new name \a new_name.
 945 *
 946 * \param cfg      config structure which contains the proc parameter
 947 * \param new_name new name of the proc parameter
 948 *
 949 * \retval valid-pointer    pointer to the newly-allocated config structure
 950 *                          which contains the renamed proc parameter
 951 * \retval ERR_PTR(-EINVAL) if \a cfg or \a new_name is NULL, or \a cfg does
 952 *                          not contain a proc parameter
 953 * \retval ERR_PTR(-ENOMEM) if memory allocation failure occurs
 954 */
 955struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
 956                                     const char *new_name)
 957{
 958        struct lustre_cfg_bufs  *bufs = NULL;
 959        struct lustre_cfg       *new_cfg = NULL;
 960        char                    *param = NULL;
 961        char                    *new_param = NULL;
 962        char                    *value = NULL;
 963        int                      name_len = 0;
 964        int                      new_len = 0;
 965
 966        if (cfg == NULL || new_name == NULL)
 967                return ERR_PTR(-EINVAL);
 968
 969        param = lustre_cfg_string(cfg, 1);
 970        if (param == NULL)
 971                return ERR_PTR(-EINVAL);
 972
 973        value = strchr(param, '=');
 974        if (value == NULL)
 975                name_len = strlen(param);
 976        else
 977                name_len = value - param;
 978
 979        new_len = LUSTRE_CFG_BUFLEN(cfg, 1) + strlen(new_name) - name_len;
 980
 981        new_param = kzalloc(new_len, GFP_NOFS);
 982        if (new_param == NULL)
 983                return ERR_PTR(-ENOMEM);
 984
 985        strcpy(new_param, new_name);
 986        if (value != NULL)
 987                strcat(new_param, value);
 988
 989        bufs = kzalloc(sizeof(*bufs), GFP_NOFS);
 990        if (bufs == NULL) {
 991                kfree(new_param);
 992                return ERR_PTR(-ENOMEM);
 993        }
 994
 995        lustre_cfg_bufs_reset(bufs, NULL);
 996        lustre_cfg_bufs_init(bufs, cfg);
 997        lustre_cfg_bufs_set_string(bufs, 1, new_param);
 998
 999        new_cfg = lustre_cfg_new(cfg->lcfg_command, bufs);
1000
1001        kfree(new_param);
1002        kfree(bufs);
1003        if (new_cfg == NULL)
1004                return ERR_PTR(-ENOMEM);
1005
1006        new_cfg->lcfg_num = cfg->lcfg_num;
1007        new_cfg->lcfg_flags = cfg->lcfg_flags;
1008        new_cfg->lcfg_nid = cfg->lcfg_nid;
1009        new_cfg->lcfg_nal = cfg->lcfg_nal;
1010
1011        return new_cfg;
1012}
1013EXPORT_SYMBOL(lustre_cfg_rename);
1014
1015static int process_param2_config(struct lustre_cfg *lcfg)
1016{
1017        char *param = lustre_cfg_string(lcfg, 1);
1018        char *upcall = lustre_cfg_string(lcfg, 2);
1019        char *argv[] = {
1020                [0] = "/usr/sbin/lctl",
1021                [1] = "set_param",
1022                [2] = param,
1023                [3] = NULL
1024        };
1025        struct timeval  start;
1026        struct timeval  end;
1027        int             rc;
1028
1029
1030        /* Add upcall processing here. Now only lctl is supported */
1031        if (strcmp(upcall, LCTL_UPCALL) != 0) {
1032                CERROR("Unsupported upcall %s\n", upcall);
1033                return -EINVAL;
1034        }
1035
1036        do_gettimeofday(&start);
1037        rc = call_usermodehelper(argv[0], argv, NULL, 1);
1038        do_gettimeofday(&end);
1039
1040        if (rc < 0) {
1041                CERROR(
1042                       "lctl: error invoking upcall %s %s %s: rc = %d; time %ldus\n",
1043                       argv[0], argv[1], argv[2], rc,
1044                       cfs_timeval_sub(&end, &start, NULL));
1045        } else {
1046                CDEBUG(D_HA, "lctl: invoked upcall %s %s %s, time %ldus\n",
1047                       argv[0], argv[1], argv[2],
1048                       cfs_timeval_sub(&end, &start, NULL));
1049                       rc = 0;
1050        }
1051
1052        return rc;
1053}
1054
1055void lustre_register_quota_process_config(int (*qpc)(struct lustre_cfg *lcfg))
1056{
1057        quota_process_config = qpc;
1058}
1059EXPORT_SYMBOL(lustre_register_quota_process_config);
1060
1061/** Process configuration commands given in lustre_cfg form.
1062 * These may come from direct calls (e.g. class_manual_cleanup)
1063 * or processing the config llog, or ioctl from lctl.
1064 */
1065int class_process_config(struct lustre_cfg *lcfg)
1066{
1067        struct obd_device *obd;
1068        int err;
1069
1070        LASSERT(lcfg && !IS_ERR(lcfg));
1071        CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
1072
1073        /* Commands that don't need a device */
1074        switch (lcfg->lcfg_command) {
1075        case LCFG_ATTACH: {
1076                err = class_attach(lcfg);
1077                goto out;
1078        }
1079        case LCFG_ADD_UUID: {
1080                CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n",
1081                       lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
1082                       libcfs_nid2str(lcfg->lcfg_nid));
1083
1084                err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
1085                goto out;
1086        }
1087        case LCFG_DEL_UUID: {
1088                CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
1089                       (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
1090                       ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
1091
1092                err = class_del_uuid(lustre_cfg_string(lcfg, 1));
1093                goto out;
1094        }
1095        case LCFG_MOUNTOPT: {
1096                CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
1097                       lustre_cfg_string(lcfg, 1),
1098                       lustre_cfg_string(lcfg, 2),
1099                       lustre_cfg_string(lcfg, 3));
1100                /* set these mount options somewhere, so ll_fill_super
1101                 * can find them. */
1102                err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
1103                                        lustre_cfg_string(lcfg, 1),
1104                                        LUSTRE_CFG_BUFLEN(lcfg, 2),
1105                                        lustre_cfg_string(lcfg, 2),
1106                                        LUSTRE_CFG_BUFLEN(lcfg, 3),
1107                                        lustre_cfg_string(lcfg, 3));
1108                goto out;
1109        }
1110        case LCFG_DEL_MOUNTOPT: {
1111                CDEBUG(D_IOCTL, "mountopt: profile %s\n",
1112                       lustre_cfg_string(lcfg, 1));
1113                class_del_profile(lustre_cfg_string(lcfg, 1));
1114                err = 0;
1115                goto out;
1116        }
1117        case LCFG_SET_TIMEOUT: {
1118                CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
1119                       obd_timeout, lcfg->lcfg_num);
1120                obd_timeout = max(lcfg->lcfg_num, 1U);
1121                obd_timeout_set = 1;
1122                err = 0;
1123                goto out;
1124        }
1125        case LCFG_SET_LDLM_TIMEOUT: {
1126                CDEBUG(D_IOCTL, "changing lustre ldlm_timeout from %d to %d\n",
1127                       ldlm_timeout, lcfg->lcfg_num);
1128                ldlm_timeout = max(lcfg->lcfg_num, 1U);
1129                if (ldlm_timeout >= obd_timeout)
1130                        ldlm_timeout = max(obd_timeout / 3, 1U);
1131                ldlm_timeout_set = 1;
1132                err = 0;
1133                goto out;
1134        }
1135        case LCFG_SET_UPCALL: {
1136                LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
1137                /* COMPAT_146 Don't fail on old configs */
1138                err = 0;
1139                goto out;
1140        }
1141        case LCFG_MARKER: {
1142                struct cfg_marker *marker;
1143                marker = lustre_cfg_buf(lcfg, 1);
1144                CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
1145                       marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
1146                err = 0;
1147                goto out;
1148        }
1149        case LCFG_PARAM: {
1150                char *tmp;
1151                /* llite has no obd */
1152                if ((class_match_param(lustre_cfg_string(lcfg, 1),
1153                                       PARAM_LLITE, NULL) == 0) &&
1154                    client_process_config) {
1155                        err = (*client_process_config)(lcfg);
1156                        goto out;
1157                } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
1158                                              PARAM_SYS, &tmp) == 0)) {
1159                        /* Global param settings */
1160                        err = class_set_global(tmp, lcfg->lcfg_num, lcfg);
1161                        /*
1162                         * Client or server should not fail to mount if
1163                         * it hits an unknown configuration parameter.
1164                         */
1165                        if (err != 0)
1166                                CWARN("Ignoring unknown param %s\n", tmp);
1167
1168                        err = 0;
1169                        goto out;
1170                } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
1171                                              PARAM_QUOTA, &tmp) == 0) &&
1172                           quota_process_config) {
1173                        err = (*quota_process_config)(lcfg);
1174                        goto out;
1175                }
1176
1177                break;
1178        }
1179        case LCFG_SET_PARAM: {
1180                err = process_param2_config(lcfg);
1181                goto out;
1182        }
1183        }
1184        /* Commands that require a device */
1185        obd = class_name2obd(lustre_cfg_string(lcfg, 0));
1186        if (obd == NULL) {
1187                if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
1188                        CERROR("this lcfg command requires a device name\n");
1189                else
1190                        CERROR("no device for: %s\n",
1191                               lustre_cfg_string(lcfg, 0));
1192
1193                err = -EINVAL;
1194                goto out;
1195        }
1196
1197        switch (lcfg->lcfg_command) {
1198        case LCFG_SETUP: {
1199                err = class_setup(obd, lcfg);
1200                goto out;
1201        }
1202        case LCFG_DETACH: {
1203                err = class_detach(obd, lcfg);
1204                err = 0;
1205                goto out;
1206        }
1207        case LCFG_CLEANUP: {
1208                err = class_cleanup(obd, lcfg);
1209                err = 0;
1210                goto out;
1211        }
1212        case LCFG_ADD_CONN: {
1213                err = class_add_conn(obd, lcfg);
1214                err = 0;
1215                goto out;
1216        }
1217        case LCFG_DEL_CONN: {
1218                err = class_del_conn(obd, lcfg);
1219                err = 0;
1220                goto out;
1221        }
1222        case LCFG_POOL_NEW: {
1223                err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
1224                err = 0;
1225                goto out;
1226        }
1227        case LCFG_POOL_ADD: {
1228                err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
1229                                   lustre_cfg_string(lcfg, 3));
1230                err = 0;
1231                goto out;
1232        }
1233        case LCFG_POOL_REM: {
1234                err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
1235                                   lustre_cfg_string(lcfg, 3));
1236                err = 0;
1237                goto out;
1238        }
1239        case LCFG_POOL_DEL: {
1240                err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
1241                err = 0;
1242                goto out;
1243        }
1244        default: {
1245                err = obd_process_config(obd, sizeof(*lcfg), lcfg);
1246                goto out;
1247
1248        }
1249        }
1250out:
1251        if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
1252                CWARN("Ignoring error %d on optional command %#x\n", err,
1253                      lcfg->lcfg_command);
1254                err = 0;
1255        }
1256        return err;
1257}
1258EXPORT_SYMBOL(class_process_config);
1259
1260int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
1261                             struct lustre_cfg *lcfg, void *data)
1262{
1263        struct lprocfs_vars *var;
1264        struct file fakefile;
1265        struct seq_file fake_seqfile;
1266        char *key, *sval;
1267        int i, keylen, vallen;
1268        int matched = 0, j = 0;
1269        int rc = 0;
1270        int skip = 0;
1271
1272        if (lcfg->lcfg_command != LCFG_PARAM) {
1273                CERROR("Unknown command: %d\n", lcfg->lcfg_command);
1274                return -EINVAL;
1275        }
1276
1277        /* fake a seq file so that var->fops->write can work... */
1278        fakefile.private_data = &fake_seqfile;
1279        fake_seqfile.private = data;
1280        /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
1281           or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
1282           or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
1283        for (i = 1; i < lcfg->lcfg_bufcount; i++) {
1284                key = lustre_cfg_buf(lcfg, i);
1285                /* Strip off prefix */
1286                class_match_param(key, prefix, &key);
1287                sval = strchr(key, '=');
1288                if (!sval || (*(sval + 1) == 0)) {
1289                        CERROR("Can't parse param %s (missing '=')\n", key);
1290                        /* rc = -EINVAL;        continue parsing other params */
1291                        continue;
1292                }
1293                keylen = sval - key;
1294                sval++;
1295                vallen = strlen(sval);
1296                matched = 0;
1297                j = 0;
1298                /* Search proc entries */
1299                while (lvars[j].name) {
1300                        var = &lvars[j];
1301                        if (class_match_param(key, (char *)var->name, NULL) == 0
1302                            && keylen == strlen(var->name)) {
1303                                matched++;
1304                                rc = -EROFS;
1305                                if (var->fops && var->fops->write) {
1306                                        mm_segment_t oldfs;
1307                                        oldfs = get_fs();
1308                                        set_fs(KERNEL_DS);
1309                                        rc = (var->fops->write)(&fakefile, sval,
1310                                                                vallen, NULL);
1311                                        set_fs(oldfs);
1312                                }
1313                                break;
1314                        }
1315                        j++;
1316                }
1317                if (!matched) {
1318                        /* If the prefix doesn't match, return error so we
1319                           can pass it down the stack */
1320                        if (strnchr(key, keylen, '.'))
1321                            return -ENOSYS;
1322                        CERROR("%s: unknown param %s\n",
1323                               (char *)lustre_cfg_string(lcfg, 0), key);
1324                        /* rc = -EINVAL;        continue parsing other params */
1325                        skip++;
1326                } else if (rc < 0) {
1327                        CERROR("writing proc entry %s err %d\n",
1328                               var->name, rc);
1329                        rc = 0;
1330                } else {
1331                        CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
1332                                         lustre_cfg_string(lcfg, 0),
1333                                         (int)strlen(prefix) - 1, prefix,
1334                                         (int)(sval - key - 1), key, sval);
1335                }
1336        }
1337
1338        if (rc > 0)
1339                rc = 0;
1340        if (!rc && skip)
1341                rc = skip;
1342        return rc;
1343}
1344EXPORT_SYMBOL(class_process_proc_param);
1345
1346extern int lustre_check_exclusion(struct super_block *sb, char *svname);
1347
1348/** Parse a configuration llog, doing various manipulations on them
1349 * for various reasons, (modifications for compatibility, skip obsolete
1350 * records, change uuids, etc), then class_process_config() resulting
1351 * net records.
1352 */
1353int class_config_llog_handler(const struct lu_env *env,
1354                              struct llog_handle *handle,
1355                              struct llog_rec_hdr *rec, void *data)
1356{
1357        struct config_llog_instance *clli = data;
1358        int cfg_len = rec->lrh_len;
1359        char *cfg_buf = (char *) (rec + 1);
1360        int rc = 0;
1361
1362        //class_config_dump_handler(handle, rec, data);
1363
1364        switch (rec->lrh_type) {
1365        case OBD_CFG_REC: {
1366                struct lustre_cfg *lcfg, *lcfg_new;
1367                struct lustre_cfg_bufs bufs;
1368                char *inst_name = NULL;
1369                int inst_len = 0;
1370                int inst = 0, swab = 0;
1371
1372                lcfg = (struct lustre_cfg *)cfg_buf;
1373                if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
1374                        lustre_swab_lustre_cfg(lcfg);
1375                        swab = 1;
1376                }
1377
1378                rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1379                if (rc)
1380                        goto out;
1381
1382                /* Figure out config state info */
1383                if (lcfg->lcfg_command == LCFG_MARKER) {
1384                        struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1385                        lustre_swab_cfg_marker(marker, swab,
1386                                               LUSTRE_CFG_BUFLEN(lcfg, 1));
1387                        CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
1388                               clli->cfg_flags, marker->cm_flags);
1389                        if (marker->cm_flags & CM_START) {
1390                                /* all previous flags off */
1391                                clli->cfg_flags = CFG_F_MARKER;
1392                                if (marker->cm_flags & CM_SKIP) {
1393                                        clli->cfg_flags |= CFG_F_SKIP;
1394                                        CDEBUG(D_CONFIG, "SKIP #%d\n",
1395                                               marker->cm_step);
1396                                } else if ((marker->cm_flags & CM_EXCLUDE) ||
1397                                           (clli->cfg_sb &&
1398                                            lustre_check_exclusion(clli->cfg_sb,
1399                                                         marker->cm_tgtname))) {
1400                                        clli->cfg_flags |= CFG_F_EXCLUDE;
1401                                        CDEBUG(D_CONFIG, "EXCLUDE %d\n",
1402                                               marker->cm_step);
1403                                }
1404                        } else if (marker->cm_flags & CM_END) {
1405                                clli->cfg_flags = 0;
1406                        }
1407                }
1408                /* A config command without a start marker before it is
1409                   illegal (post 146) */
1410                if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
1411                    !(clli->cfg_flags & CFG_F_MARKER) &&
1412                    (lcfg->lcfg_command != LCFG_MARKER)) {
1413                        CWARN("Config not inside markers, ignoring! (inst: %p, uuid: %s, flags: %#x)\n",
1414                              clli->cfg_instance,
1415                              clli->cfg_uuid.uuid, clli->cfg_flags);
1416                        clli->cfg_flags |= CFG_F_SKIP;
1417                }
1418                if (clli->cfg_flags & CFG_F_SKIP) {
1419                        CDEBUG(D_CONFIG, "skipping %#x\n",
1420                               clli->cfg_flags);
1421                        rc = 0;
1422                        /* No processing! */
1423                        break;
1424                }
1425
1426                /*
1427                 * For interoperability between 1.8 and 2.0,
1428                 * rename "mds" obd device type to "mdt".
1429                 */
1430                {
1431                        char *typename = lustre_cfg_string(lcfg, 1);
1432                        char *index = lustre_cfg_string(lcfg, 2);
1433
1434                        if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
1435                             strcmp(typename, "mds") == 0)) {
1436                                CWARN("For 1.8 interoperability, rename obd type from mds to mdt\n");
1437                                typename[2] = 't';
1438                        }
1439                        if ((lcfg->lcfg_command == LCFG_SETUP && index &&
1440                             strcmp(index, "type") == 0)) {
1441                                CDEBUG(D_INFO, "For 1.8 interoperability, set this index to '0'\n");
1442                                index[0] = '0';
1443                                index[1] = 0;
1444                        }
1445                }
1446
1447
1448                if (clli->cfg_flags & CFG_F_EXCLUDE) {
1449                        CDEBUG(D_CONFIG, "cmd: %x marked EXCLUDED\n",
1450                               lcfg->lcfg_command);
1451                        if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD)
1452                                /* Add inactive instead */
1453                                lcfg->lcfg_command = LCFG_LOV_ADD_INA;
1454                }
1455
1456                lustre_cfg_bufs_init(&bufs, lcfg);
1457
1458                if (clli && clli->cfg_instance &&
1459                    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
1460                        inst = 1;
1461                        inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
1462                                   sizeof(clli->cfg_instance) * 2 + 4;
1463                        inst_name = kzalloc(inst_len, GFP_NOFS);
1464                        if (inst_name == NULL) {
1465                                rc = -ENOMEM;
1466                                goto out;
1467                        }
1468                        sprintf(inst_name, "%s-%p",
1469                                lustre_cfg_string(lcfg, 0),
1470                                clli->cfg_instance);
1471                        lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1472                        CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1473                               lcfg->lcfg_command, inst_name);
1474                }
1475
1476                /* we override the llog's uuid for clients, to insure they
1477                are unique */
1478                if (clli && clli->cfg_instance != NULL &&
1479                    lcfg->lcfg_command == LCFG_ATTACH) {
1480                        lustre_cfg_bufs_set_string(&bufs, 2,
1481                                                   clli->cfg_uuid.uuid);
1482                }
1483                /*
1484                 * sptlrpc config record, we expect 2 data segments:
1485                 *  [0]: fs_name/target_name,
1486                 *  [1]: rule string
1487                 * moving them to index [1] and [2], and insert MGC's
1488                 * obdname at index [0].
1489                 */
1490                if (clli && clli->cfg_instance == NULL &&
1491                    lcfg->lcfg_command == LCFG_SPTLRPC_CONF) {
1492                        lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1],
1493                                            bufs.lcfg_buflen[1]);
1494                        lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0],
1495                                            bufs.lcfg_buflen[0]);
1496                        lustre_cfg_bufs_set_string(&bufs, 0,
1497                                                   clli->cfg_obdname);
1498                }
1499
1500                lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1501
1502                lcfg_new->lcfg_num   = lcfg->lcfg_num;
1503                lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1504
1505                /* XXX Hack to try to remain binary compatible with
1506                 * pre-newconfig logs */
1507                if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
1508                    (lcfg->lcfg_nid >> 32) == 0) {
1509                        __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1510
1511                        lcfg_new->lcfg_nid =
1512                                LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1513                        CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1514                              lcfg->lcfg_nal, addr,
1515                              libcfs_nid2str(lcfg_new->lcfg_nid));
1516                } else {
1517                        lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1518                }
1519
1520                lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1521
1522                rc = class_process_config(lcfg_new);
1523                lustre_cfg_free(lcfg_new);
1524
1525                if (inst)
1526                        kfree(inst_name);
1527                break;
1528        }
1529        default:
1530                CERROR("Unknown llog record type %#x encountered\n",
1531                       rec->lrh_type);
1532                break;
1533        }
1534out:
1535        if (rc) {
1536                CERROR("%s: cfg command failed: rc = %d\n",
1537                       handle->lgh_ctxt->loc_obd->obd_name, rc);
1538                class_config_dump_handler(NULL, handle, rec, data);
1539        }
1540        return rc;
1541}
1542EXPORT_SYMBOL(class_config_llog_handler);
1543
1544int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
1545                            char *name, struct config_llog_instance *cfg)
1546{
1547        struct llog_process_cat_data     cd = {0, 0};
1548        struct llog_handle              *llh;
1549        llog_cb_t                        callback;
1550        int                              rc;
1551
1552        CDEBUG(D_INFO, "looking up llog %s\n", name);
1553        rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1554        if (rc)
1555                return rc;
1556
1557        rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1558        if (rc)
1559                goto parse_out;
1560
1561        /* continue processing from where we last stopped to end-of-log */
1562        if (cfg) {
1563                cd.lpcd_first_idx = cfg->cfg_last_idx;
1564                callback = cfg->cfg_callback;
1565                LASSERT(callback != NULL);
1566        } else {
1567                callback = class_config_llog_handler;
1568        }
1569
1570        cd.lpcd_last_idx = 0;
1571
1572        rc = llog_process(env, llh, callback, cfg, &cd);
1573
1574        CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1575               cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
1576        if (cfg)
1577                cfg->cfg_last_idx = cd.lpcd_last_idx;
1578
1579parse_out:
1580        llog_close(env, llh);
1581        return rc;
1582}
1583EXPORT_SYMBOL(class_config_parse_llog);
1584
1585/**
1586 * parse config record and output dump in supplied buffer.
1587 * This is separated from class_config_dump_handler() to use
1588 * for ioctl needs as well
1589 */
1590int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf, int size)
1591{
1592        struct lustre_cfg       *lcfg = (struct lustre_cfg *)(rec + 1);
1593        char                    *ptr = buf;
1594        char                    *end = buf + size;
1595        int                      rc = 0;
1596
1597        LASSERT(rec->lrh_type == OBD_CFG_REC);
1598        rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
1599        if (rc < 0)
1600                return rc;
1601
1602        ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
1603        if (lcfg->lcfg_flags)
1604                ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1605                                lcfg->lcfg_flags);
1606
1607        if (lcfg->lcfg_num)
1608                ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
1609
1610        if (lcfg->lcfg_nid)
1611                ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n     ",
1612                                libcfs_nid2str(lcfg->lcfg_nid),
1613                                lcfg->lcfg_nid);
1614
1615        if (lcfg->lcfg_command == LCFG_MARKER) {
1616                struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1617
1618                ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1619                                marker->cm_step, marker->cm_flags,
1620                                marker->cm_tgtname, marker->cm_comment);
1621        } else {
1622                int i;
1623
1624                for (i = 0; i <  lcfg->lcfg_bufcount; i++) {
1625                        ptr += snprintf(ptr, end-ptr, "%d:%s  ", i,
1626                                        lustre_cfg_string(lcfg, i));
1627                }
1628        }
1629        /* return consumed bytes */
1630        rc = ptr - buf;
1631        return rc;
1632}
1633
1634int class_config_dump_handler(const struct lu_env *env,
1635                              struct llog_handle *handle,
1636                              struct llog_rec_hdr *rec, void *data)
1637{
1638        char    *outstr;
1639        int      rc = 0;
1640
1641        outstr = kzalloc(256, GFP_NOFS);
1642        if (outstr == NULL)
1643                return -ENOMEM;
1644
1645        if (rec->lrh_type == OBD_CFG_REC) {
1646                class_config_parse_rec(rec, outstr, 256);
1647                LCONSOLE(D_WARNING, "   %s\n", outstr);
1648        } else {
1649                LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1650                rc = -EINVAL;
1651        }
1652
1653        kfree(outstr);
1654        return rc;
1655}
1656
1657int class_config_dump_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
1658                           char *name, struct config_llog_instance *cfg)
1659{
1660        struct llog_handle      *llh;
1661        int                      rc;
1662
1663        LCONSOLE_INFO("Dumping config log %s\n", name);
1664
1665        rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1666        if (rc)
1667                return rc;
1668
1669        rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1670        if (rc)
1671                goto parse_out;
1672
1673        rc = llog_process(env, llh, class_config_dump_handler, cfg, NULL);
1674parse_out:
1675        llog_close(env, llh);
1676
1677        LCONSOLE_INFO("End config log %s\n", name);
1678        return rc;
1679}
1680EXPORT_SYMBOL(class_config_dump_llog);
1681
1682/** Call class_cleanup and class_detach.
1683 * "Manual" only in the sense that we're faking lcfg commands.
1684 */
1685int class_manual_cleanup(struct obd_device *obd)
1686{
1687        char                flags[3] = "";
1688        struct lustre_cfg      *lcfg;
1689        struct lustre_cfg_bufs  bufs;
1690        int                  rc;
1691
1692        if (!obd) {
1693                CERROR("empty cleanup\n");
1694                return -EALREADY;
1695        }
1696
1697        if (obd->obd_force)
1698                strcat(flags, "F");
1699        if (obd->obd_fail)
1700                strcat(flags, "A");
1701
1702        CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1703               obd->obd_name, flags);
1704
1705        lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1706        lustre_cfg_bufs_set_string(&bufs, 1, flags);
1707        lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1708        if (!lcfg)
1709                return -ENOMEM;
1710
1711        rc = class_process_config(lcfg);
1712        if (rc) {
1713                CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1714                goto out;
1715        }
1716
1717        /* the lcfg is almost the same for both ops */
1718        lcfg->lcfg_command = LCFG_DETACH;
1719        rc = class_process_config(lcfg);
1720        if (rc)
1721                CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1722out:
1723        lustre_cfg_free(lcfg);
1724        return rc;
1725}
1726EXPORT_SYMBOL(class_manual_cleanup);
1727
1728/*
1729 * uuid<->export lustre hash operations
1730 */
1731
1732static unsigned
1733uuid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
1734{
1735        return cfs_hash_djb2_hash(((struct obd_uuid *)key)->uuid,
1736                                  sizeof(((struct obd_uuid *)key)->uuid), mask);
1737}
1738
1739static void *
1740uuid_key(struct hlist_node *hnode)
1741{
1742        struct obd_export *exp;
1743
1744        exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1745
1746        return &exp->exp_client_uuid;
1747}
1748
1749/*
1750 * NOTE: It is impossible to find an export that is in failed
1751 *       state with this function
1752 */
1753static int
1754uuid_keycmp(const void *key, struct hlist_node *hnode)
1755{
1756        struct obd_export *exp;
1757
1758        LASSERT(key);
1759        exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1760
1761        return obd_uuid_equals(key, &exp->exp_client_uuid) &&
1762               !exp->exp_failed;
1763}
1764
1765static void *
1766uuid_export_object(struct hlist_node *hnode)
1767{
1768        return hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1769}
1770
1771static void
1772uuid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
1773{
1774        struct obd_export *exp;
1775
1776        exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1777        class_export_get(exp);
1778}
1779
1780static void
1781uuid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1782{
1783        struct obd_export *exp;
1784
1785        exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1786        class_export_put(exp);
1787}
1788
1789static cfs_hash_ops_t uuid_hash_ops = {
1790        .hs_hash        = uuid_hash,
1791        .hs_key  = uuid_key,
1792        .hs_keycmp      = uuid_keycmp,
1793        .hs_object      = uuid_export_object,
1794        .hs_get  = uuid_export_get,
1795        .hs_put_locked  = uuid_export_put_locked,
1796};
1797
1798
1799/*
1800 * nid<->export hash operations
1801 */
1802
1803static unsigned
1804nid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
1805{
1806        return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask);
1807}
1808
1809static void *
1810nid_key(struct hlist_node *hnode)
1811{
1812        struct obd_export *exp;
1813
1814        exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1815
1816        return &exp->exp_connection->c_peer.nid;
1817}
1818
1819/*
1820 * NOTE: It is impossible to find an export that is in failed
1821 *       state with this function
1822 */
1823static int
1824nid_kepcmp(const void *key, struct hlist_node *hnode)
1825{
1826        struct obd_export *exp;
1827
1828        LASSERT(key);
1829        exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1830
1831        return exp->exp_connection->c_peer.nid == *(lnet_nid_t *)key &&
1832               !exp->exp_failed;
1833}
1834
1835static void *
1836nid_export_object(struct hlist_node *hnode)
1837{
1838        return hlist_entry(hnode, struct obd_export, exp_nid_hash);
1839}
1840
1841static void
1842nid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
1843{
1844        struct obd_export *exp;
1845
1846        exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1847        class_export_get(exp);
1848}
1849
1850static void
1851nid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1852{
1853        struct obd_export *exp;
1854
1855        exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1856        class_export_put(exp);
1857}
1858
1859static cfs_hash_ops_t nid_hash_ops = {
1860        .hs_hash        = nid_hash,
1861        .hs_key  = nid_key,
1862        .hs_keycmp      = nid_kepcmp,
1863        .hs_object      = nid_export_object,
1864        .hs_get  = nid_export_get,
1865        .hs_put_locked  = nid_export_put_locked,
1866};
1867