Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa4e3c8a authored by Mikhail Pershin's avatar Mikhail Pershin Committed by Greg Kroah-Hartman
Browse files

staging/lustre/llog: MGC to use OSD API for backup logs

MGC uses lvfs API to access local llogs blocking removal of old code

- llog_is_empty() and llog_backup() are introduced

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2059
Lustre-change: http://review.whamcloud.com/5049


Cc: Levente Kurusa <levex@linux.com>
Signed-off-by: default avatarMikhail Pershin <mike.pershin@intel.com>
Reviewed-by: default avatarLai Siyao <lai.siyao@intel.com>
Reviewed-by: default avatarAlex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
[pick client side change only -- Peng Tao]
Signed-off-by: default avatarPeng Tao <bergwolf@gmail.com>
Signed-off-by: default avatarAndreas Dilger <andreas.dilger@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8cc93bc3
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -136,7 +136,11 @@ int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
	      struct llog_handle **lgh, struct llog_logid *logid,
	      struct llog_handle **lgh, struct llog_logid *logid,
	      char *name, enum llog_open_param open_param);
	      char *name, enum llog_open_param open_param);
int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
int llog_get_size(struct llog_handle *loghandle);
int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
		  char *name);
int llog_backup(const struct lu_env *env, struct obd_device *obd,
		struct llog_ctxt *ctxt, struct llog_ctxt *bak_ctxt,
		char *name, char *backup);


/* llog_process flags */
/* llog_process flags */
#define LLOG_FLAG_NODEAMON 0x0001
#define LLOG_FLAG_NODEAMON 0x0001
@@ -382,6 +386,13 @@ static inline int llog_data_len(int len)
	return cfs_size_round(len);
	return cfs_size_round(len);
}
}


static inline int llog_get_size(struct llog_handle *loghandle)
{
	if (loghandle && loghandle->lgh_hdr)
		return loghandle->lgh_hdr->llh_count;
	return 0;
}

static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
{
{
	atomic_inc(&ctxt->loc_refcount);
	atomic_inc(&ctxt->loc_refcount);
+2 −2
Original line number Original line Diff line number Diff line
@@ -399,8 +399,8 @@ struct client_obd {


	/* mgc datastruct */
	/* mgc datastruct */
	struct semaphore	 cl_mgc_sem;
	struct semaphore	 cl_mgc_sem;
	struct vfsmount	 *cl_mgc_vfsmnt;
	struct local_oid_storage *cl_mgc_los;
	struct dentry	   *cl_mgc_configs_dir;
	struct dt_object	*cl_mgc_configs_dir;
	atomic_t	     cl_mgc_refcount;
	atomic_t	     cl_mgc_refcount;
	struct obd_export       *cl_mgc_mgsexp;
	struct obd_export       *cl_mgc_mgsexp;


+0 −3
Original line number Original line Diff line number Diff line
@@ -99,11 +99,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)


static int mgc_cleanup(struct obd_device *obd)
static int mgc_cleanup(struct obd_device *obd)
{
{
	struct client_obd *cli = &obd->u.cli;
	int rc;
	int rc;


	LASSERT(cli->cl_mgc_vfsmnt == NULL);

	ptlrpcd_decref();
	ptlrpcd_decref();


	rc = client_obd_cleanup(obd);
	rc = client_obd_cleanup(obd);
+245 −149
Original line number Original line Diff line number Diff line
@@ -42,16 +42,13 @@
#define D_MGC D_CONFIG /*|D_WARNING*/
#define D_MGC D_CONFIG /*|D_WARNING*/


#include <linux/module.h>
#include <linux/module.h>
# include <linux/pagemap.h>
# include <linux/miscdevice.h>
# include <linux/init.h>

#include <obd_class.h>
#include <obd_class.h>
#include <lustre_dlm.h>
#include <lustre_dlm.h>
#include <lprocfs_status.h>
#include <lprocfs_status.h>
#include <lustre_log.h>
#include <lustre_log.h>
#include <lustre_fsfilt.h>
#include <lustre_disk.h>
#include <lustre_disk.h>
#include <dt_object.h>

#include "mgc_internal.h"
#include "mgc_internal.h"


static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
@@ -578,97 +575,175 @@ static void mgc_requeue_add(struct config_llog_data *cld)
}
}


/********************** class fns **********************/
/********************** class fns **********************/
static int mgc_local_llog_init(const struct lu_env *env,
			       struct obd_device *obd,
			       struct obd_device *disk)
{
	struct llog_ctxt	*ctxt;
	int			 rc;


static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb,
	rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk,
			struct vfsmount *mnt)
			&llog_osd_ops);
	if (rc)
		return rc;

	ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
	LASSERT(ctxt);
	ctxt->loc_dir = obd->u.cli.cl_mgc_configs_dir;
	llog_ctxt_put(ctxt);

	return 0;
}

