}
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);
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;
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;
/* 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"). */
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);
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,
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);
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)
if (rc)
GOTO(out_closer, rc);
+ /* Copy remote log */
rc = llog_process(remote_llh, mgc_copy_handler,(void *)local_llh, NULL);
out_closer:
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);
}
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 "