4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (C) 2013, Trustees of Indiana University
25 * Copyright (c) 2017, Intel Corporation.
27 * Author: Joshua Walgenbach <jjw@iu.edu>
29 #include <linux/module.h>
30 #include <linux/sort.h>
31 #include <uapi/linux/lnet/nidstr.h>
32 #include <lustre_net.h>
33 #include <lustre_acl.h>
34 #include <obd_class.h>
36 #include "nodemap_internal.h"
37 #include "ptlrpc_internal.h"
39 #define HASH_NODEMAP_BKT_BITS 3
40 #define HASH_NODEMAP_CUR_BITS 3
41 #define HASH_NODEMAP_MAX_BITS 7
43 #define DEFAULT_NODEMAP "default"
45 /* nodemap proc root proc directory under fs/lustre */
46 struct proc_dir_entry *proc_lustre_nodemap_root;
48 /* Copy of config active flag to avoid locking in mapping functions */
51 /* Lock protecting the active config, useful primarily when proc and
52 * nodemap_hash might be replaced when loading a new config
53 * Any time the active config is referenced, the lock should be held.
55 DEFINE_MUTEX(active_config_lock);
56 struct nodemap_config *active_config;
61 * \param nodemap nodemap to destroy
63 static void nodemap_destroy(struct lu_nodemap *nodemap)
67 if (nodemap->nm_pde_data != NULL)
68 lprocfs_nodemap_remove(nodemap->nm_pde_data);
70 mutex_lock(&active_config_lock);
71 down_read(&active_config->nmc_range_tree_lock);
72 nm_member_reclassify_nodemap(nodemap);
73 up_read(&active_config->nmc_range_tree_lock);
75 down_write(&nodemap->nm_idmap_lock);
76 idmap_delete_tree(nodemap);
77 up_write(&nodemap->nm_idmap_lock);
79 mutex_unlock(&active_config_lock);
81 if (!list_empty(&nodemap->nm_member_list))
82 CWARN("nodemap_destroy failed to reclassify all members\n");
84 nm_member_delete_list(nodemap);
86 OBD_FREE_PTR(nodemap);
92 * Functions used for the cfs_hash
94 void nodemap_getref(struct lu_nodemap *nodemap)
96 atomic_inc(&nodemap->nm_refcount);
97 CDEBUG(D_INFO, "GETting nodemap %s(p=%p) : new refcount %d\n",
98 nodemap->nm_name, nodemap, atomic_read(&nodemap->nm_refcount));
102 * Destroy nodemap if last reference is put. Should be called outside
105 void nodemap_putref(struct lu_nodemap *nodemap)
110 LASSERT(atomic_read(&nodemap->nm_refcount) > 0);
112 CDEBUG(D_INFO, "PUTting nodemap %s(p=%p) : new refcount %d\n",
113 nodemap->nm_name, nodemap,
114 atomic_read(&nodemap->nm_refcount) - 1);
116 if (atomic_dec_and_test(&nodemap->nm_refcount))
117 nodemap_destroy(nodemap);
119 EXPORT_SYMBOL(nodemap_putref);
122 nodemap_hashfn(struct cfs_hash *hash_body,
123 const void *key, const unsigned int bits)
125 return cfs_hash_djb2_hash(key, strlen(key), bits);
128 static void *nodemap_hs_key(struct hlist_node *hnode)
130 struct lu_nodemap *nodemap;
132 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
134 return nodemap->nm_name;
137 static int nodemap_hs_keycmp(const void *key,
138 struct hlist_node *compared_hnode)
142 nodemap_name = nodemap_hs_key(compared_hnode);
144 return !strcmp(key, nodemap_name);
147 static void *nodemap_hs_hashobject(struct hlist_node *hnode)
149 return hlist_entry(hnode, struct lu_nodemap, nm_hash);
152 static void nodemap_hs_get(struct cfs_hash *hs, struct hlist_node *hnode)
154 struct lu_nodemap *nodemap;
156 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
157 nodemap_getref(nodemap);
160 static void nodemap_hs_put_locked(struct cfs_hash *hs,
161 struct hlist_node *hnode)
163 struct lu_nodemap *nodemap;
165 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
166 nodemap_putref(nodemap);
169 static struct cfs_hash_ops nodemap_hash_operations = {
170 .hs_hash = nodemap_hashfn,
171 .hs_key = nodemap_hs_key,
172 .hs_keycmp = nodemap_hs_keycmp,
173 .hs_object = nodemap_hs_hashobject,
174 .hs_get = nodemap_hs_get,
175 .hs_put_locked = nodemap_hs_put_locked,
178 /* end of cfs_hash functions */
181 * Initialize nodemap_hash
184 * \retval -ENOMEM cannot create hash
186 static int nodemap_init_hash(struct nodemap_config *nmc)
188 nmc->nmc_nodemap_hash = cfs_hash_create("NODEMAP",
189 HASH_NODEMAP_CUR_BITS,
190 HASH_NODEMAP_MAX_BITS,
191 HASH_NODEMAP_BKT_BITS, 0,
194 &nodemap_hash_operations,
197 if (nmc->nmc_nodemap_hash == NULL) {
198 CERROR("cannot create nodemap_hash table\n");
206 * Check for valid nodemap name
208 * \param name nodemap name
210 * \retval false invalid
212 static bool nodemap_name_is_valid(const char *name)
214 if (strlen(name) > LUSTRE_NODEMAP_NAME_LENGTH ||
218 for (; *name != '\0'; name++) {
219 if (!isalnum(*name) && *name != '_')
229 * Look nodemap up in the active_config nodemap hash. Caller should hold the
230 * active_config_lock.
232 * \param name name of nodemap
233 * \retval nodemap pointer set to found nodemap
234 * \retval -EINVAL name is not valid
235 * \retval -ENOENT nodemap not found
237 struct lu_nodemap *nodemap_lookup(const char *name)
239 struct lu_nodemap *nodemap = NULL;
241 if (!nodemap_name_is_valid(name))
242 return ERR_PTR(-EINVAL);
244 nodemap = cfs_hash_lookup(active_config->nmc_nodemap_hash, name);
246 return ERR_PTR(-ENOENT);
252 * Classify the nid into the proper nodemap. Caller must hold active config and
253 * nm_range_tree_lock, and call nodemap_putref when done with nodemap.
255 * \param nid nid to classify
256 * \retval nodemap nodemap containing the nid
257 * \retval default_nodemap default nodemap
258 * \retval -EINVAL LO nid given without other local nid
260 struct lu_nodemap *nodemap_classify_nid(struct lnet_nid *nid)
262 struct lu_nid_range *range;
263 struct lu_nodemap *nodemap;
267 /* don't use 0@lo, use the first non-lo local NID instead */
268 if (nid_is_lo0(nid)) {
269 struct lnet_processid id;
273 rc = LNetGetId(i++, &id, true);
275 RETURN(ERR_PTR(-EINVAL));
276 } while (nid_is_lo0(&id.nid));
279 CDEBUG(D_INFO, "found nid %s\n", libcfs_nidstr(nid));
282 range = range_search(active_config, nid);
284 nodemap = range->rn_nodemap;
286 nodemap = active_config->nmc_default_nodemap;
288 LASSERT(nodemap != NULL);
289 nodemap_getref(nodemap);
295 * simple check for default nodemap
297 static bool is_default_nodemap(const struct lu_nodemap *nodemap)
299 return nodemap->nm_id == 0;
303 * parse a nodemap range string into two nids
305 * \param range_str string to parse
306 * \param range[2] array of two nids
307 * \reyval 0 on success
309 int nodemap_parse_range(const char *range_str, struct lnet_nid range[2],
312 char buf[LNET_NIDSTR_SIZE * 2 + 2];
318 snprintf(buf, sizeof(buf), "%s", range_str);
321 /* For large NID we use netmasks. Currently we only
322 * support /128 which is a single NID.
324 if (strchr(ptr, '/')) {
325 start_nidstr = strsep(&ptr, "/");
327 rc = kstrtou8(ptr, 10, netmask);
331 GOTO(out, rc = -ERANGE);
332 end_nidstr = start_nidstr;
334 start_nidstr = strsep(&ptr, ":");
335 end_nidstr = strsep(&ptr, ":");
338 if (start_nidstr == NULL || end_nidstr == NULL)
339 GOTO(out, rc = -EINVAL);
341 rc = libcfs_strnid(&range[0], start_nidstr);
345 rc = libcfs_strnid(&range[1], end_nidstr);
350 EXPORT_SYMBOL(nodemap_parse_range);
353 * parse a string containing an id map of form "client_id:filesystem_id"
354 * into an array of __u32 * for use in mapping functions
356 * \param idmap_str map string
357 * \param idmap array[2] of __u32
359 * \retval 0 on success
360 * \retval -EINVAL if idmap cannot be parsed
362 int nodemap_parse_idmap(char *idmap_str, __u32 idmap[2])
365 long unsigned int idmap_buf;
368 if (idmap_str == NULL)
371 sep = strchr(idmap_str, ':');
377 rc = kstrtoul(idmap_str, 10, &idmap_buf);
380 idmap[0] = idmap_buf;
382 rc = kstrtoul(sep, 10, &idmap_buf);
385 idmap[1] = idmap_buf;
389 EXPORT_SYMBOL(nodemap_parse_idmap);
392 * add a member to a nodemap
394 * \param nid nid to add to the members
395 * \param exp obd_export structure for the connection
396 * that is being added
397 * \retval -EINVAL export is NULL, or has invalid NID
398 * \retval -EEXIST export is already member of a nodemap
400 int nodemap_add_member(struct lnet_nid *nid, struct obd_export *exp)
402 struct lu_nodemap *nodemap;
406 mutex_lock(&active_config_lock);
407 down_read(&active_config->nmc_range_tree_lock);
409 nodemap = nodemap_classify_nid(nid);
410 if (IS_ERR(nodemap)) {
411 CWARN("%s: error adding to nodemap, no valid NIDs found\n",
412 exp->exp_obd->obd_name);
415 rc = nm_member_add(nodemap, exp);
418 up_read(&active_config->nmc_range_tree_lock);
419 mutex_unlock(&active_config_lock);
421 if (!IS_ERR(nodemap))
422 nodemap_putref(nodemap);
426 EXPORT_SYMBOL(nodemap_add_member);
429 * delete a member from a nodemap
431 * \param exp export to remove from a nodemap
433 void nodemap_del_member(struct obd_export *exp)
435 struct lu_nodemap *nodemap;
439 /* using ac lock to prevent nodemap reclassification while deleting */
440 mutex_lock(&active_config_lock);
442 /* use of ted_nodemap is protected by active_config_lock. we take an
443 * extra reference to make sure nodemap isn't destroyed under
446 nodemap = exp->exp_target_data.ted_nodemap;
450 nodemap_getref(nodemap);
452 mutex_lock(&nodemap->nm_member_list_lock);
453 nm_member_del(nodemap, exp);
454 mutex_unlock(&nodemap->nm_member_list_lock);
457 mutex_unlock(&active_config_lock);
460 nodemap_putref(nodemap);
464 EXPORT_SYMBOL(nodemap_del_member);
467 * add an idmap to the proper nodemap trees
469 * \param nodemap nodemap to add idmap to
470 * \param id_type NODEMAP_UID or NODEMAP_GID
471 * \param map array[2] __u32 containing the map values
472 * map[0] is client id
473 * map[1] is the filesystem id
475 * \retval 0 on success
476 * \retval < 0 if error occurs
478 int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
479 enum nodemap_id_type id_type,
482 struct lu_idmap *idmap;
483 struct lu_idmap *temp;
486 idmap = idmap_create(map[0], map[1]);
488 GOTO(out, rc = -ENOMEM);
490 down_write(&nodemap->nm_idmap_lock);
491 temp = idmap_insert(id_type, idmap, nodemap);
492 /* If the new id_client or id_fs is matched, the old idmap and its
493 * index should be deleted according to its id_client before the new
494 * idmap is added again.
497 GOTO(out_insert, rc = PTR_ERR(temp));
501 del_map[0] = temp->id_client;
502 idmap_delete(id_type, temp, nodemap);
503 rc = nodemap_idx_idmap_del(nodemap, id_type, del_map);
504 /* In case there is any corrupted idmap */
505 if (!rc || unlikely(rc == -ENOENT)) {
506 temp = idmap_insert(id_type, idmap, nodemap);
518 up_write(&nodemap->nm_idmap_lock);
519 nm_member_revoke_locks(nodemap);
525 int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
528 struct lu_nodemap *nodemap = NULL;
533 mutex_lock(&active_config_lock);
534 nodemap = nodemap_lookup(name);
535 if (IS_ERR(nodemap)) {
536 mutex_unlock(&active_config_lock);
537 GOTO(out, rc = PTR_ERR(nodemap));
540 if (is_default_nodemap(nodemap)) {
543 rc = nodemap_add_idmap_helper(nodemap, id_type, map);
545 rc = nodemap_idx_idmap_add(nodemap, id_type, map);
547 mutex_unlock(&active_config_lock);
548 nodemap_putref(nodemap);
553 EXPORT_SYMBOL(nodemap_add_idmap);
556 * delete idmap from proper nodemap tree
558 * \param name name of nodemap
559 * \param id_type NODEMAP_UID or NODEMAP_GID
560 * \param map array[2] __u32 containing the mapA values
561 * map[0] is client id
562 * map[1] is the filesystem id
564 * \retval 0 on success
566 int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
569 struct lu_nodemap *nodemap = NULL;
570 struct lu_idmap *idmap = NULL;
575 mutex_lock(&active_config_lock);
576 nodemap = nodemap_lookup(name);
577 if (IS_ERR(nodemap)) {
578 mutex_unlock(&active_config_lock);
579 GOTO(out, rc = PTR_ERR(nodemap));
582 if (is_default_nodemap(nodemap))
583 GOTO(out_putref, rc = -EINVAL);
585 down_write(&nodemap->nm_idmap_lock);
586 idmap = idmap_search(nodemap, NODEMAP_CLIENT_TO_FS, id_type,
591 idmap_delete(id_type, idmap, nodemap);
592 rc = nodemap_idx_idmap_del(nodemap, id_type, map);
594 up_write(&nodemap->nm_idmap_lock);
597 mutex_unlock(&active_config_lock);
599 nm_member_revoke_locks(nodemap);
600 nodemap_putref(nodemap);
605 EXPORT_SYMBOL(nodemap_del_idmap);
608 * Get nodemap assigned to given export. Takes a reference on the nodemap.
610 * Note that this function may return either NULL, or an ERR_PTR()
611 * or a valid nodemap pointer. All of the functions accessing the
612 * returned nodemap can check IS_ERR(nodemap) to see if an error is
613 * returned. NULL is not considered an error, which is OK since this
614 * is a valid case if nodemap are not in use. All nodemap handling
615 * functions must check for nodemap == NULL and do nothing, and the
616 * nodemap returned from this function should not be dereferenced.
618 * \param export export to get nodemap for
620 * \retval pointer to nodemap on success
621 * \retval NULL nodemap subsystem disabled
622 * \retval -EACCES export does not have nodemap assigned
624 struct lu_nodemap *nodemap_get_from_exp(struct obd_export *exp)
626 struct lu_nodemap *nodemap;
633 spin_lock(&exp->exp_target_data.ted_nodemap_lock);
634 nodemap = exp->exp_target_data.ted_nodemap;
636 nodemap_getref(nodemap);
637 spin_unlock(&exp->exp_target_data.ted_nodemap_lock);
640 CDEBUG(D_INFO, "%s: nodemap null on export %s (at %s)\n",
641 exp->exp_obd->obd_name,
642 obd_uuid2str(&exp->exp_client_uuid),
643 obd_export_nid2str(exp));
644 RETURN(ERR_PTR(-EACCES));
649 EXPORT_SYMBOL(nodemap_get_from_exp);
652 * mapping function for nodemap idmaps
654 * \param nodemap lu_nodemap structure defining nodemap
655 * \param node_type NODEMAP_UID or NODEMAP_GID or NODEMAP_PROJID
656 * \param tree_type NODEMAP_CLIENT_TO_FS or
657 * NODEMAP_FS_TO_CLIENT
658 * \param id id to map
660 * \retval mapped id according to the rules below.
662 * if the nodemap_active is false, just return the passed id without mapping
664 * if the id to be looked up is 0, check that root access is allowed and if it
665 * is, return 0. Otherwise, return the mapped uid or gid if any.
666 * Otherwise, return the squash uid or gid.
668 * if the nodemap is configured to trusted the ids from the client system, just
669 * return the passed id without mapping.
671 * if by this point, we haven't returned and the nodemap in question is the
672 * default nodemap, return the squash uid or gid.
674 * after these checks, search the proper tree for the mapping, and if found
675 * return the mapped value, otherwise return the squash uid or gid.
677 __u32 nodemap_map_id(struct lu_nodemap *nodemap,
678 enum nodemap_id_type id_type,
679 enum nodemap_tree_type tree_type, __u32 id)
681 struct lu_idmap *idmap = NULL;
689 if (unlikely(nodemap == NULL))
693 if (nodemap->nmf_allow_root_access)
698 if (id_type == NODEMAP_UID &&
699 !(nodemap->nmf_map_mode & NODEMAP_MAP_UID))
702 if (id_type == NODEMAP_GID &&
703 !(nodemap->nmf_map_mode & NODEMAP_MAP_GID))
706 if (id_type == NODEMAP_PROJID &&
707 !(nodemap->nmf_map_mode & NODEMAP_MAP_PROJID))
710 if (nodemap->nmf_trust_client_ids)
714 if (is_default_nodemap(nodemap))
717 down_read(&nodemap->nm_idmap_lock);
718 idmap = idmap_search(nodemap, tree_type, id_type, id);
720 up_read(&nodemap->nm_idmap_lock);
724 if (tree_type == NODEMAP_FS_TO_CLIENT)
725 found_id = idmap->id_client;
727 found_id = idmap->id_fs;
728 up_read(&nodemap->nm_idmap_lock);
732 if (id_type == NODEMAP_UID)
733 RETURN(nodemap->nm_squash_uid);
734 if (id_type == NODEMAP_GID)
735 RETURN(nodemap->nm_squash_gid);
736 if (id_type == NODEMAP_PROJID)
737 RETURN(nodemap->nm_squash_projid);
741 EXPORT_SYMBOL(nodemap_map_id);
744 * Map posix ACL entries according to the nodemap membership. Removes any
747 * \param lu_nodemap nodemap
748 * \param buf buffer containing xattr encoded ACLs
749 * \param size size of ACLs in bytes
750 * \param tree_type direction of mapping
751 * \retval size new size of ACLs in bytes
752 * \retval -EINVAL bad \a size param, see posix_acl_xattr_count()
754 ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size,
755 enum nodemap_tree_type tree_type)
757 posix_acl_xattr_header *header = buf;
758 posix_acl_xattr_entry *entry = GET_POSIX_ACL_XATTR_ENTRY(header);
759 posix_acl_xattr_entry *new_entry = entry;
760 posix_acl_xattr_entry *end;
768 if (unlikely(nodemap == NULL))
771 count = posix_acl_xattr_count(size);
775 /* if not proper ACL, do nothing and return initial size */
778 for (end = entry + count; entry != end; entry++) {
779 __u16 tag = le16_to_cpu(entry->e_tag);
780 __u32 id = le32_to_cpu(entry->e_id);
784 id = nodemap_map_id(nodemap, NODEMAP_UID,
786 if (id == nodemap->nm_squash_uid)
788 entry->e_id = cpu_to_le32(id);
791 id = nodemap_map_id(nodemap, NODEMAP_GID,
793 if (id == nodemap->nm_squash_gid)
795 entry->e_id = cpu_to_le32(id);
799 /* if we skip an ACL, copy the following ones over it */
800 if (new_entry != entry)
806 RETURN((void *)new_entry - (void *)header);
808 EXPORT_SYMBOL(nodemap_map_acl);
811 * Add nid range to given nodemap
813 * \param config nodemap config to work on
814 * \param nodemap nodemap to add range to
815 * \param nid nid range to add
816 * \param range_id should be 0 unless loading from disk
821 int nodemap_add_range_helper(struct nodemap_config *config,
822 struct lu_nodemap *nodemap,
823 const struct lnet_nid nid[2],
824 u8 netmask, unsigned int range_id)
826 struct lu_nid_range *range;
829 down_write(&config->nmc_range_tree_lock);
830 range = range_create(config, &nid[0], &nid[1], netmask, nodemap,
833 up_write(&config->nmc_range_tree_lock);
834 GOTO(out, rc = -ENOMEM);
837 rc = range_insert(config, range);
839 CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
840 "cannot insert nodemap range into '%s': rc = %d\n",
841 nodemap->nm_name, rc);
842 up_write(&config->nmc_range_tree_lock);
843 list_del(&range->rn_list);
844 range_destroy(range);
848 list_add(&range->rn_list, &nodemap->nm_ranges);
850 /* nodemaps have no members if they aren't on the active config */
851 if (config == active_config)
852 nm_member_reclassify_nodemap(config->nmc_default_nodemap);
854 up_write(&config->nmc_range_tree_lock);
856 /* if range_id is non-zero, we are loading from disk */
858 rc = nodemap_idx_range_add(range);
860 if (config == active_config) {
861 nm_member_revoke_locks(config->nmc_default_nodemap);
862 nm_member_revoke_locks(nodemap);
869 int nodemap_add_range(const char *name, const struct lnet_nid nid[2],
872 struct lu_nodemap *nodemap = NULL;
875 mutex_lock(&active_config_lock);
876 nodemap = nodemap_lookup(name);
877 if (IS_ERR(nodemap)) {
878 mutex_unlock(&active_config_lock);
879 GOTO(out, rc = PTR_ERR(nodemap));
882 if (is_default_nodemap(nodemap))
885 rc = nodemap_add_range_helper(active_config, nodemap, nid,
887 mutex_unlock(&active_config_lock);
888 nodemap_putref(nodemap);
892 EXPORT_SYMBOL(nodemap_add_range);
896 * \param name nodemap name
897 * \param nid nid range
898 * \retval 0 on success
900 * Delete range from global range tree, and remove it
901 * from the list in the associated nodemap.
903 int nodemap_del_range(const char *name, const struct lnet_nid nid[2],
906 struct lu_nodemap *nodemap;
907 struct lu_nid_range *range;
910 mutex_lock(&active_config_lock);
911 nodemap = nodemap_lookup(name);
912 if (IS_ERR(nodemap)) {
913 mutex_unlock(&active_config_lock);
914 GOTO(out, rc = PTR_ERR(nodemap));
917 if (is_default_nodemap(nodemap))
918 GOTO(out_putref, rc = -EINVAL);
920 down_write(&active_config->nmc_range_tree_lock);
921 range = range_find(active_config, &nid[0], &nid[1], netmask);
923 up_write(&active_config->nmc_range_tree_lock);
924 GOTO(out_putref, rc = -EINVAL);
926 if (range->rn_nodemap != nodemap) {
927 up_write(&active_config->nmc_range_tree_lock);
928 GOTO(out_putref, rc = -EINVAL);
930 rc = nodemap_idx_range_del(range);
931 range_delete(active_config, range);
932 nm_member_reclassify_nodemap(nodemap);
933 up_write(&active_config->nmc_range_tree_lock);
935 nm_member_revoke_locks(active_config->nmc_default_nodemap);
936 nm_member_revoke_locks(nodemap);
939 mutex_unlock(&active_config_lock);
940 nodemap_putref(nodemap);
944 EXPORT_SYMBOL(nodemap_del_range);
947 * set fileset on nodemap
948 * \param name nodemap to set fileset on
949 * \param fileset string containing fileset
950 * \retval 0 on success
952 * set a fileset on the named nodemap
954 static int nodemap_set_fileset_helper(struct nodemap_config *config,
955 struct lu_nodemap *nodemap,
960 /* Allow 'fileset=clear' in addition to 'fileset=""' to clear fileset
961 * because either command 'lctl set_param -P *.*.fileset=""' or
962 * 'lctl nodemap_set_fileset --fileset ""' can only work correctly
963 * on MGS, while on other servers, both commands will invoke upcall
964 * "/usr/sbin/lctl set_param nodemap.default.fileset=" by function
965 * process_param2_config(), which will cause "no value" error and
966 * won't clear fileset.
967 * 'fileset=""' is still kept for compatibility reason.
971 else if (fileset[0] == '\0' || strcmp(fileset, "clear") == 0)
972 nodemap->nm_fileset[0] = '\0';
973 else if (fileset[0] != '/')
975 else if (strscpy(nodemap->nm_fileset, fileset,
976 sizeof(nodemap->nm_fileset)) < 0)
982 int nodemap_set_fileset(const char *name, const char *fileset)
984 struct lu_nodemap *nodemap = NULL;
987 mutex_lock(&active_config_lock);
988 nodemap = nodemap_lookup(name);
989 if (IS_ERR(nodemap)) {
990 mutex_unlock(&active_config_lock);
991 GOTO(out, rc = PTR_ERR(nodemap));
994 rc = nodemap_set_fileset_helper(active_config, nodemap, fileset);
995 mutex_unlock(&active_config_lock);
997 nodemap_putref(nodemap);
1001 EXPORT_SYMBOL(nodemap_set_fileset);
1004 * get fileset defined on nodemap
1005 * \param nodemap nodemap to get fileset from
1006 * \retval fileset name, or NULL if not defined or not activated
1008 * get the fileset defined on the nodemap
1010 char *nodemap_get_fileset(const struct lu_nodemap *nodemap)
1012 if (!nodemap_active)
1015 return (char *)nodemap->nm_fileset;
1017 EXPORT_SYMBOL(nodemap_get_fileset);
1019 static int nodemap_validate_sepol(const char *sepol)
1021 char buf[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
1022 char *p = (char *)sepol;
1024 char polname[NAME_MAX + 1] = "";
1025 char hash[SELINUX_POLICY_HASH_LEN + 1] = "";
1029 BUILD_BUG_ON(sizeof(buf) != sizeof(((struct lu_nodemap *)0)->nm_sepol));
1034 /* we allow sepol = "" which means clear SELinux policy info */
1035 if (sepol[0] == '\0')
1038 /* make a copy of sepol, by replacing ':' with space
1039 * so that we can use sscanf over the string
1041 while (p-sepol < sizeof(buf)) {
1051 if (p-sepol == sizeof(buf))
1052 return -ENAMETOOLONG;
1054 if (sscanf(buf, "%1hhu %s %hu %s", &mode, polname, &ver, hash) != 4)
1057 if (mode != 0 && mode != 1)
1064 * set SELinux policy on nodemap
1065 * \param name nodemap to set SELinux policy info on
1066 * \param sepol string containing SELinux policy info
1067 * \retval 0 on success
1069 * set SELinux policy info on the named nodemap
1071 int nodemap_set_sepol(const char *name, const char *sepol)
1073 struct lu_nodemap *nodemap = NULL;
1076 rc = nodemap_validate_sepol(sepol);
1080 mutex_lock(&active_config_lock);
1081 nodemap = nodemap_lookup(name);
1082 if (IS_ERR(nodemap)) {
1083 mutex_unlock(&active_config_lock);
1084 GOTO(out, rc = PTR_ERR(nodemap));
1087 if (is_default_nodemap(nodemap)) {
1088 /* We do not want nodes in the default nodemap to have
1089 * SELinux restrictions. Sec admin should create dedicated
1090 * nodemap entries for this.
1092 GOTO(out_putref, rc = -EINVAL);
1095 /* truncation cannot happen, as string length was checked in
1096 * nodemap_validate_sepol()
1098 strscpy(nodemap->nm_sepol, sepol, sizeof(nodemap->nm_sepol));
1101 mutex_unlock(&active_config_lock);
1102 nodemap_putref(nodemap);
1106 EXPORT_SYMBOL(nodemap_set_sepol);
1109 * get SELinux policy info defined on nodemap
1110 * \param nodemap nodemap to get SELinux policy info from
1111 * \retval SELinux policy info, or NULL if not defined or not activated
1113 * get the SELinux policy info defined on the nodemap
1115 const char *nodemap_get_sepol(const struct lu_nodemap *nodemap)
1117 if (is_default_nodemap(nodemap))
1120 return (char *)nodemap->nm_sepol;
1122 EXPORT_SYMBOL(nodemap_get_sepol);
1125 * Nodemap constructor
1127 * Creates an lu_nodemap structure and assigns sane default
1128 * member values. If this is the default nodemap, the defaults
1129 * are the most restrictive in terms of mapping behavior. Otherwise
1130 * the default flags should be inherited from the default nodemap.
1131 * The adds nodemap to nodemap_hash.
1133 * Requires that the caller take the active_config_lock
1135 * \param name name of nodemap
1136 * \param is_default true if default nodemap
1137 * \retval nodemap success
1138 * \retval -EINVAL invalid nodemap name
1139 * \retval -EEXIST nodemap already exists
1140 * \retval -ENOMEM cannot allocate memory for nodemap
1142 struct lu_nodemap *nodemap_create(const char *name,
1143 struct nodemap_config *config,
1146 struct lu_nodemap *nodemap = NULL;
1147 struct lu_nodemap *default_nodemap;
1148 struct cfs_hash *hash = config->nmc_nodemap_hash;
1152 default_nodemap = config->nmc_default_nodemap;
1154 if (!nodemap_name_is_valid(name))
1155 GOTO(out, rc = -EINVAL);
1158 CERROR("Config nodemap hash is NULL, unable to add %s\n", name);
1159 GOTO(out, rc = -EINVAL);
1162 OBD_ALLOC_PTR(nodemap);
1163 if (nodemap == NULL) {
1164 CERROR("cannot allocate memory (%zu bytes) for nodemap '%s'\n",
1165 sizeof(*nodemap), name);
1166 GOTO(out, rc = -ENOMEM);
1170 * take an extra reference to prevent nodemap from being destroyed
1171 * while it's being created.
1173 atomic_set(&nodemap->nm_refcount, 2);
1174 snprintf(nodemap->nm_name, sizeof(nodemap->nm_name), "%s", name);
1175 rc = cfs_hash_add_unique(hash, name, &nodemap->nm_hash);
1177 OBD_FREE_PTR(nodemap);
1178 GOTO(out, rc = -EEXIST);
1181 INIT_LIST_HEAD(&nodemap->nm_ranges);
1182 INIT_LIST_HEAD(&nodemap->nm_list);
1183 INIT_LIST_HEAD(&nodemap->nm_member_list);
1185 mutex_init(&nodemap->nm_member_list_lock);
1186 init_rwsem(&nodemap->nm_idmap_lock);
1187 nodemap->nm_fs_to_client_uidmap = RB_ROOT;
1188 nodemap->nm_client_to_fs_uidmap = RB_ROOT;
1189 nodemap->nm_fs_to_client_gidmap = RB_ROOT;
1190 nodemap->nm_client_to_fs_gidmap = RB_ROOT;
1191 nodemap->nm_fs_to_client_projidmap = RB_ROOT;
1192 nodemap->nm_client_to_fs_projidmap = RB_ROOT;
1195 nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
1196 config->nmc_default_nodemap = nodemap;
1198 config->nmc_nodemap_highest_id++;
1199 nodemap->nm_id = config->nmc_nodemap_highest_id;
1202 if (is_default || default_nodemap == NULL) {
1203 nodemap->nmf_trust_client_ids = 0;
1204 nodemap->nmf_allow_root_access = 0;
1205 nodemap->nmf_deny_unknown = 0;
1206 nodemap->nmf_map_mode = NODEMAP_MAP_ALL;
1207 nodemap->nmf_enable_audit = 1;
1208 nodemap->nmf_forbid_encryption = 0;
1209 nodemap->nmf_readonly_mount = 0;
1210 nodemap->nmf_rbac = NODEMAP_RBAC_ALL;
1212 nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
1213 nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
1214 nodemap->nm_squash_projid = NODEMAP_NOBODY_PROJID;
1215 nodemap->nm_fileset[0] = '\0';
1216 nodemap->nm_sepol[0] = '\0';
1218 CWARN("adding nodemap '%s' to config without"
1219 " default nodemap\n", nodemap->nm_name);
1221 nodemap->nmf_trust_client_ids =
1222 default_nodemap->nmf_trust_client_ids;
1223 nodemap->nmf_allow_root_access =
1224 default_nodemap->nmf_allow_root_access;
1225 nodemap->nmf_deny_unknown = default_nodemap->nmf_deny_unknown;
1226 nodemap->nmf_map_mode = default_nodemap->nmf_map_mode;
1227 nodemap->nmf_enable_audit = default_nodemap->nmf_enable_audit;
1228 nodemap->nmf_forbid_encryption =
1229 default_nodemap->nmf_forbid_encryption;
1230 nodemap->nmf_readonly_mount =
1231 default_nodemap->nmf_readonly_mount;
1232 nodemap->nmf_rbac = default_nodemap->nmf_rbac;
1234 nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
1235 nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
1236 nodemap->nm_squash_projid = default_nodemap->nm_squash_projid;
1237 nodemap->nm_fileset[0] = '\0';
1238 nodemap->nm_sepol[0] = '\0';
1244 CERROR("cannot add nodemap: '%s': rc = %d\n", name, rc);
1245 RETURN(ERR_PTR(rc));
1249 * Set the nmf_deny_unknown flag to true or false.
1250 * \param name nodemap name
1251 * \param deny_unknown if true, squashed users will get EACCES
1252 * \retval 0 on success
1255 int nodemap_set_deny_unknown(const char *name, bool deny_unknown)
1257 struct lu_nodemap *nodemap = NULL;
1260 mutex_lock(&active_config_lock);
1261 nodemap = nodemap_lookup(name);
1262 mutex_unlock(&active_config_lock);
1263 if (IS_ERR(nodemap))
1264 GOTO(out, rc = PTR_ERR(nodemap));
1266 nodemap->nmf_deny_unknown = deny_unknown;
1267 rc = nodemap_idx_nodemap_update(nodemap);
1269 nm_member_revoke_locks(nodemap);
1270 nodemap_putref(nodemap);
1274 EXPORT_SYMBOL(nodemap_set_deny_unknown);
1277 * Set the nmf_allow_root_access flag to true or false.
1278 * \param name nodemap name
1279 * \param allow_root if true, nodemap will not squash the root user
1280 * \retval 0 on success
1283 int nodemap_set_allow_root(const char *name, bool allow_root)
1285 struct lu_nodemap *nodemap = NULL;
1288 mutex_lock(&active_config_lock);
1289 nodemap = nodemap_lookup(name);
1290 mutex_unlock(&active_config_lock);
1291 if (IS_ERR(nodemap))
1292 GOTO(out, rc = PTR_ERR(nodemap));
1294 nodemap->nmf_allow_root_access = allow_root;
1295 rc = nodemap_idx_nodemap_update(nodemap);
1297 nm_member_revoke_locks(nodemap);
1298 nodemap_putref(nodemap);
1302 EXPORT_SYMBOL(nodemap_set_allow_root);
1305 * Set the nmf_trust_client_ids flag to true or false.
1307 * \param name nodemap name
1308 * \param trust_client_ids if true, nodemap will not map its IDs
1309 * \retval 0 on success
1312 int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids)
1314 struct lu_nodemap *nodemap = NULL;
1317 mutex_lock(&active_config_lock);
1318 nodemap = nodemap_lookup(name);
1319 mutex_unlock(&active_config_lock);
1320 if (IS_ERR(nodemap))
1321 GOTO(out, rc = PTR_ERR(nodemap));
1323 nodemap->nmf_trust_client_ids = trust_client_ids;
1324 rc = nodemap_idx_nodemap_update(nodemap);
1326 nm_member_revoke_locks(nodemap);
1327 nodemap_putref(nodemap);
1331 EXPORT_SYMBOL(nodemap_set_trust_client_ids);
1333 int nodemap_set_mapping_mode(const char *name,
1334 enum nodemap_mapping_modes map_mode)
1336 struct lu_nodemap *nodemap = NULL;
1339 mutex_lock(&active_config_lock);
1340 nodemap = nodemap_lookup(name);
1341 mutex_unlock(&active_config_lock);
1342 if (IS_ERR(nodemap))
1343 GOTO(out, rc = PTR_ERR(nodemap));
1345 nodemap->nmf_map_mode = map_mode;
1346 rc = nodemap_idx_nodemap_update(nodemap);
1348 nm_member_revoke_locks(nodemap);
1349 nodemap_putref(nodemap);
1353 EXPORT_SYMBOL(nodemap_set_mapping_mode);
1355 int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
1357 struct lu_nodemap *nodemap = NULL;
1358 enum nodemap_rbac_roles old_rbac;
1361 mutex_lock(&active_config_lock);
1362 nodemap = nodemap_lookup(name);
1363 mutex_unlock(&active_config_lock);
1364 if (IS_ERR(nodemap))
1365 GOTO(out, rc = PTR_ERR(nodemap));
1367 if (is_default_nodemap(nodemap))
1368 GOTO(put, rc = -EINVAL);
1370 old_rbac = nodemap->nmf_rbac;
1371 /* if value does not change, do nothing */
1372 if (rbac == old_rbac)
1375 nodemap->nmf_rbac = rbac;
1376 if (rbac == NODEMAP_RBAC_ALL)
1377 /* if new value is ALL (default), just delete
1378 * NODEMAP_CLUSTER_ROLES idx
1380 rc = nodemap_idx_cluster_roles_del(nodemap);
1381 else if (old_rbac == NODEMAP_RBAC_ALL)
1382 /* if old value is ALL (default), need to insert
1383 * NODEMAP_CLUSTER_ROLES idx
1385 rc = nodemap_idx_cluster_roles_add(nodemap);
1387 /* otherwise just update existing NODEMAP_CLUSTER_ROLES idx */
1388 rc = nodemap_idx_cluster_roles_update(nodemap);
1390 nm_member_revoke_locks(nodemap);
1392 nodemap_putref(nodemap);
1396 EXPORT_SYMBOL(nodemap_set_rbac);
1399 * Update the squash_uid for a nodemap.
1401 * \param name nodemap name
1402 * \param uid the new uid to squash unknown users to
1403 * \retval 0 on success
1405 * Update the squash_uid for a nodemap. The squash_uid is the uid
1406 * that the all client uids are mapped to if nodemap is active,
1407 * the trust_client_ids flag is not set, and the uid is not in
1410 int nodemap_set_squash_uid(const char *name, uid_t uid)
1412 struct lu_nodemap *nodemap = NULL;
1415 mutex_lock(&active_config_lock);
1416 nodemap = nodemap_lookup(name);
1417 mutex_unlock(&active_config_lock);
1418 if (IS_ERR(nodemap))
1419 GOTO(out, rc = PTR_ERR(nodemap));
1421 nodemap->nm_squash_uid = uid;
1422 rc = nodemap_idx_nodemap_update(nodemap);
1424 nm_member_revoke_locks(nodemap);
1425 nodemap_putref(nodemap);
1429 EXPORT_SYMBOL(nodemap_set_squash_uid);
1432 * Update the squash_gid for a nodemap.
1434 * \param name nodemap name
1435 * \param gid the new gid to squash unknown gids to
1436 * \retval 0 on success
1438 * Update the squash_gid for a nodemap. The squash_gid is the gid
1439 * that the all client gids are mapped to if nodemap is active,
1440 * the trust_client_ids flag is not set, and the gid is not in
1443 int nodemap_set_squash_gid(const char *name, gid_t gid)
1445 struct lu_nodemap *nodemap = NULL;
1448 mutex_lock(&active_config_lock);
1449 nodemap = nodemap_lookup(name);
1450 mutex_unlock(&active_config_lock);
1451 if (IS_ERR(nodemap))
1452 GOTO(out, rc = PTR_ERR(nodemap));
1454 nodemap->nm_squash_gid = gid;
1455 rc = nodemap_idx_nodemap_update(nodemap);
1457 nm_member_revoke_locks(nodemap);
1458 nodemap_putref(nodemap);
1462 EXPORT_SYMBOL(nodemap_set_squash_gid);
1465 * Update the squash_projid for a nodemap.
1467 * \param name nodemap name
1468 * \param gid the new projid to squash unknown projids to
1469 * \retval 0 on success
1471 * Update the squash_projid for a nodemap. The squash_projid is the projid
1472 * that the all client projids are mapped to if nodemap is active,
1473 * the trust_client_ids flag is not set, and the projid is not in
1476 int nodemap_set_squash_projid(const char *name, projid_t projid)
1478 struct lu_nodemap *nodemap = NULL;
1481 mutex_lock(&active_config_lock);
1482 nodemap = nodemap_lookup(name);
1483 mutex_unlock(&active_config_lock);
1484 if (IS_ERR(nodemap))
1485 GOTO(out, rc = PTR_ERR(nodemap));
1487 nodemap->nm_squash_projid = projid;
1488 rc = nodemap_idx_nodemap_update(nodemap);
1490 nm_member_revoke_locks(nodemap);
1491 nodemap_putref(nodemap);
1495 EXPORT_SYMBOL(nodemap_set_squash_projid);
1498 * Check if nodemap allows setting quota.
1500 * If nodemap is not active, always allow.
1501 * For user and group quota, allow if the nodemap allows root access.
1502 * For project quota, allow if project id is not squashed or deny_unknown
1505 * \param nodemap nodemap to check access for
1506 * \param qc_type quota type
1507 * \param id client id to map
1508 * \retval true is setquota is allowed, false otherwise
1510 bool nodemap_can_setquota(struct lu_nodemap *nodemap, __u32 qc_type, __u32 id)
1512 if (!nodemap_active)
1515 if (!nodemap || !nodemap->nmf_allow_root_access ||
1516 !(nodemap->nmf_rbac & NODEMAP_RBAC_QUOTA_OPS))
1519 if (qc_type == PRJQUOTA) {
1520 id = nodemap_map_id(nodemap, NODEMAP_PROJID,
1521 NODEMAP_CLIENT_TO_FS, id);
1523 if (id == nodemap->nm_squash_projid &&
1524 nodemap->nmf_deny_unknown)
1530 EXPORT_SYMBOL(nodemap_can_setquota);
1533 * Set the nmf_enable_audit flag to true or false.
1534 * \param name nodemap name
1535 * \param audit_mode if true, allow audit
1536 * \retval 0 on success
1539 int nodemap_set_audit_mode(const char *name, bool enable_audit)
1541 struct lu_nodemap *nodemap = NULL;
1544 mutex_lock(&active_config_lock);
1545 nodemap = nodemap_lookup(name);
1546 mutex_unlock(&active_config_lock);
1547 if (IS_ERR(nodemap))
1548 GOTO(out, rc = PTR_ERR(nodemap));
1550 nodemap->nmf_enable_audit = enable_audit;
1551 rc = nodemap_idx_nodemap_update(nodemap);
1553 nm_member_revoke_locks(nodemap);
1554 nodemap_putref(nodemap);
1558 EXPORT_SYMBOL(nodemap_set_audit_mode);
1561 * Set the nmf_forbid_encryption flag to true or false.
1562 * \param name nodemap name
1563 * \param forbid_encryption if true, forbid encryption
1564 * \retval 0 on success
1567 int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption)
1569 struct lu_nodemap *nodemap = NULL;
1572 mutex_lock(&active_config_lock);
1573 nodemap = nodemap_lookup(name);
1574 mutex_unlock(&active_config_lock);
1575 if (IS_ERR(nodemap))
1576 GOTO(out, rc = PTR_ERR(nodemap));
1578 nodemap->nmf_forbid_encryption = forbid_encryption;
1579 rc = nodemap_idx_nodemap_update(nodemap);
1581 nm_member_revoke_locks(nodemap);
1582 nodemap_putref(nodemap);
1586 EXPORT_SYMBOL(nodemap_set_forbid_encryption);
1589 * Set the nmf_readonly_mount flag to true or false.
1590 * \param name nodemap name
1591 * \param readonly_mount if true, forbid rw mount
1592 * \retval 0 on success
1595 int nodemap_set_readonly_mount(const char *name, bool readonly_mount)
1597 struct lu_nodemap *nodemap = NULL;
1600 mutex_lock(&active_config_lock);
1601 nodemap = nodemap_lookup(name);
1602 mutex_unlock(&active_config_lock);
1603 if (IS_ERR(nodemap))
1604 GOTO(out, rc = PTR_ERR(nodemap));
1606 nodemap->nmf_readonly_mount = readonly_mount;
1607 rc = nodemap_idx_nodemap_update(nodemap);
1609 nm_member_revoke_locks(nodemap);
1610 nodemap_putref(nodemap);
1614 EXPORT_SYMBOL(nodemap_set_readonly_mount);
1619 * \param name name of nodemap
1621 * \retval -EINVAL invalid nodemap name
1622 * \retval -EEXIST nodemap already exists
1623 * \retval -ENOMEM cannot allocate memory for nodemap
1625 int nodemap_add(const char *nodemap_name)
1627 struct lu_nodemap *nodemap;
1630 mutex_lock(&active_config_lock);
1631 nodemap = nodemap_create(nodemap_name, active_config, 0);
1632 if (IS_ERR(nodemap)) {
1633 mutex_unlock(&active_config_lock);
1634 return PTR_ERR(nodemap);
1637 rc = nodemap_idx_nodemap_add(nodemap);
1639 rc = lprocfs_nodemap_register(nodemap, 0);
1641 mutex_unlock(&active_config_lock);
1642 nodemap_putref(nodemap);
1646 EXPORT_SYMBOL(nodemap_add);
1651 * \param name name of nodemmap
1653 * \retval -EINVAL invalid input
1654 * \retval -ENOENT no existing nodemap
1656 int nodemap_del(const char *nodemap_name)
1658 struct lu_nodemap *nodemap;
1659 struct lu_nid_range *range;
1660 struct lu_nid_range *range_temp;
1664 if (strcmp(nodemap_name, DEFAULT_NODEMAP) == 0)
1667 mutex_lock(&active_config_lock);
1668 nodemap = cfs_hash_del_key(active_config->nmc_nodemap_hash,
1670 if (nodemap == NULL) {
1671 mutex_unlock(&active_config_lock);
1672 GOTO(out, rc = -ENOENT);
1675 /* erase nodemap from active ranges to prevent client assignment */
1676 down_write(&active_config->nmc_range_tree_lock);
1677 list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
1679 rc2 = nodemap_idx_range_del(range);
1683 range_delete(active_config, range);
1685 up_write(&active_config->nmc_range_tree_lock);
1687 rc2 = nodemap_idx_nodemap_del(nodemap);
1692 * remove procfs here in case nodemap_create called with same name
1693 * before nodemap_destroy is run.
1695 lprocfs_nodemap_remove(nodemap->nm_pde_data);
1696 nodemap->nm_pde_data = NULL;
1698 /* reclassify all member exports from nodemap, so they put their refs */
1699 down_read(&active_config->nmc_range_tree_lock);
1700 nm_member_reclassify_nodemap(nodemap);
1701 up_read(&active_config->nmc_range_tree_lock);
1703 if (!list_empty(&nodemap->nm_member_list))
1704 CWARN("nodemap_del failed to reclassify all members\n");
1706 mutex_unlock(&active_config_lock);
1708 nodemap_putref(nodemap);
1713 EXPORT_SYMBOL(nodemap_del);
1716 * activate nodemap functions
1718 * \param value 1 for on, 0 for off
1720 void nodemap_activate(const bool value)
1722 mutex_lock(&active_config_lock);
1723 active_config->nmc_nodemap_is_active = value;
1725 /* copy active value to global to avoid locking in map functions */
1726 nodemap_active = value;
1727 nodemap_idx_nodemap_activate(value);
1728 mutex_unlock(&active_config_lock);
1729 nm_member_revoke_all();
1731 EXPORT_SYMBOL(nodemap_activate);
1734 * Helper iterator to convert nodemap hash to list.
1736 * \param hs hash structure
1737 * \param bd bucket descriptor
1738 * \param hnode hash node
1739 * \param nodemap_list_head list head for list of nodemaps in hash
1741 static int nodemap_cleanup_iter_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
1742 struct hlist_node *hnode,
1743 void *nodemap_list_head)
1745 struct lu_nodemap *nodemap;
1747 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
1748 list_add(&nodemap->nm_list, nodemap_list_head);
1750 cfs_hash_bd_del_locked(hs, bd, hnode);
1755 struct nodemap_config *nodemap_config_alloc(void)
1757 struct nodemap_config *config;
1760 OBD_ALLOC_PTR(config);
1762 return ERR_PTR(-ENOMEM);
1764 rc = nodemap_init_hash(config);
1766 OBD_FREE_PTR(config);
1770 init_rwsem(&config->nmc_range_tree_lock);
1772 INIT_LIST_HEAD(&config->nmc_netmask_setup);
1773 config->nmc_range_tree.nmrt_range_interval_root = INTERVAL_TREE_ROOT;
1777 EXPORT_SYMBOL(nodemap_config_alloc);
1780 * Walk the nodemap_hash and remove all nodemaps.
1782 void nodemap_config_dealloc(struct nodemap_config *config)
1784 struct lu_nodemap *nodemap = NULL;
1785 struct lu_nodemap *nodemap_temp;
1786 struct lu_nid_range *range;
1787 struct lu_nid_range *range_temp;
1788 LIST_HEAD(nodemap_list_head);
1790 cfs_hash_for_each_safe(config->nmc_nodemap_hash,
1791 nodemap_cleanup_iter_cb, &nodemap_list_head);
1792 cfs_hash_putref(config->nmc_nodemap_hash);
1794 /* Because nodemap_destroy might sleep, we can't destroy them
1795 * in cfs_hash_for_each, so we build a list there and destroy here
1797 list_for_each_entry_safe(nodemap, nodemap_temp, &nodemap_list_head,
1799 mutex_lock(&active_config_lock);
1800 down_write(&config->nmc_range_tree_lock);
1802 /* move members to new config, requires ac lock */
1803 nm_member_reclassify_nodemap(nodemap);
1804 list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
1806 range_delete(config, range);
1807 up_write(&config->nmc_range_tree_lock);
1808 mutex_unlock(&active_config_lock);
1810 /* putref must be outside of ac lock if nm could be destroyed */
1811 nodemap_putref(nodemap);
1813 OBD_FREE_PTR(config);
1815 EXPORT_SYMBOL(nodemap_config_dealloc);
1818 * callback for cfs_hash_for_each_safe used to convert a nodemap hash to a
1819 * nodemap list, generally for locking purposes as a hash cb can't sleep.
1821 int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
1822 struct hlist_node *hnode,
1823 void *nodemap_list_head)
1825 struct lu_nodemap *nodemap;
1827 nodemap = hlist_entry(hnode, struct lu_nodemap, nm_hash);
1828 list_add(&nodemap->nm_list, nodemap_list_head);
1832 void nodemap_config_set_active(struct nodemap_config *config)
1834 struct nodemap_config *old_config = active_config;
1835 struct lu_nodemap *nodemap;
1836 struct lu_nodemap *tmp;
1838 LIST_HEAD(nodemap_list_head);
1842 LASSERT(active_config != config);
1843 LASSERT(config->nmc_default_nodemap);
1845 mutex_lock(&active_config_lock);
1847 /* move proc entries from already existing nms, create for new nms */
1848 cfs_hash_for_each_safe(config->nmc_nodemap_hash,
1849 nm_hash_list_cb, &nodemap_list_head);
1850 list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list) {
1851 struct lu_nodemap *old_nm = NULL;
1853 if (active_config != NULL)
1854 old_nm = cfs_hash_lookup(
1855 active_config->nmc_nodemap_hash,
1857 if (old_nm != NULL) {
1858 nodemap->nm_pde_data = old_nm->nm_pde_data;
1859 old_nm->nm_pde_data = NULL;
1860 nodemap_putref(old_nm);
1862 bool is_def = (nodemap == config->nmc_default_nodemap);
1864 lprocfs_nodemap_register(nodemap, is_def);
1869 * We only need to revoke locks if old nodemap was active, and new
1870 * config is now nodemap inactive. nodemap_config_dealloc will
1871 * reclassify exports, triggering a lock revoke if and only if new
1872 * nodemap is active.
1874 revoke_locks = !config->nmc_nodemap_is_active && nodemap_active;
1876 /* if new config is inactive, deactivate live config before switching */
1877 if (!config->nmc_nodemap_is_active)
1878 nodemap_active = false;
1879 active_config = config;
1880 if (config->nmc_nodemap_is_active)
1881 nodemap_active = true;
1883 mutex_unlock(&active_config_lock);
1885 if (old_config != NULL)
1886 nodemap_config_dealloc(old_config);
1889 nm_member_revoke_all();
1895 * Cleanup nodemap module on exit
1897 void nodemap_mod_exit(void)
1899 nodemap_config_dealloc(active_config);
1900 nodemap_procfs_exit();
1904 * Initialize the nodemap module
1906 int nodemap_mod_init(void)
1908 struct nodemap_config *new_config;
1909 struct lu_nodemap *nodemap;
1912 rc = nodemap_procfs_init();
1916 new_config = nodemap_config_alloc();
1917 if (IS_ERR(new_config)) {
1918 nodemap_procfs_exit();
1919 GOTO(out, rc = PTR_ERR(new_config));
1922 nodemap = nodemap_create(DEFAULT_NODEMAP, new_config, 1);
1923 if (IS_ERR(nodemap)) {
1924 nodemap_config_dealloc(new_config);
1925 nodemap_procfs_exit();
1926 GOTO(out, rc = PTR_ERR(nodemap));
1929 nodemap_config_set_active(new_config);
1930 nodemap_putref(nodemap);
1937 * Revoke locks for all nodemaps.
1939 void nm_member_revoke_all(void)
1941 struct lu_nodemap *nodemap;
1942 struct lu_nodemap *tmp;
1943 LIST_HEAD(nodemap_list_head);
1945 mutex_lock(&active_config_lock);
1946 cfs_hash_for_each_safe(active_config->nmc_nodemap_hash,
1947 nm_hash_list_cb, &nodemap_list_head);
1949 /* revoke_locks sleeps, so can't call in cfs hash cb */
1950 list_for_each_entry_safe(nodemap, tmp, &nodemap_list_head, nm_list)
1951 nm_member_revoke_locks_always(nodemap);
1952 mutex_unlock(&active_config_lock);
1956 * Returns the nodemap classification for a given nid into an ioctl buffer.
1957 * Useful for testing the nodemap configuration to make sure it is working as
1960 * \param nid nid to classify
1961 * \param[out] name_buf buffer to write the nodemap name to
1962 * \param name_len length of buffer
1964 void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len)
1966 struct lu_nodemap *nodemap;
1968 mutex_lock(&active_config_lock);
1969 down_read(&active_config->nmc_range_tree_lock);
1970 nodemap = nodemap_classify_nid(nid);
1971 up_read(&active_config->nmc_range_tree_lock);
1972 mutex_unlock(&active_config_lock);
1974 if (IS_ERR(nodemap))
1977 strncpy(name_buf, nodemap->nm_name, name_len);
1979 name_buf[name_len - 1] = '\0';
1981 nodemap_putref(nodemap);
1983 EXPORT_SYMBOL(nodemap_test_nid);
1986 * Passes back the id mapping for a given nid/id pair. Useful for testing the
1987 * nodemap configuration to make sure it is working as expected.
1989 * \param nid nid to classify
1990 * \param idtype uid or gid
1991 * \param client_id id to map to fs
1992 * \param fs_id_buf pointer to save mapped fs_id to
1995 * \retval -EINVAL invalid NID
1997 int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
1998 u32 client_id, u32 *fs_id)
2000 struct lu_nodemap *nodemap;
2002 mutex_lock(&active_config_lock);
2003 down_read(&active_config->nmc_range_tree_lock);
2004 nodemap = nodemap_classify_nid(nid);
2005 up_read(&active_config->nmc_range_tree_lock);
2006 mutex_unlock(&active_config_lock);
2008 if (IS_ERR(nodemap))
2009 return PTR_ERR(nodemap);
2011 *fs_id = nodemap_map_id(nodemap, idtype, NODEMAP_CLIENT_TO_FS,
2013 nodemap_putref(nodemap);
2017 EXPORT_SYMBOL(nodemap_test_id);
2019 static int cfg_nodemap_cmd(enum lcfg_command_type cmd, const char *nodemap_name,
2020 char *param, bool dynamic)
2022 struct lnet_nid nid[2];
2031 case LCFG_NODEMAP_ADD:
2032 rc = nodemap_add(nodemap_name);
2034 case LCFG_NODEMAP_DEL:
2035 rc = nodemap_del(nodemap_name);
2037 case LCFG_NODEMAP_ADD_RANGE:
2038 rc = nodemap_parse_range(param, nid, &netmask);
2041 rc = nodemap_add_range(nodemap_name, nid, netmask);
2043 case LCFG_NODEMAP_DEL_RANGE:
2044 rc = nodemap_parse_range(param, nid, &netmask);
2047 rc = nodemap_del_range(nodemap_name, nid, netmask);
2049 case LCFG_NODEMAP_ADMIN:
2050 rc = kstrtobool(param, &bool_switch);
2053 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
2055 case LCFG_NODEMAP_DENY_UNKNOWN:
2056 rc = kstrtobool(param, &bool_switch);
2059 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
2061 case LCFG_NODEMAP_AUDIT_MODE:
2062 rc = kstrtobool(param, &bool_switch);
2064 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
2066 case LCFG_NODEMAP_FORBID_ENCRYPT:
2067 rc = kstrtobool(param, &bool_switch);
2069 rc = nodemap_set_forbid_encryption(nodemap_name,
2072 case LCFG_NODEMAP_READONLY_MOUNT:
2073 rc = kstrtobool(param, &bool_switch);
2075 rc = nodemap_set_readonly_mount(nodemap_name,
2078 case LCFG_NODEMAP_MAP_MODE:
2083 if ((p = strstr(param, "all")) != NULL) {
2084 if ((p == param || *(p-1) == ',') &&
2085 (*(p+3) == '\0' || *(p+3) == ',')) {
2086 map_mode = NODEMAP_MAP_ALL;
2092 while ((p = strsep(¶m, ",")) != NULL) {
2096 if (strcmp("both", p) == 0)
2097 map_mode |= NODEMAP_MAP_BOTH;
2098 else if (strcmp("uid_only", p) == 0 ||
2099 strcmp("uid", p) == 0)
2100 map_mode |= NODEMAP_MAP_UID;
2101 else if (strcmp("gid_only", p) == 0 ||
2102 strcmp("gid", p) == 0)
2103 map_mode |= NODEMAP_MAP_GID;
2104 else if (strcmp("projid_only", p) == 0 ||
2105 strcmp("projid", p) == 0)
2106 map_mode |= NODEMAP_MAP_PROJID;
2116 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
2119 case LCFG_NODEMAP_RBAC:
2121 enum nodemap_rbac_roles rbac;
2124 if (strcmp(param, "all") == 0) {
2125 rbac = NODEMAP_RBAC_ALL;
2126 } else if (strcmp(param, "none") == 0) {
2127 rbac = NODEMAP_RBAC_NONE;
2129 rbac = NODEMAP_RBAC_NONE;
2130 while ((p = strsep(¶m, ",")) != NULL) {
2136 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
2139 nodemap_rbac_names[i].nrn_name)
2142 nodemap_rbac_names[i].nrn_mode;
2146 if (i == ARRAY_SIZE(nodemap_rbac_names))
2155 rc = nodemap_set_rbac(nodemap_name, rbac);
2158 case LCFG_NODEMAP_TRUSTED:
2159 rc = kstrtobool(param, &bool_switch);
2162 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
2164 case LCFG_NODEMAP_SQUASH_UID:
2165 rc = kstrtouint(param, 10, &int_id);
2168 rc = nodemap_set_squash_uid(nodemap_name, int_id);
2170 case LCFG_NODEMAP_SQUASH_GID:
2171 rc = kstrtouint(param, 10, &int_id);
2174 rc = nodemap_set_squash_gid(nodemap_name, int_id);
2176 case LCFG_NODEMAP_SQUASH_PROJID:
2177 rc = kstrtouint(param, 10, &int_id);
2180 rc = nodemap_set_squash_projid(nodemap_name, int_id);
2182 case LCFG_NODEMAP_ADD_UIDMAP:
2183 case LCFG_NODEMAP_ADD_GIDMAP:
2184 case LCFG_NODEMAP_ADD_PROJIDMAP:
2185 rc = nodemap_parse_idmap(param, idmap);
2188 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
2189 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
2191 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
2192 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
2194 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
2195 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
2200 case LCFG_NODEMAP_DEL_UIDMAP:
2201 case LCFG_NODEMAP_DEL_GIDMAP:
2202 case LCFG_NODEMAP_DEL_PROJIDMAP:
2203 rc = nodemap_parse_idmap(param, idmap);
2206 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
2207 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
2209 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
2210 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
2212 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
2213 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
2218 case LCFG_NODEMAP_SET_FILESET:
2219 rc = nodemap_set_fileset(nodemap_name, param);
2221 case LCFG_NODEMAP_SET_SEPOL:
2222 rc = nodemap_set_sepol(nodemap_name, param);
2231 int server_iocontrol_nodemap(struct obd_device *obd,
2232 struct obd_ioctl_data *data, bool dynamic)
2234 char name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
2235 struct lustre_cfg *lcfg = NULL;
2236 const char *nodemap_name = NULL;
2237 const char *client_idstr = NULL;
2238 const char *idtype_str = NULL;
2239 const char *nidstr = NULL;
2240 unsigned long client_id;
2241 struct lnet_nid nid;
2250 if (data->ioc_plen1 > PAGE_SIZE)
2251 GOTO(out, rc = -E2BIG);
2253 OBD_ALLOC(lcfg, data->ioc_plen1);
2255 GOTO(out, rc = -ENOMEM);
2257 if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
2258 GOTO(out_lcfg, rc = -EFAULT);
2260 cmd = lcfg->lcfg_command;
2263 case LCFG_NODEMAP_ACTIVATE:
2264 if (lcfg->lcfg_bufcount != 2)
2265 GOTO(out_lcfg, rc = -EINVAL);
2266 param = lustre_cfg_string(lcfg, 1);
2267 if (strcmp(param, "1") == 0)
2268 nodemap_activate(1);
2270 nodemap_activate(0);
2272 case LCFG_NODEMAP_ADD:
2273 case LCFG_NODEMAP_DEL:
2274 if (lcfg->lcfg_bufcount != 2)
2275 GOTO(out_lcfg, rc = -EINVAL);
2276 nodemap_name = lustre_cfg_string(lcfg, 1);
2277 rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
2279 case LCFG_NODEMAP_TEST_NID:
2280 if (lcfg->lcfg_bufcount != 2)
2281 GOTO(out_lcfg, rc = -EINVAL);
2282 nidstr = lustre_cfg_string(lcfg, 1);
2283 rc = libcfs_strnid(&nid, nidstr);
2287 nodemap_test_nid(&nid, name_buf, sizeof(name_buf));
2288 rc = copy_to_user(data->ioc_pbuf1, name_buf,
2289 min_t(size_t, data->ioc_plen1,
2292 GOTO(out_lcfg, rc = -EFAULT);
2294 case LCFG_NODEMAP_TEST_ID:
2295 if (lcfg->lcfg_bufcount != 4)
2296 GOTO(out_lcfg, rc = -EINVAL);
2297 nidstr = lustre_cfg_string(lcfg, 1);
2298 idtype_str = lustre_cfg_string(lcfg, 2);
2299 client_idstr = lustre_cfg_string(lcfg, 3);
2301 rc = libcfs_strnid(&nid, nidstr);
2305 if (strcmp(idtype_str, "uid") == 0)
2306 idtype = NODEMAP_UID;
2307 else if (strcmp(idtype_str, "gid") == 0)
2308 idtype = NODEMAP_GID;
2309 else if (strcmp(idtype_str, "projid") == 0)
2310 idtype = NODEMAP_PROJID;
2312 GOTO(out_lcfg, rc = -EINVAL);
2314 rc = kstrtoul(client_idstr, 10, &client_id);
2316 GOTO(out_lcfg, rc = -EINVAL);
2318 rc = nodemap_test_id(&nid, idtype, client_id, &fs_id);
2320 GOTO(out_lcfg, rc = -EINVAL);
2322 if (data->ioc_plen1 < sizeof(fs_idstr))
2323 GOTO(out_lcfg, rc = -EINVAL);
2325 snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id);
2326 if (copy_to_user(data->ioc_pbuf1, fs_idstr,
2327 sizeof(fs_idstr)) != 0)
2328 GOTO(out_lcfg, rc = -EINVAL);
2330 case LCFG_NODEMAP_ADD_RANGE:
2331 case LCFG_NODEMAP_DEL_RANGE:
2332 case LCFG_NODEMAP_ADD_UIDMAP:
2333 case LCFG_NODEMAP_DEL_UIDMAP:
2334 case LCFG_NODEMAP_ADD_GIDMAP:
2335 case LCFG_NODEMAP_DEL_GIDMAP:
2336 case LCFG_NODEMAP_ADD_PROJIDMAP:
2337 case LCFG_NODEMAP_DEL_PROJIDMAP:
2338 case LCFG_NODEMAP_SET_FILESET:
2339 case LCFG_NODEMAP_SET_SEPOL:
2340 if (lcfg->lcfg_bufcount != 3)
2341 GOTO(out_lcfg, rc = -EINVAL);
2342 nodemap_name = lustre_cfg_string(lcfg, 1);
2343 param = lustre_cfg_string(lcfg, 2);
2344 rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
2346 case LCFG_NODEMAP_ADMIN:
2347 case LCFG_NODEMAP_TRUSTED:
2348 case LCFG_NODEMAP_DENY_UNKNOWN:
2349 case LCFG_NODEMAP_SQUASH_UID:
2350 case LCFG_NODEMAP_SQUASH_GID:
2351 case LCFG_NODEMAP_SQUASH_PROJID:
2352 case LCFG_NODEMAP_MAP_MODE:
2353 case LCFG_NODEMAP_AUDIT_MODE:
2354 case LCFG_NODEMAP_FORBID_ENCRYPT:
2355 case LCFG_NODEMAP_READONLY_MOUNT:
2356 case LCFG_NODEMAP_RBAC:
2357 if (lcfg->lcfg_bufcount != 4)
2358 GOTO(out_lcfg, rc = -EINVAL);
2359 nodemap_name = lustre_cfg_string(lcfg, 1);
2360 param = lustre_cfg_string(lcfg, 3);
2361 rc = cfg_nodemap_cmd(cmd, nodemap_name, param, dynamic);
2368 CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
2369 "%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n",
2370 obd->obd_name, lcfg->lcfg_command,
2376 OBD_FREE(lcfg, data->ioc_plen1);
2380 EXPORT_SYMBOL(server_iocontrol_nodemap);