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",
478 obd->obd_self_export->exp_flags |=
479 (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
480 (obd->obd_force ? OBD_OPT_FORCE : 0);
481 /* note that we'll recurse into class_decref again */
482 class_unlink_export(obd->obd_self_export);
487 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
488 obd->obd_name, obd->obd_uuid.uuid);
489 LASSERT(!obd->obd_attached);
490 if (obd->obd_stopping) {
491 /* If we're not stopping, we were never set up */
492 err = obd_cleanup(obd);
494 CERROR("Cleanup %s returned %d\n",
497 if (OBP(obd, detach)) {
498 err = OBP(obd,detach)(obd);
500 CERROR("Detach returned %d\n", err);
502 class_release_dev(obd);
506 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
508 struct obd_import *imp;
509 struct obd_uuid uuid;
513 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
514 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
515 CERROR("invalid conn_uuid\n");
518 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
519 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
520 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
521 CERROR("can't add connection on non-client dev\n");
525 imp = obd->u.cli.cl_import;
527 CERROR("try to add conn on immature client dev\n");
531 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
532 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
537 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
539 struct obd_import *imp;
540 struct obd_uuid uuid;
544 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
545 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
546 CERROR("invalid conn_uuid\n");
549 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
550 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
551 CERROR("can't del connection on non-client dev\n");
555 imp = obd->u.cli.cl_import;
557 CERROR("try to del conn on immature client dev\n");
561 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
562 rc = obd_del_conn(imp, &uuid);
567 CFS_LIST_HEAD(lustre_profile_list);
569 struct lustre_profile *class_get_profile(char * prof)
571 struct lustre_profile *lprof;
574 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
575 if (!strcmp(lprof->lp_profile, prof)) {
582 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
583 int mdclen, char *mdc)
585 struct lustre_profile *lprof;
589 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
591 OBD_ALLOC(lprof, sizeof(*lprof));
594 CFS_INIT_LIST_HEAD(&lprof->lp_list);
596 LASSERT(proflen == (strlen(prof) + 1));
597 OBD_ALLOC(lprof->lp_profile, proflen);
598 if (lprof->lp_profile == NULL)
599 GOTO(out, err = -ENOMEM);
600 memcpy(lprof->lp_profile, prof, proflen);
602 LASSERT(osclen == (strlen(osc) + 1));
603 OBD_ALLOC(lprof->lp_osc, osclen);
604 if (lprof->lp_osc == NULL)
605 GOTO(out, err = -ENOMEM);
606 memcpy(lprof->lp_osc, osc, osclen);
609 LASSERT(mdclen == (strlen(mdc) + 1));
610 OBD_ALLOC(lprof->lp_mdc, mdclen);
611 if (lprof->lp_mdc == NULL)
612 GOTO(out, err = -ENOMEM);
613 memcpy(lprof->lp_mdc, mdc, mdclen);
616 list_add(&lprof->lp_list, &lustre_profile_list);
621 OBD_FREE(lprof->lp_mdc, mdclen);
623 OBD_FREE(lprof->lp_osc, osclen);
624 if (lprof->lp_profile)
625 OBD_FREE(lprof->lp_profile, proflen);
626 OBD_FREE(lprof, sizeof(*lprof));
630 void class_del_profile(char *prof)
632 struct lustre_profile *lprof;
635 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
637 lprof = class_get_profile(prof);
639 list_del(&lprof->lp_list);
640 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
641 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
643 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
644 OBD_FREE(lprof, sizeof *lprof);
650 void class_del_profiles(void)
652 struct lustre_profile *lprof, *n;
655 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
656 list_del(&lprof->lp_list);
657 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
658 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
660 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
661 OBD_FREE(lprof, sizeof *lprof);
666 /* We can't call ll_process_config directly because it lives in a module that
667 must be loaded after this one. */
668 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
670 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
672 client_process_config = cpc;
674 EXPORT_SYMBOL(lustre_register_client_process_config);
676 int class_process_config(struct lustre_cfg *lcfg)
678 struct obd_device *obd;
681 LASSERT(lcfg && !IS_ERR(lcfg));
682 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
684 /* Commands that don't need a device */
685 switch(lcfg->lcfg_command) {
687 err = class_attach(lcfg);
690 case LCFG_ADD_UUID: {
691 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
692 " (%s)\n", lustre_cfg_string(lcfg, 1),
693 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
695 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
698 case LCFG_DEL_UUID: {
699 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
700 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
701 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
703 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
706 case LCFG_MOUNTOPT: {
707 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
708 lustre_cfg_string(lcfg, 1),
709 lustre_cfg_string(lcfg, 2),
710 lustre_cfg_string(lcfg, 3));
711 /* set these mount options somewhere, so ll_fill_super
713 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
714 lustre_cfg_string(lcfg, 1),
715 LUSTRE_CFG_BUFLEN(lcfg, 2),
716 lustre_cfg_string(lcfg, 2),
717 LUSTRE_CFG_BUFLEN(lcfg, 3),
718 lustre_cfg_string(lcfg, 3));
721 case LCFG_DEL_MOUNTOPT: {
722 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
723 lustre_cfg_string(lcfg, 1));
724 class_del_profile(lustre_cfg_string(lcfg, 1));
727 case LCFG_SET_TIMEOUT: {
728 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
729 obd_timeout, lcfg->lcfg_num);
730 obd_timeout = max(lcfg->lcfg_num, 1U);
733 case LCFG_SET_UPCALL: {
734 LCONSOLE_ERROR("recovery upcall is deprecated\n");
735 /* COMPAT_146 Don't fail on old configs */
739 struct cfg_marker *marker;
740 marker = lustre_cfg_buf(lcfg, 1);
741 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
742 marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
746 /* llite has no obd */
747 if ((class_match_param(lustre_cfg_string(lcfg, 1),
748 PARAM_LLITE, 0) == 0) &&
749 client_process_config) {
750 err = (*client_process_config)(lcfg);
758 /* Commands that require a device */
759 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
761 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
762 CERROR("this lcfg command requires a device name\n");
764 CERROR("no device for: %s\n",
765 lustre_cfg_string(lcfg, 0));
767 GOTO(out, err = -EINVAL);
770 switch(lcfg->lcfg_command) {
772 err = class_setup(obd, lcfg);
776 err = class_detach(obd, lcfg);
780 err = class_cleanup(obd, lcfg);
783 case LCFG_ADD_CONN: {
784 err = class_add_conn(obd, lcfg);
787 case LCFG_DEL_CONN: {
788 err = class_del_conn(obd, lcfg);
792 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
798 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
799 CWARN("Ignoring error %d on optional command %#x\n", err,
806 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
807 struct lustre_cfg *lcfg, void *data)
810 struct lprocfs_vars *var;
813 int matched = 0, j = 0;
817 if (lcfg->lcfg_command != LCFG_PARAM) {
818 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
822 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
823 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
824 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
825 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
826 key = lustre_cfg_buf(lcfg, i);
827 /* Strip off prefix */
828 class_match_param(key, prefix, &key);
829 sval = strchr(key, '=');
830 if (!sval || (*(sval + 1) == 0)) {
831 CERROR("Can't parse param %s\n", key);
833 /* continue parsing other params */
837 vallen = strlen(sval);
840 /* Search proc entries */
841 while (lvars[j].name) {
843 if (class_match_param(key, (char *)var->name, 0) == 0) {
846 if (var->write_fptr) {
850 rc = (var->write_fptr)(NULL, sval,
855 CERROR("writing proc entry %s err %d\n",
862 CERROR("%s: unknown param %s\n",
863 lustre_cfg_string(lcfg, 0), key);
865 /* continue parsing other params */
867 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
868 lustre_cfg_string(lcfg, 0),
869 strlen(prefix) - 1, prefix,
870 sval - key - 1, key, sval);
878 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
879 /* Don't throw config error */
884 int class_config_dump_handler(struct llog_handle * handle,
885 struct llog_rec_hdr *rec, void *data);
888 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
890 #define lustre_check_exclusion(a,b) 0
893 static int class_config_llog_handler(struct llog_handle * handle,
894 struct llog_rec_hdr *rec, void *data)
896 struct config_llog_instance *clli = data;
897 int cfg_len = rec->lrh_len;
898 char *cfg_buf = (char*) (rec + 1);
902 //class_config_dump_handler(handle, rec, data);
904 switch (rec->lrh_type) {
906 struct lustre_cfg *lcfg, *lcfg_new;
907 struct lustre_cfg_bufs bufs;
908 char *inst_name = NULL;
912 lcfg = (struct lustre_cfg *)cfg_buf;
913 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
914 lustre_swab_lustre_cfg(lcfg);
916 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
920 /* Figure out config state info */
921 if (lcfg->lcfg_command == LCFG_MARKER) {
922 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
923 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
924 clli->cfg_flags, marker->cm_flags);
925 if (marker->cm_flags & CM_START) {
926 /* all previous flags off */
927 clli->cfg_flags = CFG_F_MARKER;
928 if (marker->cm_flags & CM_SKIP) {
929 clli->cfg_flags |= CFG_F_SKIP;
930 CDEBUG(D_CONFIG, "SKIP #%d\n",
932 } else if ((marker->cm_flags & CM_EXCLUDE) ||
933 lustre_check_exclusion(clli->cfg_sb,
934 marker->cm_tgtname)) {
935 clli->cfg_flags |= CFG_F_EXCLUDE;
936 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
939 } else if (marker->cm_flags & CM_END) {
943 /* A config command without a start marker before it is
944 illegal (post 146) */
945 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
946 !(clli->cfg_flags & CFG_F_MARKER) &&
947 (lcfg->lcfg_command != LCFG_MARKER)) {
948 CWARN("Config not inside markers, ignoring! (%#x)\n",
950 clli->cfg_flags |= CFG_F_SKIP;
953 if (clli->cfg_flags & CFG_F_SKIP) {
954 CDEBUG(D_CONFIG, "skipping %#x\n",
961 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
962 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
963 /* Add inactive instead */
964 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
966 lustre_cfg_bufs_init(&bufs, lcfg);
968 if (clli && clli->cfg_instance &&
969 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
971 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
972 strlen(clli->cfg_instance) + 1;
973 OBD_ALLOC(inst_name, inst_len);
974 if (inst_name == NULL)
975 GOTO(out, rc = -ENOMEM);
976 sprintf(inst_name, "%s-%s",
977 lustre_cfg_string(lcfg, 0),
979 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
980 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
981 lcfg->lcfg_command, inst_name);
984 /* we override the llog's uuid for clients, to insure they
986 if (clli && clli->cfg_instance &&
987 lcfg->lcfg_command == LCFG_ATTACH) {
988 lustre_cfg_bufs_set_string(&bufs, 2,
989 clli->cfg_uuid.uuid);
992 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
994 lcfg_new->lcfg_num = lcfg->lcfg_num;
995 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
997 /* XXX Hack to try to remain binary compatible with
998 * pre-newconfig logs */
999 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1000 (lcfg->lcfg_nid >> 32) == 0) {
1001 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1003 lcfg_new->lcfg_nid =
1004 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1005 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1006 lcfg->lcfg_nal, addr,
1007 libcfs_nid2str(lcfg_new->lcfg_nid));
1009 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1012 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1014 rc = class_process_config(lcfg_new);
1015 lustre_cfg_free(lcfg_new);
1018 OBD_FREE(inst_name, inst_len);
1022 CERROR("Unknown llog record type %#x encountered\n",
1028 CERROR("Err %d on cfg command:\n", rc);
1029 class_config_dump_handler(handle, rec, data);
1034 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1035 struct config_llog_instance *cfg)
1037 struct llog_process_cat_data cd = {0, 0};
1038 struct llog_handle *llh;
1042 CDEBUG(D_INFO, "looking up llog %s\n", name);
1043 rc = llog_create(ctxt, &llh, NULL, name);
1047 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1049 GOTO(parse_out, rc);
1051 /* continue processing from where we last stopped to end-of-log */
1053 cd.first_idx = cfg->cfg_last_idx;
1056 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1058 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1059 cd.first_idx + 1, cd.last_idx, rc);
1061 cfg->cfg_last_idx = cd.last_idx;
1064 rc2 = llog_close(llh);
1071 int class_config_dump_handler(struct llog_handle * handle,
1072 struct llog_rec_hdr *rec, void *data)
1074 int cfg_len = rec->lrh_len;
1075 char *cfg_buf = (char*) (rec + 1);
1076 char *outstr, *ptr, *end;
1080 OBD_ALLOC(outstr, 256);
1086 if (rec->lrh_type == OBD_CFG_REC) {
1087 struct lustre_cfg *lcfg;
1090 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1093 lcfg = (struct lustre_cfg *)cfg_buf;
1095 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1096 lcfg->lcfg_command);
1097 if (lcfg->lcfg_flags) {
1098 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1101 if (lcfg->lcfg_num) {
1102 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1105 if (lcfg->lcfg_nid) {
1106 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1107 libcfs_nid2str(lcfg->lcfg_nid),
1110 if (lcfg->lcfg_command == LCFG_MARKER) {
1111 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1112 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1113 marker->cm_step, marker->cm_flags,
1114 marker->cm_tgtname, marker->cm_comment);
1116 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1117 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1118 lustre_cfg_string(lcfg, i));
1121 LCONSOLE(D_WARNING, " %s\n", outstr);
1123 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1127 OBD_FREE(outstr, 256);
1131 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1132 struct config_llog_instance *cfg)
1134 struct llog_handle *llh;
1138 LCONSOLE_INFO("Dumping config log %s\n", name);
1140 rc = llog_create(ctxt, &llh, NULL, name);
1144 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1146 GOTO(parse_out, rc);
1148 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1150 rc2 = llog_close(llh);
1154 LCONSOLE_INFO("End config log %s\n", name);
1159 /* Cleanup and detach */
1160 int class_manual_cleanup(struct obd_device *obd)
1162 struct lustre_cfg *lcfg;
1163 struct lustre_cfg_bufs bufs;
1169 CERROR("empty cleanup\n");
1178 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1179 obd->obd_name, flags);
1181 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1182 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1183 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1185 rc = class_process_config(lcfg);
1187 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1191 /* the lcfg is almost the same for both ops */
1192 lcfg->lcfg_command = LCFG_DETACH;
1193 rc = class_process_config(lcfg);
1195 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1197 lustre_cfg_free(lcfg);