#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 rc;
}
-static int mgs_completion_ast_config(struct ldlm_lock *lock, __u64 flags,
- void *cbdata)
+enum ast_type {
+ AST_CONFIG = 1,
+ AST_PARAMS = 2,
+ AST_IR = 3
+};
+
+static int mgs_completion_ast_generic(struct ldlm_lock *lock, __u64 flags,
+ void *cbdata, enum ast_type type)
{
ENTRY;
- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV))) {
- struct fs_db *fsdb;
+ if (!(flags & LDLM_FL_BLOCKED_MASK)) {
+ struct fs_db *fsdb;
/* l_ast_data is used as a marker to avoid cancel ldlm lock
* twice. See LU-2317. */
if (fsdb != NULL) {
struct lustre_handle lockh;
- /* clear the bit before lock put */
- clear_bit(FSDB_REVOKING_LOCK, &fsdb->fsdb_flags);
+ switch(type) {
+ case AST_CONFIG:
+ /* clear the bit before lock put */
+ clear_bit(FSDB_REVOKING_LOCK,
+ &fsdb->fsdb_flags);
+ break;
+ case AST_PARAMS:
+ clear_bit(FSDB_REVOKING_PARAMS,
+ &fsdb->fsdb_flags);
+ break;
+ case AST_IR:
+ mgs_ir_notify_complete(fsdb);
+ break;
+ default:
+ LBUG();
+ }
ldlm_lock2handle(lock, &lockh);
ldlm_lock_decref_and_cancel(&lockh, LCK_EX);
RETURN(ldlm_completion_ast(lock, flags, cbdata));
}
-static int mgs_completion_ast_ir(struct ldlm_lock *lock, __u64 flags,
- void *cbdata)
+static int mgs_completion_ast_config(struct ldlm_lock *lock, __u64 flags,
+ void *cbdata)
{
- ENTRY;
-
- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV))) {
- struct fs_db *fsdb;
-
- /* l_ast_data is used as a marker to avoid cancel ldlm lock
- * twice. See LU-1259. */
- lock_res_and_lock(lock);
- fsdb = (struct fs_db *)lock->l_ast_data;
- lock->l_ast_data = NULL;
- unlock_res_and_lock(lock);
-
- if (fsdb != NULL) {
- struct lustre_handle lockh;
-
- mgs_ir_notify_complete(fsdb);
+ return mgs_completion_ast_generic(lock, flags, cbdata, AST_CONFIG);
+}
- ldlm_lock2handle(lock, &lockh);
- ldlm_lock_decref_and_cancel(&lockh, LCK_EX);
- }
- }
+static int mgs_completion_ast_params(struct ldlm_lock *lock, __u64 flags,
+ void *cbdata)
+{
+ return mgs_completion_ast_generic(lock, flags, cbdata, AST_PARAMS);
+}
- RETURN(ldlm_completion_ast(lock, flags, cbdata));
+static int mgs_completion_ast_ir(struct ldlm_lock *lock, __u64 flags,
+ void *cbdata)
+{
+ return mgs_completion_ast_generic(lock, flags, cbdata, AST_IR);
}
void mgs_revoke_lock(struct mgs_device *mgs, struct fs_db *fsdb, int type)
{
- ldlm_completion_callback cp = NULL;
- struct lustre_handle lockh = { 0 };
- struct ldlm_res_id res_id;
+ ldlm_completion_callback cp = NULL;
+ struct lustre_handle lockh = { 0 };
+ struct ldlm_res_id res_id;
__u64 flags = LDLM_FL_ATOMIC_CB;
- int rc;
- ENTRY;
-
- LASSERT(fsdb->fsdb_name[0] != '\0');
- rc = mgc_fsname2resid(fsdb->fsdb_name, &res_id, type);
- LASSERT(rc == 0);
+ int rc;
+ ENTRY;
- switch (type) {
- case CONFIG_T_CONFIG:
- cp = mgs_completion_ast_config;
+ LASSERT(fsdb->fsdb_name[0] != '\0');
+ rc = mgc_fsname2resid(fsdb->fsdb_name, &res_id, type);
+ LASSERT(rc == 0);
+ switch (type) {
+ case CONFIG_T_CONFIG:
+ cp = mgs_completion_ast_config;
if (test_and_set_bit(FSDB_REVOKING_LOCK, &fsdb->fsdb_flags))
- rc = -EALREADY;
- break;
- case CONFIG_T_RECOVER:
- cp = mgs_completion_ast_ir;
- default:
- break;
- }
+ rc = -EALREADY;
+ break;
+ case CONFIG_T_PARAMS:
+ cp = mgs_completion_ast_params;
+ if (test_and_set_bit(FSDB_REVOKING_PARAMS, &fsdb->fsdb_flags))
+ rc = -EALREADY;
+ break;
+ case CONFIG_T_RECOVER:
+ cp = mgs_completion_ast_ir;
+ default:
+ break;
+ }
- if (!rc) {
- LASSERT(cp != NULL);
+ if (!rc) {
+ LASSERT(cp != NULL);
rc = ldlm_cli_enqueue_local(mgs->mgs_obd->obd_namespace,
&res_id, LDLM_PLAIN, NULL, LCK_EX,
&flags, ldlm_blocking_ast, cp,
NULL, fsdb, 0, LVB_T_NONE, NULL,
&lockh);
- if (rc != ELDLM_OK) {
- CERROR("can't take cfg lock for "LPX64"/"LPX64"(%d)\n",
- le64_to_cpu(res_id.name[0]),
- le64_to_cpu(res_id.name[1]), rc);
+ if (rc != ELDLM_OK) {
+ CERROR("can't take cfg lock for "LPX64"/"LPX64"(%d)\n",
+ le64_to_cpu(res_id.name[0]),
+ le64_to_cpu(res_id.name[1]), rc);
- if (type == CONFIG_T_CONFIG)
+ if (type == CONFIG_T_CONFIG)
clear_bit(FSDB_REVOKING_LOCK,
- &fsdb->fsdb_flags);
- }
- /* lock has been cancelled in completion_ast. */
- }
+ &fsdb->fsdb_flags);
+
+ if (type == CONFIG_T_PARAMS)
+ clear_bit(FSDB_REVOKING_PARAMS,
+ &fsdb->fsdb_flags);
+ }
+ /* lock has been cancelled in completion_ast. */
+ }
- RETURN_EXIT;
+ RETURN_EXIT;
}
/* rc=0 means ok
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);
RETURN(rc);
}
-/*
- * sec context handlers
- */
-/* XXX: Implement based on mdt_sec_ctx_handle()? */
-static int mgs_sec_ctx_handle(struct tgt_session_info *tsi)
-{
- return 0;
-}
-
static inline int mgs_init_export(struct obd_export *exp)
{
struct mgs_export_data *data = &exp->u.eu_mgs_data;
/* 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;
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;
+ 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];
+ int rc = 0;
+ __u32 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 = 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)
+ 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);
+ nodemap = nodemap_classify_nid(nid);
+ client_id = simple_strtoul(client_idstr, NULL, 10);
+
+ if (strcmp(idtype_str, "uid") == 0)
+ idtype = NODEMAP_UID;
+ else
+ idtype = NODEMAP_GID;
+
+ fs_id = nodemap_map_id(nodemap, idtype, NODEMAP_CLIENT_TO_FS,
+ 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)
rc = mgs_iocontrol_pool(&env, mgs, data);
break;
- case OBD_IOC_DUMP_LOG: {
- struct llog_ctxt *ctxt;
+ case OBD_IOC_NODEMAP:
+ 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,
break;
}
+ case OBD_IOC_CATLOGLIST:
+ rc = mgs_list_logs(&env, mgs, data);
+ break;
case OBD_IOC_LLOG_CANCEL:
case OBD_IOC_LLOG_REMOVE:
case OBD_IOC_LLOG_CHECK:
};
static struct tgt_handler mgs_dlm_handlers[] = {
-TGT_DLM_HDL(HABEO_CLAVIS, LDLM_ENQUEUE, tgt_enqueue),
+[LDLM_ENQUEUE - LDLM_FIRST_OPC] = {
+ .th_name = "LDLM_ENQUEUE",
+ /* don't use th_fail_id for MGS to don't interfere with MDS tests.
+ * * There are no tests for MGS with OBD_FAIL_LDLM_ENQUEUE_NET so it
+ * * is safe. If such tests will be needed we have to distinguish
+ * * MDS and MGS fail ids, e.g use OBD_FAIL_MGS_ENQUEUE_NET for MGS
+ * * instead of common OBD_FAIL_LDLM_ENQUEUE_NET */
+ .th_fail_id = 0,
+ .th_opc = LDLM_ENQUEUE,
+ .th_flags = HABEO_CLAVIS,
+ .th_act = tgt_enqueue,
+ .th_fmt = &RQF_LDLM_ENQUEUE,
+ .th_version = LUSTRE_DLM_VERSION,
+ },
};
static struct tgt_handler mgs_llog_handlers[] = {
TGT_LLOG_HDL (0, LLOG_ORIGIN_HANDLE_PREV_BLOCK, tgt_llog_prev_block),
};
-static struct tgt_handler mgs_sec_ctx_handlers[] = {
-TGT_SEC_HDL_VAR(0, SEC_CTX_INIT, mgs_sec_ctx_handle),
-TGT_SEC_HDL_VAR(0, SEC_CTX_INIT_CONT, mgs_sec_ctx_handle),
-TGT_SEC_HDL_VAR(0, SEC_CTX_FINI, mgs_sec_ctx_handle),
-};
-
static struct tgt_opc_slice mgs_common_slice[] = {
{
.tos_opc_start = MGS_FIRST_OPC,
{
.tos_opc_start = SEC_FIRST_OPC,
.tos_opc_end = SEC_LAST_OPC,
- .tos_hs = mgs_sec_ctx_handlers
+ .tos_hs = tgt_sec_ctx_handlers
},
{
.tos_hs = NULL
struct obd_device *obd;
struct lustre_mount_info *lmi;
struct llog_ctxt *ctxt;
+ struct fs_db *fsdb = NULL;
int rc;
ENTRY;
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);
+
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), lmi->lmi_mnt);
+ server_put_mount(lustre_cfg_string(lcfg, 0), true);
RETURN(rc);
}
obd_zombie_barrier();
tgt_fini(env, &mgs->mgs_lut);
+ mgs_params_fsdb_cleanup(env, mgs);
mgs_cleanup_fsdb_list(mgs);
lproc_mgs_cleanup(mgs);
LASSERT(mgs->mgs_bottom_exp);
obd_disconnect(mgs->mgs_bottom_exp);
- server_put_mount(obd->obd_name, NULL);
+ server_put_mount(obd->obd_name, true);
RETURN(NULL);
}
static int __init mgs_init(void)
{
- struct lprocfs_static_vars lvars;
-
- lprocfs_mgs_init_vars(&lvars);
- class_register_type(&mgs_obd_device_ops, NULL, lvars.module_vars,
- LUSTRE_MGS_NAME, &mgs_device_type);
-
- return 0;
+ return class_register_type(&mgs_obd_device_ops, NULL, true, NULL,
+ LUSTRE_MGS_NAME, &mgs_device_type);
}
static void /*__exit*/ mgs_exit(void)