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