Whamcloud - gitweb
b=18417
[fs/lustre-release.git] / lustre / mgc / mgc_request.c
index 2ab2ef3..270de52 100644 (file)
@@ -316,17 +316,29 @@ DECLARE_MUTEX(llog_process_lock);
 /* 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);
 
@@ -338,8 +350,11 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg)
         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);
@@ -671,6 +686,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
         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);
@@ -776,11 +792,14 @@ static int mgc_set_mgs_param(struct obd_export *exp,
                 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,
@@ -905,10 +924,13 @@ static int mgc_target_register(struct obd_export *exp,
                 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);
@@ -1004,6 +1026,49 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen,
                 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);
 }
@@ -1061,6 +1126,12 @@ static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
                         &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 {
@@ -1271,7 +1342,7 @@ int mgc_process_log(struct obd_device *mgc,
          */
         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) &&