static int mgc_local_llog_fini(const struct lu_env *env,
			       struct obd_device *obd)
{
	struct llog_ctxt *ctxt;

	ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
	llog_cleanup(env, ctxt);

	return 0;
}

static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb)
{
{
	struct lvfs_run_ctxt saved;
	struct lustre_sb_info	*lsi = s2lsi(sb);
	struct lustre_sb_info	*lsi = s2lsi(sb);
	struct client_obd	*cli = &obd->u.cli;
	struct client_obd	*cli = &obd->u.cli;
	struct dentry *dentry;
	struct lu_fid		 rfid, fid;
	char *label;
	struct dt_object	*root, *dto;
	int err = 0;
	struct lu_env		*env;
	int			 rc = 0;


	LASSERT(lsi);
	LASSERT(lsi);
	LASSERT(lsi->lsi_srv_mnt == mnt);
	LASSERT(lsi->lsi_dt_dev);

	OBD_ALLOC_PTR(env);
	if (env == NULL)
		return -ENOMEM;


	/* The mgc fs exclusion sem. Only one fs can be setup at a time. */
	/* The mgc fs exclusion sem. Only one fs can be setup at a time. */
	down(&cli->cl_mgc_sem);
	down(&cli->cl_mgc_sem);


	cfs_cleanup_group_info();
	cfs_cleanup_group_info();


	obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype);
	/* Setup the configs dir */
	if (IS_ERR(obd->obd_fsops)) {
	rc = lu_env_init(env, LCT_MG_THREAD);
		up(&cli->cl_mgc_sem);
	if (rc)
		CERROR("%s: No fstype %s: rc = %ld\n", lsi->lsi_fstype,
		GOTO(out_err, rc);
		       obd->obd_name, PTR_ERR(obd->obd_fsops));
		return PTR_ERR(obd->obd_fsops);
	}


	cli->cl_mgc_vfsmnt = mnt;
	fid.f_seq = FID_SEQ_LOCAL_NAME;
	err = fsfilt_setup(obd, mnt->mnt_sb);
	fid.f_oid = 1;
	if (err)
	fid.f_ver = 0;
		GOTO(err_ops, err);
	rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid,
				    &cli->cl_mgc_los);
	if (rc)
		GOTO(out_env, rc);


	OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
	rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid);
	obd->obd_lvfs_ctxt.pwdmnt = mnt;
	if (rc)
	obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
		GOTO(out_env, rc);
	obd->obd_lvfs_ctxt.fs = get_ds();


	push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
	root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid,
	dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
			    &cli->cl_mgc_los->los_dev->dd_lu_dev);
				   strlen(MOUNT_CONFIGS_DIR));
	if (unlikely(IS_ERR(root)))
	pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
		GOTO(out_los, rc = PTR_ERR(root));
	if (IS_ERR(dentry)) {

		err = PTR_ERR(dentry);
	dto = local_file_find_or_create(env, cli->cl_mgc_los, root,
		CERROR("cannot lookup %s directory: rc = %d\n",
					MOUNT_CONFIGS_DIR,
		       MOUNT_CONFIGS_DIR, err);
					S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
		GOTO(err_ops, err);
	lu_object_put_nocache(env, &root->do_lu);
	}
	if (IS_ERR(dto))
	cli->cl_mgc_configs_dir = dentry;
		GOTO(out_los, rc = PTR_ERR(dto));

	cli->cl_mgc_configs_dir = dto;

	LASSERT(lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt);
	rc = mgc_local_llog_init(env, obd, lsi->lsi_osd_exp->exp_obd);
	if (rc)
		GOTO(out_llog, rc);


	/* We take an obd ref to insure that we can't get to mgc_cleanup
	/* We take an obd ref to insure that we can't get to mgc_cleanup
	   without calling mgc_fs_cleanup first. */
	 * without calling mgc_fs_cleanup first. */
	class_incref(obd, "mgc_fs", obd);
	class_incref(obd, "mgc_fs", obd);


	label = fsfilt_get_label(obd, mnt->mnt_sb);
	if (label)
		CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label);

	/* We keep the cl_mgc_sem until mgc_fs_cleanup */
	/* We keep the cl_mgc_sem until mgc_fs_cleanup */
	return 0;
