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 CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);
231 CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
234 if (len >= sizeof(obd->obd_uuid)) {
235 CERROR("uuid must be < %d bytes long\n",
236 (int)sizeof(obd->obd_uuid));
237 GOTO(out, rc = -EINVAL);
239 memcpy(obd->obd_uuid.uuid, uuid, len);
242 if (OBP(obd, attach)) {
243 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
245 GOTO(out, rc = -EINVAL);
248 /* Detach drops this */
249 spin_lock(&obd->obd_dev_lock);
250 atomic_set(&obd->obd_refcount, 1);
251 spin_unlock(&obd->obd_dev_lock);
253 obd->obd_attached = 1;
254 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
255 obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
259 class_release_dev(obd);
264 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
267 struct obd_export *exp;
270 LASSERT(obd != NULL);
271 LASSERTF(obd == class_num2obd(obd->obd_minor),
272 "obd %p != obd_devs[%d] %p\n",
273 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
274 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
275 "obd %p obd_magic %08x != %08x\n",
276 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
278 /* have we attached a type to this device? */
279 if (!obd->obd_attached) {
280 CERROR("Device %d not attached\n", obd->obd_minor);
284 if (obd->obd_set_up) {
285 CERROR("Device %d already setup (type %s)\n",
286 obd->obd_minor, obd->obd_type->typ_name);
290 /* is someone else setting us up right now? (attach inits spinlock) */
291 spin_lock(&obd->obd_dev_lock);
292 if (obd->obd_starting) {
293 spin_unlock(&obd->obd_dev_lock);
294 CERROR("Device %d setup in progress (type %s)\n",
295 obd->obd_minor, obd->obd_type->typ_name);
298 /* just leave this on forever. I can't use obd_set_up here because
299 other fns check that status, and we're not actually set up yet. */
300 obd->obd_starting = 1;
301 obd->obd_uuid_hash = NULL;
302 obd->obd_nid_hash = NULL;
303 obd->obd_nid_stats_hash = NULL;
304 spin_unlock(&obd->obd_dev_lock);
306 /* create an uuid-export lustre hash */
307 obd->obd_uuid_hash = lustre_hash_init("UUID_HASH",
311 if (!obd->obd_uuid_hash)
312 GOTO(err_hash, err = -ENOMEM);
314 /* create a nid-export lustre hash */
315 obd->obd_nid_hash = lustre_hash_init("NID_HASH",
319 if (!obd->obd_nid_hash)
320 GOTO(err_hash, err = -ENOMEM);
322 /* create a nid-stats lustre hash */
323 obd->obd_nid_stats_hash = lustre_hash_init("NID_STATS",
324 HASH_NID_STATS_CUR_BITS,
325 HASH_NID_STATS_MAX_BITS,
326 &nid_stat_hash_ops, 0);
327 if (!obd->obd_nid_stats_hash)
328 GOTO(err_hash, err = -ENOMEM);
330 exp = class_new_export(obd, &obd->obd_uuid);
332 GOTO(err_hash, err = PTR_ERR(exp));
334 obd->obd_self_export = exp;
335 list_del_init(&exp->exp_obd_chain_timed);
336 class_export_put(exp);
338 err = obd_setup(obd, sizeof(*lcfg), lcfg);
343 spin_lock(&obd->obd_dev_lock);
344 /* cleanup drops this */
346 spin_unlock(&obd->obd_dev_lock);
348 CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
349 obd->obd_name, obd->obd_uuid.uuid);
353 class_unlink_export(obd->obd_self_export);
354 obd->obd_self_export = NULL;
356 if (obd->obd_uuid_hash) {
357 lustre_hash_exit(obd->obd_uuid_hash);
358 obd->obd_uuid_hash = NULL;
360 if (obd->obd_nid_hash) {
361 lustre_hash_exit(obd->obd_nid_hash);
362 obd->obd_nid_hash = NULL;
364 if (obd->obd_nid_stats_hash) {
365 lustre_hash_exit(obd->obd_nid_stats_hash);
366 obd->obd_nid_stats_hash = NULL;
368 obd->obd_starting = 0;
369 CERROR("setup %s failed (%d)\n", obd->obd_name, err);
373 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
377 if (obd->obd_set_up) {
378 CERROR("OBD device %d still set up\n", obd->obd_minor);
382 spin_lock(&obd->obd_dev_lock);
383 if (!obd->obd_attached) {
384 spin_unlock(&obd->obd_dev_lock);
385 CERROR("OBD device %d not attached\n", obd->obd_minor);
388 obd->obd_attached = 0;
389 spin_unlock(&obd->obd_dev_lock);
391 CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
392 obd->obd_name, obd->obd_uuid.uuid);
396 /* not strictly necessary, but cleans up eagerly */
397 obd_zombie_impexp_cull();
402 static void dump_exports(struct obd_device *obd)
404 struct obd_export *exp;
406 spin_lock(&obd->obd_dev_lock);
407 list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
408 struct ptlrpc_reply_state *rs;
409 struct ptlrpc_reply_state *first_reply = NULL;
412 spin_lock(&exp->exp_lock);
413 list_for_each_entry (rs, &exp->exp_outstanding_replies,
419 spin_unlock(&exp->exp_lock);
421 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
422 obd->obd_name, exp, exp->exp_client_uuid.uuid,
423 obd_export_nid2str(exp),
424 atomic_read(&exp->exp_refcount),
425 exp->exp_failed, nreplies, first_reply,
426 nreplies > 3 ? "..." : "");
428 spin_unlock(&obd->obd_dev_lock);
431 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
437 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
439 if (!obd->obd_set_up) {
440 CERROR("Device %d not setup\n", obd->obd_minor);
444 spin_lock(&obd->obd_dev_lock);
445 if (obd->obd_stopping) {
446 spin_unlock(&obd->obd_dev_lock);
447 CERROR("OBD %d already stopping\n", obd->obd_minor);
450 /* Leave this on forever */
451 obd->obd_stopping = 1;
452 spin_unlock(&obd->obd_dev_lock);
454 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
455 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
461 LCONSOLE_WARN("Failing over %s\n",
464 obd->obd_no_transno = 1;
465 obd->obd_no_recov = 1;
466 /* Set the obd readonly if we can */
467 if (OBP(obd, iocontrol))
468 obd_iocontrol(OBD_IOC_SET_READONLY,
469 obd->obd_self_export,
473 CERROR("unrecognised flag '%c'\n",
478 /* The three references that should be remaining are the
479 * obd_self_export and the attach and setup references. */
480 if (atomic_read(&obd->obd_refcount) > 3) {
481 #if 0 /* We should never fail to cleanup with mountconf */
482 if (!(obd->obd_fail || obd->obd_force)) {
483 CERROR("OBD %s is still busy with %d references\n"
484 "You should stop active file system users,"
485 " or use the --force option to cleanup.\n",
486 obd->obd_name, atomic_read(&obd->obd_refcount));
488 /* Allow a failed cleanup to try again. */
489 obd->obd_stopping = 0;
493 /* refcounf - 3 might be the number of real exports
494 (excluding self export). But class_incref is called
495 by other things as well, so don't count on it. */
496 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
497 obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
499 class_disconnect_exports(obd);
502 LASSERT(obd->obd_self_export);
504 /* destroy an uuid-export hash body */
505 lustre_hash_exit(obd->obd_uuid_hash);
507 /* destroy a nid-export hash body */
508 lustre_hash_exit(obd->obd_nid_hash);
510 /* destroy a nid-stats hash body */
511 lustre_hash_exit(obd->obd_nid_stats_hash);
513 /* Precleanup stage 1, we must make sure all exports (other than the
514 self-export) get destroyed. */
515 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
517 CERROR("Precleanup %s returned %d\n",
525 struct obd_device *class_incref(struct obd_device *obd)
527 atomic_inc(&obd->obd_refcount);
528 CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
529 atomic_read(&obd->obd_refcount));
534 void class_decref(struct obd_device *obd)
539 spin_lock(&obd->obd_dev_lock);
540 atomic_dec(&obd->obd_refcount);
541 refs = atomic_read(&obd->obd_refcount);
542 spin_unlock(&obd->obd_dev_lock);
544 CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
546 if ((refs == 1) && obd->obd_stopping) {
547 /* All exports (other than the self-export) have been
548 destroyed; there should be no more in-progress ops
550 /* if we're not stopping, we didn't finish setup */
551 /* Precleanup stage 2, do other type-specific
552 cleanup requiring the self-export. */
553 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
555 CERROR("Precleanup %s returned %d\n",
558 spin_lock(&obd->obd_self_export->exp_lock);
559 obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
560 spin_unlock(&obd->obd_self_export->exp_lock);
562 /* note that we'll recurse into class_decref again */
563 class_unlink_export(obd->obd_self_export);
568 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
569 obd->obd_name, obd->obd_uuid.uuid);
570 LASSERT(!obd->obd_attached);
571 if (obd->obd_stopping) {
572 /* If we're not stopping, we were never set up */
573 err = obd_cleanup(obd);
575 CERROR("Cleanup %s returned %d\n",
578 if (OBP(obd, detach)) {
579 err = OBP(obd,detach)(obd);
581 CERROR("Detach returned %d\n", err);
583 class_release_dev(obd);
587 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
589 struct obd_import *imp;
590 struct obd_uuid uuid;
594 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
595 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
596 CERROR("invalid conn_uuid\n");
599 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
600 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
601 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
602 CERROR("can't add connection on non-client dev\n");
606 imp = obd->u.cli.cl_import;
608 CERROR("try to add conn on immature client dev\n");
612 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
613 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
618 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
620 struct obd_import *imp;
621 struct obd_uuid uuid;
625 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
626 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
627 CERROR("invalid conn_uuid\n");
630 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
631 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
632 CERROR("can't del connection on non-client dev\n");
636 imp = obd->u.cli.cl_import;
638 CERROR("try to del conn on immature client dev\n");
642 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
643 rc = obd_del_conn(imp, &uuid);
648 CFS_LIST_HEAD(lustre_profile_list);
650 struct lustre_profile *class_get_profile(char * prof)
652 struct lustre_profile *lprof;
655 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
656 if (!strcmp(lprof->lp_profile, prof)) {
663 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
664 int mdclen, char *mdc)
666 struct lustre_profile *lprof;
670 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
672 OBD_ALLOC(lprof, sizeof(*lprof));
675 CFS_INIT_LIST_HEAD(&lprof->lp_list);
677 LASSERT(proflen == (strlen(prof) + 1));
678 OBD_ALLOC(lprof->lp_profile, proflen);
679 if (lprof->lp_profile == NULL)
680 GOTO(out, err = -ENOMEM);
681 memcpy(lprof->lp_profile, prof, proflen);
683 LASSERT(osclen == (strlen(osc) + 1));
684 OBD_ALLOC(lprof->lp_osc, osclen);
685 if (lprof->lp_osc == NULL)
686 GOTO(out, err = -ENOMEM);
687 memcpy(lprof->lp_osc, osc, osclen);
690 LASSERT(mdclen == (strlen(mdc) + 1));
691 OBD_ALLOC(lprof->lp_mdc, mdclen);
692 if (lprof->lp_mdc == NULL)
693 GOTO(out, err = -ENOMEM);
694 memcpy(lprof->lp_mdc, mdc, mdclen);
697 list_add(&lprof->lp_list, &lustre_profile_list);
702 OBD_FREE(lprof->lp_mdc, mdclen);
704 OBD_FREE(lprof->lp_osc, osclen);
705 if (lprof->lp_profile)
706 OBD_FREE(lprof->lp_profile, proflen);
707 OBD_FREE(lprof, sizeof(*lprof));
711 void class_del_profile(char *prof)
713 struct lustre_profile *lprof;
716 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
718 lprof = class_get_profile(prof);
720 list_del(&lprof->lp_list);
721 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
722 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
724 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
725 OBD_FREE(lprof, sizeof *lprof);
731 void class_del_profiles(void)
733 struct lustre_profile *lprof, *n;
736 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
737 list_del(&lprof->lp_list);
738 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
739 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
741 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
742 OBD_FREE(lprof, sizeof *lprof);
747 static int class_set_global(char *ptr, int val) {
750 if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
752 else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
754 else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
756 else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
757 at_early_margin = val;
758 else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
763 CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
769 /* We can't call ll_process_config directly because it lives in a module that
770 must be loaded after this one. */
771 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
773 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
775 client_process_config = cpc;
777 EXPORT_SYMBOL(lustre_register_client_process_config);
779 int class_process_config(struct lustre_cfg *lcfg)
781 struct obd_device *obd;
784 LASSERT(lcfg && !IS_ERR(lcfg));
785 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
787 /* Commands that don't need a device */
788 switch(lcfg->lcfg_command) {
790 err = class_attach(lcfg);
793 case LCFG_ADD_UUID: {
794 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
795 " (%s)\n", lustre_cfg_string(lcfg, 1),
796 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
798 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
801 case LCFG_DEL_UUID: {
802 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
803 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
804 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
806 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
809 case LCFG_MOUNTOPT: {
810 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
811 lustre_cfg_string(lcfg, 1),
812 lustre_cfg_string(lcfg, 2),
813 lustre_cfg_string(lcfg, 3));
814 /* set these mount options somewhere, so ll_fill_super
816 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
817 lustre_cfg_string(lcfg, 1),
818 LUSTRE_CFG_BUFLEN(lcfg, 2),
819 lustre_cfg_string(lcfg, 2),
820 LUSTRE_CFG_BUFLEN(lcfg, 3),
821 lustre_cfg_string(lcfg, 3));
824 case LCFG_DEL_MOUNTOPT: {
825 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
826 lustre_cfg_string(lcfg, 1));
827 class_del_profile(lustre_cfg_string(lcfg, 1));
830 case LCFG_SET_TIMEOUT: {
831 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
832 obd_timeout, lcfg->lcfg_num);
833 obd_timeout = max(lcfg->lcfg_num, 1U);
836 case LCFG_SET_LDLM_TIMEOUT: {
837 CDEBUG(D_IOCTL, "changing lustre ldlm_timeout from %d to %d\n",
838 ldlm_timeout, lcfg->lcfg_num);
839 ldlm_timeout = max(lcfg->lcfg_num, 1U);
840 if (ldlm_timeout >= obd_timeout)
841 ldlm_timeout = max(obd_timeout / 3, 1U);
845 case LCFG_SET_UPCALL: {
846 LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
847 /* COMPAT_146 Don't fail on old configs */
851 struct cfg_marker *marker;
852 marker = lustre_cfg_buf(lcfg, 1);
853 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
854 marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
859 /* llite has no obd */
860 if ((class_match_param(lustre_cfg_string(lcfg, 1),
861 PARAM_LLITE, 0) == 0) &&
862 client_process_config) {
863 err = (*client_process_config)(lcfg);
865 } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
866 PARAM_SYS, &tmp) == 0)) {
867 /* Global param settings */
868 err = class_set_global(tmp, lcfg->lcfg_num);
869 /* Note that since LCFG_PARAM is LCFG_REQUIRED, new
870 unknown globals would cause config to fail */
872 CWARN("Ignoring unknown param %s\n", tmp);
881 /* Commands that require a device */
882 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
884 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
885 CERROR("this lcfg command requires a device name\n");
887 CERROR("no device for: %s\n",
888 lustre_cfg_string(lcfg, 0));
890 GOTO(out, err = -EINVAL);
893 switch(lcfg->lcfg_command) {
895 err = class_setup(obd, lcfg);
899 err = class_detach(obd, lcfg);
903 err = class_cleanup(obd, lcfg);
906 case LCFG_ADD_CONN: {
907 err = class_add_conn(obd, lcfg);
910 case LCFG_DEL_CONN: {
911 err = class_del_conn(obd, lcfg);
914 case LCFG_POOL_NEW: {
915 err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
919 case LCFG_POOL_ADD: {
920 err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
921 lustre_cfg_string(lcfg, 3));
925 case LCFG_POOL_REM: {
926 err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
927 lustre_cfg_string(lcfg, 3));
931 case LCFG_POOL_DEL: {
932 err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
937 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
943 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
944 CWARN("Ignoring error %d on optional command %#x\n", err,
951 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
952 struct lustre_cfg *lcfg, void *data)
955 struct lprocfs_vars *var;
958 int matched = 0, j = 0;
962 if (lcfg->lcfg_command != LCFG_PARAM) {
963 CERROR("Unknown command: %x\n", lcfg->lcfg_command);
967 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
968 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
969 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
970 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
971 key = lustre_cfg_buf(lcfg, i);
972 /* Strip off prefix */
973 class_match_param(key, prefix, &key);
974 sval = strchr(key, '=');
975 if (!sval || (*(sval + 1) == 0)) {
976 CERROR("Can't parse param %s\n", key);
978 /* continue parsing other params */
982 vallen = strlen(sval);
985 /* Search proc entries */
986 while (lvars[j].name) {
988 if (class_match_param(key, (char *)var->name, 0) == 0) {
991 if (var->write_fptr) {
995 rc = (var->write_fptr)(NULL, sval,
1000 CERROR("writing proc entry %s err %d\n",
1007 CERROR("%s: unknown param %s\n",
1008 (char *)lustre_cfg_string(lcfg, 0), key);
1009 /* rc = -EINVAL; continue parsing other params */
1011 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
1012 lustre_cfg_string(lcfg, 0),
1013 (int)strlen(prefix) - 1, prefix,
1014 (int)(sval - key - 1), key, sval);
1022 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
1023 /* Don't throw config error */
1028 int class_config_dump_handler(struct llog_handle * handle,
1029 struct llog_rec_hdr *rec, void *data);
1032 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
1034 #define lustre_check_exclusion(a,b) 0
1037 static int class_config_llog_handler(struct llog_handle * handle,
1038 struct llog_rec_hdr *rec, void *data)
1040 struct config_llog_instance *clli = data;
1041 int cfg_len = rec->lrh_len;
1042 char *cfg_buf = (char*) (rec + 1);
1046 //class_config_dump_handler(handle, rec, data);
1048 switch (rec->lrh_type) {
1050 struct lustre_cfg *lcfg, *lcfg_new;
1051 struct lustre_cfg_bufs bufs;
1052 char *inst_name = NULL;
1054 int inst = 0, swab = 0;
1056 lcfg = (struct lustre_cfg *)cfg_buf;
1057 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
1058 lustre_swab_lustre_cfg(lcfg);
1062 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1066 /* Figure out config state info */
1067 if (lcfg->lcfg_command == LCFG_MARKER) {
1068 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1069 lustre_swab_cfg_marker(marker, swab,
1070 LUSTRE_CFG_BUFLEN(lcfg, 1));
1071 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
1072 clli->cfg_flags, marker->cm_flags);
1073 if (marker->cm_flags & CM_START) {
1074 /* all previous flags off */
1075 clli->cfg_flags = CFG_F_MARKER;
1076 if (marker->cm_flags & CM_SKIP) {
1077 clli->cfg_flags |= CFG_F_SKIP;
1078 CDEBUG(D_CONFIG, "SKIP #%d\n",
1080 } else if ((marker->cm_flags & CM_EXCLUDE) ||
1081 lustre_check_exclusion(clli->cfg_sb,
1082 marker->cm_tgtname)) {
1083 clli->cfg_flags |= CFG_F_EXCLUDE;
1084 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
1087 } else if (marker->cm_flags & CM_END) {
1088 clli->cfg_flags = 0;
1091 /* A config command without a start marker before it is
1092 illegal (post 146) */
1093 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
1094 !(clli->cfg_flags & CFG_F_MARKER) &&
1095 (lcfg->lcfg_command != LCFG_MARKER)) {
1096 CWARN("Config not inside markers, ignoring! (%#x)\n",
1098 clli->cfg_flags |= CFG_F_SKIP;
1101 if (clli->cfg_flags & CFG_F_SKIP) {
1102 CDEBUG(D_CONFIG, "skipping %#x\n",
1105 /* No processing! */
1110 * For interop mode between 1.8 and 2.0:
1111 * skip "lmv" configuration which exists since 2.0.
1114 char *devname = lustre_cfg_string(lcfg, 0);
1115 char *typename = lustre_cfg_string(lcfg, 1);
1118 devname += strlen(devname) - strlen("clilmv");
1120 if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
1121 strcmp(typename, "lmv") == 0) ||
1122 (devname && strcmp(devname, "clilmv") == 0)) {
1123 CWARN("skipping 'lmv' config: cmd=%x,%s:%s\n",
1124 lcfg->lcfg_command, devname, typename);
1129 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
1130 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
1131 /* Add inactive instead */
1132 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
1134 lustre_cfg_bufs_init(&bufs, lcfg);
1136 if (clli && clli->cfg_instance &&
1137 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
1139 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
1140 strlen(clli->cfg_instance) + 1;
1141 OBD_ALLOC(inst_name, inst_len);
1142 if (inst_name == NULL)
1143 GOTO(out, rc = -ENOMEM);
1144 sprintf(inst_name, "%s-%s",
1145 lustre_cfg_string(lcfg, 0),
1146 clli->cfg_instance);
1147 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1148 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1149 lcfg->lcfg_command, inst_name);
1152 /* we override the llog's uuid for clients, to insure they
1154 if (clli && clli->cfg_instance &&
1155 lcfg->lcfg_command == LCFG_ATTACH) {
1156 lustre_cfg_bufs_set_string(&bufs, 2,
1157 clli->cfg_uuid.uuid);
1160 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1162 lcfg_new->lcfg_num = lcfg->lcfg_num;
1163 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1165 /* XXX Hack to try to remain binary compatible with
1166 * pre-newconfig logs */
1167 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1168 (lcfg->lcfg_nid >> 32) == 0) {
1169 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1171 lcfg_new->lcfg_nid =
1172 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1173 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1174 lcfg->lcfg_nal, addr,
1175 libcfs_nid2str(lcfg_new->lcfg_nid));
1177 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1180 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1182 rc = class_process_config(lcfg_new);
1183 lustre_cfg_free(lcfg_new);
1186 OBD_FREE(inst_name, inst_len);
1190 CERROR("Unknown llog record type %#x encountered\n",
1196 CERROR("Err %d on cfg command:\n", rc);
1197 class_config_dump_handler(handle, rec, data);
1202 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1203 struct config_llog_instance *cfg)
1205 struct llog_process_cat_data cd = {0, 0};
1206 struct llog_handle *llh;
1210 CDEBUG(D_INFO, "looking up llog %s\n", name);
1211 rc = llog_create(ctxt, &llh, NULL, name);
1215 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1217 GOTO(parse_out, rc);
1219 /* continue processing from where we last stopped to end-of-log */
1221 cd.lpcd_first_idx = cfg->cfg_last_idx;
1222 cd.lpcd_last_idx = 0;
1224 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1226 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1227 cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
1229 cfg->cfg_last_idx = cd.lpcd_last_idx;
1232 rc2 = llog_close(llh);
1239 int class_config_dump_handler(struct llog_handle * handle,
1240 struct llog_rec_hdr *rec, void *data)
1242 int cfg_len = rec->lrh_len;
1243 char *cfg_buf = (char*) (rec + 1);
1244 char *outstr, *ptr, *end;
1248 OBD_ALLOC(outstr, 256);
1254 if (rec->lrh_type == OBD_CFG_REC) {
1255 struct lustre_cfg *lcfg;
1258 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1261 lcfg = (struct lustre_cfg *)cfg_buf;
1263 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1264 lcfg->lcfg_command);
1265 if (lcfg->lcfg_flags) {
1266 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1269 if (lcfg->lcfg_num) {
1270 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1273 if (lcfg->lcfg_nid) {
1274 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1275 libcfs_nid2str(lcfg->lcfg_nid),
1278 if (lcfg->lcfg_command == LCFG_MARKER) {
1279 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1280 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1281 marker->cm_step, marker->cm_flags,
1282 marker->cm_tgtname, marker->cm_comment);
1284 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1285 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1286 lustre_cfg_string(lcfg, i));
1289 LCONSOLE(D_WARNING, " %s\n", outstr);
1291 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1295 OBD_FREE(outstr, 256);
1299 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1300 struct config_llog_instance *cfg)
1302 struct llog_handle *llh;
1306 LCONSOLE_INFO("Dumping config log %s\n", name);
1308 rc = llog_create(ctxt, &llh, NULL, name);
1312 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1314 GOTO(parse_out, rc);
1316 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1318 rc2 = llog_close(llh);
1322 LCONSOLE_INFO("End config log %s\n", name);
1327 /* Cleanup and detach */
1328 int class_manual_cleanup(struct obd_device *obd)
1330 struct lustre_cfg *lcfg;
1331 struct lustre_cfg_bufs bufs;
1337 CERROR("empty cleanup\n");
1346 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1347 obd->obd_name, flags);
1349 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1350 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1351 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1353 rc = class_process_config(lcfg);
1355 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1359 /* the lcfg is almost the same for both ops */
1360 lcfg->lcfg_command = LCFG_DETACH;
1361 rc = class_process_config(lcfg);
1363 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1365 lustre_cfg_free(lcfg);
1370 * uuid<->export lustre hash operations
1374 uuid_hash(lustre_hash_t *lh, void *key, unsigned mask)
1376 return lh_djb2_hash(((struct obd_uuid *)key)->uuid,
1377 sizeof(((struct obd_uuid *)key)->uuid), mask);
1381 uuid_key(struct hlist_node *hnode)
1383 struct obd_export *exp;
1385 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1387 RETURN(&exp->exp_client_uuid);
1391 * NOTE: It is impossible to find an export that is in failed
1392 * state with this function
1395 uuid_compare(void *key, struct hlist_node *hnode)
1397 struct obd_export *exp;
1400 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1402 RETURN(obd_uuid_equals((struct obd_uuid *)key,&exp->exp_client_uuid) &&
1407 uuid_export_get(struct hlist_node *hnode)
1409 struct obd_export *exp;
1411 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1412 class_export_get(exp);
1418 uuid_export_put(struct hlist_node *hnode)
1420 struct obd_export *exp;
1422 exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1423 class_export_put(exp);
1428 static lustre_hash_ops_t uuid_hash_ops = {
1429 .lh_hash = uuid_hash,
1431 .lh_compare = uuid_compare,
1432 .lh_get = uuid_export_get,
1433 .lh_put = uuid_export_put,
1438 * nid<->export hash operations
1442 nid_hash(lustre_hash_t *lh, void *key, unsigned mask)
1444 return lh_djb2_hash(key, sizeof(lnet_nid_t), mask);
1448 nid_key(struct hlist_node *hnode)
1450 struct obd_export *exp;
1452 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1454 RETURN(&exp->exp_connection->c_peer.nid);
1458 * NOTE: It is impossible to find an export that is in failed
1459 * state with this function
1462 nid_compare(void *key, struct hlist_node *hnode)
1464 struct obd_export *exp;
1467 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1469 RETURN(exp->exp_connection->c_peer.nid == *(lnet_nid_t *)key &&
1474 nid_export_get(struct hlist_node *hnode)
1476 struct obd_export *exp;
1478 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1479 class_export_get(exp);
1485 nid_export_put(struct hlist_node *hnode)
1487 struct obd_export *exp;
1489 exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1490 class_export_put(exp);
1495 static lustre_hash_ops_t nid_hash_ops = {
1496 .lh_hash = nid_hash,
1498 .lh_compare = nid_compare,
1499 .lh_get = nid_export_get,
1500 .lh_put = nid_export_put,
1505 * nid<->nidstats hash operations
1509 nidstats_key(struct hlist_node *hnode)
1511 struct nid_stat *ns;
1513 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1519 nidstats_compare(void *key, struct hlist_node *hnode)
1521 RETURN(*(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key);
1525 nidstats_get(struct hlist_node *hnode)
1527 struct nid_stat *ns;
1529 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1536 nidstats_put(struct hlist_node *hnode)
1538 struct nid_stat *ns;
1540 ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1546 static lustre_hash_ops_t nid_stat_hash_ops = {
1547 .lh_hash = nid_hash,
1548 .lh_key = nidstats_key,
1549 .lh_compare = nidstats_compare,
1550 .lh_get = nidstats_get,
1551 .lh_put = nidstats_put,