From f7815c80d95b20c97317fbd7010013dca009121e Mon Sep 17 00:00:00 2001 From: Kit Westneat Date: Fri, 18 Nov 2016 09:50:02 -0500 Subject: [PATCH 1/1] LU-8851 nodemap: add uid/gid only flags to control mapping This patch adds two flags to nodemaps which control whether or not the nodemap should map UIDs, GIDs, or both. These flags can be controlled via lctl as a new nodemap parameter map_mode, with values both, uid_only, or gid_only. Signed-off-by: Kit Westneat Change-Id: I3efe6ff348d909c196a89273a0c9c046c56dbf1d Reviewed-on: https://review.whamcloud.com/23853 Reviewed-by: Chris Hanna Reviewed-by: Sebastien Buisson Reviewed-by: Stephan Thiell Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/lustre_cfg.h | 1 + lustre/include/lustre_nodemap.h | 11 +++++++++- lustre/mgs/mgs_handler.c | 1 + lustre/mgs/mgs_llog.c | 13 +++++++++++ lustre/ptlrpc/nodemap_handler.c | 48 +++++++++++++++++++++++++++++++++++++++++ lustre/ptlrpc/nodemap_lproc.c | 38 ++++++++++++++++++++++++++++++++ lustre/ptlrpc/nodemap_storage.c | 12 ++++++++++- lustre/utils/obd.c | 4 +++- 8 files changed, 125 insertions(+), 3 deletions(-) diff --git a/lustre/include/lustre_cfg.h b/lustre/include/lustre_cfg.h index 11f1576..bf2a62a 100644 --- a/lustre/include/lustre_cfg.h +++ b/lustre/include/lustre_cfg.h @@ -115,6 +115,7 @@ enum lcfg_command_type { LCFG_NODEMAP_TEST_ID = 0x00ce056, /**< test uid/gid mapping */ LCFG_NODEMAP_SET_FILESET = 0x00ce057, /**< set fileset */ LCFG_NODEMAP_DENY_UNKNOWN = 0x00ce058, /**< deny squashed nodemap users */ + LCFG_NODEMAP_MAP_MODE = 0x00ce059, /**< set the mapping mode */ }; struct lustre_cfg_bufs { diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index 9a161c2..d8553e9 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -48,6 +48,12 @@ enum nodemap_tree_type { NODEMAP_CLIENT_TO_FS, }; +enum nodemap_mapping_modes { + NODEMAP_MAP_BOTH, + NODEMAP_MAP_UID_ONLY, + NODEMAP_MAP_GID_ONLY, +}; + struct nodemap_pde { char npe_name[LUSTRE_NODEMAP_NAME_LENGTH + 1]; struct proc_dir_entry *npe_proc_entry; @@ -65,7 +71,9 @@ struct lu_nodemap { /* flags to govern nodemap behavior */ bool nmf_trust_client_ids:1, nmf_deny_unknown:1, - nmf_allow_root_access:1; + nmf_allow_root_access:1, + nmf_map_uid_only:1, + nmf_map_gid_only:1; /* unique ID set by MGS */ unsigned int nm_id; /* nodemap ref counter */ @@ -121,6 +129,7 @@ int nodemap_del_range(const char *name, const lnet_nid_t nid[2]); int nodemap_set_allow_root(const char *name, bool allow_root); int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids); int nodemap_set_deny_unknown(const char *name, bool deny_unknown); +int nodemap_set_mapping_mode(const char *name, enum nodemap_mapping_modes mode); int nodemap_set_squash_uid(const char *name, uid_t uid); int nodemap_set_squash_gid(const char *name, gid_t gid); bool nodemap_can_setquota(const struct lu_nodemap *nodemap); diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index a21acf3..8c398a2 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -862,6 +862,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env, case LCFG_NODEMAP_DENY_UNKNOWN: case LCFG_NODEMAP_SQUASH_UID: case LCFG_NODEMAP_SQUASH_GID: + case LCFG_NODEMAP_MAP_MODE: if (lcfg->lcfg_bufcount != 4) GOTO(out_lcfg, rc = -EINVAL); nodemap_name = lustre_cfg_string(lcfg, 1); diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 679ef0e..400a3ce 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -4936,6 +4936,19 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs, bool_switch = simple_strtoul(param, NULL, 10); rc = nodemap_set_deny_unknown(nodemap_name, bool_switch); break; + case LCFG_NODEMAP_MAP_MODE: + if (strcmp("both", param) == 0) + rc = nodemap_set_mapping_mode(nodemap_name, + NODEMAP_MAP_BOTH); + else if (strcmp("uid_only", param) == 0) + rc = nodemap_set_mapping_mode(nodemap_name, + NODEMAP_MAP_UID_ONLY); + else if (strcmp("gid_only", param) == 0) + rc = nodemap_set_mapping_mode(nodemap_name, + NODEMAP_MAP_GID_ONLY); + else + rc = -EINVAL; + break; case LCFG_NODEMAP_TRUSTED: bool_switch = simple_strtoul(param, NULL, 10); rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch); diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index 0cd0366..b438dda 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -638,6 +638,12 @@ __u32 nodemap_map_id(struct lu_nodemap *nodemap, if (unlikely(nodemap == NULL)) goto out; + if (nodemap->nmf_map_uid_only && id_type == NODEMAP_GID) + goto out; + + if (nodemap->nmf_map_gid_only && id_type == NODEMAP_UID) + goto out; + if (id == 0) { if (nodemap->nmf_allow_root_access) goto out; @@ -1012,6 +1018,8 @@ struct lu_nodemap *nodemap_create(const char *name, nodemap->nmf_trust_client_ids = 0; nodemap->nmf_allow_root_access = 0; nodemap->nmf_deny_unknown = 0; + nodemap->nmf_map_uid_only = 0; + nodemap->nmf_map_gid_only = 0; nodemap->nm_squash_uid = NODEMAP_NOBODY_UID; nodemap->nm_squash_gid = NODEMAP_NOBODY_GID; @@ -1025,6 +1033,10 @@ struct lu_nodemap *nodemap_create(const char *name, default_nodemap->nmf_allow_root_access; nodemap->nmf_deny_unknown = default_nodemap->nmf_deny_unknown; + nodemap->nmf_map_uid_only = + default_nodemap->nmf_map_uid_only; + nodemap->nmf_map_gid_only = + default_nodemap->nmf_map_gid_only; nodemap->nm_squash_uid = default_nodemap->nm_squash_uid; nodemap->nm_squash_gid = default_nodemap->nm_squash_gid; @@ -1123,6 +1135,42 @@ out: } EXPORT_SYMBOL(nodemap_set_trust_client_ids); +int nodemap_set_mapping_mode(const char *name, enum nodemap_mapping_modes mode) +{ + struct lu_nodemap *nodemap = NULL; + int rc = 0; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(name); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) + GOTO(out, rc = PTR_ERR(nodemap)); + + switch (mode) { + case NODEMAP_MAP_BOTH: + nodemap->nmf_map_uid_only = 0; + nodemap->nmf_map_gid_only = 0; + break; + case NODEMAP_MAP_UID_ONLY: + nodemap->nmf_map_uid_only = 1; + nodemap->nmf_map_gid_only = 0; + break; + case NODEMAP_MAP_GID_ONLY: + nodemap->nmf_map_uid_only = 0; + nodemap->nmf_map_gid_only = 1; + break; + default: + CWARN("cannot set unknown mapping mode, mode = %d\n", mode); + } + rc = nodemap_idx_nodemap_update(nodemap); + + nm_member_revoke_locks(nodemap); + nodemap_putref(nodemap); +out: + return rc; +} +EXPORT_SYMBOL(nodemap_set_mapping_mode); + /** * Update the squash_uid for a nodemap. * diff --git a/lustre/ptlrpc/nodemap_lproc.c b/lustre/ptlrpc/nodemap_lproc.c index 305f95b..c384785 100644 --- a/lustre/ptlrpc/nodemap_lproc.c +++ b/lustre/ptlrpc/nodemap_lproc.c @@ -481,6 +481,39 @@ static int nodemap_admin_seq_show(struct seq_file *m, void *data) } /** + * Reads and prints the mapping mode for the given nodemap. + * + * \param m seq file in proc fs + * \param data unused + * \retval 0 success + */ +static int nodemap_map_mode_seq_show(struct seq_file *m, void *data) +{ + struct lu_nodemap *nodemap; + int rc; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } + + if (nodemap->nmf_map_uid_only) + seq_printf(m, "uid_only\n"); + else if (nodemap->nmf_map_gid_only) + seq_printf(m, "gid_only\n"); + else + seq_printf(m, "both\n"); + + nodemap_putref(nodemap); + return 0; +} + +/** * Reads and prints the deny_unknown flag for the given nodemap. * * \param m seq file in proc fs @@ -1112,6 +1145,7 @@ LPROC_SEQ_FOPS_RO(nodemap_squash_gid); #endif LPROC_SEQ_FOPS_RO(nodemap_deny_unknown); +LPROC_SEQ_FOPS_RO(nodemap_map_mode); const struct file_operations nodemap_ranges_fops = { .open = nodemap_ranges_open, @@ -1152,6 +1186,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_deny_unknown_fops, }, { + .name = "map_mode", + .fops = &nodemap_map_mode_fops, + }, + { .name = "squash_uid", .fops = &nodemap_squash_uid_fops, }, diff --git a/lustre/ptlrpc/nodemap_storage.c b/lustre/ptlrpc/nodemap_storage.c index efed19e..04e3f13 100644 --- a/lustre/ptlrpc/nodemap_storage.c +++ b/lustre/ptlrpc/nodemap_storage.c @@ -72,6 +72,8 @@ enum nm_flag_shifts { NM_FL_ALLOW_ROOT_ACCESS = 0x1, NM_FL_TRUST_CLIENT_IDS = 0x2, NM_FL_DENY_UNKNOWN = 0x4, + NM_FL_MAP_UID_ONLY = 0x8, + NM_FL_MAP_GID_ONLY = 0x10, }; static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id) @@ -95,7 +97,11 @@ static void nodemap_cluster_rec_init(union nodemap_rec *nr, (nodemap->nmf_allow_root_access ? NM_FL_ALLOW_ROOT_ACCESS : 0) | (nodemap->nmf_deny_unknown ? - NM_FL_DENY_UNKNOWN : 0)); + NM_FL_DENY_UNKNOWN : 0) | + (nodemap->nmf_map_uid_only ? + NM_FL_MAP_UID_ONLY : 0) | + (nodemap->nmf_map_gid_only ? + NM_FL_MAP_GID_ONLY : 0)); } static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id, @@ -741,6 +747,10 @@ static int nodemap_process_keyrec(struct nodemap_config *config, flags & NM_FL_TRUST_CLIENT_IDS; nodemap->nmf_deny_unknown = flags & NM_FL_DENY_UNKNOWN; + nodemap->nmf_map_uid_only = + flags & NM_FL_MAP_UID_ONLY; + nodemap->nmf_map_gid_only = + flags & NM_FL_MAP_GID_ONLY; if (*recent_nodemap == NULL) { *recent_nodemap = nodemap; diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 4bfb0ca..0fdec22 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -3669,7 +3669,7 @@ int jt_nodemap_modify(int argc, char **argv) if (nodemap_name == NULL || param == NULL || value == NULL) { fprintf(stderr, "usage: nodemap_modify --name " "--property --value \n"); - fprintf(stderr, "valid properties: admin trusted " + fprintf(stderr, "valid properties: admin trusted map_mode " "squash_uid squash_gid deny_unknown\n"); return -1; } @@ -3684,6 +3684,8 @@ int jt_nodemap_modify(int argc, char **argv) cmd = LCFG_NODEMAP_SQUASH_UID; } else if (strcmp("squash_gid", param) == 0) { cmd = LCFG_NODEMAP_SQUASH_GID; + } else if (strcmp("map_mode", param) == 0) { + cmd = LCFG_NODEMAP_MAP_MODE; } else { fprintf(stderr, "error: %s: nodemap_modify invalid " "subcommand: %s\n", -- 1.8.3.1