out_llog:

	if (rc) {
err_ops:
		lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu);
	fsfilt_put_ops(obd->obd_fsops);
		cli->cl_mgc_configs_dir = NULL;
	obd->obd_fsops = NULL;
	}
	cli->cl_mgc_vfsmnt = NULL;
out_los:
	if (rc < 0) {
		local_oid_storage_fini(env, cli->cl_mgc_los);
		cli->cl_mgc_los = NULL;
		up(&cli->cl_mgc_sem);
		up(&cli->cl_mgc_sem);
	return err;
	}
out_env:
	lu_env_fini(env);
out_err:
	OBD_FREE_PTR(env);
	return rc;
}
}


static int mgc_fs_cleanup(struct obd_device *obd)
static int mgc_fs_cleanup(struct obd_device *obd)
{
{
	struct lu_env		 env;
	struct client_obd	*cli = &obd->u.cli;
	struct client_obd	*cli = &obd->u.cli;
	int rc = 0;
	int			 rc;


	LASSERT(cli->cl_mgc_vfsmnt != NULL);
	LASSERT(cli->cl_mgc_los != NULL);


	if (cli->cl_mgc_configs_dir != NULL) {
	rc = lu_env_init(&env, LCT_MG_THREAD);
		struct lvfs_run_ctxt saved;
	if (rc)
		push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
		GOTO(unlock, rc);
		l_dput(cli->cl_mgc_configs_dir);

	mgc_local_llog_fini(&env, obd);

	lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu);
	cli->cl_mgc_configs_dir = NULL;
	cli->cl_mgc_configs_dir = NULL;
		pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
		class_decref(obd, "mgc_fs", obd);
	}


	cli->cl_mgc_vfsmnt = NULL;
	local_oid_storage_fini(&env, cli->cl_mgc_los);
	if (obd->obd_fsops)
	cli->cl_mgc_los = NULL;
		fsfilt_put_ops(obd->obd_fsops);
	lu_env_fini(&env);


unlock:
	class_decref(obd, "mgc_fs", obd);
	up(&cli->cl_mgc_sem);
	up(&cli->cl_mgc_sem);


	return 0;
}

static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd)
{
	struct llog_ctxt	*ctxt;
	int			 rc;

	/* setup only remote ctxt, the local disk context is switched per each
	 * filesystem during mgc_fs_setup() */
	rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_REPL_CTXT, obd,
			&llog_client_ops);
	if (rc)
		return rc;
		return rc;

	ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
	LASSERT(ctxt);

	llog_initiator_connect(ctxt);
	llog_ctxt_put(ctxt);

	return 0;
}

static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd)
{
	struct llog_ctxt *ctxt;

	ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
	if (ctxt)
		llog_cleanup(env, ctxt);

	return 0;
}
}


static atomic_t mgc_count = ATOMIC_INIT(0);
static atomic_t mgc_count = ATOMIC_INIT(0);
@@ -694,7 +769,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
			}
			}
		}
		}
		obd_cleanup_client_import(obd);
		obd_cleanup_client_import(obd);
		rc = obd_llog_finish(obd, 0);
		rc = mgc_llog_fini(NULL, obd);
		if (rc != 0)
		if (rc != 0)
			CERROR("failed to cleanup llogging subsystems\n");
			CERROR("failed to cleanup llogging subsystems\n");
		break;
		break;
@@ -704,11 +779,8 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)


