X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fptlrpc%2Fnodemap_handler.c;h=b438dda6e082ac852272fc16afdd6bda20bb65e6;hp=e4f112419a6ecfe8673ea3630d840f49e71e5356;hb=f7815c80d95b20c97317fbd7010013dca009121e;hpb=d61ab8df9ab9bf452626e73136b3a3b6fbdc2bf6 diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index e4f1124..b438dda 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -265,7 +265,7 @@ struct lu_nodemap *nodemap_classify_nid(lnet_nid_t nid) /* don't use 0@lo, use the first non-lo local NID instead */ if (LNET_NETTYP(LNET_NIDNET(nid)) == LOLND) { - lnet_process_id_t id; + struct lnet_process_id id; int i = 0; do { @@ -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; @@ -777,15 +783,21 @@ int nodemap_add_range_helper(struct nodemap_config *config, } list_add(&range->rn_list, &nodemap->nm_ranges); - nm_member_reclassify_nodemap(config->nmc_default_nodemap); + + /* nodemaps have no members if they aren't on the active config */ + if (config == active_config) + nm_member_reclassify_nodemap(config->nmc_default_nodemap); + up_write(&config->nmc_range_tree_lock); /* if range_id is non-zero, we are loading from disk */ if (range_id == 0) rc = nodemap_idx_range_add(range, nid); - nm_member_revoke_locks(config->nmc_default_nodemap); - nm_member_revoke_locks(nodemap); + if (config == active_config) { + nm_member_revoke_locks(config->nmc_default_nodemap); + nm_member_revoke_locks(nodemap); + } out: return rc; @@ -1005,6 +1017,9 @@ struct lu_nodemap *nodemap_create(const char *name, if (is_default || default_nodemap == NULL) { 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; @@ -1016,6 +1031,12 @@ struct lu_nodemap *nodemap_create(const char *name, default_nodemap->nmf_trust_client_ids; nodemap->nmf_allow_root_access = 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; @@ -1030,12 +1051,39 @@ out: } /** - * update flag to turn on or off nodemap functions + * Set the nmf_deny_unknown flag to true or false. + * \param name nodemap name + * \param deny_unknown if true, squashed users will get EACCES + * \retval 0 on success + * + */ +int nodemap_set_deny_unknown(const char *name, bool deny_unknown) +{ + 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)); + + nodemap->nmf_deny_unknown = deny_unknown; + rc = nodemap_idx_nodemap_update(nodemap); + + nm_member_revoke_locks(nodemap); + nodemap_putref(nodemap); +out: + return rc; +} +EXPORT_SYMBOL(nodemap_set_deny_unknown); + +/** + * Set the nmf_allow_root_access flag to true or false. * \param name nodemap name - * \param admin_string string containing updated value + * \param allow_root if true, nodemap will not squash the root user * \retval 0 on success * - * Update admin flag to turn on or off nodemap functions. */ int nodemap_set_allow_root(const char *name, bool allow_root) { @@ -1059,13 +1107,12 @@ out: EXPORT_SYMBOL(nodemap_set_allow_root); /** - * updated trust_client_ids flag for nodemap + * Set the nmf_trust_client_ids flag to true or false. * - * \param name nodemap name - * \param trust_string new value for trust flag + * \param name nodemap name + * \param trust_client_ids if true, nodemap will not map its IDs * \retval 0 on success * - * Update the trust_client_ids flag for a nodemap. */ int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids) { @@ -1088,11 +1135,47 @@ 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 + * Update the squash_uid for a nodemap. * * \param name nodemap name - * \param uid_string string containing new squash_uid value + * \param uid the new uid to squash unknown users to * \retval 0 on success * * Update the squash_uid for a nodemap. The squash_uid is the uid @@ -1125,7 +1208,7 @@ EXPORT_SYMBOL(nodemap_set_squash_uid); * Update the squash_gid for a nodemap. * * \param name nodemap name - * \param gid_string string containing new squash_gid value + * \param gid the new gid to squash unknown gids to * \retval 0 on success * * Update the squash_gid for a nodemap. The squash_uid is the gid @@ -1346,24 +1429,31 @@ void nodemap_config_dealloc(struct nodemap_config *config) */ list_for_each_entry_safe(nodemap, nodemap_temp, &nodemap_list_head, nm_list) { + mutex_lock(&active_config_lock); down_write(&config->nmc_range_tree_lock); - /* move members to new config */ + /* move members to new config, requires ac lock */ nm_member_reclassify_nodemap(nodemap); list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges, rn_list) range_delete(&config->nmc_range_tree, range); up_write(&config->nmc_range_tree_lock); + mutex_unlock(&active_config_lock); + /* putref must be outside of ac lock if nm could be destroyed */ nodemap_putref(nodemap); } OBD_FREE_PTR(config); } EXPORT_SYMBOL(nodemap_config_dealloc); -static int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, - struct hlist_node *hnode, - void *nodemap_list_head) +/* + * callback for cfs_hash_for_each_safe used to convert a nodemap hash to a + * nodemap list, generally for locking purposes as a hash cb can't sleep. + */ +int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, + struct hlist_node *hnode, + void *nodemap_list_head) { struct lu_nodemap *nodemap; @@ -1377,6 +1467,7 @@ void nodemap_config_set_active(struct nodemap_config *config) struct nodemap_config *old_config = active_config; struct lu_nodemap *nodemap; struct lu_nodemap *tmp; + bool revoke_locks; LIST_HEAD(nodemap_list_head); ENTRY; @@ -1407,6 +1498,14 @@ void nodemap_config_set_active(struct nodemap_config *config) } } + /* + * We only need to revoke locks if old nodemap was active, and new + * config is now nodemap inactive. nodemap_config_dealloc will + * reclassify exports, triggering a lock revoke if and only if new + * nodemap is active. + */ + revoke_locks = !config->nmc_nodemap_is_active && nodemap_active; + /* if new config is inactive, deactivate live config before switching */ if (!config->nmc_nodemap_is_active) nodemap_active = false; @@ -1419,7 +1518,8 @@ void nodemap_config_set_active(struct nodemap_config *config) if (old_config != NULL) nodemap_config_dealloc(old_config); - nm_member_revoke_all(); + if (revoke_locks) + nm_member_revoke_all(); EXIT; } @@ -1481,7 +1581,7 @@ void nm_member_revoke_all(void) /* revoke_locks sleeps, so can't call in cfs hash cb */ list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list) - nm_member_revoke_locks(nodemap); + nm_member_revoke_locks_always(nodemap); mutex_unlock(&active_config_lock); }