X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmgs%2Fmgs_handler.c;h=f1a643e52262233886a6f32895dda8a4d6b2fe7a;hp=560dd1929ef397c094a6272e0d61e23c0a2ec9bd;hb=9175d6f862039cfbf6b85333d72a9d91e64ea42a;hpb=3270bfc2370884933628f95122da00d430db6072 diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 560dd19..f1a643e 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2010, 2013, Intel Corporation. + * Copyright (c) 2010, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -45,6 +45,7 @@ #include #include +#include #include #include "mgs_internal.h" @@ -59,6 +60,7 @@ static int mgs_connect(struct tgt_session_info *tsi) ENTRY; + CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_CONNECT_NET, cfs_fail_val); rc = tgt_connect(tsi); if (rc) RETURN(rc); @@ -92,11 +94,18 @@ static int mgs_exception(struct tgt_session_info *tsi) RETURN(0); } +static inline bool str_starts_with(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} + static int mgs_set_info(struct tgt_session_info *tsi) { struct mgs_thread_info *mgi; struct mgs_send_param *msp, *rep_msp; struct lustre_cfg *lcfg; + size_t param_len; + char *s; int rc; ENTRY; @@ -109,10 +118,26 @@ static int mgs_set_info(struct tgt_session_info *tsi) if (msp == NULL) RETURN(err_serious(-EFAULT)); + param_len = strnlen(msp->mgs_param, sizeof(msp->mgs_param)); + if (param_len == 0 || param_len == sizeof(msp->mgs_param)) + RETURN(-EINVAL); + + /* We only allow '*.lov.stripe{size,count,offset}=*' from an RPC. */ + s = strchr(msp->mgs_param, '.'); + if (s == NULL) + RETURN(-EINVAL); + + if (!str_starts_with(s + 1, "lov.stripesize=") && + !str_starts_with(s + 1, "lov.stripecount=") && + !str_starts_with(s + 1, "lov.stripeoffset=")) + RETURN(-EINVAL); + /* Construct lustre_cfg structure to pass to function mgs_setparam */ lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL); lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, msp->mgs_param); lcfg = lustre_cfg_new(LCFG_PARAM, &mgi->mgi_bufs); + if (lcfg == NULL) + RETURN(-ENOMEM); rc = mgs_setparam(tsi->tsi_env, exp2mgs_dev(tsi->tsi_exp), lcfg, mgi->mgi_fsname); @@ -143,8 +168,7 @@ static int mgs_completion_ast_generic(struct ldlm_lock *lock, __u64 flags, { ENTRY; - if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | - LDLM_FL_BLOCK_CONV))) { + if (!(flags & LDLM_FL_BLOCKED_MASK)) { struct fs_db *fsdb; /* l_ast_data is used as a marker to avoid cancel ldlm lock @@ -538,11 +562,14 @@ static int mgs_llog_open(struct tgt_session_info *tsi) logname = req_capsule_client_get(tsi->tsi_pill, &RMF_NAME); if (logname) { char *ptr = strchr(logname, '-'); - int len = (int)(ptr - logname); + int len = (ptr != NULL) ? (int)(ptr - logname) : 0; if (ptr == NULL || len >= sizeof(mgi->mgi_fsname)) { - LCONSOLE_WARN("%s: non-config logname received: %s\n", - tgt_name(tsi->tsi_tgt), logname); + if (strcmp(logname, PARAMS_FILENAME) != 0) + LCONSOLE_WARN("%s: non-config logname " + "received: %s\n", + tgt_name(tsi->tsi_tgt), + logname); /* not error, this can be llog test name */ } else { strncpy(mgi->mgi_fsname, logname, len); @@ -573,7 +600,7 @@ static inline int mgs_init_export(struct obd_export *exp) /* init mgs_export_data for fsc */ spin_lock_init(&data->med_lock); - CFS_INIT_LIST_HEAD(&data->med_clients); + INIT_LIST_HEAD(&data->med_clients); spin_lock(&exp->exp_lock); exp->exp_connecting = 1; @@ -620,6 +647,139 @@ static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname) RETURN(0); } +static int mgs_iocontrol_nodemap(const struct lu_env *env, + struct mgs_device *mgs, + struct obd_ioctl_data *data) +{ + struct lustre_cfg *lcfg = NULL; + lnet_nid_t nid; + const char *nodemap_name = NULL; + const char *nidstr = NULL; + const char *client_idstr = NULL; + const char *idtype_str = NULL; + char *param = NULL; + char fs_idstr[16]; + char name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1]; + int rc = 0; + unsigned long client_id; + __u32 fs_id; + __u32 cmd; + int idtype; + + ENTRY; + + if (data->ioc_type != LUSTRE_CFG_TYPE) { + CERROR("%s: unknown cfg record type: %d\n", + mgs->mgs_obd->obd_name, data->ioc_type); + GOTO(out, rc = -EINVAL); + } + + if (data->ioc_plen1 > PAGE_CACHE_SIZE) + GOTO(out, rc = -E2BIG); + + OBD_ALLOC(lcfg, data->ioc_plen1); + if (lcfg == NULL) + GOTO(out, rc = -ENOMEM); + + if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1)) + GOTO(out_lcfg, rc = -EFAULT); + + cmd = lcfg->lcfg_command; + + switch (cmd) { + case LCFG_NODEMAP_ACTIVATE: + if (lcfg->lcfg_bufcount != 2) + GOTO(out_lcfg, rc = -EINVAL); + param = lustre_cfg_string(lcfg, 1); + if (strcmp(param, "1") == 0) + nodemap_activate(1); + else + nodemap_activate(0); + break; + case LCFG_NODEMAP_ADD: + case LCFG_NODEMAP_DEL: + if (lcfg->lcfg_bufcount != 2) + GOTO(out_lcfg, rc = -EINVAL); + nodemap_name = lustre_cfg_string(lcfg, 1); + rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param); + break; + case LCFG_NODEMAP_TEST_NID: + if (lcfg->lcfg_bufcount != 2) + GOTO(out_lcfg, rc = -EINVAL); + nidstr = lustre_cfg_string(lcfg, 1); + nid = libcfs_str2nid(nidstr); + nodemap_test_nid(nid, name_buf, sizeof(name_buf)); + rc = copy_to_user(data->ioc_pbuf1, name_buf, + MIN(data->ioc_plen1, sizeof(name_buf))); + if (rc != 0) + GOTO(out_lcfg, rc = -EFAULT); + break; + case LCFG_NODEMAP_TEST_ID: + if (lcfg->lcfg_bufcount != 4) + GOTO(out_lcfg, rc = -EINVAL); + nidstr = lustre_cfg_string(lcfg, 1); + idtype_str = lustre_cfg_string(lcfg, 2); + client_idstr = lustre_cfg_string(lcfg, 3); + + nid = libcfs_str2nid(nidstr); + if (strcmp(idtype_str, "uid") == 0) + idtype = NODEMAP_UID; + else + idtype = NODEMAP_GID; + + rc = kstrtoul(client_idstr, 10, &client_id); + if (rc != 0) + GOTO(out_lcfg, rc = -EINVAL); + + fs_id = nodemap_test_id(nid, idtype, client_id); + + if (data->ioc_plen1 < sizeof(fs_idstr)) + GOTO(out_lcfg, rc = -EINVAL); + + snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id); + if (copy_to_user(data->ioc_pbuf1, fs_idstr, + sizeof(fs_idstr)) != 0) + GOTO(out_lcfg, rc = -EINVAL); + break; + case LCFG_NODEMAP_ADD_RANGE: + case LCFG_NODEMAP_DEL_RANGE: + case LCFG_NODEMAP_ADD_UIDMAP: + case LCFG_NODEMAP_DEL_UIDMAP: + case LCFG_NODEMAP_ADD_GIDMAP: + case LCFG_NODEMAP_DEL_GIDMAP: + if (lcfg->lcfg_bufcount != 3) + GOTO(out_lcfg, rc = -EINVAL); + nodemap_name = lustre_cfg_string(lcfg, 1); + param = lustre_cfg_string(lcfg, 2); + rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param); + break; + case LCFG_NODEMAP_ADMIN: + case LCFG_NODEMAP_TRUSTED: + case LCFG_NODEMAP_SQUASH_UID: + case LCFG_NODEMAP_SQUASH_GID: + if (lcfg->lcfg_bufcount != 4) + GOTO(out_lcfg, rc = -EINVAL); + nodemap_name = lustre_cfg_string(lcfg, 1); + param = lustre_cfg_string(lcfg, 3); + rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param); + break; + default: + rc = -ENOTTY; + } + + if (rc != 0) { + CERROR("%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n", + mgs->mgs_obd->obd_name, lcfg->lcfg_command, + nodemap_name, rc); + GOTO(out_lcfg, rc); + } + +out_lcfg: + OBD_FREE(lcfg, data->ioc_plen1); +out: + RETURN(rc); +} + static int mgs_iocontrol_pool(const struct lu_env *env, struct mgs_device *mgs, struct obd_ioctl_data *data) @@ -702,8 +862,8 @@ out_pool: } /* from mdt_iocontrol */ -int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len, - void *karg, void *uarg) +static int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len, + void *karg, void __user *uarg) { struct mgs_device *mgs = exp2mgs_dev(exp); struct obd_ioctl_data *data = karg; @@ -792,16 +952,9 @@ out_free: rc = mgs_iocontrol_pool(&env, mgs, data); break; - case OBD_IOC_DUMP_LOG: { - struct llog_ctxt *ctxt; - - ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); - rc = class_config_dump_llog(&env, ctxt, data->ioc_inlbuf1, - NULL); - llog_ctxt_put(ctxt); - + case OBD_IOC_NODEMAP: + rc = mgs_iocontrol_nodemap(&env, mgs, data); break; - } case OBD_IOC_CATLOGLIST: rc = mgs_list_logs(&env, mgs, data); @@ -945,6 +1098,8 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs, struct obd_device *obd; struct lustre_mount_info *lmi; struct llog_ctxt *ctxt; + struct fs_db *fsdb = NULL; + struct fs_db *fsdb_srpc = NULL; int rc; ENTRY; @@ -1008,6 +1163,7 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs, mutex_init(&mgs->mgs_mutex); mgs->mgs_start_time = cfs_time_current_sec(); spin_lock_init(&mgs->mgs_lock); + mutex_init(&mgs->mgs_health_mutex); rc = lproc_mgs_setup(mgs, lustre_cfg_string(lcfg, 3)); if (rc != 0) { @@ -1016,6 +1172,17 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs, GOTO(err_llog, rc); } + /* Setup params fsdb and log, so that other servers can make a local + * copy successfully when they are mounted. See LU-4783 */ + rc = mgs_params_fsdb_setup(env, mgs, fsdb); + if (rc) + /* params fsdb and log can be setup later */ + CERROR("%s: %s fsdb and log setup failed: rc = %d\n", + obd->obd_name, PARAMS_FILENAME, rc); + + /* Setup _mgs fsdb, useful for srpc */ + mgs__mgs_fsdb_setup(env, mgs, fsdb_srpc); + ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, "mgs_ldlm_client", &obd->obd_ldlm_client); @@ -1059,6 +1226,7 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs, lu_site_purge(env, mgs2lu_dev(mgs)->ld_site, ~0); RETURN(0); err_lproc: + mgs_params_fsdb_cleanup(env, mgs); lproc_mgs_cleanup(mgs); err_llog: ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); @@ -1084,7 +1252,7 @@ err_ops: obd_disconnect(mgs->mgs_bottom_exp); err_lmi: if (lmi) - server_put_mount(lustre_cfg_string(lcfg, 0)); + server_put_mount(lustre_cfg_string(lcfg, 0), true); RETURN(rc); } @@ -1149,15 +1317,15 @@ static int mgs_object_print(const struct lu_env *env, void *cookie, return (*p)(env, cookie, LUSTRE_MGS_NAME"-object@%p", o); } -struct lu_object_operations mgs_lu_obj_ops = { +static struct lu_object_operations mgs_lu_obj_ops = { .loo_object_init = mgs_object_init, .loo_object_free = mgs_object_free, .loo_object_print = mgs_object_print, }; -struct lu_object *mgs_object_alloc(const struct lu_env *env, - const struct lu_object_header *hdr, - struct lu_device *d) +static struct lu_object *mgs_object_alloc(const struct lu_env *env, + const struct lu_object_header *hdr, + struct lu_device *d) { struct lu_object_header *h; struct mgs_object *o; @@ -1226,13 +1394,18 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env, ping_evictor_stop(); + mutex_lock(&mgs->mgs_health_mutex); ptlrpc_unregister_service(mgs->mgs_service); + mutex_unlock(&mgs->mgs_health_mutex); + + mgs_params_fsdb_cleanup(env, mgs); + mgs_cleanup_fsdb_list(mgs); + ldlm_namespace_free_prior(obd->obd_namespace, NULL, 1); obd_exports_barrier(obd); obd_zombie_barrier(); tgt_fini(env, &mgs->mgs_lut); - mgs_cleanup_fsdb_list(mgs); lproc_mgs_cleanup(mgs); ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT); @@ -1243,7 +1416,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env, mgs_fs_cleanup(env, mgs); - ldlm_namespace_free(obd->obd_namespace, NULL, 1); + ldlm_namespace_free_post(obd->obd_namespace); obd->obd_namespace = NULL; lu_site_purge(env, d->ld_site, ~0); @@ -1255,7 +1428,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env, LASSERT(mgs->mgs_bottom_exp); obd_disconnect(mgs->mgs_bottom_exp); - server_put_mount(obd->obd_name); + server_put_mount(obd->obd_name, true); RETURN(NULL); } @@ -1363,6 +1536,18 @@ static int mgs_obd_disconnect(struct obd_export *exp) RETURN(rc); } +static int mgs_health_check(const struct lu_env *env, struct obd_device *obd) +{ + struct mgs_device *mgs = lu2mgs_dev(obd->obd_lu_dev); + int rc = 0; + + mutex_lock(&mgs->mgs_health_mutex); + rc |= ptlrpc_service_health_check(mgs->mgs_service); + mutex_unlock(&mgs->mgs_health_mutex); + + return rc != 0 ? 1 : 0; +} + /* use obd ops to offer management infrastructure */ static struct obd_ops mgs_obd_device_ops = { .o_owner = THIS_MODULE, @@ -1372,27 +1557,23 @@ static struct obd_ops mgs_obd_device_ops = { .o_init_export = mgs_init_export, .o_destroy_export = mgs_destroy_export, .o_iocontrol = mgs_iocontrol, + .o_health_check = mgs_health_check, }; static int __init mgs_init(void) { - struct lprocfs_static_vars lvars; - - lprocfs_mgs_init_vars(&lvars); - return class_register_type(&mgs_obd_device_ops, NULL, NULL, -#ifndef HAVE_ONLY_PROCFS_SEQ - lvars.module_vars, -#endif - LUSTRE_MGS_NAME, &mgs_device_type); + return class_register_type(&mgs_obd_device_ops, NULL, true, NULL, + LUSTRE_MGS_NAME, &mgs_device_type); } -static void /*__exit*/ mgs_exit(void) +static void __exit mgs_exit(void) { class_unregister_type(LUSTRE_MGS_NAME); } -MODULE_AUTHOR("Sun Microsystems, Inc. "); -MODULE_DESCRIPTION("Lustre Management Server (MGS)"); +MODULE_AUTHOR("OpenSFS, Inc. "); +MODULE_DESCRIPTION("Lustre Management Server (MGS)"); +MODULE_VERSION(LUSTRE_VERSION_STRING); MODULE_LICENSE("GPL"); module_init(mgs_init);