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>
41 #include <class_hash.h>
43 extern struct lustre_hash_operations uuid_hash_operations;
44 extern struct lustre_hash_operations nid_hash_operations;
46 /*********** string parsing utils *********/
48 /* returns 0 if we find this key in the buffer, else 1 */
49 int class_find_param(char *buf, char *key, char **valp)
56 if ((ptr = strstr(buf, key)) == NULL)
60 *valp = ptr + strlen(key);
65 /* returns 0 if this is the first key in the buffer, else 1.
66 valp points to first char after key. */
67 int class_match_param(char *buf, char *key, char **valp)
72 if (memcmp(buf, key, strlen(key)) != 0)
76 *valp = buf + strlen(key);
84 endh is set to next separator */
85 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
91 while (*buf == ',' || *buf == ':')
93 if (*buf == ' ' || *buf == '/' || *buf == '\0')
96 /* nid separators or end of nids */
97 endp = strpbrk(buf, ",: /");
99 endp = buf + strlen(buf);
103 *nid = libcfs_str2nid(buf);
104 if (*nid == LNET_NID_ANY) {
105 LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
113 CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));
117 EXPORT_SYMBOL(class_find_param);
118 EXPORT_SYMBOL(class_match_param);
119 EXPORT_SYMBOL(class_parse_nid);
121 /********************** class fns **********************/
123 /* Create a new device and set the type, name and uuid. If
124 * successful, the new device can be accessed by either name or uuid.
126 int class_attach(struct lustre_cfg *lcfg)
128 struct obd_device *obd = NULL;
129 char *typename, *name, *uuid;
133 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
134 CERROR("No type passed!\n");
137 typename = lustre_cfg_string(lcfg, 1);
139 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
140 CERROR("No name passed!\n");
143 name = lustre_cfg_string(lcfg, 0);
145 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
146 CERROR("No UUID passed!\n");
149 uuid = lustre_cfg_string(lcfg, 2);
151 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
152 MKSTR(typename), MKSTR(name), MKSTR(uuid));
154 /* Mountconf transitional hack, should go away after 1.6.
155 1.4.7 uses the old names, so translate back if the
156 mountconf flag is set.
157 1.6 should set this flag, and translate the other way here
159 if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
161 if (strcmp(typename, "mds") == 0)
163 if (strcmp(typename, "mdt") == 0)
165 if (strcmp(typename, "osd") == 0)
168 LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
169 MKSTR(typename), MKSTR(name));
174 obd = class_newdev(typename, name);
176 /* Already exists or out of obds */
179 CERROR("Cannot create device %s of type %s : %d\n",
183 LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
185 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
186 "obd %p obd_magic %08X != %08X\n",
187 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
188 LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",
189 obd, obd->obd_name, name);
191 CFS_INIT_LIST_HEAD(&obd->obd_exports);
192 CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
193 spin_lock_init(&obd->obd_dev_lock);
194 sema_init(&obd->obd_dev_sem, 1);
195 sema_init(&obd->obd_proc_exp_sem, 1);
196 spin_lock_init(&obd->obd_osfs_lock);
197 /* obd->obd_osfs_age must be set to a value in the distant
198 * past to guarantee a fresh statfs is fetched on mount. */
199 obd->obd_osfs_age = cfs_time_shift_64(-1000);
201 /* XXX belongs in setup not attach */
203 cfs_init_timer(&obd->obd_recovery_timer);
204 spin_lock_init(&obd->obd_processing_task_lock);
205 cfs_waitq_init(&obd->obd_next_transno_waitq);
206 CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);
207 CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
209 spin_lock_init(&obd->obd_uncommitted_replies_lock);
210 CFS_INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
213 if (len >= sizeof(obd->obd_uuid)) {
214 CERROR("uuid must be < "LPSZ" bytes long\n",
215 sizeof(obd->obd_uuid));
216 GOTO(out, rc = -EINVAL);
218 memcpy(obd->obd_uuid.uuid, uuid, len);
221 if (OBP(obd, attach)) {
222 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
224 GOTO(out, rc = -EINVAL);
227 /* Detach drops this */
228 spin_lock(&obd->obd_dev_lock);
229 atomic_set(&obd->obd_refcount, 1);
230 spin_unlock(&obd->obd_dev_lock);
232 obd->obd_attached = 1;
233 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
234 obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
238 class_release_dev(obd);
243 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
246 struct obd_export *exp;
249 LASSERT(obd != NULL);
250 LASSERTF(obd == class_num2obd(obd->obd_minor), "obd %p != obd_devs[%d] %p\n",
251 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
252 LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n",
253 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
255 /* have we attached a type to this device? */
256 if (!obd->obd_attached) {
257 CERROR("Device %d not attached\n", obd->obd_minor);
261 if (obd->obd_set_up) {
262 CERROR("Device %d already setup (type %s)\n",
263 obd->obd_minor, obd->obd_type->typ_name);
267 /* is someone else setting us up right now? (attach inits spinlock) */
268 spin_lock(&obd->obd_dev_lock);
269 if (obd->obd_starting) {
270 spin_unlock(&obd->obd_dev_lock);
271 CERROR("Device %d setup in progress (type %s)\n",
272 obd->obd_minor, obd->obd_type->typ_name);
275 /* just leave this on forever. I can't use obd_set_up here because
276 other fns check that status, and we're not actually set up yet. */
277 obd->obd_starting = 1;
279 /* create an uuid-export hash body */
280 err = lustre_hash_init(&obd->obd_uuid_hash_body, "UUID_HASH",
281 128, &uuid_hash_operations);
285 /* create a nid-export hash body */
286 err = lustre_hash_init(&obd->obd_nid_hash_body, "NID_HASH",
287 128, &nid_hash_operations);
291 spin_unlock(&obd->obd_dev_lock);
293 exp = class_new_export(obd, &obd->obd_uuid);
295 RETURN(PTR_ERR(exp));
296 obd->obd_self_export = exp;
297 list_del_init(&exp->exp_obd_chain_timed);
298 class_export_put(exp);
300 err = obd_setup(obd, sizeof(*lcfg), lcfg);
305 spin_lock(&obd->obd_dev_lock);
306 /* cleanup drops this */
308 spin_unlock(&obd->obd_dev_lock);
310 CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
311 obd->obd_name, obd->obd_uuid.uuid);
316 CERROR("setup %s failed (%d)\n", obd->obd_name, err);
317 lustre_hash_exit(&obd->obd_uuid_hash_body);
318 lustre_hash_exit(&obd->obd_nid_hash_body);
319 class_unlink_export(obd->obd_self_export);
320 obd->obd_self_export = NULL;
321 obd->obd_starting = 0;
325 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
329 if (obd->obd_set_up) {
330 CERROR("OBD device %d still set up\n", obd->obd_minor);
334 spin_lock(&obd->obd_dev_lock);
335 if (!obd->obd_attached) {
336 spin_unlock(&obd->obd_dev_lock);
337 CERROR("OBD device %d not attached\n", obd->obd_minor);
340 obd->obd_attached = 0;
341 spin_unlock(&obd->obd_dev_lock);
343 CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
344 obd->obd_name, obd->obd_uuid.uuid);
348 /* not strictly necessary, but cleans up eagerly */
349 obd_zombie_impexp_cull();
354 static void dump_exports(struct obd_device *obd)
356 struct obd_export *exp, *n;
358 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
359 struct ptlrpc_reply_state *rs;
360 struct ptlrpc_reply_state *first_reply = NULL;
363 list_for_each_entry (rs, &exp->exp_outstanding_replies,
370 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
371 obd->obd_name, exp, exp->exp_client_uuid.uuid,
372 obd_export_nid2str(exp),
373 atomic_read(&exp->exp_refcount),
374 exp->exp_failed, nreplies, first_reply,
375 nreplies > 3 ? "..." : "");
379 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
385 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
387 if (!obd->obd_set_up) {
388 CERROR("Device %d not setup\n", obd->obd_minor);
392 spin_lock(&obd->obd_dev_lock);
393 if (obd->obd_stopping) {
394 spin_unlock(&obd->obd_dev_lock);
395 CERROR("OBD %d already stopping\n", obd->obd_minor);
398 /* Leave this on forever */
399 obd->obd_stopping = 1;
400 spin_unlock(&obd->obd_dev_lock);
402 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
403 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
409 LCONSOLE_WARN("Failing over %s\n",
412 obd->obd_no_transno = 1;
413 obd->obd_no_recov = 1;
414 /* Set the obd readonly if we can */
415 if (OBP(obd, iocontrol))
416 obd_iocontrol(OBD_IOC_SET_READONLY,
417 obd->obd_self_export,
421 CERROR("unrecognised flag '%c'\n",
426 /* The three references that should be remaining are the
427 * obd_self_export and the attach and setup references. */
428 if (atomic_read(&obd->obd_refcount) > 3) {
429 #if 0 /* We should never fail to cleanup with mountconf */
430 if (!(obd->obd_fail || obd->obd_force)) {
431 CERROR("OBD %s is still busy with %d references\n"
432 "You should stop active file system users,"
433 " or use the --force option to cleanup.\n",
434 obd->obd_name, atomic_read(&obd->obd_refcount));
436 /* Allow a failed cleanup to try again. */
437 obd->obd_stopping = 0;
441 /* refcounf - 3 might be the number of real exports
442 (excluding self export). But class_incref is called
443 by other things as well, so don't count on it. */
444 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
445 obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
447 class_disconnect_exports(obd);
450 LASSERT(obd->obd_self_export);
452 /* destroy an uuid-export hash body */
453 lustre_hash_exit(&obd->obd_uuid_hash_body);
455 /* destroy a nid-export hash body */
456 lustre_hash_exit(&obd->obd_nid_hash_body);
458 /* Precleanup stage 1, we must make sure all exports (other than the
459 self-export) get destroyed. */
460 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
462 CERROR("Precleanup %s returned %d\n",
471 struct obd_device *class_incref(struct obd_device *obd)
473 atomic_inc(&obd->obd_refcount);
474 CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
475 atomic_read(&obd->obd_refcount));
480 void class_decref(struct obd_device *obd)
485 spin_lock(&obd->obd_dev_lock);
486 atomic_dec(&obd->obd_refcount);
487 refs = atomic_read(&obd->obd_refcount);
488 spin_unlock(&obd->obd_dev_lock);
490 CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
492 if ((refs == 1) && obd->obd_stopping) {
493 /* All exports (other than the self-export) have been
494 destroyed; there should be no more in-progress ops
496 /* if we're not stopping, we didn't finish setup */
497 /* Precleanup stage 2, do other type-specific
498 cleanup requiring the self-export. */
499 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
501 CERROR("Precleanup %s returned %d\n",
503 obd->obd_self_export->exp_flags |=
504 (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
505 (obd->obd_force ? OBD_OPT_FORCE : 0);
506 /* note that we'll recurse into class_decref again */
507 class_unlink_export(obd->obd_self_export);
512 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
513 obd->obd_name, obd->obd_uuid.uuid);
514 LASSERT(!obd->obd_attached);
515 if (obd->obd_stopping) {
516 /* If we're not stopping, we were never set up */
517 err = obd_cleanup(obd);
519 CERROR("Cleanup %s returned %d\n",
522 if (OBP(obd, detach)) {
523 err = OBP(obd,detach)(obd);
525 CERROR("Detach returned %d\n", err);
527 class_release_dev(obd);
531 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
533 struct obd_import *imp;
534 struct obd_uuid uuid;
538 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
539 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
540 CERROR("invalid conn_uuid\n");
543 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
544 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
545 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
546 CERROR("can't add connection on non-client dev\n");
550 imp = obd->u.cli.cl_import;
552 CERROR("try to add conn on immature client dev\n");
556 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
557 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
562 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
564 struct obd_import *imp;
565 struct obd_uuid uuid;
569 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
570 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
571 CERROR("invalid conn_uuid\n");
574 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
575 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
576 CERROR("can't del connection on non-client dev\n");
580 imp = obd->u.cli.cl_import;
582 CERROR("try to del conn on immature client dev\n");
586 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
587 rc = obd_del_conn(imp, &uuid);
592 CFS_LIST_HEAD(lustre_profile_list);
594 struct lustre_profile *class_get_profile(char * prof)
596 struct lustre_profile *lprof;
599 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
600 if (!strcmp(lprof->lp_profile, prof)) {
607 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
608 int mdclen, char *mdc)
610 struct lustre_profile *lprof;
614 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
616 OBD_ALLOC(lprof, sizeof(*lprof));
619 CFS_INIT_LIST_HEAD(&lprof->lp_list);
621 LASSERT(proflen == (strlen(prof) + 1));
622 OBD_ALLOC(lprof->lp_profile, proflen);
623 if (lprof->lp_profile == NULL)
624 GOTO(out, err = -ENOMEM);
625 memcpy(lprof->lp_profile, prof, proflen);
627 LASSERT(osclen == (strlen(osc) + 1));
628 OBD_ALLOC(lprof->lp_osc, osclen);
629 if (lprof->lp_osc == NULL)
630 GOTO(out, err = -ENOMEM);
631 memcpy(lprof->lp_osc, osc, osclen);
634 LASSERT(mdclen == (strlen(mdc) + 1));
635 OBD_ALLOC(lprof->lp_mdc, mdclen);
636 if (lprof->lp_mdc == NULL)
637 GOTO(out, err = -ENOMEM);
638 memcpy(lprof->lp_mdc, mdc, mdclen);
641 list_add(&lprof->lp_list, &lustre_profile_list);
646 OBD_FREE(lprof->lp_mdc, mdclen);
648 OBD_FREE(lprof->lp_osc, osclen);
649 if (lprof->lp_profile)
650 OBD_FREE(lprof->lp_profile, proflen);
651 OBD_FREE(lprof, sizeof(*lprof));
655 void class_del_profile(char *prof)
657 struct lustre_profile *lprof;
660 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
662 lprof = class_get_profile(prof);
664 list_del(&lprof->lp_list);
665 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
666 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
668 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
669 OBD_FREE(lprof, sizeof *lprof);
675 void class_del_profiles(void)
677 struct lustre_profile *lprof, *n;
680 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
681 list_del(&lprof->lp_list);
682 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
683 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
685 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
686 OBD_FREE(lprof, sizeof *lprof);
691 /* We can't call ll_process_config directly because it lives in a module that
692 must be loaded after this one. */
693 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
695 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
697 client_process_config = cpc;
699 EXPORT_SYMBOL(lustre_register_client_process_config);
701 int class_process_config(struct lustre_cfg *lcfg)
703 struct obd_device *obd;
706 LASSERT(lcfg && !IS_ERR(lcfg));
707 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
709 /* Commands that don't need a device */
710 switch(lcfg->lcfg_command) {
712 err = class_attach(lcfg);
715 case LCFG_ADD_UUID: {
716 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
717 " (%s)\n", lustre_cfg_string(lcfg, 1),
718 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
720 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
723 case LCFG_DEL_UUID: {
724 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
725 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
726 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
728 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
731 case LCFG_MOUNTOPT: {
732 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
733 lustre_cfg_string(lcfg, 1),
734 lustre_cfg_string(lcfg, 2),
735 lustre_cfg_string(lcfg, 3));
736 /* set these mount options somewhere, so ll_fill_super
738 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
739 lustre_cfg_string(lcfg, 1),
740 LUSTRE_CFG_BUFLEN(lcfg, 2),
741 lustre_cfg_string(lcfg, 2),
742 LUSTRE_CFG_BUFLEN(lcfg, 3),
743 lustre_cfg_string(lcfg, 3));
746 case LCFG_DEL_MOUNTOPT: {
747 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
748 lustre_cfg_string(lcfg, 1));
749 class_del_profile(lustre_cfg_string(lcfg, 1));
752 case LCFG_SET_TIMEOUT: {
753 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
754 obd_timeout, lcfg->lcfg_num);
755 obd_timeout = max(lcfg->lcfg_num, 1U);
758 case LCFG_SET_UPCALL: {
759 LCONSOLE_ERROR("recovery upcall is deprecated\n");
760 /* COMPAT_146 Don't fail on old configs */
764 struct cfg_marker *marker;
765 marker = lustre_cfg_buf(lcfg, 1);
766 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
767 marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
771 /* llite has no obd */
772 if ((class_match_param(lustre_cfg_string(lcfg, 1),
773 PARAM_LLITE, 0) == 0) &&
774 client_process_config) {
775 err = (*client_process_config)(lcfg);
783 /* Commands that require a device */
784 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
786 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
787 CERROR("this lcfg command requires a device name\n");
789 CERROR("no device for: %s\n",
790 lustre_cfg_string(lcfg, 0));
792 GOTO(out, err = -EINVAL);
795 switch(lcfg->lcfg_command) {
797 err = class_setup(obd, lcfg);
801 err = class_detach(obd, lcfg);
805 err = class_cleanup(obd, lcfg);
808 case LCFG_ADD_CONN: {
809 err = class_add_conn(obd, lcfg);
812 case LCFG_DEL_CONN: {
813 err = class_del_conn(obd, lcfg);
817 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
823 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
824 CWARN("Ignoring error %d on optional command %#x\n", err,
831 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
832 struct lustre_cfg *lcfg, void *data)
835 struct lprocfs_vars *var;
838 int matched = 0, j = 0;
842 if (lcfg->lcfg_command != LCFG_PARAM) {
843 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
847 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
848 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
849 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
850 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
851 key = lustre_cfg_buf(lcfg, i);
852 /* Strip off prefix */
853 class_match_param(key, prefix, &key);
854 sval = strchr(key, '=');
855 if (!sval || (*(sval + 1) == 0)) {
856 CERROR("Can't parse param %s\n", key);
858 /* continue parsing other params */
862 vallen = strlen(sval);
865 /* Search proc entries */
866 while (lvars[j].name) {
868 if (class_match_param(key, (char *)var->name, 0) == 0) {
871 if (var->write_fptr) {
875 rc = (var->write_fptr)(NULL, sval,
880 CERROR("writing proc entry %s err %d\n",
887 CERROR("%s: unknown param %s\n",
888 lustre_cfg_buf(lcfg, 0), key);
890 /* continue parsing other params */
892 LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n",
893 lustre_cfg_buf(lcfg, 0),
894 strlen(prefix) - 1, prefix,
895 sval - key - 1, key, sval);
903 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
904 /* Don't throw config error */
909 int class_config_dump_handler(struct llog_handle * handle,
910 struct llog_rec_hdr *rec, void *data);
913 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
915 #define lustre_check_exclusion(a,b) 0
918 static int class_config_llog_handler(struct llog_handle * handle,
919 struct llog_rec_hdr *rec, void *data)
921 struct config_llog_instance *clli = data;
922 int cfg_len = rec->lrh_len;
923 char *cfg_buf = (char*) (rec + 1);
927 //class_config_dump_handler(handle, rec, data);
929 switch (rec->lrh_type) {
931 struct lustre_cfg *lcfg, *lcfg_new;
932 struct lustre_cfg_bufs bufs;
933 char *inst_name = NULL;
937 lcfg = (struct lustre_cfg *)cfg_buf;
938 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
939 lustre_swab_lustre_cfg(lcfg);
941 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
945 /* Figure out config state info */
946 if (lcfg->lcfg_command == LCFG_MARKER) {
947 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
948 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
949 clli->cfg_flags, marker->cm_flags);
950 if (marker->cm_flags & CM_START) {
951 /* all previous flags off */
952 clli->cfg_flags = CFG_F_MARKER;
953 if (marker->cm_flags & CM_SKIP) {
954 clli->cfg_flags |= CFG_F_SKIP;
955 CDEBUG(D_CONFIG, "SKIP #%d\n",
957 } else if ((marker->cm_flags & CM_EXCLUDE) ||
958 lustre_check_exclusion(clli->cfg_sb,
959 marker->cm_tgtname)) {
960 clli->cfg_flags |= CFG_F_EXCLUDE;
961 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
964 } else if (marker->cm_flags & CM_END) {
968 /* A config command without a start marker before it is
969 illegal (post 146) */
970 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
971 !(clli->cfg_flags & CFG_F_MARKER) &&
972 (lcfg->lcfg_command != LCFG_MARKER)) {
973 CWARN("Config not inside markers, ignoring! (%#x)\n",
975 clli->cfg_flags |= CFG_F_SKIP;
978 if (clli->cfg_flags & CFG_F_SKIP) {
979 CDEBUG(D_CONFIG, "skipping %#x\n",
986 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
987 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
988 /* Add inactive instead */
989 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
991 lustre_cfg_bufs_init(&bufs, lcfg);
993 if (clli && clli->cfg_instance &&
994 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
996 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
997 strlen(clli->cfg_instance) + 1;
998 OBD_ALLOC(inst_name, inst_len);
999 if (inst_name == NULL)
1000 GOTO(out, rc = -ENOMEM);
1001 sprintf(inst_name, "%s-%s",
1002 lustre_cfg_string(lcfg, 0),
1003 clli->cfg_instance);
1004 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1005 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1006 lcfg->lcfg_command, inst_name);
1009 /* we override the llog's uuid for clients, to insure they
1011 if (clli && clli->cfg_instance &&
1012 lcfg->lcfg_command == LCFG_ATTACH) {
1013 lustre_cfg_bufs_set_string(&bufs, 2,
1014 clli->cfg_uuid.uuid);
1017 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1019 lcfg_new->lcfg_num = lcfg->lcfg_num;
1020 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1022 /* XXX Hack to try to remain binary compatible with
1023 * pre-newconfig logs */
1024 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1025 (lcfg->lcfg_nid >> 32) == 0) {
1026 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1028 lcfg_new->lcfg_nid =
1029 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1030 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1031 lcfg->lcfg_nal, addr,
1032 libcfs_nid2str(lcfg_new->lcfg_nid));
1034 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1037 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1039 rc = class_process_config(lcfg_new);
1040 lustre_cfg_free(lcfg_new);
1043 OBD_FREE(inst_name, inst_len);
1047 CERROR("Unknown llog record type %#x encountered\n",
1053 CERROR("Err %d on cfg command:\n", rc);
1054 class_config_dump_handler(handle, rec, data);
1059 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1060 struct config_llog_instance *cfg)
1062 struct llog_process_cat_data cd = {0, 0};
1063 struct llog_handle *llh;
1067 CDEBUG(D_INFO, "looking up llog %s\n", name);
1068 rc = llog_create(ctxt, &llh, NULL, name);
1072 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1074 GOTO(parse_out, rc);
1076 /* continue processing from where we last stopped to end-of-log */
1078 cd.first_idx = cfg->cfg_last_idx;
1081 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1083 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1084 cd.first_idx + 1, cd.last_idx, rc);
1086 cfg->cfg_last_idx = cd.last_idx;
1089 rc2 = llog_close(llh);
1096 int class_config_dump_handler(struct llog_handle * handle,
1097 struct llog_rec_hdr *rec, void *data)
1099 int cfg_len = rec->lrh_len;
1100 char *cfg_buf = (char*) (rec + 1);
1101 char *outstr, *ptr, *end;
1105 OBD_ALLOC(outstr, 256);
1111 if (rec->lrh_type == OBD_CFG_REC) {
1112 struct lustre_cfg *lcfg;
1115 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1118 lcfg = (struct lustre_cfg *)cfg_buf;
1120 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1121 lcfg->lcfg_command);
1122 if (lcfg->lcfg_flags) {
1123 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1126 if (lcfg->lcfg_num) {
1127 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1130 if (lcfg->lcfg_nid) {
1131 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1132 libcfs_nid2str(lcfg->lcfg_nid),
1135 if (lcfg->lcfg_command == LCFG_MARKER) {
1136 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1137 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1138 marker->cm_step, marker->cm_flags,
1139 marker->cm_tgtname, marker->cm_comment);
1141 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1142 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1143 lustre_cfg_string(lcfg, i));
1146 LCONSOLE(D_WARNING, " %s\n", outstr);
1148 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1152 OBD_FREE(outstr, 256);
1156 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1157 struct config_llog_instance *cfg)
1159 struct llog_handle *llh;
1163 LCONSOLE_INFO("Dumping config log %s\n", name);
1165 rc = llog_create(ctxt, &llh, NULL, name);
1169 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1171 GOTO(parse_out, rc);
1173 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1175 rc2 = llog_close(llh);
1179 LCONSOLE_INFO("End config log %s\n", name);
1184 /* Cleanup and detach */
1185 int class_manual_cleanup(struct obd_device *obd)
1187 struct lustre_cfg *lcfg;
1188 struct lustre_cfg_bufs bufs;
1194 CERROR("empty cleanup\n");
1203 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1204 obd->obd_name, flags);
1206 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1207 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1208 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1210 rc = class_process_config(lcfg);
1212 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1216 /* the lcfg is almost the same for both ops */
1217 lcfg->lcfg_command = LCFG_DETACH;
1218 rc = class_process_config(lcfg);
1220 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1222 lustre_cfg_free(lcfg);