static int mgc_cleanup(struct obd_device *obd)
static int mgc_cleanup(struct obd_device *obd)
{
{
	struct client_obd *cli = &obd->u.cli;
	int rc;
	int rc;


	LASSERT(cli->cl_mgc_vfsmnt == NULL);

	/* COMPAT_146 - old config logs may have added profiles we don't
	/* COMPAT_146 - old config logs may have added profiles we don't
	   know about */
	   know about */
	if (obd->obd_type->typ_refcnt <= 1)
	if (obd->obd_type->typ_refcnt <= 1)
@@ -733,7 +805,7 @@ static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
	if (rc)
	if (rc)
		GOTO(err_decref, rc);
		GOTO(err_decref, rc);


	rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL);
	rc = mgc_llog_init(NULL, obd);
	if (rc) {
	if (rc) {
		CERROR("failed to setup llogging subsystems\n");
		CERROR("failed to setup llogging subsystems\n");
		GOTO(err_cleanup, rc);
		GOTO(err_cleanup, rc);
@@ -1011,11 +1083,11 @@ int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
	}
	}
	if (KEY_IS(KEY_SET_FS)) {
	if (KEY_IS(KEY_SET_FS)) {
		struct super_block *sb = (struct super_block *)val;
		struct super_block *sb = (struct super_block *)val;
		struct lustre_sb_info *lsi;

		if (vallen != sizeof(struct super_block))
		if (vallen != sizeof(struct super_block))
			return -EINVAL;
			return -EINVAL;
		lsi = s2lsi(sb);

		rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt);
		rc = mgc_fs_setup(exp->exp_obd, sb);
		if (rc) {
		if (rc) {
			CERROR("set_fs got %d\n", rc);
			CERROR("set_fs got %d\n", rc);
		}
		}
@@ -1145,49 +1217,6 @@ static int mgc_import_event(struct obd_device *obd,
	return rc;
	return rc;
}
}


static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
			 struct obd_device *tgt, int *index)
{
	struct llog_ctxt *ctxt;
	int rc;

	LASSERT(olg == &obd->obd_olg);


	rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_REPL_CTXT, tgt,
			&llog_client_ops);
	if (rc)
		GOTO(out, rc);

	ctxt = llog_group_get_ctxt(olg, LLOG_CONFIG_REPL_CTXT);
	if (!ctxt)
		GOTO(out, rc = -ENODEV);

	llog_initiator_connect(ctxt);
	llog_ctxt_put(ctxt);

	return 0;
out:
	ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
	if (ctxt)
		llog_cleanup(NULL, ctxt);
	return rc;
}

static int mgc_llog_finish(struct obd_device *obd, int count)
{
	struct llog_ctxt *ctxt;

	ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
	if (ctxt)
		llog_cleanup(NULL, ctxt);

	ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
	if (ctxt)
		llog_cleanup(NULL, ctxt);
	return 0;
}

enum {
enum {
	CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT),
	CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT),
	CONFIG_READ_NRPAGES      = 4
	CONFIG_READ_NRPAGES      = 4
@@ -1540,17 +1569,58 @@ static int mgc_process_recover_log(struct obd_device *obd,
	return rc;
	return rc;
}
}


static int mgc_llog_local_copy(const struct lu_env *env,
			       struct obd_device *obd,
			       struct llog_ctxt *rctxt,
			       struct llog_ctxt *lctxt, char *logname)
{
	char	*temp_log;
	int	 rc;



	/*
	 * - copy it to backup using llog_backup()
	 * - copy remote llog to logname using llog_backup()
	 * - if failed then move bakup to logname again
	 */

	OBD_ALLOC(temp_log, strlen(logname) + 1);
	if (!temp_log)
		return -ENOMEM;
	sprintf(temp_log, "%sT", logname);

	/* make a copy of local llog at first */
	rc = llog_backup(env, obd, lctxt, lctxt, logname, temp_log);
	if (rc < 0 && rc != -ENOENT)
		GOTO(out, rc);
	/* copy remote llog to the local copy */
	rc = llog_backup(env, obd, rctxt, lctxt, logname, logname);
	if (rc == -ENOENT) {
		/* no remote llog, delete local one too */
		llog_erase(env, lctxt, NULL, logname);
	} else if (rc < 0) {
		/* error during backup, get local one back from the copy */
		llog_backup(env, obd, lctxt, lctxt, temp_log, logname);
out:
		CERROR("%s: failed to copy remote log %s: rc = %d\n",
		       obd->obd_name, logname, rc);
	}
	llog_erase(env, lctxt, NULL, temp_log);
	OBD_FREE(temp_log, strlen(logname) + 1);
	return rc;
}


