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>
32 #include <liblustre.h>
33 #include <obd_class.h>
36 #include <lustre_log.h>
37 #include <lprocfs_status.h>
38 #include <libcfs/list.h>
39 #include <lustre_param.h>
41 /*********** string parsing utils *********/
43 /* returns 0 if we find this key in the buffer, else 1 */
44 int class_find_param(char *buf, char *key, char **valp)
51 if ((ptr = strstr(buf, key)) == NULL)
55 *valp = ptr + strlen(key);
60 /* returns 0 if this is the first key in the buffer, else 1.
61 valp points to first char after key. */
62 int class_match_param(char *buf, char *key, char **valp)
67 if (memcmp(buf, key, strlen(key)) != 0)
71 *valp = buf + strlen(key);
79 endh is set to next separator */
80 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
86 while (*buf == ',' || *buf == ':')
88 if (*buf == ' ' || *buf == '/' || *buf == '\0')
91 /* nid separators or end of nids */
92 endp = strpbrk(buf, ",: /");
94 endp = buf + strlen(buf);
98 *nid = libcfs_str2nid(buf);
99 if (*nid == LNET_NID_ANY) {
100 LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
108 CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));
112 EXPORT_SYMBOL(class_find_param);
113 EXPORT_SYMBOL(class_match_param);
114 EXPORT_SYMBOL(class_parse_nid);
116 /********************** class fns **********************/
118 /* Create a new device and set the type, name and uuid. If
119 * successful, the new device can be accessed by either name or uuid.
121 int class_attach(struct lustre_cfg *lcfg)
123 struct obd_device *obd = NULL;
124 char *typename, *name, *uuid;
128 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
129 CERROR("No type passed!\n");
132 typename = lustre_cfg_string(lcfg, 1);
134 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
135 CERROR("No name passed!\n");
138 name = lustre_cfg_string(lcfg, 0);
140 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
141 CERROR("No UUID passed!\n");
144 uuid = lustre_cfg_string(lcfg, 2);
146 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
147 MKSTR(typename), MKSTR(name), MKSTR(uuid));
149 /* Mountconf transitional hack, should go away after 1.6.
150 1.4.7 uses the old names, so translate back if the
151 mountconf flag is set.
152 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 spin_lock_init(&obd->obd_osfs_lock);
192 /* obd->obd_osfs_age must be set to a value in the distant
193 * past to guarantee a fresh statfs is fetched on mount. */
194 obd->obd_osfs_age = cfs_time_shift_64(-1000);
196 /* XXX belongs in setup not attach */
198 cfs_init_timer(&obd->obd_recovery_timer);
199 spin_lock_init(&obd->obd_processing_task_lock);
200 cfs_waitq_init(&obd->obd_next_transno_waitq);
201 CFS_INIT_LIST_HEAD(&obd->obd_req_replay_queue);
202 CFS_INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
203 CFS_INIT_LIST_HEAD(&obd->obd_final_req_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, 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);
331 static void dump_exports(struct obd_device *obd)
333 struct obd_export *exp, *n;
335 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
336 struct ptlrpc_reply_state *rs;
337 struct ptlrpc_reply_state *first_reply = NULL;
340 list_for_each_entry (rs, &exp->exp_outstanding_replies,
347 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
348 obd->obd_name, exp, exp->exp_client_uuid.uuid,
349 obd_export_nid2str(exp),
350 atomic_read(&exp->exp_refcount),
351 exp->exp_failed, nreplies, first_reply,
352 nreplies > 3 ? "..." : "");
356 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
362 OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
364 if (!obd->obd_set_up) {
365 CERROR("Device %d not setup\n", obd->obd_minor);
369 spin_lock(&obd->obd_dev_lock);
370 if (obd->obd_stopping) {
371 spin_unlock(&obd->obd_dev_lock);
372 CERROR("OBD %d already stopping\n", obd->obd_minor);
375 /* Leave this on forever */
376 obd->obd_stopping = 1;
377 spin_unlock(&obd->obd_dev_lock);
379 if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
380 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
386 LCONSOLE_WARN("Failing over %s\n",
389 obd->obd_no_transno = 1;
390 obd->obd_no_recov = 1;
391 /* Set the obd readonly if we can */
392 if (OBP(obd, iocontrol))
393 obd_iocontrol(OBD_IOC_SET_READONLY,
394 obd->obd_self_export,
398 CERROR("unrecognised flag '%c'\n",
403 /* The three references that should be remaining are the
404 * obd_self_export and the attach and setup references. */
405 if (atomic_read(&obd->obd_refcount) > 3) {
406 if (!(obd->obd_fail || obd->obd_force)) {
407 CERROR("OBD %s is still busy with %d references\n"
408 "You should stop active file system users,"
409 " or use the --force option to cleanup.\n",
410 obd->obd_name, atomic_read(&obd->obd_refcount));
412 GOTO(out, err = -EBUSY);
414 /* refcounf - 3 might be the number of real exports
415 (excluding self export). But class_incref is called
416 by other things as well, so don't count on it. */
417 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
418 obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
420 class_disconnect_exports(obd);
423 LASSERT(obd->obd_self_export);
425 /* Precleanup stage 1, we must make sure all exports (other than the
426 self-export) get destroyed. */
427 err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
429 CERROR("Precleanup %s returned %d\n",
437 /* Allow a failed cleanup to try again. */
438 obd->obd_stopping = 0;
442 struct obd_device *class_incref(struct obd_device *obd)
444 atomic_inc(&obd->obd_refcount);
445 CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
446 atomic_read(&obd->obd_refcount));
451 void class_decref(struct obd_device *obd)
456 spin_lock(&obd->obd_dev_lock);
457 atomic_dec(&obd->obd_refcount);
458 refs = atomic_read(&obd->obd_refcount);
459 spin_unlock(&obd->obd_dev_lock);
461 CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
463 if ((refs == 1) && obd->obd_stopping) {
464 /* All exports (other than the self-export) have been
465 destroyed; there should be no more in-progress ops
467 /* if we're not stopping, we didn't finish setup */
468 /* Precleanup stage 2, do other type-specific
469 cleanup requiring the self-export. */
470 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
472 CERROR("Precleanup %s returned %d\n",
474 obd->obd_self_export->exp_flags |=
475 (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
476 (obd->obd_force ? OBD_OPT_FORCE : 0);
477 /* note that we'll recurse into class_decref again */
478 class_unlink_export(obd->obd_self_export);
483 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
484 obd->obd_name, obd->obd_uuid.uuid);
485 LASSERT(!obd->obd_attached);
486 if (obd->obd_stopping) {
487 /* If we're not stopping, we were never set up */
488 err = obd_cleanup(obd);
490 CERROR("Cleanup %s returned %d\n",
493 if (OBP(obd, detach)) {
494 err = OBP(obd,detach)(obd);
496 CERROR("Detach returned %d\n", err);
498 class_release_dev(obd);
502 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
504 struct obd_import *imp;
505 struct obd_uuid uuid;
509 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
510 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
511 CERROR("invalid conn_uuid\n");
514 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
515 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
516 strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
517 CERROR("can't add connection on non-client dev\n");
521 imp = obd->u.cli.cl_import;
523 CERROR("try to add conn on immature client dev\n");
527 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
528 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
533 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
535 struct obd_import *imp;
536 struct obd_uuid uuid;
540 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
541 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
542 CERROR("invalid conn_uuid\n");
545 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
546 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
547 CERROR("can't del connection on non-client dev\n");
551 imp = obd->u.cli.cl_import;
553 CERROR("try to del conn on immature client dev\n");
557 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
558 rc = obd_del_conn(imp, &uuid);
563 int class_sec_flavor(struct obd_device *obd, struct lustre_cfg *lcfg)
565 struct sec_flavor_config *conf;
568 if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
569 strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
570 CERROR("Can't set security flavor on obd %s\n",
571 obd->obd_type->typ_name);
575 if (LUSTRE_CFG_BUFLEN(lcfg, 1) != sizeof(*conf)) {
576 CERROR("invalid data\n");
580 conf = &obd->u.cli.cl_sec_conf;
581 memcpy(conf, lustre_cfg_buf(lcfg, 1), sizeof(*conf));
584 __swab32s(&conf->sfc_rpc_flavor);
585 __swab32s(&conf->sfc_bulk_csum);
586 __swab32s(&conf->sfc_bulk_priv);
587 __swab32s(&conf->sfc_flags);
593 CFS_LIST_HEAD(lustre_profile_list);
595 struct lustre_profile *class_get_profile(const char * prof)
597 struct lustre_profile *lprof;
600 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
601 if (!strcmp(lprof->lp_profile, prof)) {
608 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
609 int mdclen, char *mdc)
611 struct lustre_profile *lprof;
615 CDEBUG(D_CONFIG, "Add profile %s\n", prof);
617 OBD_ALLOC(lprof, sizeof(*lprof));
620 CFS_INIT_LIST_HEAD(&lprof->lp_list);
622 LASSERT(proflen == (strlen(prof) + 1));
623 OBD_ALLOC(lprof->lp_profile, proflen);
624 if (lprof->lp_profile == NULL)
625 GOTO(out, err = -ENOMEM);
626 memcpy(lprof->lp_profile, prof, proflen);
628 LASSERT(osclen == (strlen(osc) + 1));
629 OBD_ALLOC(lprof->lp_dt, osclen);
630 if (lprof->lp_dt == NULL)
631 GOTO(out, err = -ENOMEM);
632 memcpy(lprof->lp_dt, osc, osclen);
635 LASSERT(mdclen == (strlen(mdc) + 1));
636 OBD_ALLOC(lprof->lp_md, mdclen);
637 if (lprof->lp_md == NULL)
638 GOTO(out, err = -ENOMEM);
639 memcpy(lprof->lp_md, mdc, mdclen);
642 list_add(&lprof->lp_list, &lustre_profile_list);
647 OBD_FREE(lprof->lp_md, mdclen);
649 OBD_FREE(lprof->lp_dt, osclen);
650 if (lprof->lp_profile)
651 OBD_FREE(lprof->lp_profile, proflen);
652 OBD_FREE(lprof, sizeof(*lprof));
656 void class_del_profile(const char *prof)
658 struct lustre_profile *lprof;
661 CDEBUG(D_CONFIG, "Del profile %s\n", prof);
663 lprof = class_get_profile(prof);
665 list_del(&lprof->lp_list);
666 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
667 OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
669 OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
670 OBD_FREE(lprof, sizeof *lprof);
676 void class_del_profiles(void)
678 struct lustre_profile *lprof, *n;
681 list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
682 list_del(&lprof->lp_list);
683 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
684 OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
686 OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
687 OBD_FREE(lprof, sizeof *lprof);
692 /* We can't call ll_process_config directly because it lives in a module that
693 must be loaded after this one. */
694 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
696 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
698 client_process_config = cpc;
700 EXPORT_SYMBOL(lustre_register_client_process_config);
702 int class_process_config(struct lustre_cfg *lcfg)
704 struct obd_device *obd;
707 LASSERT(lcfg && !IS_ERR(lcfg));
708 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
710 /* Commands that don't need a device */
711 switch(lcfg->lcfg_command) {
713 err = class_attach(lcfg);
716 case LCFG_ADD_UUID: {
717 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
718 " (%s)\n", lustre_cfg_string(lcfg, 1),
719 lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
721 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
724 case LCFG_DEL_UUID: {
725 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
726 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
727 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
729 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
732 case LCFG_MOUNTOPT: {
733 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
734 lustre_cfg_string(lcfg, 1),
735 lustre_cfg_string(lcfg, 2),
736 lustre_cfg_string(lcfg, 3));
737 /* set these mount options somewhere, so ll_fill_super
739 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
740 lustre_cfg_string(lcfg, 1),
741 LUSTRE_CFG_BUFLEN(lcfg, 2),
742 lustre_cfg_string(lcfg, 2),
743 LUSTRE_CFG_BUFLEN(lcfg, 3),
744 lustre_cfg_string(lcfg, 3));
747 case LCFG_DEL_MOUNTOPT: {
748 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
749 lustre_cfg_string(lcfg, 1));
750 class_del_profile(lustre_cfg_string(lcfg, 1));
753 case LCFG_SET_TIMEOUT: {
754 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
755 obd_timeout, lcfg->lcfg_num);
756 obd_timeout = max(lcfg->lcfg_num, 1U);
759 case LCFG_SET_UPCALL: {
760 LCONSOLE_ERROR("recovery upcall is deprecated\n");
761 /* COMPAT_146 Don't fail on old configs */
765 struct cfg_marker *marker;
766 marker = lustre_cfg_buf(lcfg, 1);
767 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
768 marker->cm_flags, marker->cm_svname, marker->cm_comment);
772 /* llite has no obd */
773 if ((class_match_param(lustre_cfg_string(lcfg, 1),
774 PARAM_LLITE, 0) == 0) &&
775 client_process_config) {
776 err = (*client_process_config)(lcfg);
784 /* Commands that require a device */
785 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
787 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
788 CERROR("this lcfg command requires a device name\n");
790 CERROR("no device for: %s\n",
791 lustre_cfg_string(lcfg, 0));
793 GOTO(out, err = -EINVAL);
796 switch(lcfg->lcfg_command) {
798 err = class_setup(obd, lcfg);
802 err = class_detach(obd, lcfg);
806 err = class_cleanup(obd, lcfg);
809 case LCFG_ADD_CONN: {
810 err = class_add_conn(obd, lcfg);
813 case LCFG_DEL_CONN: {
814 err = class_del_conn(obd, lcfg);
817 case LCFG_SEC_FLAVOR: {
818 err = class_sec_flavor(obd, lcfg);
822 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
828 if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
829 CWARN("Ignoring error %d on optional command %#x\n", err,
836 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
837 struct lustre_cfg *lcfg, void *data)
840 struct lprocfs_vars *var;
842 int i, keylen, vallen;
843 int matched = 0, j = 0;
847 if (lcfg->lcfg_command != LCFG_PARAM) {
848 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
852 /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
853 or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
854 or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
855 for (i = 1; i < lcfg->lcfg_bufcount; i++) {
856 key = lustre_cfg_buf(lcfg, i);
857 /* Strip off prefix */
858 class_match_param(key, prefix, &key);
859 sval = strchr(key, '=');
860 if (!sval || (*(sval + 1) == 0)) {
861 CERROR("Can't parse param %s\n", key);
863 /* continue parsing other params */
868 vallen = strlen(sval);
871 /* Search proc entries */
872 while (lvars[j].name) {
874 if (class_match_param(key, (char *)var->name, 0) == 0 &&
875 keylen == strlen(var->name)) {
878 if (var->write_fptr) {
882 rc = (var->write_fptr)(NULL, sval,
887 CERROR("writing proc entry %s err %d\n",
894 CERROR("Unknown param %s\n", key);
896 /* continue parsing other params */
898 LCONSOLE_INFO("%s: set %s to %s\n", prefix,
907 CDEBUG(D_CONFIG, "liblustre can't process params.\n");
912 int class_config_dump_handler(struct llog_handle * handle,
913 struct llog_rec_hdr *rec, void *data);
916 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
918 #define lustre_check_exclusion(a,b) 0
921 static int class_config_llog_handler(struct llog_handle * handle,
922 struct llog_rec_hdr *rec, void *data)
924 struct config_llog_instance *clli = data;
925 int cfg_len = rec->lrh_len;
926 char *cfg_buf = (char*) (rec + 1);
930 //class_config_dump_handler(handle, rec, data);
932 switch (rec->lrh_type) {
934 struct lustre_cfg *lcfg, *lcfg_new;
935 struct lustre_cfg_bufs bufs;
936 char *inst_name = NULL;
940 lcfg = (struct lustre_cfg *)cfg_buf;
941 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
942 lustre_swab_lustre_cfg(lcfg);
944 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
948 /* Figure out config state info */
949 if (lcfg->lcfg_command == LCFG_MARKER) {
950 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
951 CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
952 clli->cfg_flags, marker->cm_flags);
953 if (marker->cm_flags & CM_START) {
954 /* all previous flags off */
955 clli->cfg_flags = CFG_F_MARKER;
956 if (marker->cm_flags & CM_SKIP) {
957 clli->cfg_flags |= CFG_F_SKIP;
958 CDEBUG(D_CONFIG, "SKIP #%d\n",
960 } else if (lustre_check_exclusion(clli->cfg_sb,
961 marker->cm_svname)) {
962 clli->cfg_flags |= CFG_F_EXCLUDE;
963 CDEBUG(D_CONFIG, "EXCLUDE %d\n",
966 } else if (marker->cm_flags & CM_END) {
970 /* A config command without a start marker before it is
971 illegal (post 146) */
972 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
973 !(clli->cfg_flags & CFG_F_MARKER) &&
974 (lcfg->lcfg_command != LCFG_MARKER)) {
975 CWARN("Config not inside markers, ignoring! (%#x)\n",
977 clli->cfg_flags |= CFG_F_SKIP;
979 if (clli->cfg_flags & CFG_F_SKIP) {
980 CDEBUG(D_CONFIG, "skipping %#x\n",
987 if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
988 (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
989 /* Add inactive instead */
990 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
992 lustre_cfg_bufs_init(&bufs, lcfg);
994 if (clli && clli->cfg_instance &&
995 LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
997 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
998 strlen(clli->cfg_instance) + 1;
999 OBD_ALLOC(inst_name, inst_len);
1000 if (inst_name == NULL)
1001 GOTO(out, rc = -ENOMEM);
1002 sprintf(inst_name, "%s-%s",
1003 lustre_cfg_string(lcfg, 0),
1004 clli->cfg_instance);
1005 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1006 CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1007 lcfg->lcfg_command, inst_name);
1010 /* we override the llog's uuid for clients, to insure they
1012 if (clli && clli->cfg_instance &&
1013 lcfg->lcfg_command == LCFG_ATTACH) {
1014 lustre_cfg_bufs_set_string(&bufs, 2,
1015 clli->cfg_uuid.uuid);
1018 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1020 lcfg_new->lcfg_num = lcfg->lcfg_num;
1021 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1023 /* XXX Hack to try to remain binary compatible with
1024 * pre-newconfig logs */
1025 if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */
1026 (lcfg->lcfg_nid >> 32) == 0) {
1027 __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1029 lcfg_new->lcfg_nid =
1030 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1031 CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1032 lcfg->lcfg_nal, addr,
1033 libcfs_nid2str(lcfg_new->lcfg_nid));
1035 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1038 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1040 rc = class_process_config(lcfg_new);
1041 lustre_cfg_free(lcfg_new);
1044 OBD_FREE(inst_name, inst_len);
1048 CERROR("Unknown llog record type %#x encountered\n",
1054 CERROR("Err %d on cfg command:\n", rc);
1055 class_config_dump_handler(handle, rec, data);
1060 void class_config_notify_end(const char *name)
1062 struct obd_device *obd;
1065 /*XXX: This is fast fix to mountconf issue when osc are set up
1066 * while recovery is in progress already.
1067 * The MDS should wait the end of config llog parsing before starting
1068 * recovery. This is done via obd_configured flag for now
1070 obd = class_name2obd(name);
1072 obd->obd_configured = 1;
1077 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1078 struct config_llog_instance *cfg)
1080 struct llog_process_cat_data cd = {0, 0};
1081 struct llog_handle *llh;
1085 CDEBUG(D_INFO, "looking up llog %s\n", name);
1086 rc = llog_create(ctxt, &llh, NULL, name);
1090 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1092 GOTO(parse_out, rc);
1094 /* continue processing from where we last stopped to end-of-log */
1096 cd.first_idx = cfg->cfg_last_idx;
1099 rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1101 class_config_notify_end(name);
1103 CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1104 cd.first_idx + 1, cd.last_idx, rc);
1106 cfg->cfg_last_idx = cd.last_idx;
1109 rc2 = llog_close(llh);
1116 int class_config_dump_handler(struct llog_handle * handle,
1117 struct llog_rec_hdr *rec, void *data)
1119 int cfg_len = rec->lrh_len;
1120 char *cfg_buf = (char*) (rec + 1);
1121 char *outstr, *ptr, *end;
1125 OBD_ALLOC(outstr, 256);
1131 if (rec->lrh_type == OBD_CFG_REC) {
1132 struct lustre_cfg *lcfg;
1135 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1138 lcfg = (struct lustre_cfg *)cfg_buf;
1140 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1141 lcfg->lcfg_command);
1142 if (lcfg->lcfg_flags) {
1143 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1146 if (lcfg->lcfg_num) {
1147 ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1150 if (lcfg->lcfg_nid) {
1151 ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
1152 libcfs_nid2str(lcfg->lcfg_nid),
1155 if (lcfg->lcfg_command == LCFG_MARKER) {
1156 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1157 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1158 marker->cm_step, marker->cm_flags,
1159 marker->cm_svname, marker->cm_comment);
1161 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1162 ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
1163 lustre_cfg_string(lcfg, i));
1166 LCONSOLE(D_WARNING, " %s\n", outstr);
1168 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1172 OBD_FREE(outstr, 256);
1176 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1177 struct config_llog_instance *cfg)
1179 struct llog_handle *llh;
1183 LCONSOLE_INFO("Dumping config log %s\n", name);
1185 rc = llog_create(ctxt, &llh, NULL, name);
1189 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1191 GOTO(parse_out, rc);
1193 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1195 rc2 = llog_close(llh);
1199 LCONSOLE_INFO("End config log %s\n", name);
1204 /* Cleanup and detach */
1205 int class_manual_cleanup(struct obd_device *obd)
1207 struct lustre_cfg *lcfg;
1208 struct lustre_cfg_bufs bufs;
1214 CERROR("empty cleanup\n");
1223 CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1224 obd->obd_name, flags);
1226 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1227 lustre_cfg_bufs_set_string(&bufs, 1, flags);
1228 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1230 rc = class_process_config(lcfg);
1232 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1236 /* the lcfg is almost the same for both ops */
1237 lcfg->lcfg_command = LCFG_DETACH;
1238 rc = class_process_config(lcfg);
1240 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1242 lustre_cfg_free(lcfg);