From dfe60d0b98a1a888ca4ffce14788938c192b1520 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 13 Dec 2017 15:05:56 -0500 Subject: [PATCH] LU-7004 obd: make LCFG_SET_PARAM functional The LCFG_SET_PARAM infrastructure was meant to replace the class_process_proc_param() functionality but various software bugs have prevented its adoption. This patch does the following: 1) Take the better print_lustre_cfg() of the mgs module and use that in llog_swab.c instead with the intent of exporting this function. I add to process_param2_config() a call to print_lustre_cfg() for debugging purposes. 2) Move obdname2fsname to obd_mount.c and make it exportable. Expanded the functionality to work for both lctl conf_param and lctl set_parm -P. 3) Split mgs_setparam() into two functions since the difference in LCFG_SET_PARAM and LCFG_PARAM are large enough. Currently virtual attributes failover.nid, sptlrpc, and quota are not fully supported. They will be addressed in later patches. Change-Id: Iced6505f39a3270139c1630270cfe1dc4a2e49ed Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/28590 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Fan Yong Reviewed-by: Dmitry Eremin Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/include/lustre_disk.h | 1 + lustre/include/obd_class.h | 1 + lustre/mgs/mgs_handler.c | 17 +- lustre/mgs/mgs_internal.h | 4 +- lustre/mgs/mgs_llog.c | 461 ++++++++++++++++++++++++++++++------------- lustre/obdclass/llog_swab.c | 17 +- lustre/obdclass/obd_mount.c | 73 +++++++ lustre/ptlrpc/sec_config.c | 43 ---- 8 files changed, 416 insertions(+), 201 deletions(-) diff --git a/lustre/include/lustre_disk.h b/lustre/include/lustre_disk.h index a091158..45380ee 100644 --- a/lustre/include/lustre_disk.h +++ b/lustre/include/lustre_disk.h @@ -325,6 +325,7 @@ int server_name2fsname(const char *svname, char *fsname, const char **endptr); int server_name2svname(const char *label, char *svname, const char **endptr, size_t svsize); +void obdname2fsname(const char *tgt, char *fsname, size_t buflen); #ifdef HAVE_SERVER_SUPPORT int server_name_is_ost(const char *svname); diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 028000b..be2bf54 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -138,6 +138,7 @@ struct cfg_interop_param { char *lustre_cfg_string(struct lustre_cfg *lcfg, u32 index); struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg, const char *new_name); +void print_lustre_cfg(struct lustre_cfg *lcfg); int class_process_config(struct lustre_cfg *lcfg); int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, struct lustre_cfg *lcfg, void *data); diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 42f2346..6db1b45 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -130,7 +130,7 @@ static int mgs_set_info(struct tgt_session_info *tsi) !str_starts_with(s + 1, "lov.stripeoffset=")) RETURN(-EINVAL); - /* Construct lustre_cfg structure to pass to function mgs_setparam */ + /* Construct lustre_cfg structure to pass to function mgs_set_param */ lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL); lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, msp->mgs_param); OBD_ALLOC(lcfg, lustre_cfg_len(mgi->mgi_bufs.lcfg_bufcount, @@ -139,12 +139,10 @@ static int mgs_set_info(struct tgt_session_info *tsi) RETURN(-ENOMEM); lustre_cfg_init(lcfg, LCFG_PARAM, &mgi->mgi_bufs); - rc = mgs_setparam(tsi->tsi_env, exp2mgs_dev(tsi->tsi_exp), lcfg, - mgi->mgi_fsname); + rc = mgs_set_param(tsi->tsi_env, exp2mgs_dev(tsi->tsi_exp), lcfg); if (rc) { - LCONSOLE_WARN("%s: Unable to set parameter %s for %s: %d\n", - tgt_name(tsi->tsi_tgt), msp->mgs_param, - mgi->mgi_fsname, rc); + LCONSOLE_WARN("%s: Unable to set parameter %s: %d\n", + tgt_name(tsi->tsi_tgt), msp->mgs_param, rc); GOTO(out_cfg, rc); } @@ -1018,9 +1016,8 @@ static int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len, switch (cmd) { - case OBD_IOC_PARAM: { - struct mgs_thread_info *mgi = mgs_env_info(&env); - struct lustre_cfg *lcfg; + case OBD_IOC_PARAM: { + struct lustre_cfg *lcfg; if (data->ioc_type != LUSTRE_CFG_TYPE) { CERROR("%s: unknown cfg record type: %d\n", @@ -1037,7 +1034,7 @@ static int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len, if (lcfg->lcfg_bufcount < 1) GOTO(out_free, rc = -EINVAL); - rc = mgs_setparam(&env, mgs, lcfg, mgi->mgi_fsname); + rc = mgs_set_param(&env, mgs, lcfg); if (rc) CERROR("%s: setparam err: rc = %d\n", exp->exp_obd->obd_name, rc); diff --git a/lustre/mgs/mgs_internal.h b/lustre/mgs/mgs_internal.h index 517422b..2e1f761 100644 --- a/lustre/mgs/mgs_internal.h +++ b/lustre/mgs/mgs_internal.h @@ -215,8 +215,8 @@ int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name); int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, const char *fsname); -int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs, - struct lustre_cfg *lcfg, char *fsname); +int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs, + struct lustre_cfg *lcfg); int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs, struct obd_ioctl_data *data); int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs, diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index c020926..530d3ca 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -1351,15 +1351,31 @@ out_put: /** * Parse device name and get file system name and/or device index * - * \param[in] devname device name (ex. lustre-MDT0000) - * \param[out] fsname file system name(optional) - * \param[out] index device index(optional) + * @devname device name (ex. lustre-MDT0000) + * @fsname file system name extracted from @devname and returned + * to the caller (optional) + * @index device index extracted from @devname and returned to + * the caller (optional) * - * \retval 0 success + * RETURN 0 success if we are only interested in + * extracting fsname from devname. + * i.e index is NULL + * + * LDD_F_SV_TYPE_* Besides extracting the fsname the + * user also wants the index. Report to + * the user the type of obd device the + * returned index belongs too. + * + * -EINVAL The obd device name is improper so + * fsname could not be extracted. + * + * -ENXIO Failed to extract the index out of + * the obd device name. Most likely an + * invalid obd device name */ -static int mgs_parse_devname(char *devname, char *fsname, __u32 *index) +static int mgs_parse_devname(char *devname, char *fsname, u32 *index) { - int rc; + int rc = 0; ENTRY; /* Extract fsname */ @@ -1377,11 +1393,12 @@ static int mgs_parse_devname(char *devname, char *fsname, __u32 *index) if (rc < 0) { CDEBUG(D_MGS, "Device name %s with wrong index\n", devname); - RETURN(-EINVAL); + RETURN(-ENXIO); } } - RETURN(0); + /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */ + RETURN(rc); } /* This is only called during replace_nids */ @@ -1461,9 +1478,9 @@ int mgs_replace_nids(const struct lu_env *env, GOTO(out, rc = -EINPROGRESS); } - /* Get fsname and index*/ + /* Get fsname and index */ rc = mgs_parse_devname(devname, fsname, &index); - if (rc) + if (rc < 0) GOTO(out, rc); rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb); @@ -2904,7 +2921,8 @@ static int mgs_write_log_add_failnid(const struct lu_env *env, /* FIXME we currently can't erase the failnids * given when a target first registers, since they aren't part of - * an "add uuid" stanza */ + * an "add uuid" stanza + */ /* Verify that we know about this target */ if (mgs_log_is_empty(env, mgs, mti->mti_svname)) { @@ -2924,12 +2942,14 @@ static int mgs_write_log_add_failnid(const struct lu_env *env, } if (rc) RETURN(rc); + /* Add failover nids to the client log */ rc = name_create(&logname, mti->mti_fsname, "-client"); if (rc) { name_destroy(&cliname); RETURN(rc); } + rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname); name_destroy(&logname); name_destroy(&cliname); @@ -3014,22 +3034,6 @@ static int mgs_wlp_lcfg(const struct lu_env *env, return rc; } -static int mgs_write_log_param2(const struct lu_env *env, - struct mgs_device *mgs, - struct fs_db *fsdb, - struct mgs_target_info *mti, char *ptr) -{ - struct lustre_cfg_bufs bufs; - int rc = 0; - ENTRY; - - CDEBUG(D_MGS, "next param '%s'\n", ptr); - rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs, - mti->mti_svname, ptr); - - RETURN(rc); -} - /* write global variable settings into log */ static int mgs_write_log_sys(const struct lu_env *env, struct mgs_device *mgs, struct fs_db *fsdb, @@ -3510,6 +3514,79 @@ out: RETURN(rc); } +static int mgs_write_log_param2(const struct lu_env *env, + struct mgs_device *mgs, + struct fs_db *fsdb, + struct mgs_target_info *mti, char *ptr) +{ + struct lustre_cfg_bufs bufs; + int rc; + + ENTRY; + CDEBUG(D_MGS, "next param '%s'\n", ptr); + + /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating + * or during the inital mount. It can never change after that. + */ + if (!class_match_param(ptr, PARAM_MGSNODE, NULL) || + !class_match_param(ptr, PARAM_NETWORK, NULL)) { + rc = 0; + goto end; + } + + /* Processed in mgs_write_log_ost. Another value that can't + * be changed by lctl set_param -P. + */ + if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) { + LCONSOLE_ERROR_MSG(0x169, + "%s can only be changed with tunefs.lustre and --writeconf\n", + ptr); + rc = -EPERM; + goto end; + } + + /* FIXME !!! Support for sptlrpc is incomplete. Currently the change + * doesn't transmit to the client. See LU-7183. + */ + if (!class_match_param(ptr, PARAM_SRPC, NULL)) { + rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr); + goto end; + } + + /* Can't use class_match_param since ptr doesn't start with + * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr. + */ + if (strstr(ptr, PARAM_FAILNODE)) { + /* Add a failover nidlist. We already processed failovers + * params for new targets in mgs_write_log_target. + */ + const char *param; + + /* can't use wildcards with failover.node */ + if (strchr(ptr, '*')) { + rc = -ENODEV; + goto end; + } + + param = strstr(ptr, PARAM_FAILNODE); + if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >= + sizeof(mti->mti_params)) { + rc = -E2BIG; + goto end; + } + + CDEBUG(D_MGS, "Adding failnode with param %s\n", + mti->mti_params); + rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti); + goto end; + } + + rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs, + mti->mti_svname, ptr); +end: + RETURN(rc); +} + /* Permanent settings of all parameters by writing into the appropriate * configuration logs. * A parameter with null value ("='\0'") means to erase it out of @@ -4681,30 +4758,6 @@ next: RETURN(rc); } -/* from llog_swab */ -static void print_lustre_cfg(struct lustre_cfg *lcfg) -{ - int i; - ENTRY; - - CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg); - CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version); - - CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command); - CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num); - CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags); - CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid)); - - CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount); - if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT) - for (i = 0; i < lcfg->lcfg_bufcount; i++) { - CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n", - i, lcfg->lcfg_buflens[i], - lustre_cfg_string(lcfg, i)); - } - EXIT; -} - /* Setup _mgs fsdb and log */ int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs) @@ -4752,123 +4805,251 @@ int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs) return rc == -ENOENT ? 0 : rc; } -/* Set a permanent (config log) param for a target or fs - * \param lcfg buf0 may contain the device (testfs-MDT0000) name - * buf1 contains the single parameter - */ -int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs, - struct lustre_cfg *lcfg, char *fsname) +/** + * Fill in the mgs_target_info based on data devname and param provide. + * + * @env thread context + * @mgs mgs device + * @mti mgs target info. We want to set this based other paramters + * passed to this function. Once setup we write it to the config + * logs. + * @devname optional OBD device name + * @param string that contains both what tunable to set and the value to + * set it to. + * + * RETURN 0 for success + * negative error number on failure + **/ +static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs, + struct mgs_target_info *mti, const char *devname, + const char *param) { struct fs_db *fsdb = NULL; - struct mgs_target_info *mti = NULL; - char *devname, *param; - char *ptr; - const char *tmp; - __u32 index; + int dev_type; int rc = 0; - bool free = false; + ENTRY; + /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */ + if (!devname) { + size_t len; + + /* We have two possible cases here: + * + * 1) the device name embedded in the param: + * lustre-OST0000.osc.max_dirty_mb=32 + * + * 2) the file system name is embedded in + * the param: lustre.sys.at.min=0 + */ + len = strcspn(param, ".="); + if (!len || param[len] == '=') + RETURN(-EINVAL); - print_lustre_cfg(lcfg); + if (len >= sizeof(mti->mti_svname)) + RETURN(-E2BIG); - /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */ - devname = lustre_cfg_string(lcfg, 0); - param = lustre_cfg_string(lcfg, 1); - if (!devname) { - /* Assume device name embedded in param: - lustre-OST0000.osc.max_dirty_mb=32 */ - ptr = strchr(param, '.'); - if (ptr) { - devname = param; - *ptr = 0; - param = ptr + 1; - } - } - if (!devname) { - LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param); - RETURN(-ENOSYS); - } + snprintf(mti->mti_svname, sizeof(mti->mti_svname), + "%.*s", (int)len, param); + param += len + 1; + } else { + if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >= + sizeof(mti->mti_svname)) + RETURN(-E2BIG); + } - rc = mgs_parse_devname(devname, fsname, NULL); - if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) { - /* param related to llite isn't allowed to set by OST or MDT */ - if (rc == 0 && strncmp(param, PARAM_LLITE, - sizeof(PARAM_LLITE) - 1) == 0) - RETURN(-EINVAL); - } else { - /* assume devname is the fsname */ - strlcpy(fsname, devname, MTI_NAME_MAXLEN); - } - CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname); + if (!strlen(mti->mti_svname)) { + LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param); + RETURN(-ENOSYS); + } - rc = mgs_find_or_make_fsdb(env, mgs, - lcfg->lcfg_command == LCFG_SET_PARAM ? - PARAMS_FILENAME : fsname, &fsdb); + dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname, + &mti->mti_stripe_index); + switch (dev_type) { + /* For this case we have an invalid obd device name */ + case -ENXIO: + CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname); + strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN); + dev_type = 0; + break; + /* Not an obd device, assume devname is the fsname. + * User might of only provided fsname and not obd device + */ + case -EINVAL: + CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname); + strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN); + dev_type = 0; + break; + default: + if (dev_type < 0) + GOTO(out, rc = dev_type); + + /* param related to llite isn't allowed to set by OST or MDT */ + if (dev_type & LDD_F_SV_TYPE_OST || + dev_type & LDD_F_SV_TYPE_MDT) { + /* param related to llite isn't allowed to set by OST + * or MDT + */ + if (!strncmp(param, PARAM_LLITE, + sizeof(PARAM_LLITE) - 1)) + GOTO(out, rc = -EINVAL); + + /* Strip -osc or -mdc suffix from svname */ + if (server_make_name(dev_type, mti->mti_stripe_index, + mti->mti_fsname, mti->mti_svname, + sizeof(mti->mti_svname))) + GOTO(out, rc = -EINVAL); + } + break; + } + + if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >= + sizeof(mti->mti_params)) + GOTO(out, rc = -E2BIG); + + CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n", + mti->mti_fsname, mti->mti_svname, mti->mti_params); + + rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb); if (rc) - RETURN(rc); + GOTO(out, rc); - if (lcfg->lcfg_command != LCFG_SET_PARAM && - !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) && + if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) && test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) { CERROR("No filesystem targets for %s. cfg_device from lctl " - "is '%s'\n", fsname, devname); - free = true; + "is '%s'\n", mti->mti_fsname, mti->mti_svname); + mgs_unlink_fsdb(mgs, fsdb); GOTO(out, rc = -EINVAL); } - /* Create a fake mti to hold everything */ - OBD_ALLOC_PTR(mti); - if (!mti) - GOTO(out, rc = -ENOMEM); - if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname)) - >= sizeof(mti->mti_fsname)) - GOTO(out, rc = -E2BIG); - if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) - >= sizeof(mti->mti_svname)) - GOTO(out, rc = -E2BIG); - if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) - >= sizeof(mti->mti_params)) - GOTO(out, rc = -E2BIG); - rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp); - if (rc < 0) - /* Not a valid server; may be only fsname */ - rc = 0; - else - /* Strip -osc or -mdc suffix from svname */ - if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname, - mti->mti_svname, sizeof(mti->mti_svname))) - GOTO(out, rc = -EINVAL); /* * Revoke lock so everyone updates. Should be alright if * someone was already reading while we were updating the logs, * so we don't really need to hold the lock while we're * writing (above). */ - if (lcfg->lcfg_command == LCFG_SET_PARAM) { - mti->mti_flags = rc | LDD_F_PARAM2; - mutex_lock(&fsdb->fsdb_mutex); - rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params); - mutex_unlock(&fsdb->fsdb_mutex); - mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS); + mti->mti_flags = dev_type | LDD_F_PARAM; + mutex_lock(&fsdb->fsdb_mutex); + rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params); + mutex_unlock(&fsdb->fsdb_mutex); + mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG); + +out: + if (fsdb) + mgs_put_fsdb(mgs, fsdb); + + RETURN(rc); +} + +static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs, + struct mgs_target_info *mti, const char *param) +{ + struct fs_db *fsdb = NULL; + int dev_type; + size_t len; + int rc; + + if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >= + sizeof(mti->mti_params)) + GOTO(out, rc = -E2BIG); + + /* obdname2fsname reports devname as an obd device */ + len = strcspn(param, ".="); + if (len && param[len] != '=') { + char *ptr; + + param += len + 1; + ptr = strchr(param, '.'); + + len = strlen(param); + if (ptr) + len -= strlen(ptr); + if (len >= sizeof(mti->mti_svname)) + GOTO(out, rc = -E2BIG); + + snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s", + (int)len, param); + + obdname2fsname(mti->mti_svname, mti->mti_fsname, + sizeof(mti->mti_fsname)); } else { - mti->mti_flags = rc | LDD_F_PARAM; - mutex_lock(&fsdb->fsdb_mutex); - rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params); - mutex_unlock(&fsdb->fsdb_mutex); - mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG); + snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general"); } + CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n", + mti->mti_fsname, mti->mti_svname, mti->mti_params); + + /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX. + * A returned error tells us we don't have a target obd device. + */ + dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index, + NULL); + if (dev_type < 0) + dev_type = 0; + + /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX. + * Strip -osc or -mdc suffix from svname + */ + if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) && + server_make_name(dev_type, mti->mti_stripe_index, + mti->mti_fsname, mti->mti_svname, + sizeof(mti->mti_svname))) + GOTO(out, rc = -EINVAL); + + rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb); + if (rc) + GOTO(out, rc); + /* + * Revoke lock so everyone updates. Should be alright if + * someone was already reading while we were updating the logs, + * so we don't really need to hold the lock while we're + * writing (above). + */ + mti->mti_flags = dev_type | LDD_F_PARAM2; + mutex_lock(&fsdb->fsdb_mutex); + rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params); + mutex_unlock(&fsdb->fsdb_mutex); + mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS); + mgs_put_fsdb(mgs, fsdb); out: - if (mti) - OBD_FREE_PTR(mti); + RETURN(rc); +} - if (fsdb) { - if (free) - mgs_unlink_fsdb(mgs, fsdb); - mgs_put_fsdb(mgs, fsdb); +/* Set a permanent (config log) param for a target or fs + * + * @lcfg buf0 may contain the device (testfs-MDT0000) name + * buf1 contains the single parameter + */ +int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs, + struct lustre_cfg *lcfg) +{ + const char *param = lustre_cfg_string(lcfg, 1); + struct mgs_target_info *mti; + int rc; + + /* Create a fake mti to hold everything */ + OBD_ALLOC_PTR(mti); + if (!mti) + return -ENOMEM; + + print_lustre_cfg(lcfg); + + if (lcfg->lcfg_command == LCFG_PARAM) { + /* For the case of lctl conf_param devname can be + * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 + */ + const char *devname = lustre_cfg_string(lcfg, 0); + + rc = mgs_set_conf_param(env, mgs, mti, devname, param); + } else { + /* In the case of lctl set_param -P lcfg[0] will always + * be 'general'. At least for now. + */ + rc = mgs_set_param2(env, mgs, mti, param); } - RETURN(rc); + OBD_FREE_PTR(mti); + + return rc; } static int mgs_write_log_pool(const struct lu_env *env, diff --git a/lustre/obdclass/llog_swab.c b/lustre/obdclass/llog_swab.c index 29c72e1..4ba4cea 100644 --- a/lustre/obdclass/llog_swab.c +++ b/lustre/obdclass/llog_swab.c @@ -355,13 +355,14 @@ void lustre_swab_llog_hdr (struct llog_log_hdr *h) } EXPORT_SYMBOL(lustre_swab_llog_hdr); -static void print_lustre_cfg(struct lustre_cfg *lcfg) +void print_lustre_cfg(struct lustre_cfg *lcfg) { int i; ENTRY; if (!(libcfs_debug & D_OTHER)) /* don't loop on nothing */ return; + CDEBUG(D_OTHER, "lustre_cfg: %p\n", lcfg); CDEBUG(D_OTHER, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version); @@ -370,13 +371,17 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg) CDEBUG(D_OTHER, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags); CDEBUG(D_OTHER, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid)); - CDEBUG(D_OTHER, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount); - if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT) - for (i = 0; i < lcfg->lcfg_bufcount; i++) - CDEBUG(D_OTHER, "\tlcfg->lcfg_buflens[%d]: %d\n", - i, lcfg->lcfg_buflens[i]); + CDEBUG(D_OTHER, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount); + if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT) + for (i = 0; i < lcfg->lcfg_bufcount; i++) { + CDEBUG(D_OTHER, "\tlcfg->lcfg_buflens[%d]: %d %s\n", + i, lcfg->lcfg_buflens[i], + lustre_cfg_string(lcfg, i)); + } + EXIT; } +EXPORT_SYMBOL(print_lustre_cfg); void lustre_swab_lustre_cfg(struct lustre_cfg *lcfg) { diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index e4e0d85..4ad23a0 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -674,6 +674,79 @@ int lustre_put_lsi(struct super_block *sb) RETURN(0); } +/* + * The goal of this function is to extract the file system name + * from the obd name. This can come in two flavors. One is + * fsname-MDTXXXX or fsname-XXXXXXX were X is a hexadecimal + * number. In both cases we should return fsname. If it is + * not a valid obd name it is assumed to be the file system + * name itself. + */ +void obdname2fsname(const char *tgt, char *fsname, size_t buflen) +{ + const char *ptr; + const char *tmp; + size_t len = 0; + + /* First we have to see if the @tgt has '-' at all. It is + * valid for the user to request something like + * lctl set_param -P llite.lustre*.xattr_cache=0 + */ + ptr = strrchr(tgt, '-'); + if (!ptr) { + /* No '-' means it should end in '*' */ + ptr = strchr(tgt, '*'); + if (!ptr) + goto no_fsname; + len = ptr - tgt; + goto valid_obd_name; + } + + /* tgt format fsname-MDT0000-* */ + if ((!strncmp(ptr, "-MDT", 4) || + !strncmp(ptr, "-OST", 4)) && + (isxdigit(ptr[4]) && isxdigit(ptr[5]) && + isxdigit(ptr[6]) && isxdigit(ptr[7]))) { + len = ptr - tgt; + goto valid_obd_name; + } + + /* tgt_format fsname-cli'dev'-'uuid' except for the llite case + * which are named fsname-'uuid'. Examples: + * + * lustre-clilov-ffff88104db5b800 + * lustre-ffff88104db5b800 (for llite device) + * + * The length of the obd uuid can vary on different platforms. + * This test if any invalid characters are in string. Allow + * wildcards with '*' character. + */ + ptr++; + if (!strspn(ptr, "0123456789abcdefABCDEF*")) { + len = 0; + goto no_fsname; + } + + /* Now that we validated the device name lets extract the + * file system name. Most of the names in this class will + * have '-cli' in its name which needs to be dropped. If + * it doesn't have '-cli' then its a llite device which + * ptr already points to the start of the uuid string. + */ + tmp = strstr(tgt, "-cli"); + if (tmp) + ptr = tmp; + else + ptr--; + len = ptr - tgt; +valid_obd_name: + len = min_t(size_t, len, LUSTRE_MAXFSNAME); + snprintf(fsname, buflen, "%.*s", (int)len, tgt); +no_fsname: + fsname[len] = '\0'; +} +EXPORT_SYMBOL(obdname2fsname); + /*** SERVER NAME *** * * FSNAME is between 1 and 8 characters (inclusive). diff --git a/lustre/ptlrpc/sec_config.c b/lustre/ptlrpc/sec_config.c index cb5ccdc..dc3178c 100644 --- a/lustre/ptlrpc/sec_config.c +++ b/lustre/ptlrpc/sec_config.c @@ -504,49 +504,6 @@ struct sptlrpc_conf { static struct mutex sptlrpc_conf_lock; static struct list_head sptlrpc_confs; -/* - * The goal of this function is to extract the file system name - * from the obd name. This can come in two flavors. One is - * fsname-MDTXXXX or fsname-XXXXXXX were X is a hexadecimal - * number. In both cases we should be returned fsname. If it is - * not a valid obd name it is assumed to be the file system - * name itself. - */ -static void obdname2fsname(const char *tgt, char *fsname, size_t buflen) -{ - const char *ptr; - size_t len; - - ptr = strrchr(tgt, '-'); - if (ptr) { - if ((!strncmp(ptr, "-MDT", 4) || - !strncmp(ptr, "-OST", 4)) && - (isxdigit(ptr[4]) && isxdigit(ptr[5]) && - isxdigit(ptr[6]) && isxdigit(ptr[7]))) - goto valid_obd_name; - - /* The length of the obdname can vary on different platforms */ - len = strlen(ptr); - while (--len) { - if (!isxdigit(ptr[len])) { - ptr = NULL; - break; - } - } - } - -valid_obd_name: - /* if we didn't find the pattern, treat the whole string as fsname */ - if (ptr == NULL) - len = strlen(tgt); - else - len = ptr - tgt; - - len = min(len, buflen - 1); - memcpy(fsname, tgt, len); - fsname[len] = '\0'; -} - static void sptlrpc_conf_free_rsets(struct sptlrpc_conf *conf) { struct sptlrpc_conf_tgt *conf_tgt, *conf_tgt_next; -- 1.8.3.1