/* Prefixes for parameters handled by obd's proc methods (XXX_process_config) */
#define PARAM_OST "ost."
+#define PARAM_OSD "osd."
#define PARAM_OSC "osc."
#define PARAM_MDT "mdt."
#define PARAM_HSM "mdt.hsm."
GOTO(end, rc);
}
- /* All mdd., ost. params in proc */
- if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
- (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
- CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+ /* All mdd., ost. and osd. params in proc */
+ if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
+ (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
+ (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
+ CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
if (mgs_log_is_empty(env, mgs, mti->mti_svname))
- GOTO(end, rc = -ENODEV);
+ GOTO(end, rc = -ENODEV);
rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
&mgi->mgi_bufs, mti->mti_svname, ptr);
- GOTO(end, rc);
- }
+ GOTO(end, rc);
+ }
LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
rc2 = -ENOSYS;
for (i = 1; i < lcfg->lcfg_bufcount; i++) {
key = lustre_cfg_buf(lcfg, i);
/* Strip off prefix */
- class_match_param(key, prefix, &key);
+ if (class_match_param(key, prefix, &key))
+ /* If the prefix doesn't match, return error so we
+ * can pass it down the stack */
+ RETURN(-ENOSYS);
sval = strchr(key, '=');
if (!sval || (*(sval + 1) == 0)) {
CERROR("Can't parse param %s (missing '=')\n", key);
}
j++;
}
- if (!matched) {
- /* If the prefix doesn't match, return error so we
- can pass it down the stack */
- if (strnchr(key, keylen, '.'))
- RETURN(-ENOSYS);
- CERROR("%s: unknown param %s\n",
- (char *)lustre_cfg_string(lcfg, 0), key);
- /* rc = -EINVAL; continue parsing other params */
- skip++;
- } else if (rc < 0) {
- CERROR("writing proc entry %s err %d\n",
- var->name, rc);
- rc = 0;
+ if (!matched) {
+ CERROR("%.*s: %s unknown param %s\n",
+ (int)strlen(prefix) - 1, prefix,
+ (char *)lustre_cfg_string(lcfg, 0), key);
+ /* rc = -EINVAL; continue parsing other params */
+ skip++;
+ } else if (rc < 0) {
+ CERROR("%s: error writing proc entry '%s': rc = %d\n",
+ prefix, var->name, rc);
+ rc = 0;
} else {
CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
lustre_cfg_string(lcfg, 0),
for (i = 1; i < lcfg->lcfg_bufcount; i++) {
key = lustre_cfg_buf(lcfg, i);
/* Strip off prefix */
- class_match_param(key, prefix, &key);
+ if (class_match_param(key, prefix, &key))
+ /* If the prefix doesn't match, return error so we
+ * can pass it down the stack */
+ RETURN(-ENOSYS);
sval = strchr(key, '=');
if (!sval || (*(sval + 1) == 0)) {
CERROR("Can't parse param %s (missing '=')\n", key);
j++;
}
if (!matched) {
- /* If the prefix doesn't match, return error so we
- can pass it down the stack */
- if (strnchr(key, keylen, '.'))
- RETURN(-ENOSYS);
- CERROR("%s: unknown param %s\n",
+ CERROR("%.*s: %s unknown param %s\n",
+ (int)strlen(prefix) - 1, prefix,
(char *)lustre_cfg_string(lcfg, 0), key);
/* rc = -EINVAL; continue parsing other params */
skip++;
} else if (rc < 0) {
- CERROR("writing proc entry %s err %d\n",
- var->name, rc);
+ CERROR("%s: error writing proc entry '%s': rc = %d\n",
+ prefix, var->name, rc);
rc = 0;
} else {
CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
{ NULL }
};
+/* Some parameters were moved from ofd to osd and only their
+ * symlinks were kept in ofd by LU-3106. They are:
+ * -writehthrough_cache_enable
+ * -readcache_max_filese
+ * -read_cache_enable
+ * -brw_stats
+ * Since they are not included by the static lprocfs var list,
+ * a pre-check is added for them to avoid "unknown param" error
+ * message confuses the customer. If they are matched in this
+ * check, they will be passed to the osd directly.
+ */
+static bool match_symlink_param(char *param)
+{
+ char *sval;
+ int paramlen;
+
+ if (class_match_param(param, PARAM_OST, ¶m) == 0) {
+ sval = strchr(param, '=');
+ if (sval != NULL) {
+ paramlen = sval - param;
+ if (strncmp(param, "writethrough_cache_enable",
+ paramlen) == 0 ||
+ strncmp(param, "readcache_max_filesize",
+ paramlen) == 0 ||
+ strncmp(param, "read_cache_enable",
+ paramlen) == 0 ||
+ strncmp(param, "brw_stats", paramlen) == 0)
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* used by MGS to process specific configurations */
static int ofd_process_config(const struct lu_env *env, struct lu_device *d,
struct lustre_cfg *cfg)
}
}
+ if (match_symlink_param(param)) {
+ rc = next->ld_ops->ldo_process_config(env, next, cfg);
+ break;
+ }
+
lprocfs_ofd_init_vars(&lvars);
rc = class_process_proc_param(PARAM_OST, lvars.obd_vars, cfg,
d->ld_obd);
- if (rc > 0 || rc == -ENOSYS)
+ if (rc > 0 || rc == -ENOSYS) {
+ CDEBUG(D_CONFIG, "pass param %s down the stack.\n",
+ param);
/* we don't understand; pass it on */
rc = next->ld_ops->ldo_process_config(env, next, cfg);
+ }
break;
}
case LCFG_SPTLRPC_CONF: {
/* struct ptlrpc_thread */
#include <lustre_net.h>
#include <lustre_fid.h>
+/* process_config */
+#include <lustre_param.h>
#include "osd_internal.h"
#include "osd_dynlocks.h"
static int osd_process_config(const struct lu_env *env,
struct lu_device *d, struct lustre_cfg *cfg)
{
- struct osd_device *o = osd_dev(d);
- int err;
- ENTRY;
+ struct osd_device *o = osd_dev(d);
+ int rc;
+ ENTRY;
- switch(cfg->lcfg_command) {
- case LCFG_SETUP:
- err = osd_mount(env, o, cfg);
- break;
- case LCFG_CLEANUP:
+ switch (cfg->lcfg_command) {
+ case LCFG_SETUP:
+ rc = osd_mount(env, o, cfg);
+ break;
+ case LCFG_CLEANUP:
lu_dev_del_linkage(d->ld_site, d);
- err = osd_shutdown(env, o);
+ rc = osd_shutdown(env, o);
break;
- default:
- err = -ENOSYS;
- }
+ case LCFG_PARAM:
+ LASSERT(&o->od_dt_dev);
+ rc = class_process_proc_param(PARAM_OSD, lprocfs_osd_obd_vars,
+ cfg, &o->od_dt_dev);
+ if (rc > 0 || rc == -ENOSYS)
+ rc = class_process_proc_param(PARAM_OST,
+ lprocfs_osd_obd_vars,
+ cfg, &o->od_dt_dev);
+ break;
+ default:
+ rc = -ENOSYS;
+ }
- RETURN(err);
+ RETURN(rc);
}
static int osd_recovery_complete(const struct lu_env *env,
static int __init osd_mod_init(void)
{
- struct lprocfs_static_vars lvars;
int rc;
osd_oi_mod_init();
- lprocfs_osd_init_vars(&lvars);
rc = lu_kmem_init(ldiskfs_caches);
if (rc)
rc = class_register_type(&osd_obd_device_ops, NULL, NULL,
#ifndef HAVE_ONLY_PROCFS_SEQ
- lvars.module_vars,
+ lprocfs_osd_module_vars,
#endif
LUSTRE_OSD_LDISKFS_NAME, &osd_device_type);
if (rc)
#ifdef LPROCFS
/* osd_lproc.c */
-void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars);
+extern struct lprocfs_vars lprocfs_osd_obd_vars[];
+extern struct lprocfs_vars lprocfs_osd_module_vars[];
int osd_procfs_init(struct osd_device *osd, const char *name);
int osd_procfs_fini(struct osd_device *osd);
void osd_brw_stats_update(struct osd_device *osd, struct osd_iobuf *iobuf);
int osd_procfs_init(struct osd_device *osd, const char *name)
{
- struct lprocfs_static_vars lvars;
struct obd_type *type;
int rc;
ENTRY;
LASSERT(type != NULL);
/* Find the type procroot and add the proc entry for this device */
- lprocfs_osd_init_vars(&lvars);
osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
- lvars.obd_vars, &osd->od_dt_dev);
+ lprocfs_osd_obd_vars,
+ &osd->od_dt_dev);
if (IS_ERR(osd->od_proc_entry)) {
rc = PTR_ERR(osd->od_proc_entry);
CERROR("Error %d setting up lprocfs for %s\n",
{ 0 }
};
-void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars)
-{
- lvars->module_vars = lprocfs_osd_module_vars;
- lvars->obd_vars = lprocfs_osd_obd_vars;
-}
#endif
#include <obd_class.h>
#include <lustre_disk.h>
#include <lustre_fid.h>
+#include <lustre_param.h>
#include <md_object.h>
#include "osd_internal.h"
struct lu_device *d, struct lustre_cfg *cfg)
{
struct osd_device *o = osd_dev(d);
- int err;
+ int rc;
ENTRY;
switch(cfg->lcfg_command) {
case LCFG_SETUP:
- err = osd_mount(env, o, cfg);
+ rc = osd_mount(env, o, cfg);
break;
case LCFG_CLEANUP:
- err = osd_shutdown(env, o);
+ rc = osd_shutdown(env, o);
+ break;
+ case LCFG_PARAM: {
+ LASSERT(&o->od_dt_dev);
+ rc = class_process_proc_param(PARAM_OSD, lprocfs_osd_obd_vars,
+ cfg, &o->od_dt_dev);
+ if (rc > 0 || rc == -ENOSYS)
+ rc = class_process_proc_param(PARAM_OST,
+ lprocfs_osd_obd_vars,
+ cfg, &o->od_dt_dev);
break;
+ }
default:
- err = -ENOTTY;
+ rc = -ENOTTY;
}
- RETURN(err);
+ RETURN(rc);
}
static int osd_recovery_complete(const struct lu_env *env, struct lu_device *d)
}
run_test 28 "permanent parameter setting"
+test_28a() { # LU-4221
+ [[ $(lustre_version_code ost1) -ge $(version_code 2.5.52) ]] ||
+ { skip "Need OST version at least 2.5.52" && return 0; }
+ [ "$(facet_fstype ost1)" = "zfs" ] &&
+ skip "LU-4221: no such proc params for ZFS OSTs" && return
+
+ local name
+ local param
+ local cmd
+ local old
+ local new
+ local device="$FSNAME-OST0000"
+
+ setup
+
+ # In this test we will set three kinds of proc parameters with
+ # lctl conf_param:
+ # 1. the ones moved from the OFD to the OSD, and only their
+ # symlinks kept in obdfilter
+ # 2. non-symlink ones in the OFD
+ # 3. non-symlink ones in the OSD
+
+ # Check 1.
+ # prepare a symlink parameter in the OFD
+ name="writethrough_cache_enable"
+ param="$device.ost.$name"
+ cmd="$LCTL get_param -n obdfilter.$device.$name"
+
+ # conf_param the symlink parameter in the OFD
+ old=$(do_facet ost1 $cmd)
+ new=$(((old + 1) % 2))
+ set_conf_param_and_check ost1 "$cmd" "$param" $new ||
+ error "lctl conf_param $device.ost.$param=$new failed"
+
+ # conf_param the target parameter in the OSD
+ param="$device.osd.$name"
+ cmd="$LCTL get_param -n osd-*.$device.$name"
+ set_conf_param_and_check ost1 "$cmd" "$param" $old ||
+ error "lctl conf_param $device.osd.$param=$old failed"
+
+ # Check 2.
+ # prepare a non-symlink parameter in the OFD
+ name="client_cache_seconds"
+ param="$device.ost.$name"
+ cmd="$LCTL get_param -n obdfilter.$device.$name"
+
+ # conf_param the parameter in the OFD
+ old=$(do_facet ost1 $cmd)
+ new=$((old * 2))
+ set_conf_param_and_check ost1 "$cmd" "$param" $new ||
+ error "lctl conf_param $device.ost.$param=$new failed"
+ set_conf_param_and_check ost1 "$cmd" "$param" $old ||
+ error "lctl conf_param $device.ost.$param=$old failed"
+
+ # Check 3.
+ # prepare a non-symlink parameter in the OSD
+ name="lma_self_repair"
+ param="$device.osd.$name"
+ cmd="$LCTL get_param -n osd-*.$device.$name"
+
+ # conf_param the parameter in the OSD
+ old=$(do_facet ost1 $cmd)
+ new=$(((old + 1) % 2))
+ set_conf_param_and_check ost1 "$cmd" "$param" $new ||
+ error "lctl conf_param $device.osd.$param=$new failed"
+ set_conf_param_and_check ost1 "$cmd" "$param" $old ||
+ error "lctl conf_param $device.osd.$param=$old failed"
+
+ cleanup
+}
+run_test 28a "set symlink parameters permanently with conf_param"
+
test_29() {
[ "$OSTCOUNT" -lt "2" ] && skip_env "$OSTCOUNT < 2, skipping" && return
setup > /dev/null 2>&1