/* Stop watching for updates on this log. */
static int config_log_end(char *logname, struct config_llog_instance *cfg)
{
- struct config_llog_data *cld, *cld_sptlrpc;
+ struct config_llog_data *cld, *cld_sptlrpc = NULL;
int rc = 0;
ENTRY;
cld = config_log_find(logname, cfg);
if (IS_ERR(cld))
RETURN(PTR_ERR(cld));
- /* drop the ref from the find */
- config_log_put(cld);
down(&llog_process_lock);
+ /*
+ * if cld_stopping is set, it means we didn't start the log thus
+ * not owning the start ref. this can happen after previous umount:
+ * the cld still hanging there waiting for lock cancel, and we
+ * remount again but failed in the middle and call log_end without
+ * calling start_log.
+ */
+ if (unlikely(cld->cld_stopping)) {
+ up(&llog_process_lock);
+ /* drop the ref from the find */
+ config_log_put(cld);
+ RETURN(rc);
+ }
+
cld->cld_stopping = 1;
up(&llog_process_lock);
if (cld_sptlrpc)
config_log_put(cld_sptlrpc);
+ /* drop the ref from the find */
+ config_log_put(cld);
/* drop the start ref */
config_log_put(cld);
+
CDEBUG(D_MGC, "end config log %s (%d)\n", logname ? logname : "client",
rc);
RETURN(rc);
lprocfs_mgc_init_vars(&lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
+ sptlrpc_lprocfs_cliobd_attach(obd);
spin_lock(&config_list_lock);
atomic_inc(&mgc_count);
RETURN(-ENOMEM);
req_msp = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, sizeof(*req_msp));
- if (!req_msp)
+ if (!req_msp) {
+ ptlrpc_req_finished(req);
RETURN(-ENOMEM);
+ }
memcpy(req_msp, msp, sizeof(*req_msp));
ptlrpc_req_set_repsize(req, 2, rep_size);
+
rc = ptlrpc_queue_wait(req);
if (!rc) {
rep_msp = lustre_swab_repbuf(req, REPLY_REC_OFF,
RETURN(-ENOMEM);
req_mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
- memcpy(req_mti, mti, sizeof(*req_mti));
+ if (!req_mti) {
+ ptlrpc_req_finished(req);
+ RETURN(-ENOMEM);
+ }
+ memcpy(req_mti, mti, sizeof(*req_mti));
ptlrpc_request_set_replen(req);
-
CDEBUG(D_MGC, "register %s\n", mti->mti_svname);
rc = ptlrpc_queue_wait(req);
rc = mgc_set_mgs_param(exp, msp);
RETURN(rc);
}
+ if (KEY_IS(KEY_MGSSEC)) {
+ struct client_obd *cli = &exp->exp_obd->u.cli;
+ struct sptlrpc_flavor flvr;
+
+ /*
+ * empty string means using current flavor, if which haven't
+ * been set yet, set it as null.
+ *
+ * if flavor has been set previously, check the asking flavor
+ * must match the existing one.
+ */
+ if (vallen == 0) {
+ if (cli->cl_flvr_mgc.sf_rpc != SPTLRPC_FLVR_INVALID)
+ RETURN(0);
+ val = "null";
+ vallen = 4;
+ }
+
+ rc = sptlrpc_parse_flavor(val, &flvr);
+ if (rc) {
+ CERROR("invalid sptlrpc flavor %s to MGS\n",
+ (char *) val);
+ RETURN(rc);
+ }
+
+ /*
+ * caller already hold a mutex
+ */
+ if (cli->cl_flvr_mgc.sf_rpc == SPTLRPC_FLVR_INVALID) {
+ cli->cl_flvr_mgc = flvr;
+ } else if (memcmp(&cli->cl_flvr_mgc, &flvr,
+ sizeof(flvr)) != 0) {
+ char str[20];
+
+ sptlrpc_flavor2name(&cli->cl_flvr_mgc,
+ str, sizeof(str));
+ LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but "
+ "currently %s is in use\n",
+ (char *) val, str);
+ rc = -EPERM;
+ }
+ RETURN(rc);
+ }
RETURN(rc);
}
&llog_client_ops);
if (rc == 0) {
ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
+ if (!ctxt) {
+ ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+ if (ctxt)
+ llog_cleanup(ctxt);
+ RETURN(-ENODEV);
+ }
llog_initiator_connect(ctxt);
llog_ctxt_put(ctxt);
} else {
*/
if (rcl && cld->cld_is_sptlrpc)
goto out_pop;
-
+
/* Copy the setup log locally if we can. Don't mess around if we're
running an MGS though (logs are already local). */
if (lctxt && lsi && (lsi->lsi_flags & LSI_SERVER) &&