-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011 Whamcloud, Inc.
- *
+ * Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <linux/string.h>
#else
#include <liblustre.h>
+#include <string.h>
#include <obd_class.h>
#include <obd.h>
#endif
#include <lustre_log.h>
#include <lprocfs_status.h>
-#include <libcfs/list.h>
#include <lustre_param.h>
+#include "llog_internal.h"
+
static cfs_hash_ops_t uuid_hash_ops;
static cfs_hash_ops_t nid_hash_ops;
static cfs_hash_ops_t nid_stat_hash_ops;
return 0;
}
+EXPORT_SYMBOL(class_find_param);
+
+/**
+ * Check whether the proc parameter \a param is an old parameter or not from
+ * the array \a ptr which contains the mapping from old parameters to new ones.
+ * If it's an old one, then return the pointer to the cfg_interop_param struc-
+ * ture which contains both the old and new parameters.
+ *
+ * \param param proc parameter
+ * \param ptr an array which contains the mapping from
+ * old parameters to new ones
+ *
+ * \retval valid-pointer pointer to the cfg_interop_param structure
+ * which contains the old and new parameters
+ * \retval NULL \a param or \a ptr is NULL,
+ * or \a param is not an old parameter
+ */
+struct cfg_interop_param *class_find_old_param(const char *param,
+ struct cfg_interop_param *ptr)
+{
+ char *value = NULL;
+ int name_len = 0;
+
+ if (param == NULL || ptr == NULL)
+ RETURN(NULL);
+
+ value = strchr(param, '=');
+ if (value == NULL)
+ name_len = strlen(param);
+ else
+ name_len = value - param;
+
+ while (ptr->old_param != NULL) {
+ if (strncmp(param, ptr->old_param, name_len) == 0 &&
+ name_len == strlen(ptr->old_param))
+ RETURN(ptr);
+ ptr++;
+ }
+
+ RETURN(NULL);
+}
+EXPORT_SYMBOL(class_find_old_param);
/**
* Finds a parameter in \a params and copies it to \a copy.
}
return 1;
}
+EXPORT_SYMBOL(class_get_next_param);
/* returns 0 if this is the first key in the buffer, else 1.
valp points to first char after key. */
return 0;
}
+EXPORT_SYMBOL(class_match_param);
-static int parse_nid(char *buf, void *value)
+static int parse_nid(char *buf, void *value, int quiet)
{
lnet_nid_t *nid = (lnet_nid_t *)value;
if (*nid != LNET_NID_ANY)
return 0;
- LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
+ if (!quiet)
+ LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
return -EINVAL;
}
1 not found
< 0 error
endh is set to next separator */
-static int class_parse_value(char *buf, int opc, void *value, char **endh)
+static int class_parse_value(char *buf, int opc, void *value, char **endh,
+ int quiet)
{
char *endp;
char tmp;
default:
LBUG();
case CLASS_PARSE_NID:
- rc = parse_nid(buf, value);
+ rc = parse_nid(buf, value, quiet);
break;
case CLASS_PARSE_NET:
rc = parse_net(buf, value);
int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
{
- return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh);
+ return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
}
+EXPORT_SYMBOL(class_parse_nid);
+
+int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
+{
+ return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
+}
+EXPORT_SYMBOL(class_parse_nid_quiet);
int class_parse_net(char *buf, __u32 *net, char **endh)
{
- return class_parse_value(buf, CLASS_PARSE_NET, (void *)net, endh);
+ return class_parse_value(buf, CLASS_PARSE_NET, (void *)net, endh, 0);
}
+EXPORT_SYMBOL(class_parse_net);
/* 1 param contains key and match
* 0 param contains key and not match
}
return rc;
}
+EXPORT_SYMBOL(class_match_nid);
int class_match_net(char *buf, char *key, __u32 net)
{
}
return rc;
}
-
-EXPORT_SYMBOL(class_find_param);
-EXPORT_SYMBOL(class_get_next_param);
-EXPORT_SYMBOL(class_match_param);
-EXPORT_SYMBOL(class_parse_nid);
-EXPORT_SYMBOL(class_parse_net);
-EXPORT_SYMBOL(class_match_nid);
EXPORT_SYMBOL(class_match_net);
/********************** class fns **********************/
LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
"%p obd_name %s != %s\n", obd, obd->obd_name, name);
- cfs_rwlock_init(&obd->obd_pool_lock);
- obd->obd_pool_limit = 0;
- obd->obd_pool_slv = 0;
-
- CFS_INIT_LIST_HEAD(&obd->obd_exports);
- CFS_INIT_LIST_HEAD(&obd->obd_unlinked_exports);
- CFS_INIT_LIST_HEAD(&obd->obd_delayed_exports);
- CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
- CFS_INIT_LIST_HEAD(&obd->obd_nid_stats);
- cfs_spin_lock_init(&obd->obd_nid_lock);
- cfs_spin_lock_init(&obd->obd_dev_lock);
- cfs_sema_init(&obd->obd_dev_sem, 1);
- cfs_spin_lock_init(&obd->obd_osfs_lock);
- /* obd->obd_osfs_age must be set to a value in the distant
- * past to guarantee a fresh statfs is fetched on mount. */
- obd->obd_osfs_age = cfs_time_shift_64(-1000);
-
- /* XXX belongs in setup not attach */
- cfs_init_rwsem(&obd->obd_observer_link_sem);
- /* recovery data */
- cfs_init_timer(&obd->obd_recovery_timer);
- cfs_spin_lock_init(&obd->obd_recovery_task_lock);
+ rwlock_init(&obd->obd_pool_lock);
+ obd->obd_pool_limit = 0;
+ obd->obd_pool_slv = 0;
+
+ CFS_INIT_LIST_HEAD(&obd->obd_exports);
+ CFS_INIT_LIST_HEAD(&obd->obd_unlinked_exports);
+ CFS_INIT_LIST_HEAD(&obd->obd_delayed_exports);
+ CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
+ CFS_INIT_LIST_HEAD(&obd->obd_nid_stats);
+ spin_lock_init(&obd->obd_nid_lock);
+ spin_lock_init(&obd->obd_dev_lock);
+ mutex_init(&obd->obd_dev_mutex);
+ spin_lock_init(&obd->obd_osfs_lock);
+ /* obd->obd_osfs_age must be set to a value in the distant
+ * past to guarantee a fresh statfs is fetched on mount. */
+ obd->obd_osfs_age = cfs_time_shift_64(-1000);
+
+ /* XXX belongs in setup not attach */
+ init_rwsem(&obd->obd_observer_link_sem);
+ /* recovery data */
+ cfs_init_timer(&obd->obd_recovery_timer);
+ spin_lock_init(&obd->obd_recovery_task_lock);
cfs_waitq_init(&obd->obd_next_transno_waitq);
cfs_waitq_init(&obd->obd_evict_inprogress_waitq);
CFS_INIT_LIST_HEAD(&obd->obd_req_replay_queue);
llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);
+ obd->obd_conn_inprogress = 0;
+
len = strlen(uuid);
if (len >= sizeof(obd->obd_uuid)) {
CERROR("uuid must be < %d bytes long\n",
}
/* Detach drops this */
- cfs_spin_lock(&obd->obd_dev_lock);
- cfs_atomic_set(&obd->obd_refcount, 1);
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_lock(&obd->obd_dev_lock);
+ cfs_atomic_set(&obd->obd_refcount, 1);
+ spin_unlock(&obd->obd_dev_lock);
lu_ref_init(&obd->obd_reference);
lu_ref_add(&obd->obd_reference, "attach", obd);
}
return rc;
}
+EXPORT_SYMBOL(class_attach);
/** Create hashes, self-export, and call type-specific setup.
* Setup is effectively the "start this obd" call.
}
/* is someone else setting us up right now? (attach inits spinlock) */
- cfs_spin_lock(&obd->obd_dev_lock);
- if (obd->obd_starting) {
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_lock(&obd->obd_dev_lock);
+ if (obd->obd_starting) {
+ spin_unlock(&obd->obd_dev_lock);
CERROR("Device %d setup in progress (type %s)\n",
obd->obd_minor, obd->obd_type->typ_name);
RETURN(-EEXIST);
obd->obd_uuid_hash = NULL;
obd->obd_nid_hash = NULL;
obd->obd_nid_stats_hash = NULL;
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_unlock(&obd->obd_dev_lock);
/* create an uuid-export lustre hash */
obd->obd_uuid_hash = cfs_hash_create("UUID_HASH",
obd->obd_set_up = 1;
- cfs_spin_lock(&obd->obd_dev_lock);
- /* cleanup drops this */
- class_incref(obd, "setup", obd);
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_lock(&obd->obd_dev_lock);
+ /* cleanup drops this */
+ class_incref(obd, "setup", obd);
+ spin_unlock(&obd->obd_dev_lock);
CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
obd->obd_name, obd->obd_uuid.uuid);
CERROR("setup %s failed (%d)\n", obd->obd_name, err);
return err;
}
+EXPORT_SYMBOL(class_setup);
/** We have finished using this obd and are ready to destroy it.
* There can be no more references to this obd.
RETURN(-EBUSY);
}
- cfs_spin_lock(&obd->obd_dev_lock);
- if (!obd->obd_attached) {
- cfs_spin_unlock(&obd->obd_dev_lock);
- CERROR("OBD device %d not attached\n", obd->obd_minor);
- RETURN(-ENODEV);
- }
- obd->obd_attached = 0;
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_lock(&obd->obd_dev_lock);
+ if (!obd->obd_attached) {
+ spin_unlock(&obd->obd_dev_lock);
+ CERROR("OBD device %d not attached\n", obd->obd_minor);
+ RETURN(-ENODEV);
+ }
+ obd->obd_attached = 0;
+ spin_unlock(&obd->obd_dev_lock);
CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
obd->obd_name, obd->obd_uuid.uuid);
class_decref(obd, "attach", obd);
RETURN(0);
}
+EXPORT_SYMBOL(class_detach);
/** Start shutting down the obd. There may be in-progess ops when
* this is called. We tell them to start shutting down with a call
RETURN(-ENODEV);
}
- cfs_spin_lock(&obd->obd_dev_lock);
- if (obd->obd_stopping) {
- cfs_spin_unlock(&obd->obd_dev_lock);
- CERROR("OBD %d already stopping\n", obd->obd_minor);
- RETURN(-ENODEV);
- }
- /* Leave this on forever */
- obd->obd_stopping = 1;
- cfs_spin_unlock(&obd->obd_dev_lock);
+ spin_lock(&obd->obd_dev_lock);
+ if (obd->obd_stopping) {
+ spin_unlock(&obd->obd_dev_lock);
+ CERROR("OBD %d already stopping\n", obd->obd_minor);
+ RETURN(-ENODEV);
+ }
+ /* Leave this on forever */
+ obd->obd_stopping = 1;
+
+ /* wait for already-arrived-connections to finish. */
+ while (obd->obd_conn_inprogress > 0) {
+ spin_unlock(&obd->obd_dev_lock);
+
+ cfs_cond_resched();
+
+ spin_lock(&obd->obd_dev_lock);
+ }
+ spin_unlock(&obd->obd_dev_lock);
if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
RETURN(0);
}
+EXPORT_SYMBOL(class_cleanup);
struct obd_device *class_incref(struct obd_device *obd,
const char *scope, const void *source)
return obd;
}
+EXPORT_SYMBOL(class_incref);
void class_decref(struct obd_device *obd, const char *scope, const void *source)
{
- int err;
- int refs;
+ int err;
+ int refs;
- cfs_spin_lock(&obd->obd_dev_lock);
- cfs_atomic_dec(&obd->obd_refcount);
- refs = cfs_atomic_read(&obd->obd_refcount);
- cfs_spin_unlock(&obd->obd_dev_lock);
- lu_ref_del(&obd->obd_reference, scope, source);
+ spin_lock(&obd->obd_dev_lock);
+ cfs_atomic_dec(&obd->obd_refcount);
+ refs = cfs_atomic_read(&obd->obd_refcount);
+ spin_unlock(&obd->obd_dev_lock);
+ lu_ref_del(&obd->obd_reference, scope, source);
- CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
+ CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
- if ((refs == 1) && obd->obd_stopping) {
- /* All exports have been destroyed; there should
- be no more in-progress ops by this point.*/
+ if ((refs == 1) && obd->obd_stopping) {
+ /* All exports have been destroyed; there should
+ be no more in-progress ops by this point.*/
- cfs_spin_lock(&obd->obd_self_export->exp_lock);
- obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
- cfs_spin_unlock(&obd->obd_self_export->exp_lock);
+ spin_lock(&obd->obd_self_export->exp_lock);
+ obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
+ spin_unlock(&obd->obd_self_export->exp_lock);
/* note that we'll recurse into class_decref again */
class_unlink_export(obd->obd_self_export);
class_release_dev(obd);
}
}
+EXPORT_SYMBOL(class_decref);
/** Add a failover nid location.
* Client obd types contact server obd types using this nid list.
}
if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
+ strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) &&
strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
CERROR("can't add connection on non-client dev\n");
RETURN(-EINVAL);
RETURN(rc);
}
+EXPORT_SYMBOL(class_add_conn);
/** Remove a failover nid location.
*/
}
RETURN(NULL);
}
+EXPORT_SYMBOL(class_get_profile);
/** Create a named "profile".
* This defines the mdc and osc names to use for a client.
}
EXIT;
}
+EXPORT_SYMBOL(class_del_profile);
/* COMPAT_146 */
void class_del_profiles(void)
}
EXIT;
}
+EXPORT_SYMBOL(class_del_profiles);
-static int class_set_global(char *ptr, int val) {
- ENTRY;
-
- if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
- at_min = val;
- else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
- at_max = val;
- else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
- at_extra = val;
- else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
- at_early_margin = val;
- else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
- at_history = val;
- else
- RETURN(-EINVAL);
-
- CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
-
- RETURN(0);
+static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
+{
+ ENTRY;
+ if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
+ at_min = val;
+ else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
+ at_max = val;
+ else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
+ at_extra = val;
+ else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
+ at_early_margin = val;
+ else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
+ at_history = val;
+ else if (class_match_param(ptr, PARAM_JOBID_VAR, NULL) == 0)
+ strlcpy(obd_jobid_var, lustre_cfg_string(lcfg, 2),
+ JOBSTATS_JOBID_VAR_MAX_LEN + 1);
+ else
+ RETURN(-EINVAL);
+
+ CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
+ RETURN(0);
}
-/* We can't call ll_process_config directly because it lives in a module that
- must be loaded after this one. */
+/* We can't call ll_process_config or lquota_process_config directly because
+ * it lives in a module that must be loaded after this one. */
static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
+static int (*quota_process_config)(struct lustre_cfg *lcfg) = NULL;
void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
{
}
EXPORT_SYMBOL(lustre_register_client_process_config);
+/**
+ * Rename the proc parameter in \a cfg with a new name \a new_name.
+ *
+ * \param cfg config structure which contains the proc parameter
+ * \param new_name new name of the proc parameter
+ *
+ * \retval valid-pointer pointer to the newly-allocated config structure
+ * which contains the renamed proc parameter
+ * \retval ERR_PTR(-EINVAL) if \a cfg or \a new_name is NULL, or \a cfg does
+ * not contain a proc parameter
+ * \retval ERR_PTR(-ENOMEM) if memory allocation failure occurs
+ */
+struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
+ const char *new_name)
+{
+ struct lustre_cfg_bufs *bufs = NULL;
+ struct lustre_cfg *new_cfg = NULL;
+ char *param = NULL;
+ char *new_param = NULL;
+ char *value = NULL;
+ int name_len = 0;
+ int new_len = 0;
+ ENTRY;
+
+ if (cfg == NULL || new_name == NULL)
+ RETURN(ERR_PTR(-EINVAL));
+
+ param = lustre_cfg_string(cfg, 1);
+ if (param == NULL)
+ RETURN(ERR_PTR(-EINVAL));
+
+ value = strchr(param, '=');
+ if (value == NULL)
+ name_len = strlen(param);
+ else
+ name_len = value - param;
+
+ new_len = LUSTRE_CFG_BUFLEN(cfg, 1) + strlen(new_name) - name_len;
+
+ OBD_ALLOC(new_param, new_len);
+ if (new_param == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ strcpy(new_param, new_name);
+ if (value != NULL)
+ strcat(new_param, value);
+
+ OBD_ALLOC_PTR(bufs);
+ if (bufs == NULL) {
+ OBD_FREE(new_param, new_len);
+ RETURN(ERR_PTR(-ENOMEM));
+ }
+
+ lustre_cfg_bufs_reset(bufs, NULL);
+ lustre_cfg_bufs_init(bufs, cfg);
+ lustre_cfg_bufs_set_string(bufs, 1, new_param);
+
+ new_cfg = lustre_cfg_new(cfg->lcfg_command, bufs);
+
+ OBD_FREE(new_param, new_len);
+ OBD_FREE_PTR(bufs);
+ if (new_cfg == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ new_cfg->lcfg_num = cfg->lcfg_num;
+ new_cfg->lcfg_flags = cfg->lcfg_flags;
+ new_cfg->lcfg_nid = cfg->lcfg_nid;
+ new_cfg->lcfg_nal = cfg->lcfg_nal;
+
+ RETURN(new_cfg);
+}
+EXPORT_SYMBOL(lustre_cfg_rename);
+
+void lustre_register_quota_process_config(int (*qpc)(struct lustre_cfg *lcfg))
+{
+ quota_process_config = qpc;
+}
+EXPORT_SYMBOL(lustre_register_quota_process_config);
+
/** Process configuration commands given in lustre_cfg form.
* These may come from direct calls (e.g. class_manual_cleanup)
* or processing the config llog, or ioctl from lctl.
CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
obd_timeout, lcfg->lcfg_num);
obd_timeout = max(lcfg->lcfg_num, 1U);
+ obd_timeout_set = 1;
GOTO(out, err = 0);
}
case LCFG_SET_LDLM_TIMEOUT: {
ldlm_timeout = max(lcfg->lcfg_num, 1U);
if (ldlm_timeout >= obd_timeout)
ldlm_timeout = max(obd_timeout / 3, 1U);
-
+ ldlm_timeout_set = 1;
GOTO(out, err = 0);
}
case LCFG_SET_UPCALL: {
} else if ((class_match_param(lustre_cfg_string(lcfg, 1),
PARAM_SYS, &tmp) == 0)) {
/* Global param settings */
- err = class_set_global(tmp, lcfg->lcfg_num);
- /* Note that since LCFG_PARAM is LCFG_REQUIRED, new
- unknown globals would cause config to fail */
- if (err)
- CWARN("Ignoring unknown param %s\n", tmp);
- GOTO(out, 0);
- }
-
+ err = class_set_global(tmp, lcfg->lcfg_num, lcfg);
+ /*
+ * Client or server should not fail to mount if
+ * it hits an unknown configuration parameter.
+ */
+ if (err != 0)
+ CWARN("Ignoring unknown param %s\n", tmp);
+
+ GOTO(out, err = 0);
+ } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
+ PARAM_QUOTA, &tmp) == 0) &&
+ quota_process_config) {
+ err = (*quota_process_config)(lcfg);
+ GOTO(out, err);
+ }
/* Fall through */
break;
}
}
return err;
}
+EXPORT_SYMBOL(class_process_config);
int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
struct lustre_cfg *lcfg, void *data)
CERROR("writing proc entry %s err %d\n",
var->name, rc);
rc = 0;
- } else {
- CDEBUG(D_CONFIG, "%s.%.*s: set parameter %.*s=%s\n",
- lustre_cfg_string(lcfg, 0),
- (int)strlen(prefix) - 1, prefix,
- (int)(sval - key - 1), key, sval);
- }
+ } else {
+ CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
+ lustre_cfg_string(lcfg, 0),
+ (int)strlen(prefix) - 1, prefix,
+ (int)(sval - key - 1), key, sval);
+ }
}
if (rc > 0)
RETURN(0);
#endif
}
-
-int class_config_dump_handler(struct llog_handle * handle,
- struct llog_rec_hdr *rec, void *data);
+EXPORT_SYMBOL(class_process_proc_param);
#ifdef __KERNEL__
extern int lustre_check_exclusion(struct super_block *sb, char *svname);
* records, change uuids, etc), then class_process_config() resulting
* net records.
*/
-static int class_config_llog_handler(struct llog_handle * handle,
- struct llog_rec_hdr *rec, void *data)
+int class_config_llog_handler(const struct lu_env *env,
+ struct llog_handle *handle,
+ struct llog_rec_hdr *rec, void *data)
{
struct config_llog_instance *clli = data;
int cfg_len = rec->lrh_len;
}
}
+#if defined(HAVE_SERVER_SUPPORT) && defined(__KERNEL__)
+ /* newer MDS replaces LOV/OSC with LOD/OSP */
+ {
+ char *typename = lustre_cfg_string(lcfg, 1);
+
+ if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
+ strcmp(typename, LUSTRE_LOV_NAME) == 0) &&
+ IS_MDT(s2lsi(clli->cfg_sb))) {
+ CDEBUG(D_CONFIG,
+ "For 2.x interoperability, rename obd "
+ "type from lov to lod (%s)\n",
+ s2lsi(clli->cfg_sb)->lsi_svname);
+ strcpy(typename, LUSTRE_LOD_NAME);
+ }
+ if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
+ strcmp(typename, LUSTRE_OSC_NAME) == 0) &&
+ IS_MDT(s2lsi(clli->cfg_sb))) {
+ CDEBUG(D_CONFIG,
+ "For 2.x interoperability, rename obd "
+ "type from osc to osp (%s)\n",
+ s2lsi(clli->cfg_sb)->lsi_svname);
+ strcpy(typename, LUSTRE_OSP_NAME);
+ }
+ }
+#endif
+
if ((clli->cfg_flags & CFG_F_EXCLUDE) &&
(lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
/* Add inactive instead */
}
out:
if (rc) {
- CERROR("Err %d on cfg command:\n", rc);
- class_config_dump_handler(handle, rec, data);
+ CERROR("%s: cfg command failed: rc = %d\n",
+ handle->lgh_ctxt->loc_obd->obd_name, rc);
+ class_config_dump_handler(NULL, handle, rec, data);
}
RETURN(rc);
}
+EXPORT_SYMBOL(class_config_llog_handler);
-int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
- struct config_llog_instance *cfg)
+int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
+ char *name, struct config_llog_instance *cfg)
{
- struct llog_process_cat_data cd = {0, 0};
- struct llog_handle *llh;
- int rc, rc2;
- ENTRY;
-
- CDEBUG(D_INFO, "looking up llog %s\n", name);
- rc = llog_create(ctxt, &llh, NULL, name);
- if (rc)
- RETURN(rc);
-
- rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
- if (rc)
- GOTO(parse_out, rc);
-
- /* continue processing from where we last stopped to end-of-log */
- if (cfg)
- cd.lpcd_first_idx = cfg->cfg_last_idx;
- cd.lpcd_last_idx = 0;
-
- rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
-
- CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
- cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
-
- if (cfg)
- cfg->cfg_last_idx = cd.lpcd_last_idx;
+ struct llog_process_cat_data cd = {0, 0};
+ struct llog_handle *llh;
+ llog_cb_t callback;
+ int rc;
+ ENTRY;
+
+ CDEBUG(D_INFO, "looking up llog %s\n", name);
+ rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
+ if (rc)
+ RETURN(rc);
+
+ rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(parse_out, rc);
+
+ /* continue processing from where we last stopped to end-of-log */
+ if (cfg) {
+ cd.lpcd_first_idx = cfg->cfg_last_idx;
+ callback = cfg->cfg_callback;
+ LASSERT(callback != NULL);
+ } else {
+ callback = class_config_llog_handler;
+ }
+
+ cd.lpcd_last_idx = 0;
+
+ rc = llog_process(env, llh, callback, cfg, &cd);
+
+ CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
+ cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
+ if (cfg)
+ cfg->cfg_last_idx = cd.lpcd_last_idx;
parse_out:
- rc2 = llog_close(llh);
- if (rc == 0)
- rc = rc2;
-
+ llog_close(env, llh);
RETURN(rc);
}
+EXPORT_SYMBOL(class_config_parse_llog);
-int class_config_dump_handler(struct llog_handle * handle,
- struct llog_rec_hdr *rec, void *data)
+/**
+ * parse config record and output dump in supplied buffer.
+ * This is separated from class_config_dump_handler() to use
+ * for ioctl needs as well
+ */
+int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf, int size)
{
- int cfg_len = rec->lrh_len;
- char *cfg_buf = (char*) (rec + 1);
- char *outstr, *ptr, *end;
- int rc = 0;
- ENTRY;
+ struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
+ char *ptr = buf;
+ char *end = buf + size;
+ int rc = 0;
+
+ ENTRY;
+
+ LASSERT(rec->lrh_type == OBD_CFG_REC);
+ rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
+ if (rc < 0)
+ RETURN(rc);
+
+ ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
+ if (lcfg->lcfg_flags)
+ ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
+ lcfg->lcfg_flags);
+
+ if (lcfg->lcfg_num)
+ ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
+
+ if (lcfg->lcfg_nid)
+ ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
+ libcfs_nid2str(lcfg->lcfg_nid),
+ lcfg->lcfg_nid);
+
+ if (lcfg->lcfg_command == LCFG_MARKER) {
+ struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
+
+ ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
+ marker->cm_step, marker->cm_flags,
+ marker->cm_tgtname, marker->cm_comment);
+ } else {
+ int i;
+
+ for (i = 0; i < lcfg->lcfg_bufcount; i++) {
+ ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
+ lustre_cfg_string(lcfg, i));
+ }
+ }
+ /* return consumed bytes */
+ rc = ptr - buf;
+ RETURN(rc);
+}
- OBD_ALLOC(outstr, 256);
- end = outstr + 256;
- ptr = outstr;
- if (!outstr) {
- RETURN(-ENOMEM);
- }
- if (rec->lrh_type == OBD_CFG_REC) {
- struct lustre_cfg *lcfg;
- int i;
+int class_config_dump_handler(const struct lu_env *env,
+ struct llog_handle *handle,
+ struct llog_rec_hdr *rec, void *data)
+{
+ char *outstr;
+ int rc = 0;
- rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
- if (rc)
- GOTO(out, rc);
- lcfg = (struct lustre_cfg *)cfg_buf;
+ ENTRY;
- ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
- lcfg->lcfg_command);
- if (lcfg->lcfg_flags) {
- ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
- lcfg->lcfg_flags);
- }
- if (lcfg->lcfg_num) {
- ptr += snprintf(ptr, end-ptr, "num=%#08x ",
- lcfg->lcfg_num);
- }
- if (lcfg->lcfg_nid) {
- ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
- libcfs_nid2str(lcfg->lcfg_nid),
- lcfg->lcfg_nid);
- }
- if (lcfg->lcfg_command == LCFG_MARKER) {
- struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
- ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
- marker->cm_step, marker->cm_flags,
- marker->cm_tgtname, marker->cm_comment);
- } else {
- for (i = 0; i < lcfg->lcfg_bufcount; i++) {
- ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
- lustre_cfg_string(lcfg, i));
- }
- }
- LCONSOLE(D_WARNING, " %s\n", outstr);
- } else {
- LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
- rc = -EINVAL;
- }
-out:
- OBD_FREE(outstr, 256);
- RETURN(rc);
+ OBD_ALLOC(outstr, 256);
+ if (outstr == NULL)
+ RETURN(-ENOMEM);
+
+ if (rec->lrh_type == OBD_CFG_REC) {
+ class_config_parse_rec(rec, outstr, 256);
+ LCONSOLE(D_WARNING, " %s\n", outstr);
+ } else {
+ LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
+ rc = -EINVAL;
+ }
+
+ OBD_FREE(outstr, 256);
+ RETURN(rc);
}
-int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
- struct config_llog_instance *cfg)
+int class_config_dump_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
+ char *name, struct config_llog_instance *cfg)
{
- struct llog_handle *llh;
- int rc, rc2;
- ENTRY;
+ struct llog_handle *llh;
+ int rc;
- LCONSOLE_INFO("Dumping config log %s\n", name);
+ ENTRY;
- rc = llog_create(ctxt, &llh, NULL, name);
- if (rc)
- RETURN(rc);
+ LCONSOLE_INFO("Dumping config log %s\n", name);
- rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
- if (rc)
- GOTO(parse_out, rc);
+ rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
+ if (rc)
+ RETURN(rc);
- rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
-parse_out:
- rc2 = llog_close(llh);
- if (rc == 0)
- rc = rc2;
+ rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(parse_out, rc);
- LCONSOLE_INFO("End config log %s\n", name);
- RETURN(rc);
+ rc = llog_process(env, llh, class_config_dump_handler, cfg, NULL);
+parse_out:
+ llog_close(env, llh);
+ LCONSOLE_INFO("End config log %s\n", name);
+ RETURN(rc);
}
+EXPORT_SYMBOL(class_config_dump_llog);
/** Call class_cleanup and class_detach.
* "Manual" only in the sense that we're faking lcfg commands.
lustre_cfg_free(lcfg);
RETURN(rc);
}
+EXPORT_SYMBOL(class_manual_cleanup);
/*
* uuid<->export lustre hash operations