1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2001-2006 Cluster File Systems, Inc.
6 * This file is part of the Lustre file system, http://www.lustre.org
7 * Lustre is a trademark of Cluster File Systems, Inc.
9 * You may have signed or agreed to another license before downloading
10 * this software. If so, you are bound by the terms and conditions
11 * of that agreement, and the following does not apply to you. See the
12 * LICENSE file included with this distribution for more information.
14 * If you did not agree to a different license, then this copy of Lustre
15 * is open source software; you can redistribute it and/or modify it
16 * under the terms of version 2 of the GNU General Public License as
17 * published by the Free Software Foundation.
19 * In either case, Lustre is distributed in the hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * license text for more details.
28 #define DEBUG_SUBSYSTEM S_CLASS
30 #include <obd_class.h>
31 #include <linux/string.h>
33 #include <liblustre.h>
34 #include <obd_class.h>
37 #include <lustre_log.h>
38 #include <lprocfs_status.h>
39 #include <libcfs/list.h>
40 #include <lustre_param.h>
42 /*********** string parsing utils *********/
44 /* returns 0 if we find this key in the buffer, else 1 */
45 int class_find_param(char *buf, char *key, char **valp)
52 if ((ptr = strstr(buf, key)) == NULL)
56 *valp = ptr + strlen(key);
61 /* returns 0 if this is the first key in the buffer, else 1.
62 valp points to first char after key. */
63 int class_match_param(char *buf, char *key, char **valp)
68 if (memcmp(buf, key, strlen(key)) != 0)
72 *valp = buf + strlen(key);
80 endh is set to next separator */
81 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
87 while (*buf == ',' || *buf == ':')
89 if (*buf == ' ' || *buf == '/' || *buf == '\0')
92 /* nid separators or end of nids */
93 endp = strpbrk(buf, ",: /");
95 endp = buf + strlen(buf);
99 *nid = libcfs_str2nid(buf);
100 if (*nid == LNET_NID_ANY) {
101 LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
109 CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));
113 EXPORT_SYMBOL(class_find_param);
114 EXPORT_SYMBOL(class_match_param);
115 EXPORT_SYMBOL(class_parse_nid);
117 /********************** class fns **********************/
119 /* Create a new device and set the type, name and uuid. If
120 * successful, the new device can be accessed by either name or uuid.
122 int class_attach(struct lustre_cfg *lcfg)
124 struct obd_device *obd = NULL;
125 char *typename, *name, *uuid;
129 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
130 CERROR("No type passed!\n");
133 typename = lustre_cfg_string(lcfg, 1);
135 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
136 CERROR("No name passed!\n");
139 name = lustre_cfg_string(lcfg, 0);
141 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
142 CERROR("No UUID passed!\n");
145 uuid = lustre_cfg_string(lcfg, 2);
147 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
148 MKSTR(typename), MKSTR(name), MKSTR(uuid));
150 /* Mountconf transitional hack, should go away after 1.6.
151 1.4.7 uses the old names, so translate back if the
152 mountconf flag is set.
153 1.6 should set this flag, and translate the other way here
155 if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
157 if (strcmp(typename, "mds") == 0)
159 if (strcmp(typename, "mdt") == 0)
161 if (strcmp(typename, "osd") == 0)
164 LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
165 MKSTR(typename), MKSTR(name));
170 obd = class_newdev(typename, name);
172 /* Already exists or out of obds */
175 CERROR("Cannot create device %s of type %s : %d\n",
179 LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
181 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
182 "obd %p obd_magic %08X != %08X\n",
183 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
184 LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",
185 obd, obd->obd_name, name);
187 CFS_INIT_LIST_HEAD(&obd->obd_exports);
188 CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
189 spin_lock_init(&obd->obd_dev_lock);
190 sema_init(&obd->obd_dev_sem, 1);
191 sema_init(&obd->obd_proc_exp_sem, 1);
192 spin_lock_init(&obd->obd_osfs_lock);
193 /* obd->obd_osfs_age must be set to a value in the distant
194 * past to guarantee a fresh statfs is fetched on mount. */
195 obd->obd_osfs_age = cfs_time_shift_64(-1000);
197 /* XXX belongs in setup not attach */
199 cfs_init_timer(&obd->obd_recovery_timer);
200 spin_lock_init(&obd->obd_processing_task_lock);
201 cfs_waitq_init(&obd->obd_next_transno_waitq);
202 CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);
203 CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
205 spin_lock_init(&obd->obd_uncommitted_replies_lock);
206 CFS_INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
209 if (len >= sizeof(obd->obd_uuid)) {
210 CERROR("uuid must be < "LPSZ" bytes long\n",
211 sizeof(obd->obd_uuid));
212 GOTO(out, rc = -EINVAL);
214 memcpy(obd->obd_uuid.uuid, uuid, len);
217 if (OBP(obd, attach)) {
218 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
220 GOTO(out, rc = -EINVAL);
223 /* Detach drops this */
224 spin_lock(&obd->obd_dev_lock);
225 atomic_set(&obd->obd_refcount, 1);
226 spin_unlock(&obd->obd_dev_lock);
228 obd->obd_attached = 1;
229 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
230 obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
234 class_release_dev(obd);
239 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
242 struct obd_export *exp;
245 LASSERT(obd != NULL);
246 LASSERTF(obd == class_num2obd(obd->obd_minor), "obd %p != obd_devs[%d] %p\n",
247 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
248 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n",
249 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
251 /* have we attached a type to this device? */
252 if (!obd->obd_attached) {
253 CERROR("Device %d not attached\n", obd->obd_minor);
257 if (obd->obd_set_up) {
258 CERROR("Device %d already setup (type %s)\n",
259 obd->obd_minor, obd->obd_type->typ_name);
263 /* is someone else setting us up right now? (attach inits spinlock) */
264 spin_lock(&obd->obd_dev_lock);
265 if (obd->obd_starting) {
266 spin_unlock(&obd->obd_dev_lock);
267 CERROR("Device %d setup in progress (type %s)\n",
268 obd->obd_minor, obd->obd_type->typ_name);
271 /* just leave this on forever. I can't use obd_set_up here because
272 other fns check that status, and we're not actually set up yet. */
273 obd->obd_starting = 1;
274 spin_unlock(&obd->obd_dev_lock);
276 exp = class_new_export(obd, &obd->obd_uuid);
278 RETURN(PTR_ERR(exp));
279 obd->obd_self_export = exp;
280 list_del_init(&exp->exp_obd_chain_timed);
281 class_export_put(exp);
283 err = obd_setup(obd, sizeof(*lcfg), lcfg);
288 spin_lock(&obd->obd_dev_lock);
289 /* cleanup drops this */
291 spin_unlock(&obd->obd_dev_lock);
293 CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
294 obd->obd_name, obd->obd_uuid.uuid);
299 CERROR("setup %s failed (%d)\n", obd->obd_name, err);
300 class_unlink_export(obd->obd_self_export);
301 obd->obd_self_export = NULL;
302 obd->obd_starting = 0;
306 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
310 if (obd->obd_set_up) {
311 CERROR("OBD device %d still set up\n", obd->obd_minor);
315 spin_lock(&obd->obd_dev_lock);
316 if (!obd->obd_attached) {
317 spin_unlock(&obd->obd_dev_lock);
318 CERROR("OBD device %d not attached\n", obd->obd_minor);
321 obd->obd_attached = 0;
322 spin_unlock(&obd->obd_dev_lock);
324 CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
325 obd->obd_name, obd->obd_uuid.uuid);
329 /* not strictly necessary, but cleans up eagerly */
330 obd_zombie_impexp_cull();
335 static void dump_exports(struct obd_device *obd)
337 struct obd_export *exp, *n;
339 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
340 struct ptlrpc_reply_state *rs;
341 struct ptlrpc_reply_state *first_reply = NULL;
344 list_for_each_entry (rs, &exp->exp_outstanding_replies,
351 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
352 obd->obd_name, exp, exp->exp_client_uuid.uuid,
353 obd_export_nid2str(exp),
354 atomic_read(&exp->exp_refcount),
355 exp->exp_failed, nreplies, first_reply,
356 nreplies > 3 ? "..." : "");
360 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
366 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
368 if (!obd->obd_set_up) {
369 CERROR("Device %d not setup\n", obd->obd_minor);
373 spin_lock(&obd->obd_dev_lock);
374 if (obd->obd_stopping) {
375 spin_unlock(&obd->obd_dev_lock);
376 CERROR("OBD %d already stopping\n", obd->obd_minor);
379 /* Leave this on forever */
380 obd->obd_stopping = 1;
381 spin_unlock(&obd->obd_dev_lock);
383 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
384 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
390 LCONSOLE_WARN("Failing over %s\n",
393 obd->obd_no_transno = 1;
394 obd->obd_no_recov = 1;
395 /* Set the obd readonly if we can */
396 if (OBP(obd, iocontrol))
397 obd_iocontrol(OBD_IOC_SET_READONLY,
398 obd->obd_self_export,
402 CERROR("unrecognised flag '%c'\n",
407 /* The three references that should be remaining are the
408 * obd_self_export and the attach and setup references. */
409 if (atomic_read(&obd->obd_refcount) > 3) {
410 #if 0 /* We should never fail to cleanup with mountconf */
411 if (!(obd->obd_fail || obd->obd_force)) {
412 CERROR("OBD %s is still busy with %d references\n"
413 "You should stop active file system users,"
414 " or use the --force option to cleanup.\n",
415 obd->obd_name, atomic_read(&obd->obd_refcount));
417 /* Allow a failed cleanup to try again. */
418 obd->obd_stopping = 0;
422 /* refcounf - 3 might be the number of real exports
423 (excluding self export). But class_incref is called
424 by other things as well, so don't count on it. */
425 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
426 obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
428 class_disconnect_exports(obd);
431 LASSERT(obd->obd_self_export);
433 /* Precleanup stage 1, we must make sure all exports (other than the
434 self-export) get destroyed. */
435 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
437 CERROR("Precleanup %s returned %d\n",
446 struct obd_device *class_incref(struct obd_device *obd)
448 atomic_inc(&obd->obd_refcount);
449 CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
450 atomic_read(&obd->obd_refcount));
455 void class_decref(struct obd_device *obd)
460 spin_lock(&obd->obd_dev_lock);
461 atomic_dec(&obd->obd_refcount);
462 refs = atomic_read(&obd->obd_refcount);
463 spin_unlock(&obd->obd_dev_lock);
465 CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
467 if ((refs == 1) && obd->obd_stopping) {
468 /* All exports (other than the self-export) have been
469 destroyed; there should be no more in-progress ops
471 /* if we're not stopping, we didn't finish setup */
472 /* Precleanup stage 2, do other type-specific
473 cleanup requiring the self-export. */
474 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
476 CERROR("Precleanup %s returned %d\n",
479 spin_lock(&obd->obd_self_export->exp_lock);
480 obd->obd_self_export->exp_flags |=
481 (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
482 (obd->obd_force ? OBD_OPT_FORCE : 0);
483 spin_unlock(&obd->obd_self_export->exp_lock);
485 /* note that we'll recurse into class_decref again */
486 class_unlink_export(obd->obd_self_export);
491 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
492 obd->obd_name, obd->obd_uuid.uuid);
493 LASSERT(!obd->obd_attached);
494 if (obd->obd_stopping) {
495 /* If we're not stopping, we were never set up */
496 err = obd_cleanup(obd);
498 CERROR("Cleanup %s returned %d\n",
501 if (OBP(obd, detach)) {
502 err = OBP(obd,detach)(obd);
504 CERROR("Detach returned %d\n", err);
506 class_release_dev(obd);
510 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
512 struct obd_import *imp;
513 struct obd_uuid uuid;
517 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
518 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
519 CERROR("invalid conn_uuid\n");
522 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
523 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
524 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
525 CERROR("can't add connection on non-client dev\n");
529 imp = obd->u.cli.cl_import;
531 CERROR("try to add conn on immature client dev\n");
535 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
536 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
541 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
543 struct obd_import *imp;
544 struct obd_uuid uuid;
548 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
549 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
550 CERROR("invalid conn_uuid\n");
553 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
554 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
555 CERROR("can't del connection on non-client dev\n");
559 imp = obd->u.cli.cl_import;
561 CERROR("try to del conn on immature client dev\n");
565 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
566 rc = obd_del_conn(imp, &uuid);
571 CFS_LIST_HEAD(lustre_profile_list);
573 struct lustre_profile *class_get_profile(char * prof)
575 struct lustre_profile *lprof;
578 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
579 if (!strcmp(lprof->lp_profile, prof)) {
586 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
587 int mdclen, char *mdc)
589 struct lustre_profile *lprof;
593 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
595 OBD_ALLOC(lprof, sizeof(*lprof));
598 CFS_INIT_LIST_HEAD(&lprof->lp_list);
600 LASSERT(proflen == (strlen(prof) + 1));
601 OBD_ALLOC(lprof->lp_profile, proflen);
602 if (lprof->lp_profile == NULL)
603 GOTO(out, err = -ENOMEM);
604 memcpy(lprof->lp_profile, prof, proflen);
606 LASSERT(osclen == (strlen(osc) + 1));
607 OBD_ALLOC(lprof->lp_osc, osclen);
608 if (lprof->lp_osc == NULL)
609 GOTO(out, err = -ENOMEM);
610 memcpy(lprof->lp_osc, osc, osclen);
613 LASSERT(mdclen == (strlen(mdc) + 1));
614 OBD_ALLOC(lprof->lp_mdc, mdclen);
615 if (lprof->lp_mdc == NULL)
616 GOTO(out, err = -ENOMEM);
617 memcpy(lprof->lp_mdc, mdc, mdclen);
620 list_add(&lprof->lp_list, &lustre_profile_list);
625 OBD_FREE(lprof->lp_mdc, mdclen);
627 OBD_FREE(lprof->lp_osc, osclen);
628 if (lprof->lp_profile)
629 OBD_FREE(lprof->lp_profile, proflen);
630 OBD_FREE(lprof, sizeof(*lprof));
634 void class_del_profile(char *prof)
636 struct lustre_profile *lprof;
639 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
641 lprof = class_get_profile(prof);
643 list_del(&lprof->lp_list);
644 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
645 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
647 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
648 OBD_FREE(lprof, sizeof *lprof);
654 void class_del_profiles(void)
656 struct lustre_profile *lprof, *n;
659 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
660 list_del(&lprof->lp_list);
661 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
662 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
664 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
665 OBD_FREE(lprof, sizeof *lprof);
670 /* We can't call ll_process_config directly because it lives in a module that
671 must be loaded after this one. */
672 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
674 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
676 client_process_config = cpc;
678 EXPORT_SYMBOL(lustre_register_client_process_config);
680 int class_process_config(struct lustre_cfg *lcfg)
682 struct obd_device *obd;
685 LASSERT(lcfg && !IS_ERR(lcfg));
686 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
688 /* Commands that don't need a device */
689 switch(lcfg->lcfg_command) {
691 err = class_attach(lcfg);
694 case LCFG_ADD_UUID: {
695 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
696 " (%s)\n", lustre_cfg_string(lcfg, 1),
697 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
699 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
702 case LCFG_DEL_UUID: {
703 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
704 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
705 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
707 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
710 case LCFG_MOUNTOPT: {
711 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
712 lustre_cfg_string(lcfg, 1),
713 lustre_cfg_string(lcfg, 2),
714 lustre_cfg_string(lcfg, 3));
715 /* set these mount options somewhere, so ll_fill_super
717 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
718 lustre_cfg_string(lcfg, 1),
719 LUSTRE_CFG_BUFLEN(lcfg, 2),
720 lustre_cfg_string(lcfg, 2),
721 LUSTRE_CFG_BUFLEN(lcfg, 3),
722 lustre_cfg_string(lcfg, 3));
725 case LCFG_DEL_MOUNTOPT: {
726 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
727 lustre_cfg_string(lcfg, 1));
728 class_del_profile(lustre_cfg_string(lcfg, 1));
731 case LCFG_SET_TIMEOUT: {
732 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
733 obd_timeout, lcfg->lcfg_num);
734 obd_timeout = max(lcfg->lcfg_num, 1U);
737 case LCFG_SET_UPCALL: {
738 LCONSOLE_ERROR("recovery upcall is deprecated\n");
739 /* COMPAT_146 Don't fail on old configs */
743 struct cfg_marker *marker;
744 marker = lustre_cfg_buf(lcfg, 1);
745 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
746 marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
750 /* llite has no obd */
751 if ((class_match_param(lustre_cfg_string(lcfg, 1),
752 PARAM_LLITE, 0) == 0) &&
753 client_process_config) {
754 err = (*client_process_config)(lcfg);
762 /* Commands that require a device */
763 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
765 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
766 CERROR("this lcfg command requires a device name\n");
768 CERROR("no device for: %s\n",
769 lustre_cfg_string(lcfg, 0));
771 GOTO(out, err = -EINVAL);
774 switch(lcfg->lcfg_command) {
776 err = class_setup(obd, lcfg);
780 err = class_detach(obd, lcfg);
784 err = class_cleanup(obd, lcfg);
787 case LCFG_ADD_CONN: {
788 err = class_add_conn(obd, lcfg);
791 case LCFG_DEL_CONN: {
792 err = class_del_conn(obd, lcfg);
796 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
802 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
803 CWARN("Ignoring error %d on optional command %#x\n", err,
810 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
811 struct lustre_cfg *lcfg, void *data)
814 struct lprocfs_vars *var;
817 int matched = 0, j = 0;
821 if (lcfg->lcfg_command != LCFG_PARAM) {
822 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
826 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
827 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
828 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
829 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
830 key = lustre_cfg_buf(lcfg, i);
831 /* Strip off prefix */
832 class_match_param(key, prefix, &key);
833 sval = strchr(key, '=');
834 if (!sval || (*(sval + 1) == 0)) {
835 CERROR("Can't parse param %s\n", key);
837 /* continue parsing other params */
841 vallen = strlen(sval);
844 /* Search proc entries */
845 while (lvars[j].name) {
847 if (class_match_param(key, (char *)var->name, 0) == 0) {
850 if (var->write_fptr) {
854 rc = (var->write_fptr)(NULL, sval,
859 CERROR("writing proc entry %s err %d\n",
866 CERROR("%s: unknown param %s\n",
867 (char *)lustre_cfg_string(lcfg, 0), key);
869 /* continue parsing other params */
871 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
872 (char *)lustre_cfg_string(lcfg, 0),
873 (int)strlen(prefix) - 1, prefix,
874 (int)(sval - key - 1), key, sval);
882 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
883 /* Don't throw config error */
888 int class_config_dump_handler(struct llog_handle * handle,
889 struct llog_rec_hdr *rec, void *data);
892 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
894 #define lustre_check_exclusion(a,b) 0
897 static int class_config_llog_handler(struct llog_handle * handle,
898 struct llog_rec_hdr *rec, void *data)
900 struct config_llog_instance *clli = data;
901 int cfg_len = rec->lrh_len;
902 char *cfg_buf = (char*) (rec + 1);
906 //class_config_dump_handler(handle, rec, data);
908 switch (rec->lrh_type) {
910 struct lustre_cfg *lcfg, *lcfg_new;
911 struct lustre_cfg_bufs bufs;
912 char *inst_name = NULL;
916 lcfg = (struct lustre_cfg *)cfg_buf;
917 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
918 lustre_swab_lustre_cfg(lcfg);
920 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
924 /* Figure out config state info */
925 if (lcfg->lcfg_command == LCFG_MARKER) {
926 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
927 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
928 clli->cfg_flags, marker->cm_flags);
929 if (marker->cm_flags & CM_START) {
930 /* all previous flags off */
931 clli->cfg_flags = CFG_F_MARKER;
932 if (marker->cm_flags & CM_SKIP) {
933 clli->cfg_flags |= CFG_F_SKIP;
934 CDEBUG(D_CONFIG, "SKIP #%d\n",
936 } else if ((marker->cm_flags & CM_EXCLUDE) ||
937 lustre_check_exclusion(clli->cfg_sb,
938 marker->cm_tgtname)) {
939 clli->cfg_flags |= CFG_F_EXCLUDE;
940 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
943 } else if (marker->cm_flags & CM_END) {
947 /* A config command without a start marker before it is
948 illegal (post 146) */
949 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
950 !(clli->cfg_flags & CFG_F_MARKER) &&
951 (lcfg->lcfg_command != LCFG_MARKER)) {
952 CWARN("Config not inside markers, ignoring! (%#x)\n",
954 clli->cfg_flags |= CFG_F_SKIP;
957 if (clli->cfg_flags & CFG_F_SKIP) {
958 CDEBUG(D_CONFIG, "skipping %#x\n",
965 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
966 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
967 /* Add inactive instead */
968 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
970 lustre_cfg_bufs_init(&bufs, lcfg);
972 if (clli && clli->cfg_instance &&
973 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
975 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
976 strlen(clli->cfg_instance) + 1;
977 OBD_ALLOC(inst_name, inst_len);
978 if (inst_name == NULL)
979 GOTO(out, rc = -ENOMEM);
980 sprintf(inst_name, "%s-%s",
981 lustre_cfg_string(lcfg, 0),
983 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
984 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
985 lcfg->lcfg_command, inst_name);
988 /* we override the llog's uuid for clients, to insure they
990 if (clli && clli->cfg_instance &&
991 lcfg->lcfg_command == LCFG_ATTACH) {
992 lustre_cfg_bufs_set_string(&bufs, 2,
993 clli->cfg_uuid.uuid);
996 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
998 lcfg_new->lcfg_num = lcfg->lcfg_num;
999 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1001 /* XXX Hack to try to remain binary compatible with
1002 * pre-newconfig logs */
1003 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1004 (lcfg->lcfg_nid >> 32) == 0) {
1005 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1007 lcfg_new->lcfg_nid =
1008 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1009 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1010 lcfg->lcfg_nal, addr,
1011 libcfs_nid2str(lcfg_new->lcfg_nid));
1013 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1016 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1018 rc = class_process_config(lcfg_new);
1019 lustre_cfg_free(lcfg_new);
1022 OBD_FREE(inst_name, inst_len);
1026 CERROR("Unknown llog record type %#x encountered\n",
1032 CERROR("Err %d on cfg command:\n", rc);
1033 class_config_dump_handler(handle, rec, data);
1038 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1039 struct config_llog_instance *cfg)
1041 struct llog_process_cat_data cd = {0, 0};
1042 struct llog_handle *llh;
1046 CDEBUG(D_INFO, "looking up llog %s\n", name);
1047 rc = llog_create(ctxt, &llh, NULL, name);
1051 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1053 GOTO(parse_out, rc);
1055 /* continue processing from where we last stopped to end-of-log */
1057 cd.first_idx = cfg->cfg_last_idx;
1060 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1062 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1063 cd.first_idx + 1, cd.last_idx, rc);
1065 cfg->cfg_last_idx = cd.last_idx;
1068 rc2 = llog_close(llh);
1075 int class_config_dump_handler(struct llog_handle * handle,
1076 struct llog_rec_hdr *rec, void *data)
1078 int cfg_len = rec->lrh_len;
1079 char *cfg_buf = (char*) (rec + 1);
1080 char *outstr, *ptr, *end;
1084 OBD_ALLOC(outstr, 256);
1090 if (rec->lrh_type == OBD_CFG_REC) {
1091 struct lustre_cfg *lcfg;
1094 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1097 lcfg = (struct lustre_cfg *)cfg_buf;
1099 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1100 lcfg->lcfg_command);
1101 if (lcfg->lcfg_flags) {
1102 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1105 if (lcfg->lcfg_num) {
1106 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1109 if (lcfg->lcfg_nid) {
1110 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1111 libcfs_nid2str(lcfg->lcfg_nid),
1114 if (lcfg->lcfg_command == LCFG_MARKER) {
1115 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1116 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1117 marker->cm_step, marker->cm_flags,
1118 marker->cm_tgtname, marker->cm_comment);
1120 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1121 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1122 lustre_cfg_string(lcfg, i));
1125 LCONSOLE(D_WARNING, " %s\n", outstr);
1127 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1131 OBD_FREE(outstr, 256);
1135 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1136 struct config_llog_instance *cfg)
1138 struct llog_handle *llh;
1142 LCONSOLE_INFO("Dumping config log %s\n", name);
1144 rc = llog_create(ctxt, &llh, NULL, name);
1148 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1150 GOTO(parse_out, rc);
1152 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1154 rc2 = llog_close(llh);
1158 LCONSOLE_INFO("End config log %s\n", name);
1163 /* Cleanup and detach */
1164 int class_manual_cleanup(struct obd_device *obd)
1166 struct lustre_cfg *lcfg;
1167 struct lustre_cfg_bufs bufs;
1173 CERROR("empty cleanup\n");
1182 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1183 obd->obd_name, flags);
1185 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1186 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1187 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1189 rc = class_process_config(lcfg);
1191 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1195 /* the lcfg is almost the same for both ops */
1196 lcfg->lcfg_command = LCFG_DETACH;
1197 rc = class_process_config(lcfg);
1199 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1201 lustre_cfg_free(lcfg);