static int mds_lov_clean(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; struct obd_device *osc = mds->mds_lov_obd; ENTRY; if (mds->mds_profile) { class_del_profile(mds->mds_profile); OBD_FREE(mds->mds_profile, strlen(mds->mds_profile) + 1); mds->mds_profile = NULL; } /* There better be a lov */ if (!osc) RETURN(0); if (IS_ERR(osc)) RETURN(PTR_ERR(osc)); obd_register_observer(osc, NULL); /* Give lov our same shutdown flags */ osc->obd_force = obd->obd_force; osc->obd_fail = obd->obd_fail; /* Cleanup the lov */ obd_disconnect(mds->mds_lov_exp); class_manual_cleanup(osc); RETURN(0); }
static int mdd_init0(const struct lu_env *env, struct mdd_device *mdd, struct lu_device_type *t, struct lustre_cfg *lcfg) { int rc; ENTRY; mdd->mdd_md_dev.md_lu_dev.ld_ops = &mdd_lu_ops; mdd->mdd_md_dev.md_ops = &mdd_ops; rc = mdd_connect_to_next(env, mdd, lustre_cfg_string(lcfg, 3)); if (rc) RETURN(rc); mdd->mdd_atime_diff = MAX_ATIME_DIFF; /* sync permission changes */ mdd->mdd_sync_permission = 1; dt_conf_get(env, mdd->mdd_child, &mdd->mdd_dt_conf); /* we are using service name but not mdd obd name * for compatibility reasons. * It is passed from MDT in lustre_cfg[2] buffer */ rc = mdd_procfs_init(mdd, lustre_cfg_string(lcfg, 2)); if (rc < 0) obd_disconnect(mdd->mdd_child_exp); RETURN(rc); }
static void mdd_device_shutdown(const struct lu_env *env, struct mdd_device *m, struct lustre_cfg *cfg) { mdd_generic_thread_stop(&m->mdd_orph_cleanup_thread); lfsck_degister(env, m->mdd_bottom); mdd_hsm_actions_llog_fini(env, m); mdd_changelog_fini(env, m); orph_index_fini(env, m); mdd_dot_lustre_cleanup(env, m); if (m->mdd_los != NULL) { local_oid_storage_fini(env, m->mdd_los); m->mdd_los = NULL; } lu_site_purge(env, mdd2lu_dev(m)->ld_site, ~0); if (m->mdd_child_exp) obd_disconnect(m->mdd_child_exp); }
/* The lsi has one reference for every server that is using the disk - e.g. MDT, MGS, and potentially MGC */ int lustre_put_lsi(struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); LASSERT(lsi != NULL); CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts)); if (atomic_dec_and_test(&lsi->lsi_mounts)) { if (IS_SERVER(lsi) && lsi->lsi_osd_exp) { lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev); lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL; lsi->lsi_dt_dev = NULL; obd_disconnect(lsi->lsi_osd_exp); /* wait till OSD is gone */ obd_zombie_barrier(); } lustre_free_lsi(sb); return 1; } return 0; }
/* * Release quota master target and all data structure associated with this * target. * Called on MDT0 cleanup. * * \param env - is the environment passed by the caller * \param ld - is the lu_device associated with the qmt device to be released * * \retval - NULL on success (backend OSD device is managed by the main stack), * appropriate error on failure */ static struct lu_device *qmt_device_fini(const struct lu_env *env, struct lu_device *ld) { struct qmt_device *qmt = lu2qmt_dev(ld); ENTRY; LASSERT(qmt != NULL); CDEBUG(D_QUOTA, "%s: initiating QMT shutdown\n", qmt->qmt_svname); qmt->qmt_stopping = true; /* kill pool instances, if any */ qmt_pool_fini(env, qmt); /* remove qmt proc entry */ if (qmt->qmt_proc != NULL && !IS_ERR(qmt->qmt_proc)) { lprocfs_remove(&qmt->qmt_proc); qmt->qmt_proc = NULL; } /* stop rebalance thread */ qmt_stop_reba_thread(qmt); /* disconnect from OSD */ if (qmt->qmt_child_exp != NULL) { obd_disconnect(qmt->qmt_child_exp); qmt->qmt_child_exp = NULL; qmt->qmt_child = NULL; } /* clear references to MDT namespace */ ld->ld_obd->obd_namespace = NULL; qmt->qmt_ns = NULL; RETURN(NULL); }
static int lustre_stop_mgc(struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); struct obd_device *obd; char *niduuid = 0, *ptr = 0; int i, rc = 0, len = 0; if (!lsi) return -ENOENT; obd = lsi->lsi_mgc; if (!obd) return -ENOENT; lsi->lsi_mgc = NULL; mutex_lock(&mgc_start_lock); LASSERT(atomic_read(&obd->u.cli.cl_mgc_refcount) > 0); if (!atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) { /* This is not fatal, every client that stops will call in here. */ CDEBUG(D_MOUNT, "mgc still has %d references.\n", atomic_read(&obd->u.cli.cl_mgc_refcount)); GOTO(out, rc = -EBUSY); } /* The MGC has no recoverable data in any case. * force shotdown set in umount_begin */ obd->obd_no_recov = 1; if (obd->u.cli.cl_mgc_mgsexp) { /* An error is not fatal, if we are unable to send the disconnect mgs ping evictor cleans up the export */ rc = obd_disconnect(obd->u.cli.cl_mgc_mgsexp); if (rc) CDEBUG(D_MOUNT, "disconnect failed %d\n", rc); } /* Save the obdname for cleaning the nid uuids, which are obdname_XX */ len = strlen(obd->obd_name) + 6; OBD_ALLOC(niduuid, len); if (niduuid) { strcpy(niduuid, obd->obd_name); ptr = niduuid + strlen(niduuid); } rc = class_manual_cleanup(obd); if (rc) GOTO(out, rc); /* Clean the nid uuids */ if (!niduuid) GOTO(out, rc = -ENOMEM); for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) { sprintf(ptr, "_%x", i); rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_DEL_UUID, niduuid, 0, 0, 0); if (rc) CERROR("del MDC UUID %s failed: rc = %d\n", niduuid, rc); } out: if (niduuid) OBD_FREE(niduuid, len); /* class_import_put will get rid of the additional connections */ mutex_unlock(&mgc_start_lock); return rc; }
/* Test client api; open log by name and process */ static int llog_test_6(const struct lu_env *env, struct obd_device *obd, char *name) { struct obd_device *mgc_obd; struct llog_ctxt *ctxt; struct obd_uuid *mgs_uuid; struct obd_export *exp; struct obd_uuid uuid = { "LLOG_TEST6_UUID" }; struct llog_handle *llh = NULL; struct llog_ctxt *nctxt; int rc, rc2; ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid; CWARN("6a: re-open log %s using client API\n", name); mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL); if (mgc_obd == NULL) { CERROR("6a: no MGC devices connected to %s found.\n", mgs_uuid->uuid); GOTO(ctxt_release, rc = -ENOENT); } rc = obd_connect(NULL, &exp, mgc_obd, &uuid, NULL /* obd_connect_data */, NULL); if (rc != -EALREADY) { CERROR("6a: connect on connected MGC (%s) failed to return" " -EALREADY", mgc_obd->obd_name); if (rc == 0) obd_disconnect(exp); GOTO(ctxt_release, rc = -EINVAL); } nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT); rc = llog_open(env, nctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); if (rc) { CERROR("6a: llog_open failed %d\n", rc); GOTO(nctxt_put, rc); } rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); if (rc) { CERROR("6a: llog_init_handle failed %d\n", rc); GOTO(parse_out, rc); } plain_counter = 1; /* llog header is first record */ CWARN("6b: process log %s using client API\n", name); rc = llog_process(env, llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6b: llog_process failed %d\n", rc); CWARN("6b: processed %d records\n", plain_counter); rc = verify_handle("6b", llh, plain_counter); if (rc) GOTO(parse_out, rc); plain_counter = 1; /* llog header is first record */ CWARN("6c: process log %s reversely using client API\n", name); rc = llog_reverse_process(env, llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6c: llog_reverse_process failed %d\n", rc); CWARN("6c: processed %d records\n", plain_counter); rc = verify_handle("6c", llh, plain_counter); if (rc) GOTO(parse_out, rc); parse_out: rc2 = llog_close(env, llh); if (rc2) { CERROR("6: llog_close failed: rc = %d\n", rc2); if (rc == 0) rc = rc2; } nctxt_put: llog_ctxt_put(nctxt); ctxt_release: llog_ctxt_put(ctxt); return rc; }
int liblustre_process_log(struct config_llog_instance *cfg, char *mgsnid, char *profile, int allow_recov) { struct lustre_cfg_bufs bufs; struct lustre_cfg *lcfg; char *peer = "MGS_UUID"; struct obd_device *obd; struct obd_export *exp; char *name = "mgc_dev"; class_uuid_t uuid; struct obd_uuid mgc_uuid; struct llog_ctxt *ctxt; lnet_nid_t nid = 0; char *mdsnid; int err, rc = 0; struct obd_connect_data *ocd = NULL; ENTRY; ll_generate_random_uuid(uuid); class_uuid_unparse(uuid, &mgc_uuid); nid = libcfs_str2nid(mgsnid); if (nid == LNET_NID_ANY) { CERROR("Can't parse NID %s\n", mgsnid); RETURN(-EINVAL); } lustre_cfg_bufs_reset(&bufs, NULL); lustre_cfg_bufs_set_string(&bufs, 1, peer); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out, rc); lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGC_NAME); lustre_cfg_bufs_set_string(&bufs, 2, mgc_uuid.uuid); lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs); rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out_del_uuid, rc); lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGS_OBDNAME); lustre_cfg_bufs_set_string(&bufs, 2, peer); lcfg = lustre_cfg_new(LCFG_SETUP, &bufs); rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out_detach, rc); while ((mdsnid = strsep(&mgsnid, ","))) { nid = libcfs_str2nid(mdsnid); lustre_cfg_bufs_reset(&bufs, NULL); lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid)); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc) { CERROR("Add uuid for %s failed %d\n", libcfs_nid2str(nid), rc); continue; } lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid)); lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc) { CERROR("Add conn for %s failed %d\n", libcfs_nid2str(nid), rc); continue; } } obd = class_name2obd(name); if (obd == NULL) GOTO(out_cleanup, rc = -EINVAL); OBD_ALLOC(ocd, sizeof(*ocd)); if (ocd == NULL) GOTO(out_cleanup, rc = -ENOMEM); ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT | OBD_CONNECT_FULL20; ocd->ocd_version = LUSTRE_VERSION_CODE; rc = obd_connect(NULL, &exp, obd, &mgc_uuid, ocd, NULL); if (rc) { CERROR("cannot connect to %s at %s: rc = %d\n", LUSTRE_MGS_OBDNAME, mgsnid, rc); GOTO(out_cleanup, rc); } ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT); cfg->cfg_flags |= CFG_F_COMPAT146; rc = class_config_parse_llog(NULL, ctxt, profile, cfg); llog_ctxt_put(ctxt); if (rc) { CERROR("class_config_parse_llog failed: rc = %d\n", rc); } /* We don't so much care about errors in cleaning up the config llog * connection, as we have already read the config by this point. */ err = obd_disconnect(exp); if (err) CERROR("obd_disconnect failed: rc = %d\n", err); out_cleanup: if (ocd) OBD_FREE(ocd, sizeof(*ocd)); lustre_cfg_bufs_reset(&bufs, name); lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err) CERROR("md_cleanup failed: rc = %d\n", err); out_detach: lustre_cfg_bufs_reset(&bufs, name); lcfg = lustre_cfg_new(LCFG_DETACH, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err) CERROR("md_detach failed: rc = %d\n", err); out_del_uuid: lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, peer); lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs); err = class_process_config(lcfg); if (err) CERROR("del MDC UUID failed: rc = %d\n", err); lustre_cfg_free(lcfg); out: RETURN(rc); }
/* Test client api; open log by name and process */ static int llog_test_6(struct obd_device *obd, char *name) { struct obd_device *mgc_obd; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); struct obd_uuid *mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid; struct obd_export *exp; struct obd_uuid uuid = {"LLOG_TEST6_UUID"}; struct llog_handle *llh = NULL; struct llog_ctxt *nctxt; int rc; CWARN("6a: re-open log %s using client API\n", name); mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL); if (mgc_obd == NULL) { CERROR("6: no MGC devices connected to %s found.\n", mgs_uuid->uuid); GOTO(ctxt_release, rc = -ENOENT); } rc = obd_connect(NULL, &exp, mgc_obd, &uuid, NULL /* obd_connect_data */, NULL); if (rc != -EALREADY) { CERROR("6: connect on connected MDC (%s) failed to return" " -EALREADY", mgc_obd->obd_name); if (rc == 0) obd_disconnect(exp); GOTO(ctxt_release, rc = -EINVAL); } nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT); rc = llog_create(nctxt, &llh, NULL, name); if (rc) { CERROR("6: llog_create failed %d\n", rc); llog_ctxt_put(nctxt); GOTO(ctxt_release, rc); } rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL); if (rc) { CERROR("6: llog_init_handle failed %d\n", rc); GOTO(parse_out, rc); } rc = llog_process(llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6: llog_process failed %d\n", rc); rc = llog_reverse_process(llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6: llog_reverse_process failed %d\n", rc); parse_out: rc = llog_close(llh); llog_ctxt_put(nctxt); if (rc) { CERROR("6: llog_close failed: rc = %d\n", rc); } ctxt_release: llog_ctxt_put(ctxt); RETURN(rc); }