/* local_only means it cannot get remote llogs */
/* local_only means it cannot get remote llogs */
static int mgc_process_cfg_log(struct obd_device *mgc,
static int mgc_process_cfg_log(struct obd_device *mgc,
			       struct config_llog_data *cld,
			       struct config_llog_data *cld, int local_only)
			       int local_only)
{
{
	struct llog_ctxt	*ctxt, *lctxt = NULL;
	struct llog_ctxt	*ctxt, *lctxt = NULL;
	struct lvfs_run_ctxt *saved_ctxt;
	struct dt_object        *cl_mgc_dir = mgc->u.cli.cl_mgc_configs_dir;
	struct lustre_sb_info	*lsi = NULL;
	struct lustre_sb_info	*lsi = NULL;
	int rc = 0, must_pop = 0;
	int			 rc = 0;
	bool			 sptlrpc_started = false;
	bool			 sptlrpc_started = false;
	struct lu_env		*env;


	LASSERT(cld);
	LASSERT(cld);
	LASSERT(mutex_is_locked(&cld->cld_lock));
	LASSERT(mutex_is_locked(&cld->cld_lock));
@@ -1565,19 +1635,47 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
	if (cld->cld_cfg.cfg_sb)
	if (cld->cld_cfg.cfg_sb)
		lsi = s2lsi(cld->cld_cfg.cfg_sb);
		lsi = s2lsi(cld->cld_cfg.cfg_sb);


	ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
	OBD_ALLOC_PTR(env);
	if (!ctxt) {
	if (env == NULL)
		CERROR("missing llog context\n");
		return -EINVAL;
	}

	OBD_ALLOC_PTR(saved_ctxt);
	if (saved_ctxt == NULL)
		return -ENOMEM;
		return -ENOMEM;


	rc = lu_env_init(env, LCT_MG_THREAD);
	if (rc)
		GOTO(out_free, rc);

	ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
	LASSERT(ctxt);

	lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
	lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);


		if (local_only) { /* no local log at client side */
	/* 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 && IS_SERVER(lsi) && !IS_MGS(lsi) &&
	    cl_mgc_dir != NULL &&
	    lu2dt_dev(cl_mgc_dir->do_lu.lo_dev) == lsi->lsi_dt_dev) {
		if (!local_only)
			/* Only try to copy log if we have the lock. */
			rc = mgc_llog_local_copy(env, mgc, ctxt, lctxt,
						 cld->cld_logname);
		if (local_only || rc) {
			if (llog_is_empty(env, lctxt, 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);
			}
			CDEBUG(D_MGC,
			       "Failed to get MGS log %s, using local copy for now, will try to update later.\n",
			       cld->cld_logname);
		}
		/* Now, whether we copied or not, start using the local llog.
		 * If we failed to copy, we'll start using whatever the old
		 * log has. */
		llog_ctxt_put(ctxt);
		ctxt = lctxt;
		lctxt = NULL;
	} else {
		if (local_only) /* no local log at client side */
			GOTO(out_pop, rc = -EIO);
			GOTO(out_pop, rc = -EIO);
	}
	}


@@ -1587,19 +1685,16 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
	}
	}


	/* logname and instance info should be the same, so use our
	/* logname and instance info should be the same, so use our
	   copy of the instance for the update.  The cfg_last_idx will
	 * copy of the instance for the update.  The cfg_last_idx will
	   be updated here. */
	 * be updated here. */
	rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname,
	rc = class_config_parse_llog(env, ctxt, cld->cld_logname,
				     &cld->cld_cfg);
				     &cld->cld_cfg);


