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)
428 struct lustre_profile *lprof;
431 OBD_ALLOC(lprof, sizeof(*lprof));
433 GOTO(out, err = -ENOMEM);
434 INIT_LIST_HEAD(&lprof->lp_list);
436 LASSERT(proflen == (strlen(prof) + 1));
437 OBD_ALLOC(lprof->lp_profile, proflen);
438 if (lprof->lp_profile == NULL)
439 GOTO(out, err = -ENOMEM);
440 memcpy(lprof->lp_profile, prof, proflen);
442 LASSERT(lovlen == (strlen(lov) + 1));
443 OBD_ALLOC(lprof->lp_lov, lovlen);
444 if (lprof->lp_profile == NULL)
445 GOTO(out, err = -ENOMEM);
446 memcpy(lprof->lp_lov, lov, lovlen);
449 LASSERT(lmvlen == (strlen(lmv) + 1));
450 OBD_ALLOC(lprof->lp_lmv, lmvlen);
451 if (lprof->lp_lmv == NULL)
452 GOTO(out, err = -ENOMEM);
453 memcpy(lprof->lp_lmv, lmv, lmvlen);
456 list_add(&lprof->lp_list, &lustre_profile_list);
462 void class_del_profile(char *prof)
464 struct lustre_profile *lprof;
466 lprof = class_get_profile(prof);
468 list_del(&lprof->lp_list);
469 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
470 OBD_FREE(lprof->lp_lov, strlen(lprof->lp_lov) + 1);
472 OBD_FREE(lprof->lp_lmv, strlen(lprof->lp_lmv) + 1);
473 OBD_FREE(lprof, sizeof *lprof);
477 int class_process_config(struct lustre_cfg *lcfg)
479 struct obd_device *obd;
480 char str[PTL_NALFMT_SIZE];
484 LASSERT(lcfg && !IS_ERR(lcfg));
486 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
488 /* Commands that don't need a device */
489 switch(lcfg->lcfg_command) {
491 err = class_attach(lcfg);
494 case LCFG_ADD_UUID: {
495 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
496 " (%s), nal %x\n", lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
497 portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
500 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
504 case LCFG_DEL_UUID: {
505 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
506 (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
507 ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
509 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
512 case LCFG_MOUNTOPT: {
513 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
514 lustre_cfg_string(lcfg, 1),
515 lustre_cfg_string(lcfg, 2),
516 lustre_cfg_string(lcfg, 3));
517 /* set these mount options somewhere, so ll_fill_super
519 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
520 lustre_cfg_string(lcfg, 1),
521 LUSTRE_CFG_BUFLEN(lcfg, 2),
522 lustre_cfg_string(lcfg, 2),
523 LUSTRE_CFG_BUFLEN(lcfg, 3),
524 lustre_cfg_string(lcfg, 3));
527 case LCFG_DEL_MOUNTOPT: {
528 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
529 lustre_cfg_string(lcfg, 1));
530 /* set these mount options somewhere, so ll_fill_super
532 class_del_profile(lustre_cfg_string(lcfg, 1));
535 case LCFG_SET_TIMEOUT: {
536 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
539 obd_timeout = lcfg->lcfg_num;
542 case LCFG_SET_UPCALL: {
543 CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
544 lustre_cfg_string(lcfg, 1));
545 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof obd_lustre_upcall)
546 GOTO(out, err = -EINVAL);
547 strncpy(obd_lustre_upcall, lustre_cfg_string(lcfg, 1),
548 sizeof (obd_lustre_upcall));
553 /* Commands that require a device */
554 obd = class_name2obd(lustre_cfg_string(lcfg, 0));
556 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
557 CERROR("this lcfg command %d requires a device name\n",
560 CERROR("no device for: %s\n",
561 lustre_cfg_string(lcfg, 0));
563 GOTO(out, err = -EINVAL);
566 switch(lcfg->lcfg_command) {
568 err = class_setup(obd, lcfg);
572 err = class_detach(obd, lcfg);
576 err = class_cleanup(obd, lcfg);
579 case LCFG_ADD_CONN: {
580 err = class_add_conn(obd, lcfg);
583 case LCFG_DEL_CONN: {
584 err = class_del_conn(obd, lcfg);
588 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
597 static int class_config_parse_handler(struct llog_handle * handle,
598 struct llog_rec_hdr *rec, void *data)
600 struct config_llog_instance *cfg = data;
601 int cfg_len = rec->lrh_len;
602 char *cfg_buf = (char*) (rec + 1);
606 if (rec->lrh_type == OBD_CFG_REC) {
607 struct lustre_cfg *lcfg, *lcfg_new;
608 struct lustre_cfg_bufs bufs;
610 char *inst_name = NULL;
614 lcfg = (struct lustre_cfg *)cfg_buf;
615 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
616 lustre_swab_lustre_cfg(lcfg);
618 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
622 lustre_cfg_bufs_init(&bufs, lcfg);
623 if (cfg && cfg->cfg_instance && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
625 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
626 strlen(cfg->cfg_instance) + 1;
627 OBD_ALLOC(inst_name, inst_len);
628 if (inst_name == NULL)
629 GOTO(out, rc = -ENOMEM);
630 sprintf(inst_name, "%s-%s",
631 lustre_cfg_string(lcfg, 0),
633 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
636 if (cfg && lcfg->lcfg_command == LCFG_ATTACH)
637 lustre_cfg_bufs_set_string(&bufs, 2,
638 (char *)cfg->cfg_uuid.uuid);
640 if (cfg && cfg->cfg_instance &&
641 lcfg->lcfg_command == LCFG_SETUP) {
642 /*add cfg_instance to the end of lcfg buffers*/
643 lustre_cfg_bufs_set_string(&bufs, bufs.lcfg_bufcount,
646 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
648 lcfg_new->lcfg_num = lcfg->lcfg_num;
649 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
650 lcfg_new->lcfg_nid = lcfg->lcfg_nid;
651 lcfg_new->lcfg_nal = lcfg->lcfg_nal;
653 rc = class_process_config(lcfg_new);
654 lustre_cfg_free(lcfg_new);
657 OBD_FREE(inst_name, inst_len);
658 } else if (rec->lrh_type == PTL_CFG_REC) {
659 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
660 if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID &&
661 cfg->cfg_local_nid != PTL_NID_ANY) {
662 pcfg->pcfg_nid = cfg->cfg_local_nid;
665 rc = libcfs_nal_cmd(pcfg);
667 CERROR("unrecognized record type: 0x%x\n", rec->lrh_type);
673 int class_config_process_llog(struct llog_ctxt *ctxt, char *name,
674 struct config_llog_instance *cfg)
676 struct llog_handle *llh;
680 rc = llog_open(ctxt, &llh, NULL, name, 0);
684 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
686 rc = llog_process(llh, class_config_parse_handler, cfg, NULL);
688 rc2 = llog_close(llh);
695 int class_config_dump_handler(struct llog_handle * handle,
696 struct llog_rec_hdr *rec, void *data)
698 int cfg_len = rec->lrh_len;
699 char *cfg_buf = (char*) (rec + 1);
702 if (rec->lrh_type == OBD_CFG_REC) {
703 struct lustre_cfg *lcfg;
706 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
709 lcfg = (struct lustre_cfg *)cfg_buf;
711 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
712 if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0)
713 CDEBUG(D_INFO, " devname: %s\n",
714 lustre_cfg_string(lcfg, 0));
715 if (lcfg->lcfg_flags)
716 CDEBUG(D_INFO, " flags: %x\n", lcfg->lcfg_flags);
718 CDEBUG(D_INFO, " nid: "LPX64"\n",
721 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_nal);
723 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_num);
724 for (i = 1; i < lcfg->lcfg_bufcount; i++)
725 if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0)
726 CDEBUG(D_INFO, " inlbuf%d: %s\n", i,
727 lustre_cfg_string(lcfg, i));
728 } else if (rec->lrh_type == PTL_CFG_REC) {
729 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
730 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
732 CDEBUG(D_INFO, " nal: %x\n",
734 if (pcfg->pcfg_gw_nal)
735 CDEBUG(D_INFO, " gw_nal: %x\n",
738 CDEBUG(D_INFO, " nid: "LPX64"\n",
741 CDEBUG(D_INFO, " nid: "LPX64"\n",
744 CDEBUG(D_INFO, " nid: "LPX64"\n",
747 CDEBUG(D_INFO, " nid: %d\n",
750 CDEBUG(D_INFO, " id: %x\n",
752 if (pcfg->pcfg_flags)
753 CDEBUG(D_INFO, " flags: %x\n",
756 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
763 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
764 struct config_llog_instance *cfg)
766 struct llog_handle *llh;
770 rc = llog_open(ctxt, &llh, NULL, name, 0);
774 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
776 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
778 rc2 = llog_close(llh);