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("Unknown param %s\n", key);
864 /* continue parsing other params */
866 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
867 lustre_cfg_buf(lcfg, 0),
868 strlen(prefix) - 1, prefix,
869 sval - key - 1, key, sval);
877 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
878 /* Don't throw config error */
883 int class_config_dump_handler(struct llog_handle * handle,
884 struct llog_rec_hdr *rec, void *data);
887 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
889 #define lustre_check_exclusion(a,b) 0
892 static int class_config_llog_handler(struct llog_handle * handle,
893 struct llog_rec_hdr *rec, void *data)
895 struct config_llog_instance *clli = data;
896 int cfg_len = rec->lrh_len;
897 char *cfg_buf = (char*) (rec + 1);
901 //class_config_dump_handler(handle, rec, data);
903 switch (rec->lrh_type) {
905 struct lustre_cfg *lcfg, *lcfg_new;
906 struct lustre_cfg_bufs bufs;
907 char *inst_name = NULL;
911 lcfg = (struct lustre_cfg *)cfg_buf;
912 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
913 lustre_swab_lustre_cfg(lcfg);
915 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
919 /* Figure out config state info */
920 if (lcfg->lcfg_command == LCFG_MARKER) {
921 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
922 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
923 clli->cfg_flags, marker->cm_flags);
924 if (marker->cm_flags & CM_START) {
925 /* all previous flags off */
926 clli->cfg_flags = CFG_F_MARKER;
927 if (marker->cm_flags & CM_SKIP) {
928 clli->cfg_flags |= CFG_F_SKIP;
929 CDEBUG(D_CONFIG, "SKIP #%d\n",
931 } else if ((marker->cm_flags & CM_EXCLUDE) ||
932 lustre_check_exclusion(clli->cfg_sb,
933 marker->cm_tgtname)) {
934 clli->cfg_flags |= CFG_F_EXCLUDE;
935 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
938 } else if (marker->cm_flags & CM_END) {
942 /* A config command without a start marker before it is
943 illegal (post 146) */
944 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
945 !(clli->cfg_flags & CFG_F_MARKER) &&
946 (lcfg->lcfg_command != LCFG_MARKER)) {
947 CWARN("Config not inside markers, ignoring! (%#x)\n",
949 clli->cfg_flags |= CFG_F_SKIP;
952 if (clli->cfg_flags & CFG_F_SKIP) {
953 CDEBUG(D_CONFIG, "skipping %#x\n",
960 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
961 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
962 /* Add inactive instead */
963 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
965 lustre_cfg_bufs_init(&bufs, lcfg);
967 if (clli && clli->cfg_instance &&
968 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
970 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
971 strlen(clli->cfg_instance) + 1;
972 OBD_ALLOC(inst_name, inst_len);
973 if (inst_name == NULL)
974 GOTO(out, rc = -ENOMEM);
975 sprintf(inst_name, "%s-%s",
976 lustre_cfg_string(lcfg, 0),
978 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
979 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
980 lcfg->lcfg_command, inst_name);
983 /* we override the llog's uuid for clients, to insure they
985 if (clli && clli->cfg_instance &&
986 lcfg->lcfg_command == LCFG_ATTACH) {
987 lustre_cfg_bufs_set_string(&bufs, 2,
988 clli->cfg_uuid.uuid);
991 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
993 lcfg_new->lcfg_num = lcfg->lcfg_num;
994 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
996 /* XXX Hack to try to remain binary compatible with
997 * pre-newconfig logs */
998 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
999 (lcfg->lcfg_nid >> 32) == 0) {
1000 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1002 lcfg_new->lcfg_nid =
1003 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1004 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1005 lcfg->lcfg_nal, addr,
1006 libcfs_nid2str(lcfg_new->lcfg_nid));
1008 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1011 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1013 rc = class_process_config(lcfg_new);
1014 lustre_cfg_free(lcfg_new);
1017 OBD_FREE(inst_name, inst_len);
1021 CERROR("Unknown llog record type %#x encountered\n",
1027 CERROR("Err %d on cfg command:\n", rc);
1028 class_config_dump_handler(handle, rec, data);
1033 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1034 struct config_llog_instance *cfg)
1036 struct llog_process_cat_data cd = {0, 0};
1037 struct llog_handle *llh;
1041 CDEBUG(D_INFO, "looking up llog %s\n", name);
1042 rc = llog_create(ctxt, &llh, NULL, name);
1046 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1048 GOTO(parse_out, rc);
1050 /* continue processing from where we last stopped to end-of-log */
1052 cd.first_idx = cfg->cfg_last_idx;
1055 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1057 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1058 cd.first_idx + 1, cd.last_idx, rc);
1060 cfg->cfg_last_idx = cd.last_idx;
1063 rc2 = llog_close(llh);
1070 int class_config_dump_handler(struct llog_handle * handle,
1071 struct llog_rec_hdr *rec, void *data)
1073 int cfg_len = rec->lrh_len;
1074 char *cfg_buf = (char*) (rec + 1);
1075 char *outstr, *ptr, *end;
1079 OBD_ALLOC(outstr, 256);
1085 if (rec->lrh_type == OBD_CFG_REC) {
1086 struct lustre_cfg *lcfg;
1089 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1092 lcfg = (struct lustre_cfg *)cfg_buf;
1094 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1095 lcfg->lcfg_command);
1096 if (lcfg->lcfg_flags) {
1097 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1100 if (lcfg->lcfg_num) {
1101 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1104 if (lcfg->lcfg_nid) {
1105 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1106 libcfs_nid2str(lcfg->lcfg_nid),
1109 if (lcfg->lcfg_command == LCFG_MARKER) {
1110 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1111 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1112 marker->cm_step, marker->cm_flags,
1113 marker->cm_tgtname, marker->cm_comment);
1115 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1116 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1117 lustre_cfg_string(lcfg, i));
1120 LCONSOLE(D_WARNING, " %s\n", outstr);
1122 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1126 OBD_FREE(outstr, 256);
1130 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1131 struct config_llog_instance *cfg)
1133 struct llog_handle *llh;
1137 LCONSOLE_INFO("Dumping config log %s\n", name);
1139 rc = llog_create(ctxt, &llh, NULL, name);
1143 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1145 GOTO(parse_out, rc);
1147 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1149 rc2 = llog_close(llh);
1153 LCONSOLE_INFO("End config log %s\n", name);
1158 /* Cleanup and detach */
1159 int class_manual_cleanup(struct obd_device *obd)
1161 struct lustre_cfg *lcfg;
1162 struct lustre_cfg_bufs bufs;
1168 CERROR("empty cleanup\n");
1177 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1178 obd->obd_name, flags);
1180 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1181 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1182 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1184 rc = class_process_config(lcfg);
1186 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1190 /* the lcfg is almost the same for both ops */
1191 lcfg->lcfg_command = LCFG_DETACH;
1192 rc = class_process_config(lcfg);
1194 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1196 lustre_cfg_free(lcfg);