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 int class_attach(struct lustre_cfg *lcfg)
48 struct obd_type *type;
49 struct obd_device *obd;
50 char *typename, *name, *uuid;
51 int minor, rc, len, dev, stage = 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);
95 obd = class_name2obd(name);
97 CERROR("obd %s already attached\n", name);
98 GOTO(out, rc = -EEXIST);
101 obd = class_newdev(&dev);
103 GOTO(out, rc = -EINVAL);
105 /* have we attached a type to this device */
106 if (obd->obd_attached || obd->obd_type) {
107 CERROR("OBD: Device %d already typed as %s.\n",
108 obd->obd_minor, MKSTR(obd->obd_type->typ_name));
109 GOTO(out, rc = -EBUSY);
112 LASSERT(obd == (obd_dev + obd->obd_minor));
114 minor = obd->obd_minor;
115 memset(obd, 0, sizeof(*obd));
116 obd->obd_minor = minor;
117 obd->obd_type = type;
118 INIT_LIST_HEAD(&obd->obd_exports);
119 obd->obd_num_exports = 0;
120 spin_lock_init(&obd->obd_dev_lock);
121 spin_lock_init(&obd->obd_osfs_lock);
122 obd->obd_osfs_age = jiffies - 1000 * HZ;
123 init_waitqueue_head(&obd->obd_refcount_waitq);
125 /* XXX belongs in setup not attach */
127 init_timer(&obd->obd_recovery_timer);
128 spin_lock_init(&obd->obd_processing_task_lock);
129 init_waitqueue_head(&obd->obd_next_transno_waitq);
130 INIT_LIST_HEAD(&obd->obd_recovery_queue);
131 INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
133 spin_lock_init(&obd->obd_uncommitted_replies_lock);
134 INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
136 len = strlen(name) + 1;
137 OBD_ALLOC(obd->obd_name, len);
139 GOTO(out, rc = -ENOMEM);
140 memcpy(obd->obd_name, name, len);
144 if (len >= sizeof(obd->obd_uuid)) {
145 CERROR("uuid must be < "LPSZ" bytes long\n",
146 sizeof(obd->obd_uuid));
147 GOTO(out, rc = -EINVAL);
149 memcpy(obd->obd_uuid.uuid, uuid, len);
152 if (OBP(obd, attach)) {
153 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
155 GOTO(out, rc = -EINVAL);
158 obd->obd_attached = 1;
160 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
161 obd->obd_minor, typename);
166 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
168 class_put_type(obd->obd_type);
169 obd->obd_type = NULL;
174 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
177 struct obd_export *exp;
180 LASSERT(obd == (obd_dev + obd->obd_minor));
182 /* have we attached a type to this device? */
183 if (!obd->obd_attached) {
184 CERROR("Device %d not attached\n", obd->obd_minor);
188 /* has this been done already? */
189 if (obd->obd_set_up) {
190 CERROR("Device %d already setup (type %s)\n",
191 obd->obd_minor, obd->obd_type->typ_name);
195 atomic_set(&obd->obd_refcount, 0);
197 exp = class_new_export(obd);
200 memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
201 sizeof(exp->exp_client_uuid));
202 obd->obd_self_export = exp;
203 class_export_put(exp);
205 err = obd_setup(obd, sizeof(*lcfg), lcfg);
209 obd->obd_type->typ_refcnt++;
215 class_unlink_export(obd->obd_self_export);
216 obd->obd_self_export = NULL;
220 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
226 if (obd->obd_set_up) {
227 CERROR("OBD device %d still set up\n", obd->obd_minor);
230 if (!obd->obd_attached) {
231 CERROR("OBD device %d not attached\n", obd->obd_minor);
234 if (OBP(obd, detach))
235 err = OBP(obd,detach)(obd);
238 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
239 obd->obd_name = NULL;
241 CERROR("device %d: no name at detach\n", obd->obd_minor);
244 obd->obd_attached = 0;
245 obd->obd_type->typ_refcnt--;
246 class_put_type(obd->obd_type);
247 obd->obd_type = NULL;
248 minor = obd->obd_minor;
249 memset(obd, 0, sizeof(*obd));
250 obd->obd_minor = minor;
254 static void dump_exports(struct obd_device *obd)
256 struct obd_export *exp, *n;
258 list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
259 struct ptlrpc_reply_state *rs;
260 struct ptlrpc_reply_state *first_reply = NULL;
263 list_for_each_entry (rs, &exp->exp_outstanding_replies,
270 CERROR("%s: %p %s %d %d %d: %p %s\n",
271 obd->obd_name, exp, exp->exp_client_uuid.uuid,
272 atomic_read(&exp->exp_refcount),
273 exp->exp_failed, nreplies, first_reply,
274 nreplies > 3 ? "..." : "");
278 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
285 if (!obd->obd_set_up) {
286 CERROR("Device %d not setup\n", obd->obd_minor);
290 if (lcfg->lcfg_inlbuf1) {
291 for (flag = lcfg->lcfg_inlbuf1; *flag != 0; flag++)
294 flags |= OBD_OPT_FORCE;
297 flags |= OBD_OPT_FAILOVER;
300 CERROR("unrecognised flag '%c'\n",
305 /* The one reference that should be remaining is the
307 if (atomic_read(&obd->obd_refcount) <= 1 ||
308 flags & OBD_OPT_FORCE) {
309 /* this will stop new connections, and need to
310 do it before class_disconnect_exports() */
311 obd->obd_stopping = 1;
314 if (atomic_read(&obd->obd_refcount) > 1) {
315 struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
319 if (!(flags & OBD_OPT_FORCE)) {
320 CERROR("OBD device %d (%p) has refcount %d\n",
322 atomic_read(&obd->obd_refcount));
324 GOTO(out, err = -EBUSY);
326 class_disconnect_exports(obd, flags);
328 "%s: waiting for obd refs to go away: %d\n",
329 obd->obd_name, atomic_read(&obd->obd_refcount));
331 rc = l_wait_event(obd->obd_refcount_waitq,
332 atomic_read(&obd->obd_refcount) < 2, &lwi);
334 LASSERT(atomic_read(&obd->obd_refcount) == 1);
336 CERROR("wait cancelled cleaning anyway. "
338 atomic_read(&obd->obd_refcount));
341 CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
345 if (obd->obd_self_export) {
346 err = obd_precleanup(obd, flags);
349 class_unlink_export(obd->obd_self_export);
350 obd->obd_self_export = NULL;
353 err = obd_cleanup(obd, flags);
356 obd->obd_set_up = obd->obd_stopping = 0;
357 obd->obd_type->typ_refcnt--;
358 /* XXX this should be an LASSERT */
359 if (atomic_read(&obd->obd_refcount) > 0)
360 CERROR("%s still has refcount %d after "
361 "cleanup.\n", obd->obd_name,
362 atomic_read(&obd->obd_refcount));
369 LIST_HEAD(lustre_profile_list);
371 struct lustre_profile *class_get_profile(char * prof)
373 struct lustre_profile *lprof;
375 list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
376 if (!strcmp(lprof->lp_profile, prof)) {
383 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
384 int mdclen, char *mdc)
386 struct lustre_profile *lprof;
389 OBD_ALLOC(lprof, sizeof(*lprof));
391 GOTO(out, err = -ENOMEM);
392 INIT_LIST_HEAD(&lprof->lp_list);
394 LASSERT(proflen == (strlen(prof) + 1));
395 OBD_ALLOC(lprof->lp_profile, proflen);
396 if (lprof->lp_profile == NULL)
397 GOTO(out, err = -ENOMEM);
398 memcpy(lprof->lp_profile, prof, proflen);
400 LASSERT(osclen == (strlen(osc) + 1));
401 OBD_ALLOC(lprof->lp_osc, osclen);
402 if (lprof->lp_profile == NULL)
403 GOTO(out, err = -ENOMEM);
404 memcpy(lprof->lp_osc, osc, osclen);
407 LASSERT(mdclen == (strlen(mdc) + 1));
408 OBD_ALLOC(lprof->lp_mdc, mdclen);
409 if (lprof->lp_mdc == NULL)
410 GOTO(out, err = -ENOMEM);
411 memcpy(lprof->lp_mdc, mdc, mdclen);
414 list_add(&lprof->lp_list, &lustre_profile_list);
420 void class_del_profile(char *prof)
422 struct lustre_profile *lprof;
424 lprof = class_get_profile(prof);
426 list_del(&lprof->lp_list);
427 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
428 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
430 OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
431 OBD_FREE(lprof, sizeof *lprof);
435 int class_process_config(struct lustre_cfg *lcfg)
437 struct obd_device *obd;
438 char str[PTL_NALFMT_SIZE];
441 LASSERT(lcfg && !IS_ERR(lcfg));
443 CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
445 /* Commands that don't need a device */
446 switch(lcfg->lcfg_command) {
448 err = class_attach(lcfg);
451 case LCFG_ADD_UUID: {
452 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
453 " (%s), nal %d\n", lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
454 portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
457 err = class_add_uuid(lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
461 case LCFG_DEL_UUID: {
462 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
463 lcfg->lcfg_inlbuf1 == NULL ? "<all uuids>" :
466 err = class_del_uuid(lcfg->lcfg_inlbuf1);
469 case LCFG_MOUNTOPT: {
470 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
471 lcfg->lcfg_inlbuf1, lcfg->lcfg_inlbuf2,
473 /* set these mount options somewhere, so ll_fill_super
475 err = class_add_profile(lcfg->lcfg_inllen1, lcfg->lcfg_inlbuf1,
476 lcfg->lcfg_inllen2, lcfg->lcfg_inlbuf2,
477 lcfg->lcfg_inllen3, lcfg->lcfg_inlbuf3);
480 case LCFG_DEL_MOUNTOPT: {
481 CDEBUG(D_IOCTL, "mountopt: profile %s\n", lcfg->lcfg_inlbuf1);
482 /* set these mount options somewhere, so ll_fill_super
484 class_del_profile(lcfg->lcfg_inlbuf1);
487 case LCFG_SET_TIMEOUT: {
488 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
491 obd_timeout = lcfg->lcfg_num;
494 case LCFG_SET_UPCALL: {
495 CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
497 if (lcfg->lcfg_inllen1 > sizeof obd_lustre_upcall)
498 GOTO(out, err = -EINVAL);
499 memcpy(obd_lustre_upcall, lcfg->lcfg_inlbuf1,
505 /* Commands that require a device */
506 obd = class_name2obd(lcfg->lcfg_dev_name);
508 if (lcfg->lcfg_dev_name == NULL)
509 CERROR("this lcfg command requires a device name\n");
511 CERROR("no device for: %s\n", lcfg->lcfg_dev_name);
513 GOTO(out, err = -EINVAL);
516 switch(lcfg->lcfg_command) {
518 err = class_setup(obd, lcfg);
522 err = class_detach(obd, lcfg);
526 err = class_cleanup(obd, lcfg);
530 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
531 GOTO(out, err = -EINVAL);
539 static int class_config_llog_handler(struct llog_handle * handle,
540 struct llog_rec_hdr *rec, void *data)
542 struct config_llog_instance *cfg = data;
543 int cfg_len = rec->lrh_len;
544 char *cfg_buf = (char*) (rec + 1);
547 if (rec->lrh_type == OBD_CFG_REC) {
549 struct lustre_cfg *lcfg;
550 char *old_name = NULL;
552 char *old_uuid = NULL;
553 int old_uuid_len = 0;
554 char *inst_name = NULL;
557 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
560 lcfg = (struct lustre_cfg* ) buf;
562 if (cfg && cfg->cfg_instance && lcfg->lcfg_dev_name) {
563 inst_len = strlen(lcfg->lcfg_dev_name) +
564 strlen(cfg->cfg_instance) + 2;
565 OBD_ALLOC(inst_name, inst_len);
566 if (inst_name == NULL)
567 GOTO(out, rc = -ENOMEM);
568 sprintf(inst_name, "%s-%s", lcfg->lcfg_dev_name,
570 old_name = lcfg->lcfg_dev_name;
571 old_len = lcfg->lcfg_dev_namelen;
572 lcfg->lcfg_dev_name = inst_name;
573 lcfg->lcfg_dev_namelen = strlen(inst_name) + 1;
576 if (cfg && lcfg->lcfg_command == LCFG_ATTACH) {
577 old_uuid = lcfg->lcfg_inlbuf2;
578 old_uuid_len = lcfg->lcfg_inllen2;
580 lcfg->lcfg_inlbuf2 = (char*)&cfg->cfg_uuid.uuid;
581 lcfg->lcfg_inllen2 = sizeof(cfg->cfg_uuid);
584 rc = class_process_config(lcfg);
587 lcfg->lcfg_dev_name = old_name;
588 lcfg->lcfg_dev_namelen = old_len;
589 OBD_FREE(inst_name, inst_len);
593 lcfg->lcfg_inlbuf2 = old_uuid;
594 lcfg->lcfg_inllen2 = old_uuid_len;
597 lustre_cfg_freedata(buf, cfg_len);
598 } else if (rec->lrh_type == PTL_CFG_REC) {
599 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
600 if (pcfg->pcfg_command ==NAL_CMD_REGISTER_MYNID &&
601 cfg->cfg_local_nid != PTL_NID_ANY) {
602 pcfg->pcfg_nid = cfg->cfg_local_nid;
605 rc = libcfs_nal_cmd(pcfg);
611 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
612 struct config_llog_instance *cfg)
614 struct llog_handle *llh;
618 rc = llog_create(ctxt, &llh, NULL, name);
622 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
626 rc = llog_process(llh, class_config_llog_handler, cfg, NULL);
628 rc2 = llog_close(llh);
636 static int class_config_dump_handler(struct llog_handle * handle,
637 struct llog_rec_hdr *rec, void *data)
639 int cfg_len = rec->lrh_len;
640 char *cfg_buf = (char*) (rec + 1);
643 if (rec->lrh_type == OBD_CFG_REC) {
645 struct lustre_cfg *lcfg;
647 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
650 lcfg = (struct lustre_cfg* ) buf;
652 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
653 if (lcfg->lcfg_dev_name)
654 CDEBUG(D_INFO, " devname: %s\n",
655 lcfg->lcfg_dev_name);
656 if (lcfg->lcfg_flags)
657 CDEBUG(D_INFO, " flags: %x\n", lcfg->lcfg_flags);
659 CDEBUG(D_INFO, " nid: "LPX64"\n",
662 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_nal);
664 CDEBUG(D_INFO, " nal: %x\n", lcfg->lcfg_num);
665 if (lcfg->lcfg_inlbuf1)
666 CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf1);
667 if (lcfg->lcfg_inlbuf2)
668 CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf2);
669 if (lcfg->lcfg_inlbuf3)
670 CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf3);
671 if (lcfg->lcfg_inlbuf4)
672 CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf4);
674 lustre_cfg_freedata(buf, cfg_len);
675 } else if (rec->lrh_type == PTL_CFG_REC) {
676 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
678 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
680 CDEBUG(D_INFO, " nal: %d\n",
682 if (pcfg->pcfg_gw_nal)
683 CDEBUG(D_INFO, " gw_nal: %d\n",
686 CDEBUG(D_INFO, " nid: "LPX64"\n",
689 CDEBUG(D_INFO, " nid: "LPX64"\n",
692 CDEBUG(D_INFO, " nid: "LPX64"\n",
695 CDEBUG(D_INFO, " nid: %d\n",
698 CDEBUG(D_INFO, " id: %x\n",
700 if (pcfg->pcfg_flags)
701 CDEBUG(D_INFO, " flags: %x\n",
704 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
711 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
712 struct config_llog_instance *cfg)
714 struct llog_handle *llh;
718 rc = llog_create(ctxt, &llh, NULL, name);
722 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
726 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
728 rc2 = llog_close(llh);