1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/obd_config.c
41 #define DEBUG_SUBSYSTEM S_CLASS
43 #include <obd_class.h>
44 #include <linux/string.h>
46 #include <liblustre.h>
47 #include <obd_class.h>
50 #include <lustre_disk.h>
51 #include <lustre_log.h>
52 #include <lprocfs_status.h>
53 #include <libcfs/list.h>
54 #include <lustre_param.h>
55 #include <class_hash.h>
57 static lustre_hash_ops_t uuid_hash_ops;
58 static lustre_hash_ops_t nid_hash_ops;
59 static lustre_hash_ops_t nid_stat_hash_ops;
61 /*********** string parsing utils *********/
63 /* returns 0 if we find this key in the buffer, else 1 */
64 int class_find_param(char *buf, char *key, char **valp)
71 if ((ptr = strstr(buf, key)) == NULL)
75 *valp = ptr + strlen(key);
80 /* returns 0 if this is the first key in the buffer, else 1.
81 valp points to first char after key. */
82 int class_match_param(char *buf, char *key, char **valp)
87 if (memcmp(buf, key, strlen(key)) != 0)
91 *valp = buf + strlen(key);
99 endh is set to next separator */
100 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
106 while (*buf == ',' || *buf == ':')
108 if (*buf == ' ' || *buf == '/' || *buf == '\0')
111 /* nid separators or end of nids */
112 endp = strpbrk(buf, ",: /");
114 endp = buf + strlen(buf);
118 *nid = libcfs_str2nid(buf);
119 if (*nid == LNET_NID_ANY) {
120 LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
128 CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));
132 EXPORT_SYMBOL(class_find_param);
133 EXPORT_SYMBOL(class_match_param);
134 EXPORT_SYMBOL(class_parse_nid);
136 /********************** class fns **********************/
138 /* Create a new device and set the type, name and uuid. If
139 * successful, the new device can be accessed by either name or uuid.
141 int class_attach(struct lustre_cfg *lcfg)
143 struct obd_device *obd = NULL;
144 char *typename, *name, *uuid;
148 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
149 CERROR("No type passed!\n");
152 typename = lustre_cfg_string(lcfg, 1);
154 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
155 CERROR("No name passed!\n");
158 name = lustre_cfg_string(lcfg, 0);
160 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
161 CERROR("No UUID passed!\n");
164 uuid = lustre_cfg_string(lcfg, 2);
166 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
167 MKSTR(typename), MKSTR(name), MKSTR(uuid));
169 /* Mountconf transitional hack, should go away after 1.6.
170 1.4.7 uses the old names, so translate back if the
171 mountconf flag is set.
172 1.6 should set this flag, and translate the other way here
174 if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
176 if (strcmp(typename, "mds") == 0)
178 if (strcmp(typename, "mdt") == 0)
180 if (strcmp(typename, "osd") == 0)
183 LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
184 MKSTR(typename), MKSTR(name));
189 obd = class_newdev(typename, name);
191 /* Already exists or out of obds */
194 CERROR("Cannot create device %s of type %s : %d\n",
198 LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
200 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
201 "obd %p obd_magic %08X != %08X\n",
202 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
203 LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
204 "%p obd_name %s != %s\n", obd, obd->obd_name, name);
206 rwlock_init(&obd->obd_pool_lock);
207 obd->obd_pool_limit = 0;
208 obd->obd_pool_slv = 0;
210 CFS_INIT_LIST_HEAD(&obd->obd_exports);
211 CFS_INIT_LIST_HEAD(&obd->obd_delayed_exports);
212 CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
213 CFS_INIT_LIST_HEAD(&obd->obd_nid_stats);
214 spin_lock_init(&obd->obd_nid_lock);
215 spin_lock_init(&obd->obd_dev_lock);
216 sema_init(&obd->obd_dev_sem, 1);
217 spin_lock_init(&obd->obd_osfs_lock);
218 /* obd->obd_osfs_age must be set to a value in the distant
219 * past to guarantee a fresh statfs is fetched on mount. */
220 obd->obd_osfs_age = cfs_time_shift_64(-1000);
222 /* XXX belongs in setup not attach */
224 cfs_init_timer(&obd->obd_recovery_timer);
225 spin_lock_init(&obd->obd_processing_task_lock);
226 cfs_waitq_init(&obd->obd_next_transno_waitq);
227 cfs_waitq_init(&obd->obd_evict_inprogress_waitq);
228 cfs_waitq_init(&obd->obd_llog_waitq);
229 init_mutex(&obd->obd_llog_cat_process);
230 init_rwsem(&obd->obd_observer_link_sem);
231 CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);
232 CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
233 CFS_INIT_LIST_HEAD(&obd->obd_evict_list);
236 if (len >= sizeof(obd->obd_uuid)) {
237 CERROR("uuid must be < %d bytes long\n",
238 (int)sizeof(obd->obd_uuid));
239 GOTO(out, rc = -EINVAL);
241 memcpy(obd->obd_uuid.uuid, uuid, len);
244 if (OBP(obd, attach)) {
245 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
247 GOTO(out, rc = -EINVAL);
250 /* Detach drops this */
251 spin_lock(&obd->obd_dev_lock);
252 atomic_set(&obd->obd_refcount, 1);
253 spin_unlock(&obd->obd_dev_lock);
255 obd->obd_attached = 1;
256 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
257 obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
261 class_release_dev(obd);
266 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
269 struct obd_export *exp;
272 LASSERT(obd != NULL);
273 LASSERTF(obd == class_num2obd(obd->obd_minor),
274 "obd %p != obd_devs[%d] %p\n",
275 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
276 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
277 "obd %p obd_magic %08x != %08x\n",
278 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
280 /* have we attached a type to this device? */
281 if (!obd->obd_attached) {
282 CERROR("Device %d not attached\n", obd->obd_minor);
286 if (obd->obd_set_up) {
287 CERROR("Device %d already setup (type %s)\n",
288 obd->obd_minor, obd->obd_type->typ_name);
292 /* is someone else setting us up right now? (attach inits spinlock) */
293 spin_lock(&obd->obd_dev_lock);
294 if (obd->obd_starting) {
295 spin_unlock(&obd->obd_dev_lock);
296 CERROR("Device %d setup in progress (type %s)\n",
297 obd->obd_minor, obd->obd_type->typ_name);
300 /* just leave this on forever. I can't use obd_set_up here because
301 other fns check that status, and we're not actually set up yet. */
302 obd->obd_starting = 1;
303 obd->obd_uuid_hash = NULL;
304 obd->obd_nid_hash = NULL;
305 obd->obd_nid_stats_hash = NULL;
306 spin_unlock(&obd->obd_dev_lock);
308 /* create an uuid-export lustre hash */
309 obd->obd_uuid_hash = lustre_hash_init("UUID_HASH",
312 &uuid_hash_ops, LH_REHASH);
313 if (!obd->obd_uuid_hash)
314 GOTO(err_hash, err = -ENOMEM);
316 /* create a nid-export lustre hash */
317 obd->obd_nid_hash = lustre_hash_init("NID_HASH",
320 &nid_hash_ops, LH_REHASH);
321 if (!obd->obd_nid_hash)
322 GOTO(err_hash, err = -ENOMEM);
324 /* create a nid-stats lustre hash */
325 obd->obd_nid_stats_hash = lustre_hash_init("NID_STATS",
326 HASH_NID_STATS_CUR_BITS,
327 HASH_NID_STATS_MAX_BITS,
330 if (!obd->obd_nid_stats_hash)
331 GOTO(err_hash, err = -ENOMEM);
333 exp = class_new_export(obd, &obd->obd_uuid);
335 GOTO(err_hash, err = PTR_ERR(exp));
337 obd->obd_self_export = exp;
338 list_del_init(&exp->exp_obd_chain_timed);
339 class_export_put(exp);
341 err = obd_setup(obd, sizeof(*lcfg), lcfg);
346 spin_lock(&obd->obd_dev_lock);
347 /* cleanup drops this */
349 spin_unlock(&obd->obd_dev_lock);
351 CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
352 obd->obd_name, obd->obd_uuid.uuid);
356 class_unlink_export(obd->obd_self_export);
357 obd->obd_self_export = NULL;
359 if (obd->obd_uuid_hash) {
360 lustre_hash_exit(obd->obd_uuid_hash);
361 obd->obd_uuid_hash = NULL;
363 if (obd->obd_nid_hash) {
364 lustre_hash_exit(obd->obd_nid_hash);
365 obd->obd_nid_hash = NULL;
367 if (obd->obd_nid_stats_hash) {
368 lustre_hash_exit(obd->obd_nid_stats_hash);
369 obd->obd_nid_stats_hash = NULL;
371 obd->obd_starting = 0;
372 CERROR("setup %s failed (%d)\n", obd->obd_name, err);
376 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
380 if (obd->obd_set_up) {
381 CERROR("OBD device %d still set up\n", obd->obd_minor);
385 spin_lock(&obd->obd_dev_lock);
386 if (!obd->obd_attached) {
387 spin_unlock(&obd->obd_dev_lock);
388 CERROR("OBD device %d not attached\n", obd->obd_minor);
391 obd->obd_attached = 0;
392 spin_unlock(&obd->obd_dev_lock);
394 CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
395 obd->obd_name, obd->obd_uuid.uuid);
399 /* not strictly necessary, but cleans up eagerly */
400 obd_zombie_impexp_cull();
405 static void dump_exports(struct obd_device *obd)
407 struct obd_export *exp;
409 spin_lock(&obd->obd_dev_lock);
410 list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
411 struct ptlrpc_reply_state *rs;
412 struct ptlrpc_reply_state *first_reply = NULL;
415 spin_lock(&exp->exp_lock);
416 list_for_each_entry (rs, &exp->exp_outstanding_replies,
422 spin_unlock(&exp->exp_lock);
424 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
425 obd->obd_name, exp, exp->exp_client_uuid.uuid,
426 obd_export_nid2str(exp),
427 atomic_read(&exp->exp_refcount),
428 exp->exp_failed, nreplies, first_reply,
429 nreplies > 3 ? "..." : "");
431 spin_unlock(&obd->obd_dev_lock);
434 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
440 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
442 if (!obd->obd_set_up) {
443 CERROR("Device %d not setup\n", obd->obd_minor);
447 spin_lock(&obd->obd_dev_lock);
448 if (obd->obd_stopping) {
449 spin_unlock(&obd->obd_dev_lock);
450 CERROR("OBD %d already stopping\n", obd->obd_minor);
453 /* Leave this on forever */
454 obd->obd_stopping = 1;
455 spin_unlock(&obd->obd_dev_lock);
457 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
458 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
464 LCONSOLE_WARN("Failing over %s\n",
467 obd->obd_no_transno = 1;
468 obd->obd_no_recov = 1;
469 /* Set the obd readonly if we can */
470 if (OBP(obd, iocontrol))
471 obd_iocontrol(OBD_IOC_SET_READONLY,
472 obd->obd_self_export,
476 CERROR("unrecognised flag '%c'\n",
481 /* The three references that should be remaining are the
482 * obd_self_export and the attach and setup references. */
483 if (atomic_read(&obd->obd_refcount) > 3) {
484 #if 0 /* We should never fail to cleanup with mountconf */
485 if (!(obd->obd_fail || obd->obd_force)) {
486 CERROR("OBD %s is still busy with %d references\n"
487 "You should stop active file system users,"
488 " or use the --force option to cleanup.\n",
489 obd->obd_name, atomic_read(&obd->obd_refcount));
491 /* Allow a failed cleanup to try again. */
492 obd->obd_stopping = 0;
496 /* refcounf - 3 might be the number of real exports
497 (excluding self export). But class_incref is called
498 by other things as well, so don't count on it. */
499 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
500 obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
502 class_disconnect_exports(obd);
505 LASSERT(obd->obd_self_export);
507 /* destroy an uuid-export hash body */
508 lustre_hash_exit(obd->obd_uuid_hash);
510 /* destroy a nid-export hash body */
511 lustre_hash_exit(obd->obd_nid_hash);
513 /* destroy a nid-stats hash body */
514 lustre_hash_exit(obd->obd_nid_stats_hash);
516 /* Precleanup stage 1, we must make sure all exports (other than the
517 self-export) get destroyed. */
518 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
520 CERROR("Precleanup %s returned %d\n",
528 struct obd_device *class_incref(struct obd_device *obd)
530 atomic_inc(&obd->obd_refcount);
531 CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
532 atomic_read(&obd->obd_refcount));
537 void class_decref(struct obd_device *obd)
542 spin_lock(&obd->obd_dev_lock);
543 atomic_dec(&obd->obd_refcount);
544 refs = atomic_read(&obd->obd_refcount);
545 spin_unlock(&obd->obd_dev_lock);
547 CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
549 if ((refs == 1) && obd->obd_stopping) {
550 /* All exports (other than the self-export) have been
551 destroyed; there should be no more in-progress ops
553 /* if we're not stopping, we didn't finish setup */
554 /* Precleanup stage 2, do other type-specific
555 cleanup requiring the self-export. */
556 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
558 CERROR("Precleanup %s returned %d\n",
561 spin_lock(&obd->obd_self_export->exp_lock);
562 obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
563 spin_unlock(&obd->obd_self_export->exp_lock);
565 /* note that we'll recurse into class_decref again */
566 class_unlink_export(obd->obd_self_export);
571 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
572 obd->obd_name, obd->obd_uuid.uuid);
573 LASSERT(!obd->obd_attached);
574 if (obd->obd_stopping) {
575 /* If we're not stopping, we were never set up */
576 err = obd_cleanup(obd);
578 CERROR("Cleanup %s returned %d\n",
581 if (OBP(obd, detach)) {
582 err = OBP(obd,detach)(obd);
584 CERROR("Detach returned %d\n", err);
586 class_release_dev(obd);
590 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
592 struct obd_import *imp;
593 struct obd_uuid uuid;
597 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
598 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
599 CERROR("invalid conn_uuid\n");
602 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
603 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
604 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
605 CERROR("can't add connection on non-client dev\n");
609 imp = obd->u.cli.cl_import;
611 CERROR("try to add conn on immature client dev\n");
615 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
616 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
621 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
623 struct obd_import *imp;
624 struct obd_uuid uuid;
628 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
629 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
630 CERROR("invalid conn_uuid\n");
633 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
634 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
635 CERROR("can't del connection on non-client dev\n");
639 imp = obd->u.cli.cl_import;
641 CERROR("try to del conn on immature client dev\n");
645 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
646 rc = obd_del_conn(imp, &uuid);
651 CFS_LIST_HEAD(lustre_profile_list);
653 struct lustre_profile *class_get_profile(char * prof)
655 struct lustre_profile *lprof;
658 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
659 if (!strcmp(lprof->lp_profile, prof)) {
666 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
667 int mdclen, char *mdc)
669 struct lustre_profile *lprof;
673 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
675 OBD_ALLOC(lprof, sizeof(*lprof));
678 CFS_INIT_LIST_HEAD(&lprof->lp_list);
680 LASSERT(proflen == (strlen(prof) + 1));
681 OBD_ALLOC(lprof->lp_profile, proflen);
682 if (lprof->lp_profile == NULL)
683 GOTO(out, err = -ENOMEM);
684 memcpy(lprof->lp_profile, prof, proflen);
686 LASSERT(osclen == (strlen(osc) + 1));
687 OBD_ALLOC(lprof->lp_osc, osclen);
688 if (lprof->lp_osc == NULL)
689 GOTO(out, err = -ENOMEM);
690 memcpy(lprof->lp_osc, osc, osclen);
693 LASSERT(mdclen == (strlen(mdc) + 1));
694 OBD_ALLOC(lprof->lp_mdc, mdclen);
695 if (lprof->lp_mdc == NULL)
696 GOTO(out, err = -ENOMEM);
697 memcpy(lprof->lp_mdc, mdc, mdclen);
700 list_add(&lprof->lp_list, &lustre_profile_list);
705 OBD_FREE(lprof->lp_mdc, mdclen);
707 OBD_FREE(lprof->lp_osc, osclen);
708 if (lprof->lp_profile)
709 OBD_FREE(lprof->lp_profile, proflen);
710 OBD_FREE(lprof, sizeof(*lprof));
714 void class_del_profile(char *prof)
716 struct lustre_profile *lprof;
719 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
721 lprof = class_get_profile(prof);
723 list_del(&lprof->lp_list);
724 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
725 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
727 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
728 OBD_FREE(lprof, sizeof *lprof);
734 void class_del_profiles(void)
736 struct lustre_profile *lprof, *n;
739 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
740 list_del(&lprof->lp_list);
741 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
742 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
744 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
745 OBD_FREE(lprof, sizeof *lprof);
750 static int class_set_global(char *ptr, int val) {
753 if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
755 else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
757 else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
759 else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
760 at_early_margin = val;
761 else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
766 CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
772 /* We can't call ll_process_config directly because it lives in a module that
773 must be loaded after this one. */
774 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
776 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
778 client_process_config = cpc;
780 EXPORT_SYMBOL(lustre_register_client_process_config);
782 int class_process_config(struct lustre_cfg *lcfg)
784 struct obd_device *obd;
787 LASSERT(lcfg && !IS_ERR(lcfg));
788 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
790 /* Commands that don't need a device */
791 switch(lcfg->lcfg_command) {
793 err = class_attach(lcfg);
796 case LCFG_ADD_UUID: {
797 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
798 " (%s)\n", lustre_cfg_string(lcfg, 1),
799 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
801 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
804 case LCFG_DEL_UUID: {
805 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
806 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
807 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
809 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
812 case LCFG_MOUNTOPT: {
813 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
814 lustre_cfg_string(lcfg, 1),
815 lustre_cfg_string(lcfg, 2),
816 lustre_cfg_string(lcfg, 3));
817 /* set these mount options somewhere, so ll_fill_super
819 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
820 lustre_cfg_string(lcfg, 1),
821 LUSTRE_CFG_BUFLEN(lcfg, 2),
822 lustre_cfg_string(lcfg, 2),
823 LUSTRE_CFG_BUFLEN(lcfg, 3),
824 lustre_cfg_string(lcfg, 3));
827 case LCFG_DEL_MOUNTOPT: {
828 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
829 lustre_cfg_string(lcfg, 1));
830 class_del_profile(lustre_cfg_string(lcfg, 1));
833 case LCFG_SET_TIMEOUT: {
834 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
835 obd_timeout, lcfg->lcfg_num);
836 obd_timeout = max(lcfg->lcfg_num, 1U);
839 case LCFG_SET_LDLM_TIMEOUT: {
840 CDEBUG(D_IOCTL, "changing lustre ldlm_timeout from %d to %d\n",
841 ldlm_timeout, lcfg->lcfg_num);
842 ldlm_timeout = max(lcfg->lcfg_num, 1U);
843 if (ldlm_timeout >= obd_timeout)
844 ldlm_timeout = max(obd_timeout / 3, 1U);
848 case LCFG_SET_UPCALL: {
849 LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
850 /* COMPAT_146 Don't fail on old configs */
854 struct cfg_marker *marker;
855 marker = lustre_cfg_buf(lcfg, 1);
856 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
857 marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
862 /* llite has no obd */
863 if ((class_match_param(lustre_cfg_string(lcfg, 1),
864 PARAM_LLITE, 0) == 0) &&
865 client_process_config) {
866 err = (*client_process_config)(lcfg);
868 } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
869 PARAM_SYS, &tmp) == 0)) {
870 /* Global param settings */
871 err = class_set_global(tmp, lcfg->lcfg_num);
872 /* Note that since LCFG_PARAM is LCFG_REQUIRED, new
873 unknown globals would cause config to fail */
875 CWARN("Ignoring unknown param %s\n", tmp);
884 /* Commands that require a device */
885 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
887 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
888 CERROR("this lcfg command requires a device name\n");
890 CERROR("no device for: %s\n",
891 lustre_cfg_string(lcfg, 0));
893 GOTO(out, err = -EINVAL);
896 switch(lcfg->lcfg_command) {
898 err = class_setup(obd, lcfg);
902 err = class_detach(obd, lcfg);
906 err = class_cleanup(obd, lcfg);
909 case LCFG_ADD_CONN: {
910 err = class_add_conn(obd, lcfg);
913 case LCFG_DEL_CONN: {
914 err = class_del_conn(obd, lcfg);
917 case LCFG_POOL_NEW: {
918 err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
922 case LCFG_POOL_ADD: {
923 err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
924 lustre_cfg_string(lcfg, 3));
928 case LCFG_POOL_REM: {
929 err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
930 lustre_cfg_string(lcfg, 3));
934 case LCFG_POOL_DEL: {
935 err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
940 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
946 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
947 CWARN("Ignoring error %d on optional command %#x\n", err,
954 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
955 struct lustre_cfg *lcfg, void *data)
958 struct lprocfs_vars *var;
961 int matched = 0, j = 0;
965 if (lcfg->lcfg_command != LCFG_PARAM) {
966 CERROR("Unknown command: %x\n", lcfg->lcfg_command);
970 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
971 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
972 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
973 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
974 key = lustre_cfg_buf(lcfg, i);
975 /* Strip off prefix */
976 class_match_param(key, prefix, &key);
977 sval = strchr(key, '=');
978 if (!sval || (*(sval + 1) == 0)) {
979 CERROR("Can't parse param %s\n", key);
981 /* continue parsing other params */
985 vallen = strlen(sval);
988 /* Search proc entries */
989 while (lvars[j].name) {
991 if (class_match_param(key, (char *)var->name, 0) == 0) {
994 if (var->write_fptr) {
998 rc = (var->write_fptr)(NULL, sval,
1003 CERROR("writing proc entry %s err %d\n",
1010 CERROR("%s: unknown param %s\n",
1011 (char *)lustre_cfg_string(lcfg, 0), key);
1012 /* rc = -EINVAL; continue parsing other params */
1014 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
1015 lustre_cfg_string(lcfg, 0),
1016 (int)strlen(prefix) - 1, prefix,
1017 (int)(sval - key - 1), key, sval);
1025 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
1026 /* Don't throw config error */
1031 int class_config_dump_handler(struct llog_handle * handle,
1032 struct llog_rec_hdr *rec, void *data);
1035 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
1037 #define lustre_check_exclusion(a,b) 0
1040 static int class_config_llog_handler(struct llog_handle * handle,
1041 struct llog_rec_hdr *rec, void *data)
1043 struct config_llog_instance *clli = data;
1044 int cfg_len = rec->lrh_len;
1045 char *cfg_buf = (char*) (rec + 1);
1049 //class_config_dump_handler(handle, rec, data);
1051 switch (rec->lrh_type) {
1053 struct lustre_cfg *lcfg, *lcfg_new;
1054 struct lustre_cfg_bufs bufs;
1055 char *inst_name = NULL;
1057 int inst = 0, swab = 0;
1059 lcfg = (struct lustre_cfg *)cfg_buf;
1060 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
1061 lustre_swab_lustre_cfg(lcfg);
1065 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1069 /* Figure out config state info */
1070 if (lcfg->lcfg_command == LCFG_MARKER) {
1071 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1072 lustre_swab_cfg_marker(marker, swab,
1073 LUSTRE_CFG_BUFLEN(lcfg, 1));
1074 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
1075 clli->cfg_flags, marker->cm_flags);
1076 if (marker->cm_flags & CM_START) {
1077 /* all previous flags off */
1078 clli->cfg_flags = CFG_F_MARKER;
1079 if (marker->cm_flags & CM_SKIP) {
1080 clli->cfg_flags |= CFG_F_SKIP;
1081 CDEBUG(D_CONFIG, "SKIP #%d\n",
1083 } else if ((marker->cm_flags & CM_EXCLUDE) ||
1084 lustre_check_exclusion(clli->cfg_sb,
1085 marker->cm_tgtname)) {
1086 clli->cfg_flags |= CFG_F_EXCLUDE;
1087 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
1090 } else if (marker->cm_flags & CM_END) {
1091 clli->cfg_flags = 0;
1094 /* A config command without a start marker before it is
1095 illegal (post 146) */
1096 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
1097 !(clli->cfg_flags & CFG_F_MARKER) &&
1098 (lcfg->lcfg_command != LCFG_MARKER)) {
1099 CWARN("Config not inside markers, ignoring! (%#x)\n",
1101 clli->cfg_flags |= CFG_F_SKIP;
1104 if (clli->cfg_flags & CFG_F_SKIP) {
1105 CDEBUG(D_CONFIG, "skipping %#x\n",
1108 /* No processing! */
1113 * For interop mode between 1.8 and 2.0:
1114 * skip "lmv" configuration which exists since 2.0.
1117 char *devname = lustre_cfg_string(lcfg, 0);
1118 char *typename = lustre_cfg_string(lcfg, 1);
1121 devname += strlen(devname) - strlen("clilmv");
1123 if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
1124 strcmp(typename, "lmv") == 0) ||
1125 (devname && strcmp(devname, "clilmv") == 0)) {
1126 CWARN("skipping 'lmv' config: cmd=%x,%s:%s\n",
1127 lcfg->lcfg_command, devname, typename);
1132 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
1133 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
1134 /* Add inactive instead */
1135 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
1137 lustre_cfg_bufs_init(&bufs, lcfg);
1139 if (clli && clli->cfg_instance &&
1140 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
1142 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
1143 strlen(clli->cfg_instance) + 1;
1144 OBD_ALLOC(inst_name, inst_len);
1145 if (inst_name == NULL)
1146 GOTO(out, rc = -ENOMEM);
1147 sprintf(inst_name, "%s-%s",
1148 lustre_cfg_string(lcfg, 0),
1149 clli->cfg_instance);
1150 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1151 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1152 lcfg->lcfg_command, inst_name);
1155 /* we override the llog's uuid for clients, to insure they
1157 if (clli && clli->cfg_instance &&
1158 lcfg->lcfg_command == LCFG_ATTACH) {
1159 lustre_cfg_bufs_set_string(&bufs, 2,
1160 clli->cfg_uuid.uuid);
1163 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1165 lcfg_new->lcfg_num = lcfg->lcfg_num;
1166 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1168 /* XXX Hack to try to remain binary compatible with
1169 * pre-newconfig logs */
1170 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1171 (lcfg->lcfg_nid >> 32) == 0) {
1172 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1174 lcfg_new->lcfg_nid =
1175 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1176 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1177 lcfg->lcfg_nal, addr,
1178 libcfs_nid2str(lcfg_new->lcfg_nid));
1180 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1183 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1185 rc = class_process_config(lcfg_new);
1186 lustre_cfg_free(lcfg_new);
1189 OBD_FREE(inst_name, inst_len);
1193 CERROR("Unknown llog record type %#x encountered\n",
1199 CERROR("Err %d on cfg command:\n", rc);
1200 class_config_dump_handler(handle, rec, data);
1205 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1206 struct config_llog_instance *cfg)
1208 struct llog_process_cat_data cd = {0, 0};
1209 struct llog_handle *llh;
1213 CDEBUG(D_INFO, "looking up llog %s\n", name);
1214 rc = llog_create(ctxt, &llh, NULL, name);
1218 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1220 GOTO(parse_out, rc);
1222 /* continue processing from where we last stopped to end-of-log */
1224 cd.lpcd_first_idx = cfg->cfg_last_idx;
1225 cd.lpcd_last_idx = 0;
1227 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1229 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1230 cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
1232 cfg->cfg_last_idx = cd.lpcd_last_idx;
1235 rc2 = llog_close(llh);
1242 int class_config_dump_handler(struct llog_handle * handle,
1243 struct llog_rec_hdr *rec, void *data)
1245 int cfg_len = rec->lrh_len;
1246 char *cfg_buf = (char*) (rec + 1);
1247 char *outstr, *ptr, *end;
1251 OBD_ALLOC(outstr, 256);
1257 if (rec->lrh_type == OBD_CFG_REC) {
1258 struct lustre_cfg *lcfg;
1261 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1264 lcfg = (struct lustre_cfg *)cfg_buf;
1266 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1267 lcfg->lcfg_command);
1268 if (lcfg->lcfg_flags) {
1269 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1272 if (lcfg->lcfg_num) {
1273 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1276 if (lcfg->lcfg_nid) {
1277 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1278 libcfs_nid2str(lcfg->lcfg_nid),
1281 if (lcfg->lcfg_command == LCFG_MARKER) {
1282 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1283 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1284 marker->cm_step, marker->cm_flags,
1285 marker->cm_tgtname, marker->cm_comment);
1287 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1288 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1289 lustre_cfg_string(lcfg, i));
1292 LCONSOLE(D_WARNING, " %s\n", outstr);
1294 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1298 OBD_FREE(outstr, 256);
1302 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1303 struct config_llog_instance *cfg)
1305 struct llog_handle *llh;
1309 LCONSOLE_INFO("Dumping config log %s\n", name);
1311 rc = llog_create(ctxt, &llh, NULL, name);
1315 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1317 GOTO(parse_out, rc);
1319 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1321 rc2 = llog_close(llh);
1325 LCONSOLE_INFO("End config log %s\n", name);
1330 /* Cleanup and detach */
1331 int class_manual_cleanup(struct obd_device *obd)
1333 struct lustre_cfg *lcfg;
1334 struct lustre_cfg_bufs bufs;
1340 CERROR("empty cleanup\n");
1349 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1350 obd->obd_name, flags);
1352 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1353 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1354 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1356 rc = class_process_config(lcfg);
1358 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1362 /* the lcfg is almost the same for both ops */
1363 lcfg->lcfg_command = LCFG_DETACH;
1364 rc = class_process_config(lcfg);
1366 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1368 lustre_cfg_free(lcfg);
1373 * uuid<->export lustre hash operations
1377 uuid_hash(lustre_hash_t *lh, void *key, unsigned mask)
1379 return lh_djb2_hash(((struct obd_uuid *)key)->uuid,
1380 sizeof(((struct obd_uuid *)key)->uuid), mask);
1384 uuid_key(struct hlist_node *hnode)
1386 struct obd_export *exp;
1388 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1390 RETURN(&exp->exp_client_uuid);
1394 * NOTE: It is impossible to find an export that is in failed
1395 * state with this function
1398 uuid_compare(void *key, struct hlist_node *hnode)
1400 struct obd_export *exp;
1403 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1405 RETURN(obd_uuid_equals((struct obd_uuid *)key,&exp->exp_client_uuid) &&
1410 uuid_export_get(struct hlist_node *hnode)
1412 struct obd_export *exp;
1414 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1415 class_export_get(exp);
1421 uuid_export_put(struct hlist_node *hnode)
1423 struct obd_export *exp;
1425 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1426 class_export_put(exp);
1431 static lustre_hash_ops_t uuid_hash_ops = {
1432 .lh_hash = uuid_hash,
1434 .lh_compare = uuid_compare,
1435 .lh_get = uuid_export_get,
1436 .lh_put = uuid_export_put,
1441 * nid<->export hash operations
1445 nid_hash(lustre_hash_t *lh, void *key, unsigned mask)
1447 return lh_djb2_hash(key, sizeof(lnet_nid_t), mask);
1451 nid_key(struct hlist_node *hnode)
1453 struct obd_export *exp;
1455 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1457 RETURN(&exp->exp_connection->c_peer.nid);
1461 * NOTE: It is impossible to find an export that is in failed
1462 * state with this function
1465 nid_compare(void *key, struct hlist_node *hnode)
1467 struct obd_export *exp;
1470 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1472 RETURN(exp->exp_connection->c_peer.nid == *(lnet_nid_t *)key &&
1477 nid_export_get(struct hlist_node *hnode)
1479 struct obd_export *exp;
1481 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1482 class_export_get(exp);
1488 nid_export_put(struct hlist_node *hnode)
1490 struct obd_export *exp;
1492 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1493 class_export_put(exp);
1498 static lustre_hash_ops_t nid_hash_ops = {
1499 .lh_hash = nid_hash,
1501 .lh_compare = nid_compare,
1502 .lh_get = nid_export_get,
1503 .lh_put = nid_export_put,
1508 * nid<->nidstats hash operations
1512 nidstats_key(struct hlist_node *hnode)
1514 struct nid_stat *ns;
1516 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1522 nidstats_compare(void *key, struct hlist_node *hnode)
1524 RETURN(*(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key);
1528 nidstats_get(struct hlist_node *hnode)
1530 struct nid_stat *ns;
1532 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1539 nidstats_put(struct hlist_node *hnode)
1541 struct nid_stat *ns;
1543 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1549 static lustre_hash_ops_t nid_stat_hash_ops = {
1550 .lh_hash = nid_hash,
1551 .lh_key = nidstats_key,
1552 .lh_compare = nidstats_compare,
1553 .lh_get = nidstats_get,
1554 .lh_put = nidstats_put,