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_IOCTL, "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 (LUSTRE_CFG_BUFLEN(lcfg, 2) != sizeof(int)) {
359 CERROR("invalid priority\n");
362 if (strcmp(obd->obd_type->typ_name, "mdc") &&
363 strcmp(obd->obd_type->typ_name, "osc")) {
364 CERROR("can't add connection on non-client dev\n");
368 imp = obd->u.cli.cl_import;
370 CERROR("try to add conn on immature client dev\n");
374 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
375 rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
379 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
381 struct obd_import *imp;
382 struct obd_uuid uuid;
386 if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
387 LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
388 CERROR("invalid conn_uuid\n");
392 if (strcmp(obd->obd_type->typ_name, "mdc") &&
393 strcmp(obd->obd_type->typ_name, "osc")) {
394 CERROR("can't add connection on non-client dev\n");
398 imp = obd->u.cli.cl_import;
400 CERROR("try to del conn on immature client dev\n");
404 obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
405 rc = obd_del_conn(imp, &uuid);
410 LIST_HEAD(lustre_profile_list);
412 struct lustre_profile *class_get_profile(char * prof)
414 struct lustre_profile *lprof;
416 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
417 if (!strcmp(lprof->lp_profile, prof)) {
424 int class_add_profile(int proflen, char *prof,
425 int lovlen, char *lov,
426 int lmvlen, char *lmv,
427 int gkclen, char *gkc)
429 struct lustre_profile *lprof;
432 OBD_ALLOC(lprof, sizeof(*lprof));
434 GOTO(out, err = -ENOMEM);
435 INIT_LIST_HEAD(&lprof->lp_list);
437 LASSERT(proflen == (strlen(prof) + 1));
438 OBD_ALLOC(lprof->lp_profile, proflen);
439 if (lprof->lp_profile == NULL)
440 GOTO(out, err = -ENOMEM);
441 memcpy(lprof->lp_profile, prof, proflen);
443 LASSERT(lovlen == (strlen(lov) + 1));
444 OBD_ALLOC(lprof->lp_lov, lovlen);
445 if (lprof->lp_profile == NULL)
446 GOTO(out, err = -ENOMEM);
447 memcpy(lprof->lp_lov, lov, lovlen);
450 LASSERT(lmvlen == (strlen(lmv) + 1));
451 OBD_ALLOC(lprof->lp_lmv, lmvlen);
452 if (lprof->lp_lmv == NULL)
453 GOTO(out, err = -ENOMEM);
454 memcpy(lprof->lp_lmv, lmv, lmvlen);
457 LASSERT(gkclen == (strlen(gkc) + 1));
458 OBD_ALLOC(lprof->lp_gkc, gkclen);
459 if (lprof->lp_gkc == NULL)
460 GOTO(out, err = -ENOMEM);
461 memcpy(lprof->lp_gkc, gkc, gkclen);
464 list_add(&lprof->lp_list, &lustre_profile_list);
469 void class_del_profile(char *prof)
471 struct lustre_profile *lprof;
473 lprof = class_get_profile(prof);
475 list_del(&lprof->lp_list);
476 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
477 OBD_FREE(lprof->lp_lov, strlen(lprof->lp_lov) + 1);
479 OBD_FREE(lprof->lp_lmv, strlen(lprof->lp_lmv) + 1);
480 OBD_FREE(lprof, sizeof *lprof);
484 int class_process_config(struct lustre_cfg *lcfg)
486 struct obd_device *obd;
487 char str[PTL_NALFMT_SIZE];
491 LASSERT(lcfg && !IS_ERR(lcfg));
493 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
495 /* Commands that don't need a device */
496 switch(lcfg->lcfg_command) {
498 err = class_attach(lcfg);
501 case LCFG_ADD_UUID: {
502 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
503 " (%s), nal %x\n", lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
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_IOCTL, "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_IOCTL, "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_IOCTL, "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_IOCTL, "changing lustre timeout from %d to %d\n",
549 obd_timeout = lcfg->lcfg_num;
552 case LCFG_SET_UPCALL: {
553 CDEBUG(D_IOCTL, "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;
620 char *inst_name = NULL;
624 lcfg = (struct lustre_cfg *)cfg_buf;
625 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
626 lustre_swab_lustre_cfg(lcfg);
628 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
632 lustre_cfg_bufs_init(&bufs, lcfg);
633 if (cfg && cfg->cfg_instance && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
635 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
636 strlen(cfg->cfg_instance) + 1;
637 OBD_ALLOC(inst_name, inst_len);
638 if (inst_name == NULL)
639 GOTO(out, rc = -ENOMEM);
640 sprintf(inst_name, "%s-%s",
641 lustre_cfg_string(lcfg, 0),
643 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
646 if (cfg && lcfg->lcfg_command == LCFG_ATTACH)
647 lustre_cfg_bufs_set_string(&bufs, 2,
648 (char *)cfg->cfg_uuid.uuid);
650 if (cfg && cfg->cfg_instance &&
651 lcfg->lcfg_command == LCFG_SETUP) {
652 /*add cfg_instance to the end of lcfg buffers*/
653 lustre_cfg_bufs_set_string(&bufs, bufs.lcfg_bufcount,
656 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
658 lcfg_new->lcfg_num = lcfg->lcfg_num;
659 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
660 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
661 lcfg_new->lcfg_nal = lcfg->lcfg_nal;
663 rc = class_process_config(lcfg_new);
664 lustre_cfg_free(lcfg_new);
667 OBD_FREE(inst_name, inst_len);
668 } else if (rec->lrh_type == PTL_CFG_REC) {
669 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
670 if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID &&
671 cfg->cfg_local_nid != PTL_NID_ANY) {
672 pcfg->pcfg_nid = cfg->cfg_local_nid;
675 rc = libcfs_nal_cmd(pcfg);
677 CERROR("unrecognized record type: 0x%x\n", rec->lrh_type);
683 int class_config_process_llog(struct llog_ctxt *ctxt, char *name,
684 struct config_llog_instance *cfg)
686 struct llog_handle *llh;
690 rc = llog_open(ctxt, &llh, NULL, name, 0);
694 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
696 rc = llog_process(llh, class_config_parse_handler, cfg, NULL);
698 rc2 = llog_close(llh);
705 int class_config_dump_handler(struct llog_handle * handle,
706 struct llog_rec_hdr *rec, void *data)
708 int cfg_len = rec->lrh_len;
709 char *cfg_buf = (char*) (rec + 1);
712 if (rec->lrh_type == OBD_CFG_REC) {
713 struct lustre_cfg *lcfg;
716 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
719 lcfg = (struct lustre_cfg *)cfg_buf;
721 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
722 if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0)
723 CDEBUG(D_INFO, " devname: %s\n",
724 lustre_cfg_string(lcfg, 0));
725 if (lcfg->lcfg_flags)
726 CDEBUG(D_INFO, " flags: %x\n", lcfg->lcfg_flags);
728 CDEBUG(D_INFO, " nid: "LPX64"\n",
731 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_nal);
733 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_num);
734 for (i = 1; i < lcfg->lcfg_bufcount; i++)
735 if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0)
736 CDEBUG(D_INFO, " inlbuf%d: %s\n", i,
737 lustre_cfg_string(lcfg, i));
738 } else if (rec->lrh_type == PTL_CFG_REC) {
739 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
740 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
742 CDEBUG(D_INFO, " nal: %x\n",
744 if (pcfg->pcfg_gw_nal)
745 CDEBUG(D_INFO, " gw_nal: %x\n",
748 CDEBUG(D_INFO, " nid: "LPX64"\n",
751 CDEBUG(D_INFO, " nid: "LPX64"\n",
754 CDEBUG(D_INFO, " nid: "LPX64"\n",
757 CDEBUG(D_INFO, " nid: %d\n",
760 CDEBUG(D_INFO, " id: %x\n",
762 if (pcfg->pcfg_flags)
763 CDEBUG(D_INFO, " flags: %x\n",
766 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
773 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
774 struct config_llog_instance *cfg)
776 struct llog_handle *llh;
780 rc = llog_open(ctxt, &llh, NULL, name, 0);
784 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
786 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
788 rc2 = llog_close(llh);