1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2001-2003 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 <linux/kmod.h> /* for request_module() */
31 #include <linux/module.h>
32 #include <linux/obd_class.h>
33 #include <linux/random.h>
34 #include <linux/slab.h>
35 #include <linux/pagemap.h>
37 #include <liblustre.h>
38 #include <linux/obd_class.h>
39 #include <linux/obd.h>
41 #include <linux/lustre_log.h>
42 #include <linux/lprocfs_status.h>
43 #include <libcfs/list.h>
46 /* Create a new device and set the type, name and uuid. If
47 * successful, the new device can be accessed by either name or uuid.
49 int class_attach(struct lustre_cfg *lcfg)
51 struct obd_type *type;
52 struct obd_device *obd = NULL;
53 char *typename, *name, *namecopy, *uuid;
54 int rc, len, cleanup_phase = 0;
56 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
57 CERROR("No type passed!\n");
60 typename = lustre_cfg_string(lcfg, 1);
62 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
63 CERROR("No name passed!\n");
66 name = lustre_cfg_string(lcfg, 0);
68 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
69 CERROR("No UUID passed!\n");
72 uuid = lustre_cfg_string(lcfg, 2);
74 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
75 MKSTR(typename), MKSTR(name), MKSTR(uuid));
77 /* Mountconf transitional hack, should go away after 1.6.
78 1.4.7 uses the old names, so translate back if the
79 mountconf flag is set.
80 1.6 should set this flag, and translate the other way here
82 if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
84 if (strcmp(typename, "mds") == 0)
86 if (strcmp(typename, "mdt") == 0)
88 if (strcmp(typename, "osd") == 0)
91 LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
92 MKSTR(typename), MKSTR(name));
98 type = class_get_type(typename);
100 CERROR("OBD: unknown type: %s\n", typename);
103 cleanup_phase = 1; /* class_put_type */
105 len = strlen(name) + 1;
106 OBD_ALLOC(namecopy, len);
108 GOTO(out, rc = -ENOMEM);
109 memcpy(namecopy, name, len);
110 cleanup_phase = 2; /* free obd_name */
112 obd = class_newdev(type, namecopy);
114 /* Already exists or out of obds */
115 CERROR("Can't create device %s\n", name);
116 GOTO(out, rc = -EEXIST);
118 cleanup_phase = 3; /* class_release_dev */
120 INIT_LIST_HEAD(&obd->obd_exports);
121 INIT_LIST_HEAD(&obd->obd_exports_timed);
122 obd->obd_num_exports = 0;
123 spin_lock_init(&obd->obd_dev_lock);
124 spin_lock_init(&obd->obd_osfs_lock);
125 obd->obd_osfs_age = jiffies - 1000 * HZ;
127 /* XXX belongs in setup not attach */
129 init_timer(&obd->obd_recovery_timer);
130 spin_lock_init(&obd->obd_processing_task_lock);
131 init_waitqueue_head(&obd->obd_next_transno_waitq);
132 INIT_LIST_HEAD(&obd->obd_recovery_queue);
133 INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
135 spin_lock_init(&obd->obd_uncommitted_replies_lock);
136 INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
139 if (len >= sizeof(obd->obd_uuid)) {
140 CERROR("uuid must be < "LPSZ" bytes long\n",
141 sizeof(obd->obd_uuid));
142 GOTO(out, rc = -EINVAL);
144 memcpy(obd->obd_uuid.uuid, uuid, len);
147 if (OBP(obd, attach)) {
148 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
150 GOTO(out, rc = -EINVAL);
153 /* Detach drops this */
154 atomic_set(&obd->obd_refcount, 1);
156 obd->obd_attached = 1;
158 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
159 obd->obd_minor, typename);
162 switch (cleanup_phase) {
164 class_release_dev(obd);
166 OBD_FREE(namecopy, strlen(namecopy) + 1);
168 class_put_type(type);
173 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
176 struct obd_export *exp;
179 LASSERT(obd == (obd_dev + obd->obd_minor));
181 /* have we attached a type to this device? */
182 if (!obd->obd_attached) {
183 CERROR("Device %d not attached\n", obd->obd_minor);
187 if (obd->obd_set_up) {
188 CERROR("Device %d already setup (type %s)\n",
189 obd->obd_minor, obd->obd_type->typ_name);
193 /* is someone else setting us up right now? (attach inits spinlock) */
194 spin_lock(&obd->obd_dev_lock);
195 if (obd->obd_starting) {
196 spin_unlock(&obd->obd_dev_lock);
197 CERROR("Device %d setup in progress (type %s)\n",
198 obd->obd_minor, obd->obd_type->typ_name);
201 /* just leave this on forever. I can't use obd_set_up here because
202 other fns check that status, and we're not actually set up yet. */
203 obd->obd_starting = 1;
204 spin_unlock(&obd->obd_dev_lock);
206 exp = class_new_export(obd);
208 CERROR("Fail to build export.\n");
211 memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
212 sizeof(exp->exp_client_uuid));
213 obd->obd_self_export = exp;
214 list_del_init(&exp->exp_obd_chain_timed);
215 class_export_put(exp);
217 err = obd_setup(obd, sizeof(*lcfg), lcfg);
221 obd->obd_type->typ_refcnt++;
223 spin_lock(&obd->obd_dev_lock);
224 /* cleanup drops this */
225 atomic_inc(&obd->obd_refcount);
226 spin_unlock(&obd->obd_dev_lock);
228 CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
229 obd->obd_name, obd->obd_uuid.uuid);
234 class_unlink_export(obd->obd_self_export);
235 obd->obd_self_export = NULL;
236 obd->obd_starting = 0;
240 static int __class_detach(struct obd_device *obd)
245 CDEBUG(D_CONFIG, "destroying obd %d (%s)\n",
246 obd->obd_minor, obd->obd_name);
248 if (OBP(obd, detach))
249 err = OBP(obd,detach)(obd);
252 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
253 obd->obd_name = NULL;
255 CERROR("device %d: no name at detach\n", obd->obd_minor);
259 /* Attach took type refcount */
260 obd->obd_type->typ_refcnt--;
261 class_put_type(obd->obd_type);
262 class_release_dev(obd);
266 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
270 if (obd->obd_set_up) {
271 CERROR("OBD device %d still set up\n", obd->obd_minor);
275 spin_lock(&obd->obd_dev_lock);
276 if (!obd->obd_attached) {
277 spin_unlock(&obd->obd_dev_lock);
278 CERROR("OBD device %d not attached\n", obd->obd_minor);
281 obd->obd_attached = 0;
282 spin_unlock(&obd->obd_dev_lock);
284 CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
285 obd->obd_name, obd->obd_uuid.uuid);
291 static void dump_exports(struct obd_device *obd)
293 struct obd_export *exp, *n;
295 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
296 struct ptlrpc_reply_state *rs;
297 struct ptlrpc_reply_state *first_reply = NULL;
300 list_for_each_entry (rs, &exp->exp_outstanding_replies,
307 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
308 obd->obd_name, exp, exp->exp_client_uuid.uuid,
309 obd_export_nid2str(exp),
310 atomic_read(&exp->exp_refcount),
311 exp->exp_failed, nreplies, first_reply,
312 nreplies > 3 ? "..." : "");
316 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
322 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
324 if (!obd->obd_set_up) {
325 CERROR("Device %d not setup\n", obd->obd_minor);
329 spin_lock(&obd->obd_dev_lock);
330 if (obd->obd_stopping) {
331 spin_unlock(&obd->obd_dev_lock);
332 CERROR("OBD %d already stopping\n", obd->obd_minor);
335 /* Leave this on forever */
336 obd->obd_stopping = 1;
337 spin_unlock(&obd->obd_dev_lock);
339 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
340 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
346 LCONSOLE_WARN("Failing %s by user command\n",
349 obd->obd_no_transno = 1;
350 obd->obd_no_recov = 1;
351 /* Set the obd readonly if we can */
352 if (OBP(obd, iocontrol))
353 obd_iocontrol(OBD_IOC_SET_READONLY,
354 obd->obd_self_export,
358 CERROR("unrecognised flag '%c'\n",
363 /* The three references that should be remaining are the
364 * obd_self_export and the attach and setup references. */
365 if (atomic_read(&obd->obd_refcount) > 3) {
366 if (!(obd->obd_fail || obd->obd_force)) {
367 CERROR("OBD %s is still busy with %d references\n"
368 "You should stop active file system users,"
369 " or use the --force option to cleanup.\n",
370 obd->obd_name, atomic_read(&obd->obd_refcount));
372 GOTO(out, err = -EBUSY);
374 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
375 obd->obd_name, atomic_read(&obd->obd_refcount) - 1);
377 class_disconnect_exports(obd);
380 LASSERT(obd->obd_self_export);
382 /* Precleanup stage 1, we must make sure all exports (other than the
383 self-export) get destroyed. */
384 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
386 CERROR("Precleanup %s returned %d\n",
391 obd->obd_type->typ_refcnt--;
395 /* Allow a failed cleanup to try again. */
396 obd->obd_stopping = 0;
400 void class_decref(struct obd_device *obd)
405 spin_lock(&obd->obd_dev_lock);
406 atomic_dec(&obd->obd_refcount);
407 refs = atomic_read(&obd->obd_refcount);
408 spin_unlock(&obd->obd_dev_lock);
410 CDEBUG(D_INFO, "Decref %s now %d\n", obd->obd_name, refs);
412 if ((refs == 1) && obd->obd_stopping) {
413 /* All exports (other than the self-export) have been
414 destroyed; there should be no more in-progress ops
416 /* if we're not stopping, we didn't finish setup */
417 /* Precleanup stage 2, do other type-specific
418 cleanup requiring the self-export. */
419 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
421 CERROR("Precleanup %s returned %d\n",
423 obd->obd_self_export->exp_flags |=
424 (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
425 (obd->obd_force ? OBD_OPT_FORCE : 0);
426 /* note that we'll recurse into class_decref again */
427 class_unlink_export(obd->obd_self_export);
432 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
433 obd->obd_name, obd->obd_uuid.uuid);
434 LASSERT(!obd->obd_attached);
435 if (obd->obd_stopping) {
436 /* If we're not stopping, we were never set up */
437 err = obd_cleanup(obd);
439 CERROR("Cleanup %s returned %d\n",
442 err = __class_detach(obd);
444 CERROR("Detach returned %d\n", err);
448 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
450 struct obd_import *imp;
451 struct obd_uuid uuid;
455 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
456 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
457 CERROR("invalid conn_uuid\n");
460 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
461 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
462 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
463 CERROR("can't add connection on non-client dev\n");
467 imp = obd->u.cli.cl_import;
469 CERROR("try to add conn on immature client dev\n");
473 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
474 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
479 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
481 struct obd_import *imp;
482 struct obd_uuid uuid;
486 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
487 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
488 CERROR("invalid conn_uuid\n");
491 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
492 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
493 CERROR("can't del connection on non-client dev\n");
497 imp = obd->u.cli.cl_import;
499 CERROR("try to del conn on immature client dev\n");
503 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
504 rc = obd_del_conn(imp, &uuid);
509 LIST_HEAD(lustre_profile_list);
511 struct lustre_profile *class_get_profile(char * prof)
513 struct lustre_profile *lprof;
515 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
516 if (!strcmp(lprof->lp_profile, prof)) {
523 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
524 int mdclen, char *mdc)
526 struct lustre_profile *lprof;
529 OBD_ALLOC(lprof, sizeof(*lprof));
532 INIT_LIST_HEAD(&lprof->lp_list);
534 LASSERT(proflen == (strlen(prof) + 1));
535 OBD_ALLOC(lprof->lp_profile, proflen);
536 if (lprof->lp_profile == NULL)
537 GOTO(out, err = -ENOMEM);
538 memcpy(lprof->lp_profile, prof, proflen);
540 LASSERT(osclen == (strlen(osc) + 1));
541 OBD_ALLOC(lprof->lp_osc, osclen);
542 if (lprof->lp_osc == NULL)
543 GOTO(out, err = -ENOMEM);
544 memcpy(lprof->lp_osc, osc, osclen);
547 LASSERT(mdclen == (strlen(mdc) + 1));
548 OBD_ALLOC(lprof->lp_mdc, mdclen);
549 if (lprof->lp_mdc == NULL)
550 GOTO(out, err = -ENOMEM);
551 memcpy(lprof->lp_mdc, mdc, mdclen);
554 list_add(&lprof->lp_list, &lustre_profile_list);
559 OBD_FREE(lprof->lp_mdc, mdclen);
561 OBD_FREE(lprof->lp_osc, osclen);
562 if (lprof->lp_profile)
563 OBD_FREE(lprof->lp_profile, proflen);
564 OBD_FREE(lprof, sizeof(*lprof));
568 void class_del_profile(char *prof)
570 struct lustre_profile *lprof;
572 lprof = class_get_profile(prof);
574 list_del(&lprof->lp_list);
575 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
576 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
578 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
579 OBD_FREE(lprof, sizeof *lprof);
583 int class_process_config(struct lustre_cfg *lcfg)
585 struct obd_device *obd;
588 LASSERT(lcfg && !IS_ERR(lcfg));
589 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
591 /* Commands that don't need a device */
592 switch(lcfg->lcfg_command) {
594 err = class_attach(lcfg);
597 case LCFG_ADD_UUID: {
598 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
599 " (%s)\n", lustre_cfg_string(lcfg, 1),
600 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
602 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
605 case LCFG_DEL_UUID: {
606 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
607 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
608 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
610 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
613 case LCFG_MOUNTOPT: {
614 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
615 lustre_cfg_string(lcfg, 1),
616 lustre_cfg_string(lcfg, 2),
617 lustre_cfg_string(lcfg, 3));
618 /* set these mount options somewhere, so ll_fill_super
620 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
621 lustre_cfg_string(lcfg, 1),
622 LUSTRE_CFG_BUFLEN(lcfg, 2),
623 lustre_cfg_string(lcfg, 2),
624 LUSTRE_CFG_BUFLEN(lcfg, 3),
625 lustre_cfg_string(lcfg, 3));
628 case LCFG_DEL_MOUNTOPT: {
629 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
630 lustre_cfg_string(lcfg, 1));
631 /* set these mount options somewhere, so ll_fill_super
633 class_del_profile(lustre_cfg_string(lcfg, 1));
636 case LCFG_SET_TIMEOUT: {
637 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
638 obd_timeout, lcfg->lcfg_num);
639 obd_timeout = max(lcfg->lcfg_num, 1U);
640 if (ldlm_timeout >= obd_timeout)
641 ldlm_timeout = max(obd_timeout / 3, 1U);
644 case LCFG_SET_UPCALL: {
645 CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
646 lustre_cfg_string(lcfg, 1));
647 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof obd_lustre_upcall)
648 GOTO(out, err = -EINVAL);
649 strncpy(obd_lustre_upcall, lustre_cfg_string(lcfg, 1),
650 sizeof (obd_lustre_upcall));
654 struct cfg_marker *marker;
655 LCONSOLE_WARN("LCFG_MARKER not yet implemented.\n");
656 marker = lustre_cfg_buf(lcfg, 1);
657 CDEBUG(D_WARNING, "%d (%x) %s\n", marker->cm_step,
658 marker->cm_flags, marker->cm_comment);
663 /* Commands that require a device */
664 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
666 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
667 CERROR("this lcfg command requires a device name\n");
669 CERROR("no device for: %s\n",
670 lustre_cfg_string(lcfg, 0));
672 GOTO(out, err = -EINVAL);
675 switch(lcfg->lcfg_command) {
677 err = class_setup(obd, lcfg);
681 err = class_detach(obd, lcfg);
685 err = class_cleanup(obd, lcfg);
688 case LCFG_ADD_CONN: {
689 err = class_add_conn(obd, lcfg);
692 case LCFG_DEL_CONN: {
693 err = class_del_conn(obd, lcfg);
697 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
706 int class_config_dump_handler(struct llog_handle * handle,
707 struct llog_rec_hdr *rec, void *data);
709 static int class_config_llog_handler(struct llog_handle * handle,
710 struct llog_rec_hdr *rec, void *data)
712 struct config_llog_instance *cfg = data;
713 int cfg_len = rec->lrh_len;
714 char *cfg_buf = (char*) (rec + 1);
719 class_config_dump_handler(handle, rec, data);
721 switch (rec->lrh_type) {
723 struct lustre_cfg *lcfg, *lcfg_new;
724 struct lustre_cfg_bufs bufs;
725 char *inst_name = NULL;
729 lcfg = (struct lustre_cfg *)cfg_buf;
730 if (lcfg->lcfg_magic == __swab32(LUSTRE_CFG_MAGIC))
731 lustre_swab_lustre_cfg(lcfg);
733 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
737 lustre_cfg_bufs_init(&bufs, lcfg);
739 if (cfg && cfg->cfg_instance && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
741 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
742 strlen(cfg->cfg_instance) + 1;
743 OBD_ALLOC(inst_name, inst_len);
744 if (inst_name == NULL)
745 GOTO(out, rc = -ENOMEM);
746 sprintf(inst_name, "%s-%s",
747 lustre_cfg_string(lcfg, 0),
749 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
750 CERROR("cmd %x, instance name: %s\n",
751 lcfg->lcfg_command, inst_name);
754 /* we override the llog's uuid for clients, to insure they
756 if (cfg && cfg->cfg_instance &&
757 lcfg->lcfg_command == LCFG_ATTACH) {
758 lustre_cfg_bufs_set_string(&bufs, 2, cfg->cfg_uuid.uuid);
761 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
763 lcfg_new->lcfg_num = lcfg->lcfg_num;
764 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
766 /* XXX Hack to try to remain binary compatible with
767 * pre-newconfig logs */
768 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
769 (lcfg->lcfg_nid >> 32) == 0) {
770 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
773 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
774 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
775 lcfg->lcfg_nal, addr,
776 libcfs_nid2str(lcfg_new->lcfg_nid));
778 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
781 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
783 rc = class_process_config(lcfg_new);
784 lustre_cfg_free(lcfg_new);
787 OBD_FREE(inst_name, inst_len);
791 CWARN("Ignoring obsolete portals config\n");
795 CERROR("Unknown llog record type %#x encountered\n",
803 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
804 struct config_llog_instance *cfg)
806 struct llog_handle *llh;
810 CDEBUG(D_INFO, "looking up llog %s\n", name);
811 rc = llog_create(ctxt, &llh, NULL, name);
815 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
819 rc = llog_process(llh, class_config_llog_handler, cfg, NULL);
821 rc2 = llog_close(llh);
828 #define D_DUMP D_INFO|D_WARNING
829 int class_config_dump_handler(struct llog_handle * handle,
830 struct llog_rec_hdr *rec, void *data)
832 int cfg_len = rec->lrh_len;
833 char *cfg_buf = (char*) (rec + 1);
834 char *outstr, *ptr, *end;
838 OBD_ALLOC(outstr, 256);
844 if (rec->lrh_type == OBD_CFG_REC) {
845 struct lustre_cfg *lcfg;
848 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
851 lcfg = (struct lustre_cfg *)cfg_buf;
853 ptr += snprintf(ptr, end-ptr, "\n cmd=%05x ",
855 if (lcfg->lcfg_flags) {
856 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
859 if (lcfg->lcfg_num) {
860 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
863 if (lcfg->lcfg_nid) {
864 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n",
865 libcfs_nid2str(lcfg->lcfg_nid),
868 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
869 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
870 lustre_cfg_string(lcfg, i));
872 CDEBUG(D_DUMP, "%s\n", outstr);
873 } else if (rec->lrh_type == PTL_CFG_REC) {
874 CDEBUG(D_DUMP, "Obsolete pcfg command\n");
876 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
880 OBD_FREE(outstr, end - outstr);
884 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
885 struct config_llog_instance *cfg)
887 struct llog_handle *llh;
891 CDEBUG(D_DUMP, "Dumping config log %s\n", name);
893 rc = llog_create(ctxt, &llh, NULL, name);
897 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
901 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
903 rc2 = llog_close(llh);
907 CDEBUG(D_DUMP, "End config log %s\n", name);
912 /* Cleanup and detach */
913 int class_manual_cleanup(struct obd_device *obd)
915 struct lustre_cfg *lcfg;
916 struct lustre_cfg_bufs bufs;
922 CERROR("empty cleanup\n");
931 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
932 obd->obd_name, flags);
934 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
935 lustre_cfg_bufs_set_string(&bufs, 1, flags);
936 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
938 rc = class_process_config(lcfg);
940 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
944 /* the lcfg is almost the same for both ops */
945 lcfg->lcfg_command = LCFG_DETACH;
946 rc = class_process_config(lcfg);
948 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
950 lustre_cfg_free(lcfg);