* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, Whamcloud, Inc.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define DEBUG_SUBSYSTEM S_MGC
#define D_MGC D_CONFIG /*|D_WARNING*/
-#ifdef __KERNEL__
-# include <linux/module.h>
-# include <linux/pagemap.h>
-# include <linux/miscdevice.h>
-# include <linux/init.h>
-#else
-# include <liblustre.h>
-#endif
-
+#include <linux/module.h>
#include <obd_class.h>
#include <lustre_dlm.h>
#include <lprocfs_status.h>
#include <lustre_log.h>
-#include <lustre_fsfilt.h>
#include <lustre_disk.h>
+#include <dt_object.h>
+
#include "mgc_internal.h"
static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
{
__u64 resname = 0;
- if (len > 8) {
+ if (len > sizeof(resname)) {
CERROR("name too long: %s\n", name);
return -EINVAL;
}
case CONFIG_T_SPTLRPC:
resname = 0;
break;
- case CONFIG_T_RECOVER:
+ case CONFIG_T_RECOVER:
+ case CONFIG_T_PARAMS:
resname = type;
break;
default:
}
EXPORT_SYMBOL(mgc_fsname2resid);
-int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id, int type)
+static int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id,
+ int type)
{
- char *name_end;
- int len;
-
- /* logname consists of "fsname-nodetype".
- * e.g. "lustre-MDT0001", "SUN-000-client" */
- name_end = strrchr(logname, '-');
- LASSERT(name_end);
- len = name_end - logname;
- return mgc_name2resid(logname, len, res_id, type);
+ char *name_end;
+ int len;
+
+ /* logname consists of "fsname-nodetype".
+ * e.g. "lustre-MDT0001", "SUN-000-client"
+ * there is an exception: llog "params" */
+ name_end = strrchr(logname, '-');
+ if (!name_end)
+ len = strlen(logname);
+ else
+ len = name_end - logname;
+ return mgc_name2resid(logname, len, res_id, type);
}
/********************** config llog list **********************/
-static CFS_LIST_HEAD(config_llog_list);
+static struct list_head config_llog_list = LIST_HEAD_INIT(config_llog_list);
static DEFINE_SPINLOCK(config_list_lock);
/* Take a reference to a config log */
static int config_log_get(struct config_llog_data *cld)
{
- ENTRY;
- cfs_atomic_inc(&cld->cld_refcount);
- CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
- cfs_atomic_read(&cld->cld_refcount));
- RETURN(0);
+ ENTRY;
+ atomic_inc(&cld->cld_refcount);
+ CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
+ atomic_read(&cld->cld_refcount));
+ RETURN(0);
}
/* Drop a reference to a config log. When no longer referenced,
we can free the config log data */
static void config_log_put(struct config_llog_data *cld)
{
- ENTRY;
+ ENTRY;
- CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
- cfs_atomic_read(&cld->cld_refcount));
- LASSERT(cfs_atomic_read(&cld->cld_refcount) > 0);
+ CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
+ atomic_read(&cld->cld_refcount));
+ LASSERT(atomic_read(&cld->cld_refcount) > 0);
- /* spinlock to make sure no item with 0 refcount in the list */
- if (cfs_atomic_dec_and_lock(&cld->cld_refcount, &config_list_lock)) {
- cfs_list_del(&cld->cld_list_chain);
- cfs_spin_unlock(&config_list_lock);
+ /* spinlock to make sure no item with 0 refcount in the list */
+ if (atomic_dec_and_lock(&cld->cld_refcount, &config_list_lock)) {
+ list_del(&cld->cld_list_chain);
+ spin_unlock(&config_list_lock);
CDEBUG(D_MGC, "dropping config log %s\n", cld->cld_logname);
config_log_put(cld->cld_recover);
if (cld->cld_sptlrpc)
config_log_put(cld->cld_sptlrpc);
+ if (cld->cld_params)
+ config_log_put(cld->cld_params);
if (cld_is_sptlrpc(cld))
sptlrpc_conf_log_stop(cld->cld_logname);
LASSERT(logname != NULL);
instance = cfg ? cfg->cfg_instance : NULL;
- cfs_spin_lock(&config_list_lock);
- cfs_list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
+ spin_lock(&config_list_lock);
+ list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
/* check if instance equals */
if (instance != cld->cld_cfg.cfg_instance)
continue;
- /* instance may be NULL, should check name */
- if (strcmp(logname, cld->cld_logname) == 0) {
- found = cld;
- break;
- }
- }
- if (found) {
- cfs_atomic_inc(&found->cld_refcount);
- LASSERT(found->cld_stopping == 0 || cld_is_sptlrpc(found) == 0);
- }
- cfs_spin_unlock(&config_list_lock);
- RETURN(found);
+ /* instance may be NULL, should check name */
+ if (strcmp(logname, cld->cld_logname) == 0) {
+ found = cld;
+ break;
+ }
+ }
+ if (found) {
+ atomic_inc(&found->cld_refcount);
+ LASSERT(found->cld_stopping == 0 || cld_is_sptlrpc(found) == 0);
+ }
+ spin_unlock(&config_list_lock);
+ RETURN(found);
}
static
if (!cld)
RETURN(ERR_PTR(-ENOMEM));
- strcpy(cld->cld_logname, logname);
- if (cfg)
- cld->cld_cfg = *cfg;
+ strcpy(cld->cld_logname, logname);
+ if (cfg)
+ cld->cld_cfg = *cfg;
else
cld->cld_cfg.cfg_callback = class_config_llog_handler;
- cfs_mutex_init(&cld->cld_lock);
- cld->cld_cfg.cfg_last_idx = 0;
- cld->cld_cfg.cfg_flags = 0;
- cld->cld_cfg.cfg_sb = sb;
- cld->cld_type = type;
- cfs_atomic_set(&cld->cld_refcount, 1);
+ mutex_init(&cld->cld_lock);
+ cld->cld_cfg.cfg_last_idx = 0;
+ cld->cld_cfg.cfg_flags = 0;
+ cld->cld_cfg.cfg_sb = sb;
+ cld->cld_type = type;
+ atomic_set(&cld->cld_refcount, 1);
/* Keep the mgc around until we are done */
cld->cld_mgcexp = class_export_get(obd->obd_self_export);
rc = mgc_logname2resid(logname, &cld->cld_resid, type);
- cfs_spin_lock(&config_list_lock);
- cfs_list_add(&cld->cld_list_chain, &config_llog_list);
- cfs_spin_unlock(&config_list_lock);
+ spin_lock(&config_list_lock);
+ list_add(&cld->cld_list_chain, &config_llog_list);
+ spin_unlock(&config_list_lock);
if (rc) {
config_log_put(cld);
if (cld_is_sptlrpc(cld)) {
rc = mgc_process_log(obd, cld);
- if (rc)
+ if (rc && rc != -ENOENT)
CERROR("failed processing sptlrpc log: %d\n", rc);
}
return cld;
}
+static struct config_llog_data *config_params_log_add(struct obd_device *obd,
+ struct config_llog_instance *cfg, struct super_block *sb)
+{
+ struct config_llog_instance lcfg = *cfg;
+ struct config_llog_data *cld;
+
+ lcfg.cfg_instance = sb;
+
+ cld = do_config_log_add(obd, PARAMS_FILENAME, CONFIG_T_PARAMS,
+ &lcfg, sb);
+
+ return cld;
+}
/** Add this log to the list of active logs watched by an MGC.
* Active means we're watching for updates.
struct config_llog_instance *cfg,
struct super_block *sb)
{
- struct lustre_sb_info *lsi = s2lsi(sb);
- struct config_llog_data *cld;
- struct config_llog_data *sptlrpc_cld;
- char seclogname[32];
- char *ptr;
- ENTRY;
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ struct config_llog_data *cld;
+ struct config_llog_data *sptlrpc_cld;
+ struct config_llog_data *params_cld;
+ char seclogname[32];
+ char *ptr;
+ int rc;
+ ENTRY;
CDEBUG(D_MGC, "adding config log %s:%p\n", logname, cfg->cfg_instance);
CONFIG_T_SPTLRPC, NULL, NULL);
if (IS_ERR(sptlrpc_cld)) {
CERROR("can't create sptlrpc log: %s\n", seclogname);
- RETURN(PTR_ERR(sptlrpc_cld));
+ GOTO(out_err, rc = PTR_ERR(sptlrpc_cld));
}
}
+ params_cld = config_params_log_add(obd, cfg, sb);
+ if (IS_ERR(params_cld)) {
+ rc = PTR_ERR(params_cld);
+ CERROR("%s: can't create params log: rc = %d\n",
+ obd->obd_name, rc);
+ GOTO(out_err1, rc);
+ }
- cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb);
- if (IS_ERR(cld)) {
- CERROR("can't create log: %s\n", logname);
- config_log_put(sptlrpc_cld);
- RETURN(PTR_ERR(cld));
- }
+ cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb);
+ if (IS_ERR(cld)) {
+ CERROR("can't create log: %s\n", logname);
+ GOTO(out_err2, rc = PTR_ERR(cld));
+ }
- cld->cld_sptlrpc = sptlrpc_cld;
+ cld->cld_sptlrpc = sptlrpc_cld;
+ cld->cld_params = params_cld;
LASSERT(lsi->lsi_lmd);
if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)) {
struct config_llog_data *recover_cld;
- *strrchr(seclogname, '-') = 0;
+ ptr = strrchr(seclogname, '-');
+ if (ptr != NULL) {
+ *ptr = 0;
+ }
+ else {
+ CERROR("%s: sptlrpc log name not correct, %s: "
+ "rc = %d\n", obd->obd_name, seclogname, -EINVAL);
+ config_log_put(cld);
+ RETURN(-EINVAL);
+ }
recover_cld = config_recover_log_add(obd, seclogname, cfg, sb);
- if (IS_ERR(recover_cld)) {
- config_log_put(cld);
- RETURN(PTR_ERR(recover_cld));
- }
- cld->cld_recover = recover_cld;
- }
+ if (IS_ERR(recover_cld))
+ GOTO(out_err3, rc = PTR_ERR(recover_cld));
+ cld->cld_recover = recover_cld;
+ }
- RETURN(0);
+ RETURN(0);
+
+out_err3:
+ config_log_put(cld);
+
+out_err2:
+ config_log_put(params_cld);
+
+out_err1:
+ config_log_put(sptlrpc_cld);
+
+out_err:
+ RETURN(rc);
}
-CFS_DEFINE_MUTEX(llog_process_lock);
+DEFINE_MUTEX(llog_process_lock);
/** Stop watching for updates on this log.
*/
{
struct config_llog_data *cld;
struct config_llog_data *cld_sptlrpc = NULL;
+ struct config_llog_data *cld_params = NULL;
struct config_llog_data *cld_recover = NULL;
int rc = 0;
ENTRY;
if (cld == NULL)
RETURN(-ENOENT);
- cfs_mutex_lock(&cld->cld_lock);
+ mutex_lock(&cld->cld_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:
* calling start_log.
*/
if (unlikely(cld->cld_stopping)) {
- cfs_mutex_unlock(&cld->cld_lock);
+ mutex_unlock(&cld->cld_lock);
/* drop the ref from the find */
config_log_put(cld);
RETURN(rc);
cld_recover = cld->cld_recover;
cld->cld_recover = NULL;
- cfs_mutex_unlock(&cld->cld_lock);
+ mutex_unlock(&cld->cld_lock);
- if (cld_recover) {
- cfs_mutex_lock(&cld_recover->cld_lock);
- cld_recover->cld_stopping = 1;
- cfs_mutex_unlock(&cld_recover->cld_lock);
- config_log_put(cld_recover);
- }
+ if (cld_recover) {
+ mutex_lock(&cld_recover->cld_lock);
+ cld_recover->cld_stopping = 1;
+ mutex_unlock(&cld_recover->cld_lock);
+ config_log_put(cld_recover);
+ }
- cfs_spin_lock(&config_list_lock);
- cld_sptlrpc = cld->cld_sptlrpc;
- cld->cld_sptlrpc = NULL;
- cfs_spin_unlock(&config_list_lock);
+ spin_lock(&config_list_lock);
+ cld_sptlrpc = cld->cld_sptlrpc;
+ cld->cld_sptlrpc = NULL;
+ cld_params = cld->cld_params;
+ cld->cld_params = NULL;
+ spin_unlock(&config_list_lock);
if (cld_sptlrpc)
config_log_put(cld_sptlrpc);
+ if (cld_params) {
+ mutex_lock(&cld_params->cld_lock);
+ cld_params->cld_stopping = 1;
+ mutex_unlock(&cld_params->cld_lock);
+ config_log_put(cld_params);
+ }
+
/* drop the ref from the find */
config_log_put(cld);
/* drop the start ref */
RETURN(rc);
}
-int lprocfs_mgc_rd_ir_state(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+#ifdef LPROCFS
+int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
{
- struct obd_device *obd = data;
- struct obd_import *imp = obd->u.cli.cl_import;
- struct obd_connect_data *ocd = &imp->imp_connect_data;
- struct config_llog_data *cld;
- int rc = 0;
- ENTRY;
-
- rc = snprintf(page, count, "imperative_recovery: %s\n",
- OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED");
- rc += snprintf(page + rc, count - rc, "client_state:\n");
+ struct obd_device *obd = data;
+ struct obd_import *imp;
+ struct obd_connect_data *ocd;
+ struct config_llog_data *cld;
+ ENTRY;
- cfs_spin_lock(&config_list_lock);
- cfs_list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
- if (cld->cld_recover == NULL)
- continue;
- rc += snprintf(page + rc, count - rc,
- " - { client: %s, nidtbl_version: %u }\n",
- cld->cld_logname,
- cld->cld_recover->cld_cfg.cfg_last_idx);
- }
- cfs_spin_unlock(&config_list_lock);
+ LASSERT(obd != NULL);
+ LPROCFS_CLIMP_CHECK(obd);
+ imp = obd->u.cli.cl_import;
+ ocd = &imp->imp_connect_data;
+
+ seq_printf(m, "imperative_recovery: %s\n",
+ OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED");
+ seq_printf(m, "client_state:\n");
+
+ spin_lock(&config_list_lock);
+ list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
+ if (cld->cld_recover == NULL)
+ continue;
+ seq_printf(m, " - { client: %s, nidtbl_version: %u }\n",
+ cld->cld_logname,
+ cld->cld_recover->cld_cfg.cfg_last_idx);
+ }
+ spin_unlock(&config_list_lock);
- RETURN(rc);
+ LPROCFS_CLIMP_EXIT(obd);
+ RETURN(0);
}
+#endif
/* reenqueue any lost locks */
-#define RQ_RUNNING 0x1
-#define RQ_NOW 0x2
-#define RQ_LATER 0x4
-#define RQ_STOP 0x8
+#define RQ_RUNNING 0x1
+#define RQ_NOW 0x2
+#define RQ_LATER 0x4
+#define RQ_STOP 0x8
+#define RQ_PRECLEANUP 0x10
static int rq_state = 0;
-static cfs_waitq_t rq_waitq;
-static CFS_DECLARE_COMPLETION(rq_exit);
+static wait_queue_head_t rq_waitq;
+static DECLARE_COMPLETION(rq_exit);
+static DECLARE_COMPLETION(rq_start);
static void do_requeue(struct config_llog_data *cld)
{
- ENTRY;
- LASSERT(cfs_atomic_read(&cld->cld_refcount) > 0);
-
- /* Do not run mgc_process_log on a disconnected export or an
- export which is being disconnected. Take the client
- semaphore to make the check non-racy. */
- cfs_down_read(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem);
- if (cld->cld_mgcexp->exp_obd->u.cli.cl_conn_count != 0) {
- CDEBUG(D_MGC, "updating log %s\n", cld->cld_logname);
- mgc_process_log(cld->cld_mgcexp->exp_obd, cld);
- } else {
- CDEBUG(D_MGC, "disconnecting, won't update log %s\n",
- cld->cld_logname);
- }
- cfs_up_read(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem);
+ int rc = 0;
+ ENTRY;
+
+ LASSERT(atomic_read(&cld->cld_refcount) > 0);
+
+ /* Do not run mgc_process_log on a disconnected export or an
+ * export which is being disconnected. Take the client
+ * semaphore to make the check non-racy. */
+ down_read(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem);
+ if (cld->cld_mgcexp->exp_obd->u.cli.cl_conn_count != 0) {
+ CDEBUG(D_MGC, "updating log %s\n", cld->cld_logname);
+ rc = mgc_process_log(cld->cld_mgcexp->exp_obd, cld);
+ if (rc && rc != -ENOENT)
+ CERROR("failed processing log: %d\n", rc);
+ } else {
+ CDEBUG(D_MGC, "disconnecting, won't update log %s\n",
+ cld->cld_logname);
+ }
+ up_read(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem);
EXIT;
}
static int mgc_requeue_thread(void *data)
{
- char name[] = "ll_cfg_requeue";
- int rc = 0;
- ENTRY;
-
- cfs_daemonize(name);
-
- CDEBUG(D_MGC, "Starting requeue thread\n");
-
- /* Keep trying failed locks periodically */
- cfs_spin_lock(&config_list_lock);
- rq_state |= RQ_RUNNING;
- while (1) {
- struct l_wait_info lwi;
- struct config_llog_data *cld, *cld_prev;
- int rand = cfs_rand() & MGC_TIMEOUT_RAND_CENTISEC;
- int stopped = !!(rq_state & RQ_STOP);
- int to;
+ int rc = 0;
+ bool first = true;
+ ENTRY;
- /* Any new or requeued lostlocks will change the state */
- rq_state &= ~(RQ_NOW | RQ_LATER);
- cfs_spin_unlock(&config_list_lock);
+ CDEBUG(D_MGC, "Starting requeue thread\n");
+
+ /* Keep trying failed locks periodically */
+ spin_lock(&config_list_lock);
+ rq_state |= RQ_RUNNING;
+ while (1) {
+ struct l_wait_info lwi;
+ struct config_llog_data *cld, *cld_prev;
+ int rand = cfs_rand() & MGC_TIMEOUT_RAND_CENTISEC;
+ int stopped = !!(rq_state & RQ_STOP);
+ int to;
+
+ /* Any new or requeued lostlocks will change the state */
+ rq_state &= ~(RQ_NOW | RQ_LATER);
+ spin_unlock(&config_list_lock);
+
+ if (first) {
+ first = false;
+ complete(&rq_start);
+ }
- /* Always wait a few seconds to allow the server who
- caused the lock revocation to finish its setup, plus some
- random so everyone doesn't try to reconnect at once. */
- to = MGC_TIMEOUT_MIN_SECONDS * CFS_HZ;
- to += rand * CFS_HZ / 100; /* rand is centi-seconds */
- lwi = LWI_TIMEOUT(to, NULL, NULL);
- l_wait_event(rq_waitq, rq_state & RQ_STOP, &lwi);
+ /* Always wait a few seconds to allow the server who
+ caused the lock revocation to finish its setup, plus some
+ random so everyone doesn't try to reconnect at once. */
+ to = msecs_to_jiffies(MGC_TIMEOUT_MIN_SECONDS * MSEC_PER_SEC);
+ /* rand is centi-seconds */
+ to += msecs_to_jiffies(rand * MSEC_PER_SEC / 100);
+ lwi = LWI_TIMEOUT(to, NULL, NULL);
+ l_wait_event(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP),
+ &lwi);
/*
* iterate & processing through the list. for each cld, process
*/
cld_prev = NULL;
- cfs_spin_lock(&config_list_lock);
- cfs_list_for_each_entry(cld, &config_llog_list,
- cld_list_chain) {
- if (!cld->cld_lostlock)
- continue;
+ spin_lock(&config_list_lock);
+ rq_state &= ~RQ_PRECLEANUP;
+ list_for_each_entry(cld, &config_llog_list,
+ cld_list_chain) {
+ if (!cld->cld_lostlock)
+ continue;
- cfs_spin_unlock(&config_list_lock);
+ spin_unlock(&config_list_lock);
- LASSERT(cfs_atomic_read(&cld->cld_refcount) > 0);
+ LASSERT(atomic_read(&cld->cld_refcount) > 0);
- /* Whether we enqueued again or not in mgc_process_log,
- * we're done with the ref from the old enqueue */
- if (cld_prev)
- config_log_put(cld_prev);
- cld_prev = cld;
+ /* Whether we enqueued again or not in mgc_process_log,
+ * we're done with the ref from the old enqueue */
+ if (cld_prev)
+ config_log_put(cld_prev);
+ cld_prev = cld;
cld->cld_lostlock = 0;
- if (likely(!stopped))
- do_requeue(cld);
+ if (likely(!stopped))
+ do_requeue(cld);
- cfs_spin_lock(&config_list_lock);
- }
- cfs_spin_unlock(&config_list_lock);
- if (cld_prev)
- config_log_put(cld_prev);
-
- /* break after scanning the list so that we can drop
- * refcount to losing lock clds */
- if (unlikely(stopped)) {
- cfs_spin_lock(&config_list_lock);
- break;
- }
+ spin_lock(&config_list_lock);
+ }
+ spin_unlock(&config_list_lock);
+ if (cld_prev)
+ config_log_put(cld_prev);
+
+ /* break after scanning the list so that we can drop
+ * refcount to losing lock clds */
+ if (unlikely(stopped)) {
+ spin_lock(&config_list_lock);
+ break;
+ }
- /* Wait a bit to see if anyone else needs a requeue */
- lwi = (struct l_wait_info) { 0 };
- l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP),
- &lwi);
- cfs_spin_lock(&config_list_lock);
- }
- /* spinlock and while guarantee RQ_NOW and RQ_LATER are not set */
- rq_state &= ~RQ_RUNNING;
- cfs_spin_unlock(&config_list_lock);
+ /* Wait a bit to see if anyone else needs a requeue */
+ lwi = (struct l_wait_info) { 0 };
+ l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP),
+ &lwi);
+ spin_lock(&config_list_lock);
+ }
+ /* spinlock and while guarantee RQ_NOW and RQ_LATER are not set */
+ rq_state &= ~RQ_RUNNING;
+ spin_unlock(&config_list_lock);
- cfs_complete(&rq_exit);
+ complete(&rq_exit);
- CDEBUG(D_MGC, "Ending requeue thread\n");
- RETURN(rc);
+ CDEBUG(D_MGC, "Ending requeue thread\n");
+ RETURN(rc);
}
/* Add a cld to the list to requeue. Start the requeue thread if needed.
We are responsible for dropping the config log reference from here on out. */
static void mgc_requeue_add(struct config_llog_data *cld)
{
- ENTRY;
+ ENTRY;
- CDEBUG(D_INFO, "log %s: requeue (r=%d sp=%d st=%x)\n",
- cld->cld_logname, cfs_atomic_read(&cld->cld_refcount),
- cld->cld_stopping, rq_state);
- LASSERT(cfs_atomic_read(&cld->cld_refcount) > 0);
+ CDEBUG(D_INFO, "log %s: requeue (r=%d sp=%d st=%x)\n",
+ cld->cld_logname, atomic_read(&cld->cld_refcount),
+ cld->cld_stopping, rq_state);
+ LASSERT(atomic_read(&cld->cld_refcount) > 0);
- cfs_mutex_lock(&cld->cld_lock);
- if (cld->cld_stopping || cld->cld_lostlock) {
- cfs_mutex_unlock(&cld->cld_lock);
- RETURN_EXIT;
- }
- /* this refcount will be released in mgc_requeue_thread. */
- config_log_get(cld);
- cld->cld_lostlock = 1;
- cfs_mutex_unlock(&cld->cld_lock);
-
- /* Hold lock for rq_state */
- cfs_spin_lock(&config_list_lock);
- if (rq_state & RQ_STOP) {
- cfs_spin_unlock(&config_list_lock);
- cld->cld_lostlock = 0;
- config_log_put(cld);
- } else {
- rq_state |= RQ_NOW;
- cfs_spin_unlock(&config_list_lock);
- cfs_waitq_signal(&rq_waitq);
- }
- EXIT;
+ mutex_lock(&cld->cld_lock);
+ if (cld->cld_stopping || cld->cld_lostlock) {
+ mutex_unlock(&cld->cld_lock);
+ RETURN_EXIT;
+ }
+ /* this refcount will be released in mgc_requeue_thread. */
+ config_log_get(cld);
+ cld->cld_lostlock = 1;
+ mutex_unlock(&cld->cld_lock);
+
+ /* Hold lock for rq_state */
+ spin_lock(&config_list_lock);
+ if (rq_state & RQ_STOP) {
+ spin_unlock(&config_list_lock);
+ cld->cld_lostlock = 0;
+ config_log_put(cld);
+ } else {
+ rq_state |= RQ_NOW;
+ spin_unlock(&config_list_lock);
+ wake_up(&rq_waitq);
+ }
+ EXIT;
}
/********************** 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,
- struct vfsmount *mnt)
+ ENTRY;
+
+ rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_ORIG_CTXT, disk,
+ &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 lvfs_run_ctxt saved;
- struct lustre_sb_info *lsi = s2lsi(sb);
- struct client_obd *cli = &obd->u.cli;
- struct dentry *dentry;
- char *label;
- int err = 0;
- ENTRY;
+ struct llog_ctxt *ctxt;
+
+ ENTRY;
+
+ ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+ llog_cleanup(env, ctxt);
- LASSERT(lsi);
- LASSERT(lsi->lsi_srv_mnt == mnt);
+ RETURN(0);
+}
- /* The mgc fs exclusion sem. Only one fs can be setup at a time. */
- cfs_down(&cli->cl_mgc_sem);
+static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb)
+{
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ struct client_obd *cli = &obd->u.cli;
+ struct lu_fid rfid, fid;
+ struct dt_object *root, *dto;
+ struct lu_env *env;
+ int rc = 0;
- cfs_cleanup_group_info();
+ ENTRY;
- obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype);
- if (IS_ERR(obd->obd_fsops)) {
- cfs_up(&cli->cl_mgc_sem);
- CERROR("No fstype %s rc=%ld\n", lsi->lsi_fstype,
- PTR_ERR(obd->obd_fsops));
- RETURN(PTR_ERR(obd->obd_fsops));
- }
+ LASSERT(lsi);
+ LASSERT(lsi->lsi_dt_dev);
- cli->cl_mgc_vfsmnt = mnt;
- err = fsfilt_setup(obd, mnt->mnt_sb);
- if (err)
- GOTO(err_ops, err);
-
- OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
- obd->obd_lvfs_ctxt.pwdmnt = mnt;
- obd->obd_lvfs_ctxt.pwd = mnt->mnt_root;
- obd->obd_lvfs_ctxt.fs = get_ds();
-
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
- strlen(MOUNT_CONFIGS_DIR));
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- if (IS_ERR(dentry)) {
- err = PTR_ERR(dentry);
- CERROR("cannot lookup %s directory: rc = %d\n",
- MOUNT_CONFIGS_DIR, err);
- GOTO(err_ops, err);
- }
- cli->cl_mgc_configs_dir = dentry;
+ OBD_ALLOC_PTR(env);
+ if (env == NULL)
+ RETURN(-ENOMEM);
- /* We take an obd ref to insure that we can't get to mgc_cleanup
- without calling mgc_fs_cleanup first. */
- class_incref(obd, "mgc_fs", obd);
+ /* The mgc fs exclusion mutex. Only one fs can be setup at a time. */
+ mutex_lock(&cli->cl_mgc_mutex);
- label = fsfilt_get_label(obd, mnt->mnt_sb);
- if (label)
- CDEBUG(D_MGC, "MGC using disk labelled=%s\n", label);
+ /* Setup the configs dir */
+ rc = lu_env_init(env, LCT_MG_THREAD);
+ if (rc)
+ GOTO(out_err, rc);
- /* We keep the cl_mgc_sem until mgc_fs_cleanup */
- RETURN(0);
+ fid.f_seq = FID_SEQ_LOCAL_NAME;
+ fid.f_oid = 1;
+ fid.f_ver = 0;
+ rc = local_oid_storage_init(env, lsi->lsi_dt_dev, &fid,
+ &cli->cl_mgc_los);
+ if (rc)
+ GOTO(out_env, rc);
+
+ rc = dt_root_get(env, lsi->lsi_dt_dev, &rfid);
+ if (rc)
+ GOTO(out_env, rc);
-err_ops:
- fsfilt_put_ops(obd->obd_fsops);
- obd->obd_fsops = NULL;
- cli->cl_mgc_vfsmnt = NULL;
- cfs_up(&cli->cl_mgc_sem);
- RETURN(err);
+ root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid,
+ &cli->cl_mgc_los->los_dev->dd_lu_dev, NULL);
+ if (unlikely(IS_ERR(root)))
+ GOTO(out_los, rc = PTR_ERR(root));
+
+ dto = local_file_find_or_create(env, cli->cl_mgc_los, root,
+ MOUNT_CONFIGS_DIR,
+ S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
+ lu_object_put_nocache(env, &root->do_lu);
+ if (IS_ERR(dto))
+ 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
+ * without calling mgc_fs_cleanup first. */
+ class_incref(obd, "mgc_fs", obd);
+
+ /* We keep the cl_mgc_sem until mgc_fs_cleanup */
+ EXIT;
+out_llog:
+ if (rc) {
+ lu_object_put(env, &cli->cl_mgc_configs_dir->do_lu);
+ cli->cl_mgc_configs_dir = NULL;
+ }
+out_los:
+ if (rc < 0) {
+ local_oid_storage_fini(env, cli->cl_mgc_los);
+ cli->cl_mgc_los = NULL;
+ mutex_unlock(&cli->cl_mgc_mutex);
+ }
+out_env:
+ lu_env_fini(env);
+out_err:
+ OBD_FREE_PTR(env);
+ return rc;
}
static int mgc_fs_cleanup(struct obd_device *obd)
{
- struct client_obd *cli = &obd->u.cli;
- int rc = 0;
- ENTRY;
+ struct lu_env env;
+ struct client_obd *cli = &obd->u.cli;
+ int rc;
- LASSERT(cli->cl_mgc_vfsmnt != NULL);
+ ENTRY;
- if (cli->cl_mgc_configs_dir != NULL) {
- struct lvfs_run_ctxt saved;
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- l_dput(cli->cl_mgc_configs_dir);
- cli->cl_mgc_configs_dir = NULL;
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- class_decref(obd, "mgc_fs", obd);
- }
+ LASSERT(cli->cl_mgc_los != NULL);
+
+ rc = lu_env_init(&env, LCT_MG_THREAD);
+ if (rc)
+ GOTO(unlock, rc);
- cli->cl_mgc_vfsmnt = NULL;
- if (obd->obd_fsops)
- fsfilt_put_ops(obd->obd_fsops);
+ mgc_local_llog_fini(&env, obd);
- cfs_up(&cli->cl_mgc_sem);
+ lu_object_put_nocache(&env, &cli->cl_mgc_configs_dir->do_lu);
+ cli->cl_mgc_configs_dir = NULL;
- RETURN(rc);
+ local_oid_storage_fini(&env, cli->cl_mgc_los);
+ cli->cl_mgc_los = NULL;
+ lu_env_fini(&env);
+
+unlock:
+ class_decref(obd, "mgc_fs", obd);
+ mutex_unlock(&cli->cl_mgc_mutex);
+
+ RETURN(0);
}
-static cfs_atomic_t mgc_count = CFS_ATOMIC_INIT(0);
+static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd)
+{
+ struct llog_ctxt *ctxt;
+ int rc;
+
+ ENTRY;
+
+ /* 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);
+
+ 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;
+
+ ENTRY;
+
+ 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 int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
{
- int rc = 0;
- ENTRY;
+ int rc = 0;
+ int temp;
+ ENTRY;
- switch (stage) {
- case OBD_CLEANUP_EARLY:
- break;
- case OBD_CLEANUP_EXPORTS:
- if (cfs_atomic_dec_and_test(&mgc_count)) {
- int running;
- /* stop requeue thread */
- cfs_spin_lock(&config_list_lock);
- running = rq_state & RQ_RUNNING;
- if (running)
- rq_state |= RQ_STOP;
- cfs_spin_unlock(&config_list_lock);
- if (running) {
- cfs_waitq_signal(&rq_waitq);
- cfs_wait_for_completion(&rq_exit);
- }
- }
- obd_cleanup_client_import(obd);
- rc = obd_llog_finish(obd, 0);
- if (rc != 0)
- CERROR("failed to cleanup llogging subsystems\n");
- break;
- }
- RETURN(rc);
+ switch (stage) {
+ case OBD_CLEANUP_EARLY:
+ break;
+ case OBD_CLEANUP_EXPORTS:
+ if (atomic_dec_and_test(&mgc_count)) {
+ LASSERT(rq_state & RQ_RUNNING);
+ /* stop requeue thread */
+ temp = RQ_STOP;
+ } else {
+ /* wakeup requeue thread to clean our cld */
+ temp = RQ_NOW | RQ_PRECLEANUP;
+ }
+ spin_lock(&config_list_lock);
+ rq_state |= temp;
+ spin_unlock(&config_list_lock);
+ wake_up(&rq_waitq);
+ if (temp & RQ_STOP)
+ wait_for_completion(&rq_exit);
+ obd_cleanup_client_import(obd);
+ rc = mgc_llog_fini(NULL, obd);
+ if (rc != 0)
+ CERROR("failed to cleanup llogging subsystems\n");
+ break;
+ }
+ RETURN(rc);
}
static int mgc_cleanup(struct obd_device *obd)
{
- struct client_obd *cli = &obd->u.cli;
int rc;
ENTRY;
- LASSERT(cli->cl_mgc_vfsmnt == NULL);
-
/* COMPAT_146 - old config logs may have added profiles we don't
know about */
if (obd->obd_type->typ_refcnt <= 1)
static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
{
- struct lprocfs_static_vars lvars;
- int rc;
- ENTRY;
-
- ptlrpcd_addref();
-
- rc = client_obd_setup(obd, lcfg);
- if (rc)
- GOTO(err_decref, rc);
+ struct task_struct *task;
+ int rc;
+ ENTRY;
- rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL);
- if (rc) {
- CERROR("failed to setup llogging subsystems\n");
- GOTO(err_cleanup, rc);
- }
+ rc = ptlrpcd_addref();
+ if (rc < 0)
+ RETURN(rc);
- lprocfs_mgc_init_vars(&lvars);
- lprocfs_obd_setup(obd, lvars.obd_vars);
- sptlrpc_lprocfs_cliobd_attach(obd);
+ rc = client_obd_setup(obd, lcfg);
+ if (rc)
+ GOTO(err_decref, rc);
- if (cfs_atomic_inc_return(&mgc_count) == 1) {
- rq_state = 0;
- cfs_waitq_init(&rq_waitq);
+ rc = mgc_llog_init(NULL, obd);
+ if (rc) {
+ CERROR("failed to setup llogging subsystems\n");
+ GOTO(err_cleanup, rc);
+ }
- /* start requeue thread */
- rc = cfs_create_thread(mgc_requeue_thread, NULL,
- CFS_DAEMON_FLAGS);
- if (rc < 0) {
- CERROR("%s: Cannot start requeue thread (%d),"
- "no more log updates!\n",
- obd->obd_name, rc);
- GOTO(err_cleanup, rc);
- }
- /* rc is the pid of mgc_requeue_thread. */
- rc = 0;
- }
+#ifdef LPROCFS
+ obd->obd_vars = lprocfs_mgc_obd_vars;
+ lprocfs_obd_setup(obd);
+#endif
+ sptlrpc_lprocfs_cliobd_attach(obd);
+
+ if (atomic_inc_return(&mgc_count) == 1) {
+ rq_state = 0;
+ init_waitqueue_head(&rq_waitq);
+
+ /* start requeue thread */
+ task = kthread_run(mgc_requeue_thread, NULL, "ll_cfg_requeue");
+ if (IS_ERR(task)) {
+ rc = PTR_ERR(task);
+ CERROR("%s: cannot start requeue thread: rc = %d; "
+ "no more log updates\n",
+ obd->obd_name, rc);
+ GOTO(err_cleanup, rc);
+ }
+ /* rc is the task_struct pointer of mgc_requeue_thread. */
+ rc = 0;
+ wait_for_completion(&rq_start);
+ }
- RETURN(rc);
+ RETURN(rc);
err_cleanup:
- client_obd_cleanup(obd);
+ client_obd_cleanup(obd);
err_decref:
- ptlrpcd_decref();
- RETURN(rc);
+ ptlrpcd_decref();
+ RETURN(rc);
}
/* based on ll_mdc_blocking_ast */
/* mgs wants the lock, give it up... */
LDLM_DEBUG(lock, "MGC blocking CB");
ldlm_lock2handle(lock, &lockh);
- rc = ldlm_cli_cancel(&lockh);
- break;
- case LDLM_CB_CANCELING:
- /* We've given up the lock, prepare ourselves to update. */
- LDLM_DEBUG(lock, "MGC cancel CB");
-
- CDEBUG(D_MGC, "Lock res "LPX64" (%.8s)\n",
- lock->l_resource->lr_name.name[0],
- (char *)&lock->l_resource->lr_name.name[0]);
-
- if (!cld) {
- CDEBUG(D_INFO, "missing data, won't requeue\n");
- break;
- }
+ rc = ldlm_cli_cancel(&lockh, LCF_ASYNC);
+ break;
+ case LDLM_CB_CANCELING:
+ /* We've given up the lock, prepare ourselves to update. */
+ LDLM_DEBUG(lock, "MGC cancel CB");
+
+ CDEBUG(D_MGC, "Lock res "DLDLMRES" (%.8s)\n",
+ PLDLMRES(lock->l_resource),
+ (char *)&lock->l_resource->lr_name.name[0]);
+
+ if (!cld) {
+ CDEBUG(D_INFO, "missing data, won't requeue\n");
+ break;
+ }
- /* held at mgc_process_log(). */
- LASSERT(cfs_atomic_read(&cld->cld_refcount) > 0);
- /* Are we done with this log? */
- if (cld->cld_stopping) {
- CDEBUG(D_MGC, "log %s: stopping, won't requeue\n",
- cld->cld_logname);
- config_log_put(cld);
- break;
- }
- /* Make sure not to re-enqueue when the mgc is stopping
- (we get called from client_disconnect_export) */
- if (!lock->l_conn_export ||
- !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) {
- CDEBUG(D_MGC, "log %.8s: disconnecting, won't requeue\n",
- cld->cld_logname);
- config_log_put(cld);
- break;
- }
+ /* held at mgc_process_log(). */
+ LASSERT(atomic_read(&cld->cld_refcount) > 0);
+ /* Are we done with this log? */
+ if (cld->cld_stopping) {
+ CDEBUG(D_MGC, "log %s: stopping, won't requeue\n",
+ cld->cld_logname);
+ config_log_put(cld);
+ break;
+ }
+ /* Make sure not to re-enqueue when the mgc is stopping
+ (we get called from client_disconnect_export) */
+ if (!lock->l_conn_export ||
+ !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) {
+ CDEBUG(D_MGC, "log %.8s: disconnecting, won't requeue\n",
+ cld->cld_logname);
+ config_log_put(cld);
+ break;
+ }
/* Re-enqueue now */
mgc_requeue_add(cld);
}
/* Not sure where this should go... */
-#define MGC_ENQUEUE_LIMIT 50
+/* This is the timeout value for MGS_CONNECT request plus a ping interval, such
+ * that we can have a chance to try the secondary MGS if any. */
+#define MGC_ENQUEUE_LIMIT (INITIAL_CONNECT_TIMEOUT + (AT_OFF ? 0 : at_min) \
+ + PING_INTERVAL)
#define MGC_TARGET_REG_LIMIT 10
#define MGC_SEND_PARAM_LIMIT 10
void *data, __u32 lvb_len, void *lvb_swabber,
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, NULL, NULL };
- struct ptlrpc_request *req;
- int short_limit = cld_is_sptlrpc(cld);
- int rc;
- ENTRY;
+ struct config_llog_data *cld = (struct config_llog_data *)data;
+ struct ldlm_enqueue_info einfo = {
+ .ei_type = type,
+ .ei_mode = mode,
+ .ei_cb_bl = mgc_blocking_ast,
+ .ei_cb_cp = ldlm_completion_ast,
+ };
+ struct ptlrpc_request *req;
+ int short_limit = cld_is_sptlrpc(cld);
+ int rc;
+ ENTRY;
CDEBUG(D_MGC, "Enqueue for %s (res "LPX64")\n", cld->cld_logname,
cld->cld_resid.name[0]);
LDLM_ENQUEUE);
if (req == NULL)
RETURN(-ENOMEM);
+
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER, 0);
ptlrpc_request_set_replen(req);
/* check if this is server or client */
/* Limit how long we will wait for the enqueue to complete */
req->rq_delay_limit = short_limit ? 5 : MGC_ENQUEUE_LIMIT;
rc = ldlm_cli_enqueue(exp, &req, &einfo, &cld->cld_resid, NULL, flags,
- NULL, 0, lockh, 0);
+ NULL, 0, LVB_T_NONE, lockh, 0);
/* A failed enqueue should still call the mgc_blocking_ast,
where it will be requeued if needed ("grant failed"). */
ptlrpc_req_finished(req);
RETURN(rc);
}
-static int mgc_cancel(struct obd_export *exp, struct lov_stripe_md *md,
- __u32 mode, struct lustre_handle *lockh)
+static int mgc_cancel(struct obd_export *exp, ldlm_mode_t mode,
+ struct lustre_handle *lockh)
{
ENTRY;
static void mgc_notify_active(struct obd_device *unused)
{
- /* wakeup mgc_requeue_thread to requeue mgc lock */
- cfs_spin_lock(&config_list_lock);
- rq_state |= RQ_NOW;
- cfs_spin_unlock(&config_list_lock);
- cfs_waitq_signal(&rq_waitq);
+ /* wakeup mgc_requeue_thread to requeue mgc lock */
+ spin_lock(&config_list_lock);
+ rq_state |= RQ_NOW;
+ spin_unlock(&config_list_lock);
+ wake_up(&rq_waitq);
- /* TODO: Help the MGS rebuild nidtbl. -jay */
+ /* TODO: Help the MGS rebuild nidtbl. -jay */
}
/* Send target_reg message to MGS */
RETURN(rc);
}
-int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
- obd_count keylen, void *key, obd_count vallen,
- void *val, struct ptlrpc_request_set *set)
+static int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
+ obd_count keylen, void *key, obd_count vallen,
+ void *val, struct ptlrpc_request_set *set)
{
int rc = -EINVAL;
ENTRY;
rc = mgc_target_register(exp, mti);
RETURN(rc);
}
- if (KEY_IS(KEY_SET_FS)) {
- struct super_block *sb = (struct super_block *)val;
- struct lustre_sb_info *lsi;
- if (vallen != sizeof(struct super_block))
- RETURN(-EINVAL);
- lsi = s2lsi(sb);
- rc = mgc_fs_setup(exp->exp_obd, sb, lsi->lsi_srv_mnt);
- if (rc) {
- CERROR("set_fs got %d\n", rc);
- }
- RETURN(rc);
- }
- if (KEY_IS(KEY_CLEAR_FS)) {
- if (vallen != 0)
- RETURN(-EINVAL);
- rc = mgc_fs_cleanup(exp->exp_obd);
- if (rc) {
- CERROR("clear_fs got %d\n", rc);
- }
- RETURN(rc);
- }
+ if (KEY_IS(KEY_SET_FS)) {
+ struct super_block *sb = (struct super_block *)val;
+
+ if (vallen != sizeof(struct super_block))
+ RETURN(-EINVAL);
+
+ rc = mgc_fs_setup(exp->exp_obd, sb);
+ RETURN(rc);
+ }
+ if (KEY_IS(KEY_CLEAR_FS)) {
+ if (vallen != 0)
+ RETURN(-EINVAL);
+ rc = mgc_fs_cleanup(exp->exp_obd);
+ RETURN(rc);
+ }
if (KEY_IS(KEY_SET_INFO)) {
struct mgs_send_param *msp;
switch (event) {
case IMP_EVENT_DISCON:
/* MGC imports should not wait for recovery */
+ if (OCD_HAS_FLAG(&imp->imp_connect_data, IMP_RECOV))
+ ptlrpc_pinger_ir_down();
break;
case IMP_EVENT_INACTIVE:
break;
ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
break;
}
- case IMP_EVENT_ACTIVE:
- LCONSOLE_WARN("%s: Reactivating import\n", obd->obd_name);
- /* Clearing obd_no_recov allows us to continue pinging */
- obd->obd_no_recov = 0;
- mgc_notify_active(obd);
- break;
+ case IMP_EVENT_ACTIVE:
+ CDEBUG(D_INFO, "%s: Reactivating import\n", obd->obd_name);
+ /* Clearing obd_no_recov allows us to continue pinging */
+ obd->obd_no_recov = 0;
+ mgc_notify_active(obd);
+ if (OCD_HAS_FLAG(&imp->imp_connect_data, IMP_RECOV))
+ ptlrpc_pinger_ir_up();
+ break;
case IMP_EVENT_OCD:
break;
case IMP_EVENT_DEACTIVATE:
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;
- ENTRY;
-
- LASSERT(olg == &obd->obd_olg);
-
-#ifdef HAVE_LDISKFS_OSD
- rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_ORIG_CTXT, tgt,
- &llog_lvfs_ops);
- if (rc)
- RETURN(rc);
-#endif
-
- 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;
-
- ENTRY;
-
- 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 {
- CONFIG_READ_NRPAGES_INIT = 1 << (20 - CFS_PAGE_SHIFT),
+ CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_CACHE_SHIFT),
CONFIG_READ_NRPAGES = 4
};
LASSERT(cfg->cfg_instance != NULL);
LASSERT(cfg->cfg_sb == cfg->cfg_instance);
- OBD_ALLOC(inst, CFS_PAGE_SIZE);
- if (inst == NULL)
- RETURN(-ENOMEM);
+ OBD_ALLOC(inst, PAGE_CACHE_SIZE);
+ if (inst == NULL)
+ RETURN(-ENOMEM);
if (!IS_SERVER(lsi)) {
- pos = sprintf(inst, "%p", cfg->cfg_instance);
+ pos = snprintf(inst, PAGE_CACHE_SIZE, "%p", cfg->cfg_instance);
+ if (pos >= PAGE_CACHE_SIZE) {
+ OBD_FREE(inst, PAGE_CACHE_SIZE);
+ return -E2BIG;
+ }
} else {
LASSERT(IS_MDT(lsi));
- rc = server_name2svname(lsi->lsi_svname, inst, NULL);
- if (rc)
+ rc = server_name2svname(lsi->lsi_svname, inst, NULL,
+ PAGE_CACHE_SIZE);
+ if (rc) {
+ OBD_FREE(inst, PAGE_CACHE_SIZE);
RETURN(-EINVAL);
+ }
pos = strlen(inst);
}
++pos;
buf = inst + pos;
- bufsz = CFS_PAGE_SIZE - pos;
+ bufsz = PAGE_CACHE_SIZE - pos;
while (datalen > 0) {
int entry_len = sizeof(*entry);
- int is_ost;
+ int is_ost, i;
struct obd_device *obd;
char *obdname;
char *cname;
/* Keep this swab for normal mixed endian handling. LU-1644 */
if (mne_swab)
lustre_swab_mgs_nidtbl_entry(entry);
- if (entry->mne_length > CFS_PAGE_SIZE) {
+ if (entry->mne_length > PAGE_CACHE_SIZE) {
CERROR("MNE too large (%u)\n", entry->mne_length);
break;
}
pos += sprintf(params, "%s.import=%s", cname, "connection=");
uuid = buf + pos;
- /* TODO: iterate all nids to find one */
- /* find uuid by nid */
- rc = client_import_find_conn(obd->u.cli.cl_import,
- entry->u.nids[0],
- (struct obd_uuid *)uuid);
+ down_read(&obd->u.cli.cl_sem);
+ if (obd->u.cli.cl_import == NULL) {
+ /* client does not connect to the OST yet */
+ up_read(&obd->u.cli.cl_sem);
+ rc = 0;
+ continue;
+ }
+
+ /* iterate all nids to find one */
+ /* find uuid by nid */
+ rc = -ENOENT;
+ for (i = 0; i < entry->mne_nid_count; i++) {
+ rc = client_import_find_conn(obd->u.cli.cl_import,
+ entry->u.nids[i],
+ (struct obd_uuid *)uuid);
+ if (rc == 0)
+ break;
+ }
+
+ up_read(&obd->u.cli.cl_sem);
if (rc < 0) {
CERROR("mgc: cannot find uuid by nid %s\n",
libcfs_nid2str(entry->u.nids[0]));
lustre_cfg_bufs_set_string(&bufs, 1, params);
- rc = -ENOMEM;
- lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
- if (lcfg == NULL) {
- CERROR("mgc: cannot allocate memory\n");
- break;
- }
+ lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
+ if (lcfg == NULL) {
+ rc = -ENOMEM;
+ break;
+ }
CDEBUG(D_INFO, "ir apply logs "LPD64"/"LPD64" for %s -> %s\n",
prev_version, max_version, obdname, params);
/* continue, even one with error */
}
- OBD_FREE(inst, CFS_PAGE_SIZE);
+ OBD_FREE(inst, PAGE_CACHE_SIZE);
RETURN(rc);
}
struct mgs_config_body *body;
struct mgs_config_res *res;
struct ptlrpc_bulk_desc *desc;
- cfs_page_t **pages;
+ struct page **pages;
int nrpages;
bool eof = true;
bool mne_swab = false;
GOTO(out, rc = -ENOMEM);
for (i = 0; i < nrpages; i++) {
- pages[i] = cfs_alloc_page(CFS_ALLOC_STD);
+ pages[i] = alloc_page(GFP_IOFS);
if (pages[i] == NULL)
GOTO(out, rc = -ENOMEM);
}
again:
LASSERT(cld_is_recover(cld));
- LASSERT(cfs_mutex_is_locked(&cld->cld_lock));
+ LASSERT(mutex_is_locked(&cld->cld_lock));
req = ptlrpc_request_alloc(class_exp2cliimp(cld->cld_mgcexp),
&RQF_MGS_CONFIG_READ);
if (req == NULL)
body = req_capsule_client_get(&req->rq_pill, &RMF_MGS_CONFIG_BODY);
LASSERT(body != NULL);
LASSERT(sizeof(body->mcb_name) > strlen(cld->cld_logname));
- strncpy(body->mcb_name, cld->cld_logname, sizeof(body->mcb_name));
+ if (strlcpy(body->mcb_name, cld->cld_logname, sizeof(body->mcb_name))
+ >= sizeof(body->mcb_name))
+ GOTO(out, rc = -E2BIG);
body->mcb_offset = cfg->cfg_last_idx + 1;
body->mcb_type = cld->cld_type;
- body->mcb_bits = CFS_PAGE_SHIFT;
+ body->mcb_bits = PAGE_CACHE_SHIFT;
body->mcb_units = nrpages;
- /* allocate bulk transfer descriptor */
- desc = ptlrpc_prep_bulk_imp(req, nrpages, BULK_PUT_SINK,
- MGS_BULK_PORTAL);
- if (desc == NULL)
- GOTO(out, rc = -ENOMEM);
+ /* allocate bulk transfer descriptor */
+ desc = ptlrpc_prep_bulk_imp(req, nrpages, 1, BULK_PUT_SINK,
+ MGS_BULK_PORTAL);
+ if (desc == NULL)
+ GOTO(out, rc = -ENOMEM);
- for (i = 0; i < nrpages; i++)
- ptlrpc_prep_bulk_page_pin(desc, pages[i], 0, CFS_PAGE_SIZE);
+ for (i = 0; i < nrpages; i++)
+ ptlrpc_prep_bulk_page_pin(desc, pages[i], 0, PAGE_CACHE_SIZE);
ptlrpc_request_set_replen(req);
rc = ptlrpc_queue_wait(req);
if (ealen < 0)
GOTO(out, rc = ealen);
- if (ealen > nrpages << CFS_PAGE_SHIFT)
- GOTO(out, rc = -EINVAL);
+ if (ealen > nrpages << PAGE_CACHE_SHIFT)
+ GOTO(out, rc = -EINVAL);
- if (ealen == 0) { /* no logs transferred */
- if (!eof)
- rc = -EINVAL;
- GOTO(out, rc);
- }
+ if (ealen == 0) { /* no logs transferred */
+ if (!eof)
+ rc = -EINVAL;
+ GOTO(out, rc);
+ }
mne_swab = !!ptlrpc_rep_need_swab(req);
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
/* This import flag means the server did an extra swab of IR MNE
* records (fixed in LU-1252), reverse it here if needed. LU-1644 */
if (unlikely(req->rq_import->imp_need_mne_swab))
mne_swab = !mne_swab;
-#else
-#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif
- for (i = 0; i < nrpages && ealen > 0; i++) {
- int rc2;
- void *ptr;
+ for (i = 0; i < nrpages && ealen > 0; i++) {
+ int rc2;
+ void *ptr;
- ptr = cfs_kmap(pages[i]);
- rc2 = mgc_apply_recover_logs(obd, cld, res->mcr_offset, ptr,
- min_t(int, ealen, CFS_PAGE_SIZE),
+ ptr = kmap(pages[i]);
+ rc2 = mgc_apply_recover_logs(obd, cld, res->mcr_offset, ptr,
+ min_t(int, ealen, PAGE_CACHE_SIZE),
mne_swab);
- cfs_kunmap(pages[i]);
- if (rc2 < 0) {
- CWARN("Process recover log %s error %d\n",
- cld->cld_logname, rc2);
- break;
+ kunmap(pages[i]);
+ if (rc2 < 0) {
+ CWARN("Process recover log %s error %d\n",
+ cld->cld_logname, rc2);
+ break;
}
- ealen -= CFS_PAGE_SIZE;
+ ealen -= PAGE_CACHE_SIZE;
}
out:
if (rc == 0 && !eof)
goto again;
- if (pages) {
- for (i = 0; i < nrpages; i++) {
- if (pages[i] == NULL)
- break;
- cfs_free_page(pages[i]);
- }
- OBD_FREE(pages, sizeof(*pages) * nrpages);
- }
- return rc;
-}
-
-#ifdef HAVE_LDISKFS_OSD
-
-/*
- * XXX: mgc_copy_llog() does not support osd-based llogs yet
- */
-
-/* identical to mgs_log_is_empty */
-static int mgc_llog_is_empty(struct obd_device *obd, struct llog_ctxt *ctxt,
- char *name)
-{
- struct lvfs_run_ctxt saved;
- struct llog_handle *llh;
- int rc = 0;
-
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
- if (rc == 0) {
- llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
- rc = llog_get_size(llh);
- llog_close(NULL, llh);
- } else if (rc == -ENOENT) {
- rc = 0;
+ if (pages) {
+ for (i = 0; i < nrpages; i++) {
+ if (pages[i] == NULL)
+ break;
+ __free_page(pages[i]);
+ }
+ OBD_FREE(pages, sizeof(*pages) * nrpages);
}
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- /* header is record 1 */
- return (rc <= 1);
-}
-
-static int mgc_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;
- ENTRY;
-
- /* 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);
+ 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)
+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)
{
- struct llog_handle *local_llh, *remote_llh;
- struct obd_uuid *uuid;
- char *temp_log;
- int rc, rc2;
- ENTRY;
+ char *temp_log;
+ int rc;
- /* Write new log to a temp name, then vfs_rename over logname
- upon successful completion. */
+ ENTRY;
- OBD_ALLOC(temp_log, strlen(logname) + 1);
- if (!temp_log)
- RETURN(-ENOMEM);
- sprintf(temp_log, "%sT", logname);
+ /*
+ * - copy it to backup using llog_backup()
+ * - copy remote llog to logname using llog_backup()
+ * - if failed then move bakup to logname again
+ */
- /* Make sure there's no old temp log */
- rc = llog_erase(NULL, lctxt, NULL, temp_log);
- if (rc < 0 && rc != -ENOENT)
- GOTO(out, rc);
+ OBD_ALLOC(temp_log, strlen(logname) + 1);
+ if (!temp_log)
+ RETURN(-ENOMEM);
+ sprintf(temp_log, "%sT", logname);
- /* open local log */
- rc = llog_open_create(NULL, lctxt, &local_llh, NULL, temp_log);
- if (rc)
+ /* 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);
-
- /* set the log header uuid for fun */
- OBD_ALLOC_PTR(uuid);
- obd_str2uuid(uuid, logname);
- rc = llog_init_handle(NULL, local_llh, LLOG_F_IS_PLAIN, uuid);
- OBD_FREE_PTR(uuid);
- if (rc)
- GOTO(out_closel, rc);
-
- /* open remote log */
- rc = llog_open(NULL, rctxt, &remote_llh, NULL, logname,
- LLOG_OPEN_EXISTS);
- if (rc < 0) {
- if (rc == -ENOENT)
- rc = 0;
- GOTO(out_closel, rc);
- }
-
- rc = llog_init_handle(NULL, remote_llh, LLOG_F_IS_PLAIN, NULL);
- if (rc)
- GOTO(out_closer, rc);
-
- /* Copy remote log */
- rc = llog_process(NULL, remote_llh, mgc_copy_handler,
- (void *)local_llh, NULL);
-
-out_closer:
- rc2 = llog_close(NULL, remote_llh);
- if (!rc)
- rc = rc2;
-out_closel:
- rc2 = llog_close(NULL, local_llh);
- 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 == 0) {
- struct client_obd *cli = &obd->u.cli;
-
- LASSERT(cli);
- LASSERT(cli->cl_mgc_configs_dir);
- rc = lustre_rename(cli->cl_mgc_configs_dir, cli->cl_mgc_vfsmnt,
- temp_log, logname);
- }
- CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, 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:
- if (rc)
- CERROR("Failed to copy remote log %s (%d)\n", logname, rc);
- OBD_FREE(temp_log, strlen(logname) + 1);
- RETURN(rc);
+ 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;
}
-#endif
/* local_only means it cannot get remote llogs */
static int mgc_process_cfg_log(struct obd_device *mgc,
- struct config_llog_data *cld,
- int local_only)
+ struct config_llog_data *cld, int local_only)
{
- struct llog_ctxt *ctxt, *lctxt = NULL;
-#ifdef HAVE_LDISKFS_OSD
- struct client_obd *cli = &mgc->u.cli;
-#endif
- struct lvfs_run_ctxt *saved_ctxt;
- struct lustre_sb_info *lsi = NULL;
- int rc = 0, must_pop = 0;
- bool sptlrpc_started = false;
-
- ENTRY;
-
- LASSERT(cld);
- LASSERT(cfs_mutex_is_locked(&cld->cld_lock));
+ struct llog_ctxt *ctxt, *lctxt = NULL;
+ struct client_obd *cli = &mgc->u.cli;
+ struct lustre_sb_info *lsi = NULL;
+ int rc = 0;
+ bool sptlrpc_started = false;
+ struct lu_env *env;
- /*
- * local copy of sptlrpc log is controlled elsewhere, don't try to
- * read it up here.
- */
- if (cld_is_sptlrpc(cld) && local_only)
- RETURN(0);
+ ENTRY;
- if (cld->cld_cfg.cfg_sb)
- lsi = s2lsi(cld->cld_cfg.cfg_sb);
+ LASSERT(cld);
+ LASSERT(mutex_is_locked(&cld->cld_lock));
- ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
- if (!ctxt) {
- CERROR("missing llog context\n");
- RETURN(-EINVAL);
- }
+ /*
+ * local copy of sptlrpc log is controlled elsewhere, don't try to
+ * read it up here.
+ */
+ if (cld_is_sptlrpc(cld) && local_only)
+ RETURN(0);
- OBD_ALLOC_PTR(saved_ctxt);
- if (saved_ctxt == NULL)
- RETURN(-ENOMEM);
+ if (cld->cld_cfg.cfg_sb)
+ lsi = s2lsi(cld->cld_cfg.cfg_sb);
- lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
+ OBD_ALLOC_PTR(env);
+ if (env == NULL)
+ RETURN(-ENOMEM);
-#ifdef HAVE_LDISKFS_OSD
- /*
- * XXX: at the moment mgc_copy_llog() works with lvfs-based llogs
- */
- /* 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) &&
- (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) &&
- !IS_MGS(lsi) && lsi->lsi_srv_mnt) {
- push_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);
- must_pop++;
- if (!local_only)
- /* Only try to copy log if we have the lock. */
- rc = mgc_copy_llog(mgc, ctxt, lctxt, cld->cld_logname);
- if (local_only || rc) {
- if (mgc_llog_is_empty(mgc, 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
-#endif
- if (local_only) { /* no local log at client side */
- GOTO(out_pop, rc = -EIO);
- }
+ 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);
+
+ /* 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) &&
+ cli->cl_mgc_configs_dir != NULL &&
+ lu2dt_dev(cli->cl_mgc_configs_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 (strcmp(cld->cld_logname, PARAMS_FILENAME) != 0 &&
+ 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 = -ENOENT);
+ }
+ CDEBUG(D_MGC, "Failed to get MGS log %s, using local "
+ "copy for now, will try to update later.\n",
+ cld->cld_logname);
+ rc = 0;
+ }
+ /* 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);
+ }
- if (cld_is_sptlrpc(cld)) {
- sptlrpc_conf_log_update_begin(cld->cld_logname);
- sptlrpc_started = true;
- }
+ if (cld_is_sptlrpc(cld)) {
+ sptlrpc_conf_log_update_begin(cld->cld_logname);
+ sptlrpc_started = true;
+ }
- /* logname and instance info should be the same, so use our
- copy of the instance for the update. The cfg_last_idx will
- be updated here. */
- rc = class_config_parse_llog(NULL, ctxt, cld->cld_logname,
+ /* logname and instance info should be the same, so use our
+ * copy of the instance for the update. The cfg_last_idx will
+ * be updated here. */
+ rc = class_config_parse_llog(env, ctxt, cld->cld_logname,
&cld->cld_cfg);
- EXIT;
+ EXIT;
out_pop:
- llog_ctxt_put(ctxt);
- if (lctxt)
- llog_ctxt_put(lctxt);
- if (must_pop)
- pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL);
+ __llog_ctxt_put(env, ctxt);
+ if (lctxt)
+ __llog_ctxt_put(env, lctxt);
- OBD_FREE_PTR(saved_ctxt);
- /*
- * update settings on existing OBDs. doing it inside
- * of llog_process_lock so no device is attaching/detaching
- * in parallel.
- * the logname must be <fsname>-sptlrpc
- */
- if (sptlrpc_started) {
- LASSERT(cld_is_sptlrpc(cld));
- sptlrpc_conf_log_update_end(cld->cld_logname);
- class_notify_sptlrpc_conf(cld->cld_logname,
- strlen(cld->cld_logname) -
- strlen("-sptlrpc"));
- }
+ /*
+ * update settings on existing OBDs. doing it inside
+ * of llog_process_lock so no device is attaching/detaching
+ * in parallel.
+ * the logname must be <fsname>-sptlrpc
+ */
+ if (sptlrpc_started) {
+ LASSERT(cld_is_sptlrpc(cld));
+ sptlrpc_conf_log_update_end(cld->cld_logname);
+ class_notify_sptlrpc_conf(cld->cld_logname,
+ strlen(cld->cld_logname) -
+ strlen("-sptlrpc"));
+ }
- RETURN(rc);
+ lu_env_fini(env);
+out_free:
+ OBD_FREE_PTR(env);
+ return rc;
}
/** Get a config log from the MGS and process it.
sounds like badness. It actually might be fine, as long as
we're not trying to update from the same log
simultaneously (in which case we should use a per-log sem.) */
- cfs_mutex_lock(&cld->cld_lock);
- if (cld->cld_stopping) {
- cfs_mutex_unlock(&cld->cld_lock);
+ mutex_lock(&cld->cld_lock);
+ if (cld->cld_stopping) {
+ mutex_unlock(&cld->cld_lock);
RETURN(0);
}
CDEBUG(D_MGC, "%s: configuration from log '%s' %sed (%d).\n",
mgc->obd_name, cld->cld_logname, rc ? "fail" : "succeed", rc);
- cfs_mutex_unlock(&cld->cld_lock);
+ mutex_unlock(&cld->cld_lock);
- /* Now drop the lock so MGS can revoke it */
- if (!rcl) {
- rcl = mgc_cancel(mgc->u.cli.cl_mgc_mgsexp, NULL,
- LCK_CR, &lockh);
- if (rcl)
- CERROR("Can't drop cfg lock: %d\n", rcl);
- }
+ /* Now drop the lock so MGS can revoke it */
+ if (!rcl) {
+ rcl = mgc_cancel(mgc->u.cli.cl_mgc_mgsexp, LCK_CR, &lockh);
+ if (rcl)
+ CERROR("Can't drop cfg lock: %d\n", rcl);
+ }
- RETURN(rc);
+ RETURN(rc);
}
if (rc)
CERROR("Cannot process recover llog %d\n", rc);
}
+
+ if (rc == 0 && cld->cld_params != NULL) {
+ rc = mgc_process_log(obd, cld->cld_params);
+ if (rc == -ENOENT) {
+ CDEBUG(D_MGC, "There is no params "
+ "config file yet\n");
+ rc = 0;
+ }
+ /* params log is optional */
+ if (rc)
+ CERROR("%s: can't process params llog: rc = %d\n",
+ obd->obd_name, rc);
+ }
config_log_put(cld);
break;
RETURN(rc);
}
-struct obd_ops mgc_obd_ops = {
+static struct obd_ops mgc_obd_ops = {
.o_owner = THIS_MODULE,
.o_setup = mgc_setup,
.o_precleanup = mgc_precleanup,
.o_del_conn = client_import_del_conn,
.o_connect = client_connect_import,
.o_disconnect = client_disconnect_export,
- //.o_enqueue = mgc_enqueue,
- .o_cancel = mgc_cancel,
- //.o_iocontrol = mgc_iocontrol,
.o_set_info_async = mgc_set_info_async,
.o_get_info = mgc_get_info,
.o_import_event = mgc_import_event,
- .o_llog_init = mgc_llog_init,
- .o_llog_finish = mgc_llog_finish,
.o_process_config = mgc_process_config,
};
-int __init mgc_init(void)
+static int __init mgc_init(void)
{
- return class_register_type(&mgc_obd_ops, NULL, NULL,
- LUSTRE_MGC_NAME, NULL);
+ return class_register_type(&mgc_obd_ops, NULL, true, NULL,
+ LUSTRE_MGC_NAME, NULL);
}
-#ifdef __KERNEL__
static void /*__exit*/ mgc_exit(void)
{
class_unregister_type(LUSTRE_MGC_NAME);
module_init(mgc_init);
module_exit(mgc_exit);
-#endif