X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmgs%2Fmgs_handler.c;h=0df7efc9e0c1c66ef4282336f76365b69f2b0ea4;hb=7c56e3c31e230be251a9aaffce4fc0d2d31aa679;hp=9fbe6c2ad38dba871d8221c1a3a4be5f9e968dfa;hpb=f31b79be5a0380df3ed05c16fa43feca2bf5905c;p=fs%2Flustre-release.git diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 9fbe6c2..0df7efc 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -63,39 +63,39 @@ /* Establish a connection to the MGS.*/ static int mgs_connect(const struct lu_env *env, - struct lustre_handle *conn, struct obd_device *obd, + struct obd_export **exp, struct obd_device *obd, struct obd_uuid *cluuid, struct obd_connect_data *data, void *localdata) { - struct obd_export *exp; + struct obd_export *lexp; + struct lustre_handle conn = { 0 }; int rc; ENTRY; - if (!conn || !obd || !cluuid) + if (!exp || !obd || !cluuid) RETURN(-EINVAL); - rc = class_connect(conn, obd, cluuid); + rc = class_connect(&conn, obd, cluuid); if (rc) RETURN(rc); - exp = class_conn2export(conn); - LASSERT(exp); - exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_NULL; + lexp = class_conn2export(&conn); + LASSERT(lexp); - mgs_counter_incr(exp, LPROC_MGS_CONNECT); + mgs_counter_incr(lexp, LPROC_MGS_CONNECT); if (data != NULL) { data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED; - exp->exp_connect_flags = data->ocd_connect_flags; + lexp->exp_connect_flags = data->ocd_connect_flags; data->ocd_version = LUSTRE_VERSION_CODE; } - rc = mgs_client_add(obd, exp, localdata); + rc = mgs_client_add(obd, lexp, localdata); if (rc) { - class_disconnect(exp); + class_disconnect(lexp); } else { - class_export_put(exp); + *exp = lexp; } RETURN(rc); @@ -148,7 +148,9 @@ static int mgs_disconnect(struct obd_export *exp) spin_lock(&svc->srv_lock); list_del_init(&rs->rs_exp_list); + spin_lock(&rs->rs_lock); ptlrpc_schedule_difficult_reply(rs); + spin_unlock(&rs->rs_lock); spin_unlock(&svc->srv_lock); } spin_unlock(&exp->exp_lock); @@ -210,6 +212,12 @@ static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg) if (IS_ERR(obd->obd_fsops)) GOTO(err_put, rc = PTR_ERR(obd->obd_fsops)); + if (lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))) { + CERROR("%s: Underlying device is marked as read-only. " + "Setup failed\n", obd->obd_name); + GOTO(err_ops, rc = -EROFS); + } + /* namespace for mgs llog */ obd->obd_namespace = ldlm_namespace_new(obd ,"MGS", LDLM_NAMESPACE_SERVER, LDLM_NAMESPACE_MODEST); @@ -220,8 +228,6 @@ static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, "mgs_ldlm_client", &obd->obd_ldlm_client); - LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))); - rc = mgs_fs_setup(obd, mnt); if (rc) { CERROR("%s: MGS filesystem method init failed: rc = %d\n", @@ -244,7 +250,7 @@ static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg) mgs->mgs_service = ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE, MGS_MAXREPSIZE, MGS_REQUEST_PORTAL, - MGC_REPLY_PORTAL, 2000, + MGC_REPLY_PORTAL, 2, mgs_handle, LUSTRE_MGS_NAME, obd->obd_proc_entry, target_print_req, MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX, @@ -560,6 +566,60 @@ static int mgs_set_info_rpc(struct ptlrpc_request *req) RETURN(rc); } +/* + * similar as in ost_connect_check_sptlrpc() + */ +static int mgs_connect_check_sptlrpc(struct ptlrpc_request *req) +{ + struct obd_export *exp = req->rq_export; + struct obd_device *obd = exp->exp_obd; + struct fs_db *fsdb; + struct sptlrpc_flavor flvr; + int rc = 0; + + if (exp->exp_flvr.sf_rpc == SPTLRPC_FLVR_INVALID) { + rc = mgs_find_or_make_fsdb(obd, MGSSELF_NAME, &fsdb); + if (rc) + return rc; + + down(&fsdb->fsdb_sem); + if (sptlrpc_rule_set_choose(&fsdb->fsdb_srpc_gen, + LUSTRE_SP_MGC, LUSTRE_SP_MGS, + req->rq_peer.nid, + &flvr) == 0) { + /* by defualt allow any flavors */ + flvr.sf_rpc = SPTLRPC_FLVR_ANY; + } + up(&fsdb->fsdb_sem); + + spin_lock(&exp->exp_lock); + + exp->exp_sp_peer = req->rq_sp_from; + exp->exp_flvr = flvr; + + if (exp->exp_flvr.sf_rpc != SPTLRPC_FLVR_ANY && + exp->exp_flvr.sf_rpc != req->rq_flvr.sf_rpc) { + CERROR("invalid rpc flavor %x, expect %x, from %s\n", + req->rq_flvr.sf_rpc, exp->exp_flvr.sf_rpc, + libcfs_nid2str(req->rq_peer.nid)); + rc = -EACCES; + } + + spin_unlock(&exp->exp_lock); + } else { + if (exp->exp_sp_peer != req->rq_sp_from) { + CERROR("RPC source %s doesn't match %s\n", + sptlrpc_part2name(req->rq_sp_from), + sptlrpc_part2name(exp->exp_sp_peer)); + rc = -EACCES; + } else { + rc = sptlrpc_target_export_check(exp, req); + } + } + + return rc; +} + /* Called whenever a target cleans up. */ /* XXX - Currently unused */ static int mgs_handle_target_del(struct ptlrpc_request *req) @@ -591,6 +651,12 @@ int mgs_handle(struct ptlrpc_request *req) LASSERT(current->journal_info == NULL); opc = lustre_msg_get_opc(req->rq_reqmsg); + + if (opc == SEC_CTX_INIT || + opc == SEC_CTX_INIT_CONT || + opc == SEC_CTX_FINI) + GOTO(out, rc = 0); + if (opc != MGS_CONNECT) { if (req->rq_export == NULL) { CERROR("lustre_mgs: operation %d on unconnected MGS\n", @@ -606,6 +672,9 @@ int mgs_handle(struct ptlrpc_request *req) /* MGS and MDS have same request format for connect */ req_capsule_set(&req->rq_pill, &RQF_MDS_CONNECT); rc = target_handle_connect(req); + if (rc == 0) + rc = mgs_connect_check_sptlrpc(req); + if (!rc && (lustre_msg_get_conn_cnt(req->rq_reqmsg) > 1)) /* Make clients trying to reconnect after a MGS restart happy; also requires obd_replayable */