1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2001-2003 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define DEBUG_SUBSYSTEM S_CLASS
27 #include <linux/kmod.h> /* for request_module() */
28 #include <linux/module.h>
29 #include <linux/obd_class.h>
30 #include <linux/random.h>
31 #include <linux/slab.h>
32 #include <linux/pagemap.h>
34 #include <liblustre.h>
35 #include <linux/obd_class.h>
36 #include <linux/obd.h>
38 #include <linux/lustre_log.h>
39 #include <linux/lprocfs_status.h>
40 #include <libcfs/list.h>
43 /* Create a new device and set the type, name and uuid. If
44 * successful, the new device can be accessed by either name or uuid.
46 static int class_attach(struct lustre_cfg *lcfg)
48 struct obd_type *type;
49 struct obd_device *obd;
50 char *typename, *name, *uuid;
51 int rc, len, cleanup_phase = 0;
53 if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
54 CERROR("No type passed!\n");
57 typename = lustre_cfg_string(lcfg, 1);
59 if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
60 CERROR("No name passed!\n");
63 name = lustre_cfg_string(lcfg, 0);
65 if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
66 CERROR("No UUID passed!\n");
69 uuid = lustre_cfg_string(lcfg, 2);
71 CDEBUG(D_CONFIG, "attach type %s name: %s uuid: %s\n",
72 MKSTR(typename), MKSTR(name), MKSTR(uuid));
75 type = class_get_type(typename);
77 CERROR("OBD: unknown type: %s\n", typename);
80 cleanup_phase = 1; /* class_put_type */
82 obd = class_name2obd(name);
84 CERROR("obd %s already attached\n", name);
85 GOTO(out, rc = -EEXIST);
88 obd = class_newdev(type);
90 GOTO(out, rc = -EINVAL);
92 cleanup_phase = 2; /* class_release_dev */
94 INIT_LIST_HEAD(&obd->obd_exports);
95 obd->obd_num_exports = 0;
96 spin_lock_init(&obd->obd_dev_lock);
97 spin_lock_init(&obd->obd_osfs_lock);
98 obd->obd_osfs_age = jiffies - 1000 * HZ;
99 init_waitqueue_head(&obd->obd_refcount_waitq);
101 /* XXX belongs in setup not attach */
103 init_timer(&obd->obd_recovery_timer);
104 spin_lock_init(&obd->obd_processing_task_lock);
105 init_waitqueue_head(&obd->obd_next_transno_waitq);
106 INIT_LIST_HEAD(&obd->obd_req_replay_queue);
107 INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
108 INIT_LIST_HEAD(&obd->obd_final_req_queue);
110 spin_lock_init(&obd->obd_uncommitted_replies_lock);
111 INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
113 len = strlen(name) + 1;
114 OBD_ALLOC(obd->obd_name, len);
116 GOTO(out, rc = -ENOMEM);
117 memcpy(obd->obd_name, name, len);
119 cleanup_phase = 3; /* free obd_name */
122 if (len >= sizeof(obd->obd_uuid)) {
123 CERROR("uuid must be < "LPSZ" bytes long\n",
124 sizeof(obd->obd_uuid));
125 GOTO(out, rc = -EINVAL);
127 memcpy(obd->obd_uuid.uuid, uuid, len);
130 if (OBP(obd, attach)) {
131 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
133 GOTO(out, rc = -EINVAL);
136 obd->obd_attached = 1;
138 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
139 obd->obd_minor, typename);
142 switch (cleanup_phase) {
144 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
146 class_release_dev(obd);
148 class_put_type(type);
153 static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
156 struct obd_export *exp;
159 LASSERT(obd == (obd_dev + obd->obd_minor));
161 /* have we attached a type to this device? */
162 if (!obd->obd_attached) {
163 CERROR("Device %d not attached\n", obd->obd_minor);
167 /* has this been done already? */
168 if (obd->obd_set_up) {
169 CERROR("Device %d already setup (type %s)\n",
170 obd->obd_minor, obd->obd_type->typ_name);
174 atomic_set(&obd->obd_refcount, 0);
176 exp = class_new_export(obd);
179 memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
180 sizeof(exp->exp_client_uuid));
181 obd->obd_self_export = exp;
182 class_export_put(exp);
184 err = obd_setup(obd, sizeof(*lcfg), lcfg);
188 obd->obd_type->typ_refcnt++;
194 class_unlink_export(obd->obd_self_export);
195 obd->obd_self_export = NULL;
199 static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
204 if (obd->obd_set_up) {
205 CERROR("OBD device %d still set up\n", obd->obd_minor);
208 if (!obd->obd_attached) {
209 CERROR("OBD device %d not attached\n", obd->obd_minor);
212 if (OBP(obd, detach))
213 err = OBP(obd,detach)(obd);
216 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
217 obd->obd_name = NULL;
219 CERROR("device %d: no name at detach\n", obd->obd_minor);
222 obd->obd_attached = 0;
223 obd->obd_type->typ_refcnt--;
224 class_put_type(obd->obd_type);
225 class_release_dev(obd);
229 static void dump_exports(struct obd_device *obd)
231 struct obd_export *exp, *n;
233 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
234 struct ptlrpc_reply_state *rs;
235 struct ptlrpc_reply_state *first_reply = NULL;
238 list_for_each_entry (rs, &exp->exp_outstanding_replies,
245 CERROR("%s: %p %s %d %d %d: %p %s\n",
246 obd->obd_name, exp, exp->exp_client_uuid.uuid,
247 atomic_read(&exp->exp_refcount),
248 exp->exp_failed, nreplies, first_reply,
249 nreplies > 3 ? "..." : "");
253 static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
260 if (!obd->obd_set_up) {
261 CERROR("Device %d not setup\n", obd->obd_minor);
264 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
265 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
268 flags |= OBD_OPT_FORCE;
271 flags |= OBD_OPT_FAILOVER;
274 CERROR("unrecognised flag '%c'\n",
279 /* The one reference that should be remaining is the
281 if (atomic_read(&obd->obd_refcount) <= 1 ||
282 flags & OBD_OPT_FORCE) {
283 /* this will stop new connections, and need to
284 do it before class_disconnect_exports() */
285 obd->obd_stopping = 1;
288 if (atomic_read(&obd->obd_refcount) > 1) {
289 struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
293 if (!(flags & OBD_OPT_FORCE)) {
294 CERROR("OBD device %d (%p,%s) has refcount %d\n",
295 obd->obd_minor, obd, obd->obd_name,
296 atomic_read(&obd->obd_refcount));
297 portals_debug_dumplog();
299 GOTO(out, err = -EBUSY);
301 class_disconnect_exports(obd, flags);
303 "%s: waiting for obd refs to go away: %d\n",
304 obd->obd_name, atomic_read(&obd->obd_refcount));
306 rc = l_wait_event(obd->obd_refcount_waitq,
307 atomic_read(&obd->obd_refcount) < 2, &lwi);
309 LASSERT(atomic_read(&obd->obd_refcount) == 1);
311 CERROR("wait cancelled cleaning anyway. "
313 atomic_read(&obd->obd_refcount));
316 CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
320 if (obd->obd_self_export) {
321 err = obd_precleanup(obd, flags);
324 class_unlink_export(obd->obd_self_export);
325 obd->obd_self_export = NULL;
328 err = obd_cleanup(obd, flags);
331 obd->obd_set_up = obd->obd_stopping = 0;
332 obd->obd_type->typ_refcnt--;
333 /* XXX this should be an LASSERT */
334 if (atomic_read(&obd->obd_refcount) > 0) {
335 CERROR("%s (%p) still has refcount %d after "
336 "cleanup.\n", obd->obd_name, obd,
337 atomic_read(&obd->obd_refcount));
345 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
347 struct obd_import *imp;
348 struct obd_uuid uuid;
352 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
353 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
354 CERROR("invalid conn_uuid\n");
358 if (strcmp(obd->obd_type->typ_name, OBD_MDC_DEVICENAME) &&
359 strcmp(obd->obd_type->typ_name, OBD_OSC_DEVICENAME)) {
360 CERROR("can't add connection on non-client dev\n");
364 imp = obd->u.cli.cl_import;
366 CERROR("try to add conn on immature client dev\n");
370 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
371 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
376 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
378 struct obd_import *imp;
379 struct obd_uuid uuid;
383 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
384 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
385 CERROR("invalid conn_uuid\n");
389 if (strcmp(obd->obd_type->typ_name, OBD_MDC_DEVICENAME) &&
390 strcmp(obd->obd_type->typ_name, OBD_OSC_DEVICENAME)) {
391 CERROR("can't add connection on non-client dev\n");
395 imp = obd->u.cli.cl_import;
397 CERROR("try to del conn on immature client dev\n");
401 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
402 rc = obd_del_conn(imp, &uuid);
407 LIST_HEAD(lustre_profile_list);
409 struct lustre_profile *class_get_profile(char * prof)
411 struct lustre_profile *lprof;
413 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
414 if (!strcmp(lprof->lp_profile, prof)) {
421 int class_add_profile(int proflen, char *prof,
422 int lovlen, char *lov,
423 int lmvlen, char *lmv,
424 int gkclen, char *gkc)
426 struct lustre_profile *lprof;
429 OBD_ALLOC(lprof, sizeof(*lprof));
431 GOTO(out, err = -ENOMEM);
432 INIT_LIST_HEAD(&lprof->lp_list);
434 LASSERT(proflen == (strlen(prof) + 1));
435 OBD_ALLOC(lprof->lp_profile, proflen);
436 if (lprof->lp_profile == NULL)
437 GOTO(out, err = -ENOMEM);
438 memcpy(lprof->lp_profile, prof, proflen);
440 LASSERT(lovlen == (strlen(lov) + 1));
441 OBD_ALLOC(lprof->lp_lov, lovlen);
442 if (lprof->lp_profile == NULL)
443 GOTO(out, err = -ENOMEM);
444 memcpy(lprof->lp_lov, lov, lovlen);
447 LASSERT(lmvlen == (strlen(lmv) + 1));
448 OBD_ALLOC(lprof->lp_lmv, lmvlen);
449 if (lprof->lp_lmv == NULL)
450 GOTO(out, err = -ENOMEM);
451 memcpy(lprof->lp_lmv, lmv, lmvlen);
454 LASSERT(gkclen == (strlen(gkc) + 1));
455 OBD_ALLOC(lprof->lp_gkc, gkclen);
456 if (lprof->lp_gkc == NULL)
457 GOTO(out, err = -ENOMEM);
458 memcpy(lprof->lp_gkc, gkc, gkclen);
461 list_add(&lprof->lp_list, &lustre_profile_list);
466 void class_del_profile(char *prof)
468 struct lustre_profile *lprof;
470 lprof = class_get_profile(prof);
472 list_del(&lprof->lp_list);
473 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
474 OBD_FREE(lprof->lp_lov, strlen(lprof->lp_lov) + 1);
476 OBD_FREE(lprof->lp_lmv, strlen(lprof->lp_lmv) + 1);
478 OBD_FREE(lprof->lp_gkc, strlen(lprof->lp_gkc) + 1);
479 OBD_FREE(lprof, sizeof *lprof);
483 int class_process_config(struct lustre_cfg *lcfg)
485 struct obd_device *obd;
486 char str[PTL_NALFMT_SIZE];
490 LASSERT(lcfg && !IS_ERR(lcfg));
492 CDEBUG(D_CONFIG, "processing cmd: %x\n", lcfg->lcfg_command);
494 /* Commands that don't need a device */
495 switch(lcfg->lcfg_command) {
497 err = class_attach(lcfg);
500 case LCFG_ADD_UUID: {
501 CDEBUG(D_CONFIG, "adding mapping from uuid %s to nid "LPX64
502 " (%s), nal %x\n", lustre_cfg_string(lcfg, 1),
504 portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
507 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
511 case LCFG_DEL_UUID: {
512 CDEBUG(D_CONFIG, "removing mappings for uuid %s\n",
513 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
514 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
516 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
519 case LCFG_MOUNTOPT: {
520 CDEBUG(D_CONFIG, "mountopt: profile %s osc %s mdc %s gkc %s \n",
521 lustre_cfg_string(lcfg, 1),
522 lustre_cfg_string(lcfg, 2),
523 lustre_cfg_string(lcfg, 3),
524 lustre_cfg_string(lcfg, 4));
525 /* set these mount options somewhere, so ll_fill_super
527 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
528 lustre_cfg_string(lcfg, 1),
529 LUSTRE_CFG_BUFLEN(lcfg, 2),
530 lustre_cfg_string(lcfg, 2),
531 LUSTRE_CFG_BUFLEN(lcfg, 3),
532 lustre_cfg_string(lcfg, 3),
533 LUSTRE_CFG_BUFLEN(lcfg, 4),
534 lustre_cfg_string(lcfg, 4));
537 case LCFG_DEL_MOUNTOPT: {
538 CDEBUG(D_CONFIG, "mountopt: profile %s\n",
539 lustre_cfg_string(lcfg, 1));
540 /* set these mount options somewhere, so ll_fill_super
542 class_del_profile(lustre_cfg_string(lcfg, 1));
545 case LCFG_SET_TIMEOUT: {
546 CDEBUG(D_CONFIG, "changing lustre timeout from %d to %d\n",
549 obd_timeout = lcfg->lcfg_num;
552 case LCFG_SET_UPCALL: {
553 CDEBUG(D_CONFIG, "setting lustre ucpall to: %s\n",
554 lustre_cfg_string(lcfg, 1));
555 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof obd_lustre_upcall)
556 GOTO(out, err = -EINVAL);
557 strncpy(obd_lustre_upcall, lustre_cfg_string(lcfg, 1),
558 sizeof (obd_lustre_upcall));
563 /* Commands that require a device */
564 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
566 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
567 CERROR("this lcfg command %d requires a device name\n",
570 CERROR("no device for: %s\n",
571 lustre_cfg_string(lcfg, 0));
573 GOTO(out, err = -EINVAL);
576 switch(lcfg->lcfg_command) {
578 err = class_setup(obd, lcfg);
582 err = class_detach(obd, lcfg);
586 err = class_cleanup(obd, lcfg);
589 case LCFG_ADD_CONN: {
590 err = class_add_conn(obd, lcfg);
593 case LCFG_DEL_CONN: {
594 err = class_del_conn(obd, lcfg);
598 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
607 static int class_config_parse_handler(struct llog_handle * handle,
608 struct llog_rec_hdr *rec, void *data)
610 struct config_llog_instance *cfg = data;
611 int cfg_len = rec->lrh_len;
612 char *cfg_buf = (char*) (rec + 1);
616 if (rec->lrh_type == OBD_CFG_REC) {
617 struct lustre_cfg *lcfg, *lcfg_new;
618 struct lustre_cfg_bufs bufs;
619 char *inst_name = NULL;
622 lcfg = (struct lustre_cfg *)cfg_buf;
623 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
624 lustre_swab_lustre_cfg(lcfg);
626 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
630 lustre_cfg_bufs_init(&bufs, lcfg);
631 if (cfg && cfg->cfg_instance) {
632 if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
633 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
634 strlen(cfg->cfg_instance) + 1;
635 OBD_ALLOC(inst_name, inst_len);
636 if (inst_name == NULL)
637 GOTO(out, rc = -ENOMEM);
638 sprintf(inst_name, "%s-%s",
639 lustre_cfg_string(lcfg, 0),
641 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
643 if (lcfg->lcfg_command == LCFG_SETUP) {
644 /*add cfg_instance to the end of lcfg buffers*/
645 lustre_cfg_bufs_set_string(&bufs,
651 if (cfg && (lcfg->lcfg_command == LCFG_ATTACH)){
652 /*Very Dirty Hack fix here, for mds add,
653 *the mdc in mds should not
654 *change uuid FIXME: Wangdi
656 if (memcmp(lustre_cfg_string(lcfg, 1), OBD_MDC_DEVICENAME,
657 strlen(OBD_MDC_DEVICENAME)) ||
658 (cfg->cfg_flags & CFG_MODIFY_UUID_FL))
659 lustre_cfg_bufs_set_string(&bufs, 2,
660 (char *)cfg->cfg_uuid.uuid);
662 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
664 lcfg_new->lcfg_num = lcfg->lcfg_num;
665 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
666 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
667 lcfg_new->lcfg_nal = lcfg->lcfg_nal;
669 rc = class_process_config(lcfg_new);
670 lustre_cfg_free(lcfg_new);
673 OBD_FREE(inst_name, inst_len);
674 } else if (rec->lrh_type == PTL_CFG_REC) {
675 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
676 if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID &&
677 cfg->cfg_local_nid != PTL_NID_ANY) {
678 pcfg->pcfg_nid = cfg->cfg_local_nid;
681 rc = libcfs_nal_cmd(pcfg);
683 CERROR("unrecognized record type: 0x%x\n", rec->lrh_type);
689 int class_config_process_llog(struct llog_ctxt *ctxt, char *name,
690 struct config_llog_instance *cfg)
692 struct llog_handle *llh;
696 rc = llog_open(ctxt, &llh, NULL, name, 0);
700 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
702 rc = llog_process(llh, class_config_parse_handler, cfg, NULL);
704 rc2 = llog_close(llh);
711 int class_config_dump_handler(struct llog_handle * handle,
712 struct llog_rec_hdr *rec, void *data)
714 int cfg_len = rec->lrh_len;
715 char *cfg_buf = (char*) (rec + 1);
718 if (rec->lrh_type == OBD_CFG_REC) {
719 struct lustre_cfg *lcfg;
722 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
725 lcfg = (struct lustre_cfg *)cfg_buf;
727 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
728 if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0)
729 CDEBUG(D_INFO, " devname: %s\n",
730 lustre_cfg_string(lcfg, 0));
731 if (lcfg->lcfg_flags)
732 CDEBUG(D_INFO, " flags: %x\n", lcfg->lcfg_flags);
734 CDEBUG(D_INFO, " nid: "LPX64"\n",
737 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_nal);
739 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_num);
740 for (i = 1; i < lcfg->lcfg_bufcount; i++)
741 if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0)
742 CDEBUG(D_INFO, " inlbuf%d: %s\n", i,
743 lustre_cfg_string(lcfg, i));
744 } else if (rec->lrh_type == PTL_CFG_REC) {
745 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
746 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
748 CDEBUG(D_INFO, " nal: %x\n",
750 if (pcfg->pcfg_gw_nal)
751 CDEBUG(D_INFO, " gw_nal: %x\n",
754 CDEBUG(D_INFO, " nid: "LPX64"\n",
757 CDEBUG(D_INFO, " nid: "LPX64"\n",
760 CDEBUG(D_INFO, " nid: "LPX64"\n",
763 CDEBUG(D_INFO, " nid: %d\n",
766 CDEBUG(D_INFO, " id: %x\n",
768 if (pcfg->pcfg_flags)
769 CDEBUG(D_INFO, " flags: %x\n",
772 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
779 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
780 struct config_llog_instance *cfg)
782 struct llog_handle *llh;
786 rc = llog_open(ctxt, &llh, NULL, name, 0);
790 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
792 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
794 rc2 = llog_close(llh);