LASSERT_REQSWAB(req, REQ_REC_OFF);
str = lustre_msg_string(req->rq_reqmsg, REQ_REC_OFF, sizeof(tgtuuid)-1);
if (str == NULL) {
- DEBUG_REQ(D_ERROR, req, "bad target UUID for connect");
+ DEBUG_REQ(D_ERROR, req, "bad target UUID for connect\n");
GOTO(out, rc = -EINVAL);
}
if (!target || target->obd_stopping || !target->obd_set_up) {
LCONSOLE_ERROR("UUID '%s' is not available "
- " for connect (%s)", str,
+ " for connect (%s)\n", str,
!target ? "no target" :
(target->obd_stopping ? "stopping" :
"not set up"));
str = lustre_msg_string(req->rq_reqmsg, REQ_REC_OFF + 1,
sizeof(cluuid) - 1);
if (str == NULL) {
- DEBUG_REQ(D_ERROR, req, "bad client UUID for connect");
+ DEBUG_REQ(D_ERROR, req, "bad client UUID for connect\n");
GOTO(out, rc = -EINVAL);
}
}
EXPORT_SYMBOL(simple_mkdir);
+/* utility to rename a file */
+int lustre_rename(struct dentry *dir, char *oldname, char *newname)
+{
+ struct dentry *dchild_old, *dchild_new;
+ int err = 0;
+ ENTRY;
+
+ ASSERT_KERNEL_CTXT("kernel doing rename outside kernel context\n");
+ CDEBUG(D_INODE, "renaming file %.*s to %.*s\n",
+ (int)strlen(oldname), oldname, (int)strlen(newname), newname);
+
+ dchild_old = ll_lookup_one_len(oldname, dir, strlen(oldname));
+ if (IS_ERR(dchild_old))
+ RETURN(PTR_ERR(dchild_old));
+
+ if (!dchild_old->d_inode)
+ GOTO(put_old, err = -ENOENT);
+
+ dchild_new = ll_lookup_one_len(newname, dir, strlen(newname));
+ if (IS_ERR(dchild_new))
+ GOTO(put_old, err = PTR_ERR(dchild_new));
+
+ err = vfs_rename(dir->d_inode, dchild_old, dir->d_inode, dchild_new);
+
+ dput(dchild_new);
+put_old:
+ dput(dchild_old);
+ RETURN(err);
+}
+EXPORT_SYMBOL(lustre_rename);
+
/*
* Read a file from within kernel context. Prior to calling this
* function we should already have done a push_ctxt().
int rc = 0;
ENTRY;
- lcfg = (struct lustre_cfg *)cfg_buf;
-
- /* 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);
+ /* 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);
- 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);
}