Whamcloud - gitweb
Land b1_6_elc onto b1_6 (20070621_0218)
[fs/lustre-release.git] / lustre / mgc / mgc_request.c
index 2b6fa06..1d22aa1 100644 (file)
@@ -147,7 +147,7 @@ static struct config_llog_data *config_log_find(char *logname,
         }
         spin_unlock(&config_list_lock);
 
-        CERROR("can't get log %s\n", logid);
+        CDEBUG(D_CONFIG, "can't get log %s\n", logid);
         RETURN(ERR_PTR(-ENOENT));
 out_found:
         atomic_inc(&cld->cld_refcount);
@@ -308,7 +308,7 @@ static int mgc_requeue_add(struct config_llog_data *cld, int later)
         CDEBUG(D_INFO, "log %s: requeue (l=%d r=%d sp=%d st=%x)\n", 
                cld->cld_logname, later, atomic_read(&cld->cld_refcount),
                cld->cld_stopping, rq_state);
-
+        
         /* Hold lock for rq_state */
         spin_lock(&config_list_lock);
         cld->cld_lostlock = 1;
@@ -598,6 +598,9 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
                        struct lustre_handle *lockh)
 {                       
         struct config_llog_data *cld = (struct config_llog_data *)data;
+        struct ldlm_enqueue_info einfo = { type, mode, mgc_blocking_ast,
+                ldlm_completion_ast, NULL, data};
+
         int rc;
         ENTRY;
 
@@ -611,10 +614,8 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
         /* We need a callback for every lockholder, so don't try to
            ldlm_lock_match (see rev 1.1.2.11.2.47) */
 
-        rc = ldlm_cli_enqueue(exp, NULL, cld->cld_resid,
-                              type, NULL, mode, flags, 
-                              mgc_blocking_ast, ldlm_completion_ast, NULL,
-                              data, NULL, 0, NULL, lockh, 0);
+        rc = ldlm_cli_enqueue(exp, NULL, &einfo, cld->cld_resid,
+                              NULL, flags, NULL, 0, NULL, lockh, 0);
         /* A failed enqueue should still call the mgc_blocking_ast, 
            where it will be requeued if needed ("grant failed"). */ 
 
@@ -744,7 +745,9 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen,
         if (KEY_IS(KEY_INIT_RECOV)) {
                 if (vallen != sizeof(int))
                         RETURN(-EINVAL);
+                spin_lock(&imp->imp_lock);
                 imp->imp_initial_recov = *(int *)val;
+                spin_unlock(&imp->imp_lock);
                 CDEBUG(D_HA, "%s: set imp_initial_recov = %d\n",
                        exp->exp_obd->obd_name, imp->imp_initial_recov);
                 RETURN(0);
@@ -755,10 +758,12 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen,
                 if (vallen != sizeof(int))
                         RETURN(-EINVAL);
                 value = *(int *)val;
+                spin_lock(&imp->imp_lock);
                 imp->imp_initial_recov_bk = value > 0;
                 /* Even after the initial connection, give up all comms if 
                    nobody answers the first time. */
                 imp->imp_recon_bk = 1;
+                spin_unlock(&imp->imp_lock);
                 CDEBUG(D_MGC, "InitRecov %s %d/%d:d%d:i%d:r%d:or%d:%s\n", 
                        imp->imp_obd->obd_name, value, imp->imp_initial_recov,
                        imp->imp_deactive, imp->imp_invalid, 
@@ -914,35 +919,54 @@ static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
         int rc = 0;
         ENTRY;
 
-        lcfg = (struct lustre_cfg *)cfg_buf;
+        /* Append all records */
+        local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
+        rc = llog_write_rec(local_llh, &local_rec, NULL, 0, 
+                            (void *)cfg_buf, -1);
 
-        /* append new records */
-        if (rec->lrh_index >= llog_get_size(local_llh)) { 
-                rc = llog_write_rec(local_llh, &local_rec, NULL, 0, 
-                                    (void *)cfg_buf, -1);
-
-                CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", 
-                       rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, 
-                       lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
-        } else {
-                CDEBUG(D_INFO, "skip idx=%d\n",  rec->lrh_index);
-        }
+        lcfg = (struct lustre_cfg *)cfg_buf;
+        CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", 
+               rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, 
+               lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
 
         RETURN(rc);
 }
 
+/* Copy a remote log locally */
 static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt,
                          struct llog_ctxt *lctxt, char *logname)
 {
         struct llog_handle *local_llh, *remote_llh;
         struct obd_uuid *uuid;
+        char *temp_log;
         int rc, rc2;
         ENTRY;
 
+        /* Write new log to a temp name, then vfs_rename over logname
+           upon successful completion. */
+
+        OBD_ALLOC(temp_log, strlen(logname) + 1);
+        if (!temp_log) 
+                RETURN(-ENOMEM);
+        sprintf(temp_log, "%sT", logname);
+
+        /* Make sure there's no old temp log */
+        rc = llog_create(lctxt, &local_llh, NULL, temp_log);
+        if (rc)
+                GOTO(out, rc);
+        rc = llog_init_handle(local_llh, LLOG_F_IS_PLAIN, NULL);
+        if (rc) 
+                GOTO(out, rc);
+        rc = llog_destroy(local_llh);
+        llog_free_handle(local_llh);
+        if (rc)
+                GOTO(out, rc);
+
         /* open local log */
-        rc = llog_create(lctxt, &local_llh, NULL, logname);
+        rc = llog_create(lctxt, &local_llh, NULL, temp_log);
         if (rc)
-                RETURN(rc);
+                GOTO(out, rc);
+
         /* set the log header uuid for fun */
         OBD_ALLOC_PTR(uuid);
         obd_str2uuid(uuid, logname);
@@ -951,9 +975,6 @@ static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt,
         if (rc)
                 GOTO(out_closel, rc);
 
-        /* FIXME write new log to a temp name, then vfs_rename over logname
-           upon successful completion. */
-
         /* open remote log */
         rc = llog_create(rctxt, &remote_llh, NULL, logname);
         if (rc)
@@ -962,6 +983,7 @@ static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt,
         if (rc)
                 GOTO(out_closer, rc);
 
+        /* Copy remote log */
         rc = llog_process(remote_llh, mgc_copy_handler,(void *)local_llh, NULL);
 
 out_closer:
@@ -973,7 +995,19 @@ out_closel:
         if (!rc)
                 rc = rc2;
 
+        /* We've copied the remote log to the local temp log, now
+           replace the old local log with the temp log. */
+        if (!rc) {
+                struct client_obd *cli = &obd->u.cli;
+                LASSERT(cli);
+                LASSERT(cli->cl_mgc_configs_dir);
+                rc = lustre_rename(cli->cl_mgc_configs_dir, temp_log, logname);
+        }
         CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, rc);
+out:
+        if (rc)
+                CERROR("Failed to copy remote log %s (%d)\n", logname, rc);
+        OBD_FREE(temp_log, strlen(logname) + 1);
         RETURN(rc);
 }
 
@@ -1040,9 +1074,9 @@ static int mgc_process_log(struct obd_device *mgc,
                         rc = mgc_copy_llog(mgc, ctxt, lctxt, cld->cld_logname);
                 if (rcl || rc) {
                         if (mgc_llog_is_empty(mgc, lctxt, cld->cld_logname)) {
-                                LCONSOLE_ERROR("Failed to get MGS log %s "
-                                               "and no local copy.\n",
-                                               cld->cld_logname);
+                                LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS "
+                                                   "log %s and no local copy."
+                                                   "\n", cld->cld_logname);
                                 GOTO(out_pop, rc = -ENOTCONN);
                         }
                         LCONSOLE_WARN("Failed to get MGS log %s, using "