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 <portals/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 (!lcfg->lcfg_inllen1 || !lcfg->lcfg_inlbuf1) {
54 CERROR("No type passed!\n");
57 if (lcfg->lcfg_inlbuf1[lcfg->lcfg_inllen1 - 1] != 0) {
58 CERROR("Type not nul terminated!\n");
61 typename = lcfg->lcfg_inlbuf1;
63 if (!lcfg->lcfg_dev_namelen || !lcfg->lcfg_dev_name) {
64 CERROR("No name passed!\n");
67 if (lcfg->lcfg_dev_name[lcfg->lcfg_dev_namelen - 1] != 0) {
68 CERROR("Name not nul terminated!\n");
71 name = lcfg->lcfg_dev_name;
73 if (!lcfg->lcfg_inllen2 || !lcfg->lcfg_inlbuf2) {
74 CERROR("No UUID passed!\n");
77 if (lcfg->lcfg_inlbuf2[lcfg->lcfg_inllen2 - 1] != 0) {
78 CERROR("UUID not nul terminated!\n");
81 uuid = lcfg->lcfg_inlbuf2;
83 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
84 MKSTR(lcfg->lcfg_inlbuf1),
85 MKSTR(lcfg->lcfg_dev_name), MKSTR(lcfg->lcfg_inlbuf2));
88 type = class_get_type(typename);
90 CERROR("OBD: unknown type: %s\n", typename);
93 cleanup_phase = 1; /* class_put_type */
95 obd = class_name2obd(name);
97 CERROR("obd %s already attached\n", name);
98 GOTO(out, rc = -EEXIST);
101 obd = class_newdev(type);
103 GOTO(out, rc = -EINVAL);
105 cleanup_phase = 2; /* class_release_dev */
107 INIT_LIST_HEAD(&obd->obd_exports);
108 obd->obd_num_exports = 0;
109 spin_lock_init(&obd->obd_dev_lock);
110 spin_lock_init(&obd->obd_osfs_lock);
111 obd->obd_osfs_age = jiffies - 1000 * HZ;
112 init_waitqueue_head(&obd->obd_refcount_waitq);
114 /* XXX belongs in setup not attach */
116 init_timer(&obd->obd_recovery_timer);
117 spin_lock_init(&obd->obd_processing_task_lock);
118 init_waitqueue_head(&obd->obd_next_transno_waitq);
119 INIT_LIST_HEAD(&obd->obd_recovery_queue);
120 INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
122 spin_lock_init(&obd->obd_uncommitted_replies_lock);
123 INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
125 len = strlen(name) + 1;
126 OBD_ALLOC(obd->obd_name, len);
128 GOTO(out, rc = -ENOMEM);
129 memcpy(obd->obd_name, name, len);
131 cleanup_phase = 3; /* free obd_name */
134 if (len >= sizeof(obd->obd_uuid)) {
135 CERROR("uuid must be < "LPSZ" bytes long\n",
136 sizeof(obd->obd_uuid));
137 GOTO(out, rc = -EINVAL);
139 memcpy(obd->obd_uuid.uuid, uuid, len);
142 if (OBP(obd, attach)) {
143 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
145 GOTO(out, rc = -EINVAL);
148 obd->obd_attached = 1;
150 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
151 obd->obd_minor, typename);
154 switch (cleanup_phase) {
156 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
158 class_release_dev(obd);
160 class_put_type(type);
161 obd->obd_type = NULL;
166 static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
169 struct obd_export *exp;
172 LASSERT(obd == (obd_dev + obd->obd_minor));
174 /* have we attached a type to this device? */
175 if (!obd->obd_attached) {
176 CERROR("Device %d not attached\n", obd->obd_minor);
180 /* has this been done already? */
181 if (obd->obd_set_up) {
182 CERROR("Device %d already setup (type %s)\n",
183 obd->obd_minor, obd->obd_type->typ_name);
187 atomic_set(&obd->obd_refcount, 0);
189 exp = class_new_export(obd);
192 memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
193 sizeof(exp->exp_client_uuid));
194 obd->obd_self_export = exp;
195 class_export_put(exp);
197 err = obd_setup(obd, sizeof(*lcfg), lcfg);
201 obd->obd_type->typ_refcnt++;
207 class_unlink_export(obd->obd_self_export);
208 obd->obd_self_export = NULL;
212 static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
217 if (obd->obd_set_up) {
218 CERROR("OBD device %d still set up\n", obd->obd_minor);
221 if (!obd->obd_attached) {
222 CERROR("OBD device %d not attached\n", obd->obd_minor);
225 if (OBP(obd, detach))
226 err = OBP(obd,detach)(obd);
229 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
230 obd->obd_name = NULL;
232 CERROR("device %d: no name at detach\n", obd->obd_minor);
235 obd->obd_attached = 0;
236 obd->obd_type->typ_refcnt--;
237 class_put_type(obd->obd_type);
238 class_release_dev(obd);
242 static void dump_exports(struct obd_device *obd)
244 struct obd_export *exp, *n;
246 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
247 struct ptlrpc_reply_state *rs;
248 struct ptlrpc_reply_state *first_reply = NULL;
251 list_for_each_entry (rs, &exp->exp_outstanding_replies,
258 CERROR("%s: %p %s %d %d %d: %p %s\n",
259 obd->obd_name, exp, exp->exp_client_uuid.uuid,
260 atomic_read(&exp->exp_refcount),
261 exp->exp_failed, nreplies, first_reply,
262 nreplies > 3 ? "..." : "");
266 static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
273 if (!obd->obd_set_up) {
274 CERROR("Device %d not setup\n", obd->obd_minor);
278 if (lcfg->lcfg_inlbuf1) {
279 for (flag = lcfg->lcfg_inlbuf1; *flag != 0; flag++)
282 flags |= OBD_OPT_FORCE;
285 flags |= OBD_OPT_FAILOVER;
288 CERROR("unrecognised flag '%c'\n",
293 /* The one reference that should be remaining is the
295 if (atomic_read(&obd->obd_refcount) <= 1 ||
296 flags & OBD_OPT_FORCE) {
297 /* this will stop new connections, and need to
298 do it before class_disconnect_exports() */
299 obd->obd_stopping = 1;
302 if (atomic_read(&obd->obd_refcount) > 1) {
303 struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
307 if (!(flags & OBD_OPT_FORCE)) {
308 CERROR("OBD device %d (%p,%s) has refcount %d\n",
309 obd->obd_minor, obd, obd->obd_name,
310 atomic_read(&obd->obd_refcount));
312 GOTO(out, err = -EBUSY);
314 class_disconnect_exports(obd, flags);
316 "%s: waiting for obd refs to go away: %d\n",
317 obd->obd_name, atomic_read(&obd->obd_refcount));
319 rc = l_wait_event(obd->obd_refcount_waitq,
320 atomic_read(&obd->obd_refcount) < 2, &lwi);
322 LASSERT(atomic_read(&obd->obd_refcount) == 1);
324 CERROR("wait cancelled cleaning anyway. "
326 atomic_read(&obd->obd_refcount));
329 CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
333 if (obd->obd_self_export) {
334 err = obd_precleanup(obd, flags);
337 class_unlink_export(obd->obd_self_export);
338 obd->obd_self_export = NULL;
341 err = obd_cleanup(obd, flags);
344 obd->obd_set_up = obd->obd_stopping = 0;
345 obd->obd_type->typ_refcnt--;
346 /* XXX this should be an LASSERT */
347 if (atomic_read(&obd->obd_refcount) > 0) {
348 CERROR("%s (%p) still has refcount %d after "
349 "cleanup.\n", obd->obd_name, obd,
350 atomic_read(&obd->obd_refcount));
358 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
360 struct obd_import *imp;
361 struct obd_uuid uuid;
365 if (lcfg->lcfg_inllen1 <= 0 ||
366 lcfg->lcfg_inllen1 > sizeof(struct obd_uuid)) {
367 CERROR("invalid conn_uuid\n");
370 if (lcfg->lcfg_inllen2 != sizeof(int)) {
371 CERROR("invalid priority\n");
374 if (strcmp(obd->obd_type->typ_name, "mdc") &&
375 strcmp(obd->obd_type->typ_name, "osc")) {
376 CERROR("can't add connection on non-client dev\n");
380 imp = obd->u.cli.cl_import;
382 CERROR("try to add conn on immature client dev\n");
386 obd_str2uuid(&uuid, lcfg->lcfg_inlbuf1);
387 priority = *((int*) lcfg->lcfg_inlbuf2);
388 rc = obd_add_conn(imp, &uuid, priority);
392 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
394 struct obd_import *imp;
395 struct obd_uuid uuid;
399 if (lcfg->lcfg_inllen1 <= 0 ||
400 lcfg->lcfg_inllen1 > sizeof(struct obd_uuid)) {
401 CERROR("invalid conn_uuid\n");
404 if (strcmp(obd->obd_type->typ_name, "mdc") &&
405 strcmp(obd->obd_type->typ_name, "osc")) {
406 CERROR("can't add connection on non-client dev\n");
410 imp = obd->u.cli.cl_import;
412 CERROR("try to del conn on immature client dev\n");
416 obd_str2uuid(&uuid, lcfg->lcfg_inlbuf1);
417 rc = obd_del_conn(imp, &uuid);
422 LIST_HEAD(lustre_profile_list);
424 struct lustre_profile *class_get_profile(char * prof)
426 struct lustre_profile *lprof;
428 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
429 if (!strcmp(lprof->lp_profile, prof)) {
436 int class_add_profile(int proflen, char *prof,
437 int lovlen, char *lov,
438 int lmvlen, char *lmv)
440 struct lustre_profile *lprof;
443 OBD_ALLOC(lprof, sizeof(*lprof));
445 GOTO(out, err = -ENOMEM);
446 INIT_LIST_HEAD(&lprof->lp_list);
448 LASSERT(proflen == (strlen(prof) + 1));
449 OBD_ALLOC(lprof->lp_profile, proflen);
450 if (lprof->lp_profile == NULL)
451 GOTO(out, err = -ENOMEM);
452 memcpy(lprof->lp_profile, prof, proflen);
454 LASSERT(lovlen == (strlen(lov) + 1));
455 OBD_ALLOC(lprof->lp_lov, lovlen);
456 if (lprof->lp_profile == NULL)
457 GOTO(out, err = -ENOMEM);
458 memcpy(lprof->lp_lov, lov, lovlen);
461 LASSERT(lmvlen == (strlen(lmv) + 1));
462 OBD_ALLOC(lprof->lp_lmv, lmvlen);
463 if (lprof->lp_lmv == NULL)
464 GOTO(out, err = -ENOMEM);
465 memcpy(lprof->lp_lmv, lmv, lmvlen);
468 list_add(&lprof->lp_list, &lustre_profile_list);
474 void class_del_profile(char *prof)
476 struct lustre_profile *lprof;
478 lprof = class_get_profile(prof);
480 list_del(&lprof->lp_list);
481 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
482 OBD_FREE(lprof->lp_lov, strlen(lprof->lp_lov) + 1);
484 OBD_FREE(lprof->lp_lmv, strlen(lprof->lp_lmv) + 1);
485 OBD_FREE(lprof, sizeof *lprof);
489 int class_process_config(struct lustre_cfg *lcfg)
491 struct obd_device *obd;
492 char str[PTL_NALFMT_SIZE];
496 LASSERT(lcfg && !IS_ERR(lcfg));
498 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
500 /* Commands that don't need a device */
501 switch(lcfg->lcfg_command) {
503 err = class_attach(lcfg);
506 case LCFG_ADD_UUID: {
507 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
508 " (%s), nal %d\n", lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
509 portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
512 err = class_add_uuid(lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
516 case LCFG_DEL_UUID: {
517 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
518 lcfg->lcfg_inlbuf1 == NULL ? "<all uuids>" :
521 err = class_del_uuid(lcfg->lcfg_inlbuf1);
524 case LCFG_MOUNTOPT: {
525 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
526 lcfg->lcfg_inlbuf1, lcfg->lcfg_inlbuf2,
528 /* set these mount options somewhere, so ll_fill_super
530 err = class_add_profile(lcfg->lcfg_inllen1, lcfg->lcfg_inlbuf1,
531 lcfg->lcfg_inllen2, lcfg->lcfg_inlbuf2,
532 lcfg->lcfg_inllen3, lcfg->lcfg_inlbuf3);
535 case LCFG_DEL_MOUNTOPT: {
536 CDEBUG(D_IOCTL, "mountopt: profile %s\n", lcfg->lcfg_inlbuf1);
537 /* set these mount options somewhere, so ll_fill_super
539 class_del_profile(lcfg->lcfg_inlbuf1);
542 case LCFG_SET_TIMEOUT: {
543 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
546 obd_timeout = lcfg->lcfg_num;
549 case LCFG_SET_UPCALL: {
550 CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
552 if (lcfg->lcfg_inllen1 > sizeof obd_lustre_upcall)
553 GOTO(out, err = -EINVAL);
554 memcpy(obd_lustre_upcall, lcfg->lcfg_inlbuf1,
560 /* Commands that require a device */
561 obd = class_name2obd(lcfg->lcfg_dev_name);
563 if (lcfg->lcfg_dev_name == NULL)
564 CERROR("this lcfg command requires a device name\n");
566 CERROR("no device for: %s\n", lcfg->lcfg_dev_name);
568 GOTO(out, err = -EINVAL);
571 switch(lcfg->lcfg_command) {
573 err = class_setup(obd, lcfg);
577 err = class_detach(obd, lcfg);
581 err = class_cleanup(obd, lcfg);
584 case LCFG_ADD_CONN: {
585 err = class_add_conn(obd, lcfg);
588 case LCFG_DEL_CONN: {
589 err = class_del_conn(obd, lcfg);
593 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
602 static int class_config_parse_handler(struct llog_handle * handle,
603 struct llog_rec_hdr *rec, void *data)
605 struct config_llog_instance *cfg = data;
606 int cfg_len = rec->lrh_len;
607 char *cfg_buf = (char*) (rec + 1);
611 if (rec->lrh_type == OBD_CFG_REC) {
613 struct lustre_cfg *lcfg;
614 char *old_name = NULL;
616 char *old_uuid = NULL;
617 int old_uuid_len = 0;
618 char *inst_name = NULL;
621 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
624 lcfg = (struct lustre_cfg* ) buf;
626 if (cfg && cfg->cfg_instance && lcfg->lcfg_dev_name) {
627 inst_len = strlen(lcfg->lcfg_dev_name) +
628 strlen(cfg->cfg_instance) + 2;
629 OBD_ALLOC(inst_name, inst_len);
630 if (inst_name == NULL)
631 GOTO(out, rc = -ENOMEM);
632 sprintf(inst_name, "%s-%s", lcfg->lcfg_dev_name,
634 old_name = lcfg->lcfg_dev_name;
635 old_len = lcfg->lcfg_dev_namelen;
636 lcfg->lcfg_dev_name = inst_name;
637 lcfg->lcfg_dev_namelen = strlen(inst_name) + 1;
640 if (cfg && lcfg->lcfg_command == LCFG_ATTACH) {
641 old_uuid = lcfg->lcfg_inlbuf2;
642 old_uuid_len = lcfg->lcfg_inllen2;
644 lcfg->lcfg_inlbuf2 = (char*)&cfg->cfg_uuid.uuid;
645 lcfg->lcfg_inllen2 = sizeof(cfg->cfg_uuid);
648 rc = class_process_config(lcfg);
651 lcfg->lcfg_dev_name = old_name;
652 lcfg->lcfg_dev_namelen = old_len;
653 OBD_FREE(inst_name, inst_len);
657 lcfg->lcfg_inlbuf2 = old_uuid;
658 lcfg->lcfg_inllen2 = old_uuid_len;
661 lustre_cfg_freedata(buf, cfg_len);
662 } else if (rec->lrh_type == PTL_CFG_REC) {
663 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
664 if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID &&
665 cfg->cfg_local_nid != PTL_NID_ANY) {
666 pcfg->pcfg_nid = cfg->cfg_local_nid;
669 rc = libcfs_nal_cmd(pcfg);
671 CERROR("unrecognized record type: 0x%x\n", rec->lrh_type);
677 int class_config_process_llog(struct llog_ctxt *ctxt, char *name,
678 struct config_llog_instance *cfg)
680 struct llog_handle *llh;
684 rc = llog_open(ctxt, &llh, NULL, name, 0);
688 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
690 rc = llog_process(llh, class_config_parse_handler, cfg, NULL);
692 rc2 = llog_close(llh);
699 static int class_config_dump_handler(struct llog_handle * handle,
700 struct llog_rec_hdr *rec, void *data)
702 int cfg_len = rec->lrh_len;
703 char *cfg_buf = (char*) (rec + 1);
707 if (rec->lrh_type == OBD_CFG_REC) {
709 struct lustre_cfg *lcfg;
711 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
714 lcfg = (struct lustre_cfg* ) buf;
716 CDEBUG(D_INFO, "lcfg command: 0x%x\n", lcfg->lcfg_command);
717 if (lcfg->lcfg_dev_name)
718 CDEBUG(D_INFO, " devname: %s\n",
719 lcfg->lcfg_dev_name);
720 if (lcfg->lcfg_flags)
721 CDEBUG(D_INFO, " flags: 0x%x\n", lcfg->lcfg_flags);
723 CDEBUG(D_INFO, " nid: "LPX64"\n",
726 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_nal);
728 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_num);
729 if (lcfg->lcfg_inlbuf1)
730 CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf1);
731 if (lcfg->lcfg_inlbuf2)
732 CDEBUG(D_INFO, " inlbuf2: %s\n",lcfg->lcfg_inlbuf2);
733 if (lcfg->lcfg_inlbuf3)
734 CDEBUG(D_INFO, " inlbuf3: %s\n",lcfg->lcfg_inlbuf3);
735 if (lcfg->lcfg_inlbuf4)
736 CDEBUG(D_INFO, " inlbuf4: %s\n",lcfg->lcfg_inlbuf4);
737 if (lcfg->lcfg_inlbuf5)
738 CDEBUG(D_INFO, " inlbuf5: %s\n",lcfg->lcfg_inlbuf5);
739 if (lcfg->lcfg_inlbuf6)
740 CDEBUG(D_INFO, " inlbuf6: %s\n",lcfg->lcfg_inlbuf6);
742 lustre_cfg_freedata(buf, cfg_len);
743 } else if (rec->lrh_type == PTL_CFG_REC) {
744 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
746 CDEBUG(D_INFO, "pcfg command: 0x%x\n", pcfg->pcfg_command);
748 CDEBUG(D_INFO, " nal: %d\n",
750 if (pcfg->pcfg_gw_nal)
751 CDEBUG(D_INFO, " gw_nal: %d\n",
754 CDEBUG(D_INFO, " nid: "LPX64"\n",
757 CDEBUG(D_INFO, " nid2: "LPX64"\n",
760 CDEBUG(D_INFO, " nid3: "LPX64"\n",
763 CDEBUG(D_INFO, " misc: %d\n",
766 CDEBUG(D_INFO, " id: 0x%x\n",
768 if (pcfg->pcfg_flags)
769 CDEBUG(D_INFO, " flags: 0x%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);