X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fobd_config.c;h=325c2c1ecd047bf3343f1ef372c5b5f0931c4e09;hb=191061ee668400324f4505cf498f1ee2d57e4962;hp=41f2258d75b88210c015dc4a3b4ac69fcc5c0112;hpb=c658964f36b60ce36e42c88005d5bbb74bf7bc4d;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 41f2258..325c2c1 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -43,17 +43,12 @@ /* Create a new device and set the type, name and uuid. If * successful, the new device can be accessed by either name or uuid. */ -int class_attach(struct lustre_cfg *lcfg) +static int class_attach(struct lustre_cfg *lcfg) { - int minor; struct obd_type *type; - int err = 0; - int len; - char *typename; - char *name; - char *uuid; struct obd_device *obd; - int dev; + char *typename, *name, *uuid; + int rc, len, cleanup_phase = 0; if (!lcfg->lcfg_inllen1 || !lcfg->lcfg_inlbuf1) { CERROR("No type passed!\n"); @@ -95,30 +90,20 @@ int class_attach(struct lustre_cfg *lcfg) CERROR("OBD: unknown type: %s\n", typename); RETURN(-EINVAL); } + cleanup_phase = 1; /* class_put_type */ obd = class_name2obd(name); if (obd != NULL) { CERROR("obd %s already attached\n", name); - RETURN(-EEXIST); + GOTO(out, rc = -EEXIST); } - obd = class_newdev(&dev); + obd = class_newdev(type); if (obd == NULL) - RETURN(-EINVAL); - - /* have we attached a type to this device */ - if (obd->obd_attached || obd->obd_type) { - CERROR("OBD: Device %d already typed as %s.\n", - obd->obd_minor, MKSTR(obd->obd_type->typ_name)); - RETURN(-EBUSY); - } + GOTO(out, rc = -EINVAL); - LASSERT(obd == (obd_dev + obd->obd_minor)); - - minor = obd->obd_minor; - memset(obd, 0, sizeof(*obd)); - obd->obd_minor = minor; - obd->obd_type = type; + cleanup_phase = 2; /* class_release_dev */ + INIT_LIST_HEAD(&obd->obd_exports); obd->obd_num_exports = 0; spin_lock_init(&obd->obd_dev_lock); @@ -128,52 +113,57 @@ int class_attach(struct lustre_cfg *lcfg) /* XXX belongs in setup not attach */ /* recovery data */ + init_timer(&obd->obd_recovery_timer); spin_lock_init(&obd->obd_processing_task_lock); init_waitqueue_head(&obd->obd_next_transno_waitq); INIT_LIST_HEAD(&obd->obd_recovery_queue); INIT_LIST_HEAD(&obd->obd_delayed_reply_queue); - spin_lock_init (&obd->obd_uncommitted_replies_lock); - INIT_LIST_HEAD (&obd->obd_uncommitted_replies); + spin_lock_init(&obd->obd_uncommitted_replies_lock); + INIT_LIST_HEAD(&obd->obd_uncommitted_replies); len = strlen(name) + 1; OBD_ALLOC(obd->obd_name, len); - if (!obd->obd_name) { - class_put_type(obd->obd_type); - obd->obd_type = NULL; - RETURN(-ENOMEM); - } + if (!obd->obd_name) + GOTO(out, rc = -ENOMEM); memcpy(obd->obd_name, name, len); + + cleanup_phase = 3; /* free obd_name */ len = strlen(uuid); if (len >= sizeof(obd->obd_uuid)) { CERROR("uuid must be < "LPSZ" bytes long\n", sizeof(obd->obd_uuid)); - OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1); - class_put_type(obd->obd_type); - obd->obd_type = NULL; - RETURN(-EINVAL); + GOTO(out, rc = -EINVAL); } memcpy(obd->obd_uuid.uuid, uuid, len); /* do the attach */ - if (OBP(obd, attach)) - err = OBP(obd,attach)(obd, sizeof *lcfg, lcfg); + if (OBP(obd, attach)) { + rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg); + if (rc) + GOTO(out, rc = -EINVAL); + } - if (err) { + obd->obd_attached = 1; + type->typ_refcnt++; + CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n", + obd->obd_minor, typename); + RETURN(0); + out: + switch (cleanup_phase) { + case 3: OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1); - class_put_type(obd->obd_type); + case 2: + class_release_dev(obd); + case 1: + class_put_type(type); obd->obd_type = NULL; - } else { - obd->obd_attached = 1; - type->typ_refcnt++; - CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n", - obd->obd_minor, typename); } - RETURN(err); + return rc; } -int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) +static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { int err = 0; struct obd_export *exp; @@ -219,9 +209,8 @@ err_exp: RETURN(err); } -int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) +static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) { - int minor; int err = 0; ENTRY; @@ -246,10 +235,7 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_attached = 0; obd->obd_type->typ_refcnt--; class_put_type(obd->obd_type); - obd->obd_type = NULL; - minor = obd->obd_minor; - memset(obd, 0, sizeof(*obd)); - obd->obd_minor = minor; + class_release_dev(obd); RETURN(err); } @@ -277,7 +263,7 @@ static void dump_exports(struct obd_device *obd) } } -int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) +static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) { int flags = 0; int err = 0; @@ -319,8 +305,8 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) int rc; if (!(flags & OBD_OPT_FORCE)) { - CERROR("OBD device %d (%p) has refcount %d\n", - obd->obd_minor, obd, + CERROR("OBD device %d (%p,%s) has refcount %d\n", + obd->obd_minor, obd, obd->obd_name, atomic_read(&obd->obd_refcount)); dump_exports(obd); GOTO(out, err = -EBUSY); @@ -358,14 +344,79 @@ out: obd->obd_set_up = obd->obd_stopping = 0; obd->obd_type->typ_refcnt--; /* XXX this should be an LASSERT */ - if (atomic_read(&obd->obd_refcount) > 0) - CERROR("%s still has refcount %d after " - "cleanup.\n", obd->obd_name, + if (atomic_read(&obd->obd_refcount) > 0) { + CERROR("%s (%p) still has refcount %d after " + "cleanup.\n", obd->obd_name, obd, atomic_read(&obd->obd_refcount)); + dump_exports(obd); + } } RETURN(err); +} + +int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg) +{ + struct obd_import *imp; + struct obd_uuid uuid; + int priority, rc; + ENTRY; + if (lcfg->lcfg_inllen1 <= 0 || + lcfg->lcfg_inllen1 > sizeof(struct obd_uuid)) { + CERROR("invalid conn_uuid\n"); + RETURN(-EINVAL); + } + if (lcfg->lcfg_inllen2 != sizeof(int)) { + CERROR("invalid priority\n"); + RETURN(-EINVAL); + } + if (strcmp(obd->obd_type->typ_name, "mdc") && + strcmp(obd->obd_type->typ_name, "osc")) { + CERROR("can't add connection on non-client dev\n"); + RETURN(-EINVAL); + } + + imp = obd->u.cli.cl_import; + if (!imp) { + CERROR("try to add conn on immature client dev\n"); + RETURN(-EINVAL); + } + + obd_str2uuid(&uuid, lcfg->lcfg_inlbuf1); + priority = *((int*) lcfg->lcfg_inlbuf2); + rc = obd_add_conn(imp, &uuid, priority); + + RETURN(rc); +} +int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg) +{ + struct obd_import *imp; + struct obd_uuid uuid; + int rc; + ENTRY; + + if (lcfg->lcfg_inllen1 <= 0 || + lcfg->lcfg_inllen1 > sizeof(struct obd_uuid)) { + CERROR("invalid conn_uuid\n"); + RETURN(-EINVAL); + } + if (strcmp(obd->obd_type->typ_name, "mdc") && + strcmp(obd->obd_type->typ_name, "osc")) { + CERROR("can't add connection on non-client dev\n"); + RETURN(-EINVAL); + } + + imp = obd->u.cli.cl_import; + if (!imp) { + CERROR("try to del conn on immature client dev\n"); + RETURN(-EINVAL); + } + + obd_str2uuid(&uuid, lcfg->lcfg_inlbuf1); + rc = obd_del_conn(imp, &uuid); + + RETURN(rc); } LIST_HEAD(lustre_profile_list); @@ -439,6 +490,7 @@ int class_process_config(struct lustre_cfg *lcfg) struct obd_device *obd; char str[PTL_NALFMT_SIZE]; int err; + ENTRY; LASSERT(lcfg && !IS_ERR(lcfg)); @@ -528,9 +580,17 @@ int class_process_config(struct lustre_cfg *lcfg) err = class_cleanup(obd, lcfg); GOTO(out, err = 0); } + case LCFG_ADD_CONN: { + err = class_add_conn(obd, lcfg); + GOTO(out, err = 0); + } + case LCFG_DEL_CONN: { + err = class_del_conn(obd, lcfg); + GOTO(out, err = 0); + } default: { - CERROR("Unknown command: %d\n", lcfg->lcfg_command); - GOTO(out, err = -EINVAL); + err = obd_process_config(obd, sizeof(*lcfg), lcfg); + GOTO(out, err); } } @@ -538,14 +598,15 @@ out: RETURN(err); } -static int class_config_llog_handler(struct llog_handle * handle, - struct llog_rec_hdr *rec, void *data) +static int class_config_parse_handler(struct llog_handle * handle, + struct llog_rec_hdr *rec, void *data) { struct config_llog_instance *cfg = data; int cfg_len = rec->lrh_len; char *cfg_buf = (char*) (rec + 1); int rc = 0; ENTRY; + if (rec->lrh_type == OBD_CFG_REC) { char *buf; struct lustre_cfg *lcfg; @@ -599,40 +660,39 @@ static int class_config_llog_handler(struct llog_handle * handle, lustre_cfg_freedata(buf, cfg_len); } else if (rec->lrh_type == PTL_CFG_REC) { struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf; - if (pcfg->pcfg_command ==NAL_CMD_REGISTER_MYNID && + if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID && cfg->cfg_local_nid != PTL_NID_ANY) { pcfg->pcfg_nid = cfg->cfg_local_nid; } - rc = kportal_nal_cmd(pcfg); + rc = libcfs_nal_cmd(pcfg); + } else { + CERROR("unrecognized record type: 0x%x\n", rec->lrh_type); } out: RETURN(rc); } -int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, - struct config_llog_instance *cfg) +int class_config_process_llog(struct llog_ctxt *ctxt, char *name, + struct config_llog_instance *cfg) { struct llog_handle *llh; int rc, rc2; ENTRY; - rc = llog_create(ctxt, &llh, NULL, name); + rc = llog_open(ctxt, &llh, NULL, name, 0); if (rc) RETURN(rc); rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(parse_out, rc); + if (rc == 0) + rc = llog_process(llh, class_config_parse_handler, cfg, NULL); - rc = llog_process(llh, class_config_llog_handler, cfg, NULL); -parse_out: rc2 = llog_close(llh); if (rc == 0) rc = rc2; RETURN(rc); - } static int class_config_dump_handler(struct llog_handle * handle, @@ -642,6 +702,7 @@ static int class_config_dump_handler(struct llog_handle * handle, char *cfg_buf = (char*) (rec + 1); int rc = 0; ENTRY; + if (rec->lrh_type == OBD_CFG_REC) { char *buf; struct lustre_cfg *lcfg; @@ -651,12 +712,12 @@ static int class_config_dump_handler(struct llog_handle * handle, GOTO(out, rc); lcfg = (struct lustre_cfg* ) buf; - CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command); + CDEBUG(D_INFO, "lcfg command: 0x%x\n", lcfg->lcfg_command); if (lcfg->lcfg_dev_name) CDEBUG(D_INFO, " devname: %s\n", lcfg->lcfg_dev_name); if (lcfg->lcfg_flags) - CDEBUG(D_INFO, " flags: %x\n", lcfg->lcfg_flags); + CDEBUG(D_INFO, " flags: 0x%x\n", lcfg->lcfg_flags); if (lcfg->lcfg_nid) CDEBUG(D_INFO, " nid: "LPX64"\n", lcfg->lcfg_nid); @@ -667,17 +728,21 @@ static int class_config_dump_handler(struct llog_handle * handle, if (lcfg->lcfg_inlbuf1) CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf1); if (lcfg->lcfg_inlbuf2) - CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf2); + CDEBUG(D_INFO, " inlbuf2: %s\n",lcfg->lcfg_inlbuf2); if (lcfg->lcfg_inlbuf3) - CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf3); + CDEBUG(D_INFO, " inlbuf3: %s\n",lcfg->lcfg_inlbuf3); if (lcfg->lcfg_inlbuf4) - CDEBUG(D_INFO, " inlbuf1: %s\n",lcfg->lcfg_inlbuf4); + CDEBUG(D_INFO, " inlbuf4: %s\n",lcfg->lcfg_inlbuf4); + if (lcfg->lcfg_inlbuf5) + CDEBUG(D_INFO, " inlbuf5: %s\n",lcfg->lcfg_inlbuf5); + if (lcfg->lcfg_inlbuf6) + CDEBUG(D_INFO, " inlbuf6: %s\n",lcfg->lcfg_inlbuf6); lustre_cfg_freedata(buf, cfg_len); } else if (rec->lrh_type == PTL_CFG_REC) { struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf; - CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command); + CDEBUG(D_INFO, "pcfg command: 0x%x\n", pcfg->pcfg_command); if (pcfg->pcfg_nal) CDEBUG(D_INFO, " nal: %d\n", pcfg->pcfg_nal); @@ -688,19 +753,19 @@ static int class_config_dump_handler(struct llog_handle * handle, CDEBUG(D_INFO, " nid: "LPX64"\n", pcfg->pcfg_nid); if (pcfg->pcfg_nid2) - CDEBUG(D_INFO, " nid: "LPX64"\n", + CDEBUG(D_INFO, " nid2: "LPX64"\n", pcfg->pcfg_nid2); if (pcfg->pcfg_nid3) - CDEBUG(D_INFO, " nid: "LPX64"\n", + CDEBUG(D_INFO, " nid3: "LPX64"\n", pcfg->pcfg_nid3); if (pcfg->pcfg_misc) - CDEBUG(D_INFO, " nid: %d\n", + CDEBUG(D_INFO, " misc: %d\n", pcfg->pcfg_misc); if (pcfg->pcfg_id) - CDEBUG(D_INFO, " id: %x\n", + CDEBUG(D_INFO, " id: 0x%x\n", pcfg->pcfg_id); if (pcfg->pcfg_flags) - CDEBUG(D_INFO, " flags: %x\n", + CDEBUG(D_INFO, " flags: 0x%x\n", pcfg->pcfg_flags); } else { CERROR("unhandled lrh_type: %#x\n", rec->lrh_type); @@ -717,20 +782,17 @@ int class_config_dump_llog(struct llog_ctxt *ctxt, char *name, int rc, rc2; ENTRY; - rc = llog_create(ctxt, &llh, NULL, name); + rc = llog_open(ctxt, &llh, NULL, name, 0); if (rc) RETURN(rc); rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(parse_out, rc); + if (rc == 0) + rc = llog_process(llh, class_config_dump_handler, cfg, NULL); - rc = llog_process(llh, class_config_dump_handler, cfg, NULL); -parse_out: rc2 = llog_close(llh); if (rc == 0) rc = rc2; RETURN(rc); - }