* 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/
#include <obd_class.h>
#include <lprocfs_status.h>
+#include <lustre_ioctl.h>
#include <lustre_param.h>
#include "mgs_internal.h"
ENTRY;
+ CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_CONNECT_NET, cfs_fail_val);
rc = tgt_connect(tsi);
if (rc)
RETURN(rc);
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;
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);
{
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
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);
/* 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;
struct obd_ioctl_data *data)
{
struct lustre_cfg *lcfg = NULL;
- struct lu_nodemap *nodemap;
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;
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);
nidstr = lustre_cfg_string(lcfg, 1);
nid = libcfs_str2nid(nidstr);
- nodemap = nodemap_classify_nid(nid);
- memset(data->ioc_pbuf1, 0, data->ioc_plen1);
- if (copy_to_user(data->ioc_pbuf1, nodemap->nm_name,
- strlen(nodemap->nm_name)) != 0)
+ 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, 3);
rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
break;
-
default:
rc = -ENOTTY;
}
}
/* 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;
rc = mgs_iocontrol_nodemap(&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);
-
- break;
- }
-
case OBD_IOC_CATLOGLIST:
rc = mgs_list_logs(&env, mgs, data);
break;
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;
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) {
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);
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);
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);
}
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;
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);
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);
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);
}
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,
.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. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre Management Server (MGS)");
+MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre Management Server (MGS)");
+MODULE_VERSION(LUSTRE_VERSION_STRING);
MODULE_LICENSE("GPL");
module_init(mgs_init);