out_pop:
out_pop:
	llog_ctxt_put(ctxt);
	__llog_ctxt_put(env, ctxt);
	if (lctxt)
	if (lctxt)
		llog_ctxt_put(lctxt);
		__llog_ctxt_put(env, lctxt);
	if (must_pop)
		pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);


	OBD_FREE_PTR(saved_ctxt);
	/*
	/*
	 * update settings on existing OBDs. doing it inside
	 * update settings on existing OBDs. doing it inside
	 * of llog_process_lock so no device is attaching/detaching
	 * of llog_process_lock so no device is attaching/detaching
@@ -1614,6 +1709,9 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
					  strlen("-sptlrpc"));
					  strlen("-sptlrpc"));
	}
	}


	lu_env_fini(env);
out_free:
	OBD_FREE_PTR(env);
	return rc;
	return rc;
}
}


@@ -1801,8 +1899,6 @@ struct obd_ops mgc_obd_ops = {
	.o_set_info_async = mgc_set_info_async,
	.o_set_info_async = mgc_set_info_async,
	.o_get_info       = mgc_get_info,
	.o_get_info       = mgc_get_info,
	.o_import_event = mgc_import_event,
	.o_import_event = mgc_import_event,
	.o_llog_init    = mgc_llog_init,
	.o_llog_finish  = mgc_llog_finish,
	.o_process_config = mgc_process_config,
	.o_process_config = mgc_process_config,
};
};


+134 −78
Original line number Original line Diff line number Diff line
@@ -265,31 +265,6 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
}
}
EXPORT_SYMBOL(llog_init_handle);
EXPORT_SYMBOL(llog_init_handle);


int llog_copy_handler(const struct lu_env *env,
		      struct llog_handle *llh,
		      struct llog_rec_hdr *rec,
		      void *data)
{
	struct llog_rec_hdr local_rec = *rec;
	struct llog_handle *local_llh = (struct llog_handle *)data;
	char *cfg_buf = (char*) (rec + 1);
	struct lustre_cfg *lcfg;
	int rc = 0;

	/* Append all records */
	local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
	rc = llog_write(env, local_llh, &local_rec, NULL, 0,
			(void *)cfg_buf, -1);

	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;
}
EXPORT_SYMBOL(llog_copy_handler);

static int llog_process_thread(void *arg)
static int llog_process_thread(void *arg)
{
{
	struct llog_process_info	*lpi = arg;
	struct llog_process_info	*lpi = arg;
@@ -493,14 +468,6 @@ int llog_process(const struct lu_env *env, struct llog_handle *loghandle,
}
}
EXPORT_SYMBOL(llog_process);
EXPORT_SYMBOL(llog_process);


inline int llog_get_size(struct llog_handle *loghandle)
{
	if (loghandle && loghandle->lgh_hdr)
		return loghandle->lgh_hdr->llh_count;
	return 0;
}
EXPORT_SYMBOL(llog_get_size);

int llog_reverse_process(const struct lu_env *env,
int llog_reverse_process(const struct lu_env *env,
			 struct llog_handle *loghandle, llog_cb_t cb,
			 struct llog_handle *loghandle, llog_cb_t cb,
			 void *data, void *catdata)
			 void *data, void *catdata)
@@ -767,6 +734,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
		     struct llog_handle **res, struct llog_logid *logid,
		     struct llog_handle **res, struct llog_logid *logid,
		     char *name)
		     char *name)
{
{
	struct dt_device	*d;
	struct thandle		*th;
	struct thandle		*th;
	int			 rc;
	int			 rc;


@@ -777,8 +745,7 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
	if (llog_exist(*res))
	if (llog_exist(*res))
		return 0;
		return 0;


	if ((*res)->lgh_obj != NULL) {
	LASSERT((*res)->lgh_obj != NULL);
		struct dt_device *d;


	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);
	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);


@@ -793,11 +760,6 @@ int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
			rc = llog_create(env, *res, th);
			rc = llog_create(env, *res, th);
	}
	}
	dt_trans_stop(env, d, th);
	dt_trans_stop(env, d, th);
	} else {
		/* lvfs compat code */
		LASSERT((*res)->lgh_file == NULL);
		rc = llog_create(env, *res, NULL);
	}
out:
out:
	if (rc)
	if (rc)
		llog_close(env, *res);
		llog_close(env, *res);
@@ -842,14 +804,13 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
	       struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
	       struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
	       int cookiecount, void *buf, int idx)
	       int cookiecount, void *buf, int idx)
{
{
	struct dt_device	*dt;
	struct thandle		*th;
	int			 rc;
	int			 rc;


	LASSERT(loghandle);
	LASSERT(loghandle);
	LASSERT(loghandle->lgh_ctxt);
	LASSERT(loghandle->lgh_ctxt);

	LASSERT(loghandle->lgh_obj != NULL);
	if (loghandle->lgh_obj != NULL) {
		struct dt_device	*dt;
		struct thandle		*th;


	dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);
	dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);


@@ -871,12 +832,6 @@ int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
	up_write(&loghandle->lgh_lock);
	up_write(&loghandle->lgh_lock);
out_trans:
out_trans:
	dt_trans_stop(env, dt, th);
	dt_trans_stop(env, dt, th);
	} else { /* lvfs compatibility */
		down_write(&loghandle->lgh_lock);
		rc = llog_write_rec(env, loghandle, rec, reccookie,
				    cookiecount, buf, idx, NULL);
		up_write(&loghandle->lgh_lock);
	}
	return rc;
	return rc;
}
}
EXPORT_SYMBOL(llog_write);
EXPORT_SYMBOL(llog_write);
@@ -932,3 +887,104 @@ int llog_close(const struct lu_env *env, struct llog_handle *loghandle)
	return rc;
	return rc;
}
}
EXPORT_SYMBOL(llog_close);
EXPORT_SYMBOL(llog_close);

int llog_is_empty(const struct lu_env *env, struct llog_ctxt *ctxt,
		  char *name)
{
	struct llog_handle	*llh;
	int			 rc = 0;

	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc < 0) {
		if (likely(rc == -ENOENT))
			rc = 0;
		GOTO(out, rc);
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_close, rc);
	rc = llog_get_size(llh);

out_close:
	llog_close(env, llh);
out:
	/* header is record 1 */
	return rc <= 1;
}
EXPORT_SYMBOL(llog_is_empty);

int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh,
		      struct llog_rec_hdr *rec, void *data)
{
	struct llog_handle	*copy_llh = data;

	/* Append all records */
	return llog_write(env, copy_llh, rec, NULL, 0, NULL, -1);
}
EXPORT_SYMBOL(llog_copy_handler);

/* backup plain llog */
int llog_backup(const struct lu_env *env, struct obd_device *obd,
		struct llog_ctxt *ctxt, struct llog_ctxt *bctxt,
		char *name, char *backup)
{
	struct llog_handle	*llh, *bllh;
	int			 rc;



	/* open original log */
	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc < 0) {
		/* the -ENOENT case is also reported to the caller
		 * but silently so it should handle that if needed.
		 */
		if (rc != -ENOENT)
			CERROR("%s: failed to open log %s: rc = %d\n",
			       obd->obd_name, name, rc);
		return rc;
	}

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_close, rc);

	/* Make sure there's no old backup log */
	rc = llog_erase(env, bctxt, NULL, backup);
	if (rc < 0 && rc != -ENOENT)
		GOTO(out_close, rc);

	/* open backup log */
	rc = llog_open_create(env, bctxt, &bllh, NULL, backup);
	if (rc) {
		CERROR("%s: failed to open backup logfile %s: rc = %d\n",
		       obd->obd_name, backup, rc);
		GOTO(out_close, rc);
	}

	/* check that backup llog is not the same object as original one */
	if (llh->lgh_obj == bllh->lgh_obj) {
		CERROR("%s: backup llog %s to itself (%s), objects %p/%p\n",
		       obd->obd_name, name, backup, llh->lgh_obj,
		       bllh->lgh_obj);
		GOTO(out_backup, rc = -EEXIST);
	}

	rc = llog_init_handle(env, bllh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		GOTO(out_backup, rc);

	/* Copy log record by record */
	rc = llog_process_or_fork(env, llh, llog_copy_handler, (void *)bllh,
				  NULL, false);
	if (rc)
		CERROR("%s: failed to backup log %s: rc = %d\n",
		       obd->obd_name, name, rc);
out_backup:
	llog_close(env, bllh);
out_close:
	llog_close(env, llh);
	return rc;
}
EXPORT_SYMBOL(llog_backup);
Loading