Whamcloud - gitweb
LU-16524 nodemap: add rbac property to nodemap 73/49873/11
authorSebastien Buisson <sbuisson@ddn.com>
Wed, 25 Jan 2023 12:54:00 +0000 (13:54 +0100)
committerOleg Drokin <green@whamcloud.com>
Tue, 21 Mar 2023 23:35:06 +0000 (23:35 +0000)
Add new rbac property to nodemap. Internally this is a mask of allowed
roles. Externally it defaults to all, which means all roles are
allowed, and it can take the following values (multiple can be
specified, comma separated), with the semantic:
- byfid_ops, to allow operations by FID (e.g. 'lfs rmfid').
- chlg_ops, to allow access to Lustre Changelogs.
- dne_ops, to allow operations related to DNE (e.g. 'lfs mkdir').
- file_perms, to allow modifications of file permissions and owners.
- quota_ops, to allow quota modifications.
Apart from all, any role not explicitly specified is forbidden. And to
forbid all roles, use 'none' value.

Update lctl-nodemap-modify man page to mention this new property.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I4cedf03c75948f4b1e9b55292414ab9110701874
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49873
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
18 files changed:
lustre/doc/lctl-nodemap-modify.8
lustre/include/lustre_nodemap.h
lustre/include/uapi/linux/lustre/lustre_cfg.h
lustre/include/uapi/linux/lustre/lustre_disk.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/obdclass/dt_object.c
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_internal.h
lustre/ptlrpc/nodemap_lproc.c
lustre/ptlrpc/nodemap_storage.c
lustre/ptlrpc/wiretest.c
lustre/utils/lr_reader.c
lustre/utils/mount_utils.h
lustre/utils/obd.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 1bead96..caa9df1 100644 (file)
@@ -80,6 +80,19 @@ readonly_mount
 Defaults to off, which lets clients mount in read-write mode. If set to 1,
 clients are forced to a read-only mount if not specified explicitly.
 .RE
+.PP
+rbac
+.RS 4
+Defaults to all, which means all roles are allowed. Other possible values
+(multiple can be specified, comma separated) are:
+- byfid_ops, to allow operations by FID (e.g. 'lfs rmfid').
+- chlg_ops, to allow access to Lustre Changelogs.
+- dne_ops, to allow operations related to DNE (e.g. 'lfs mkdir').
+- file_perms, to allow modifications of file permissions and owners.
+- quota_ops, to allow quota modifications.
+Apart from all, any role not explicitly specified is forbidden. And to forbid
+all roles, use 'none' value.
+.RE
 
 .RE
 .I value
index d0df6af..59f227d 100644 (file)
 
 #define LUSTRE_NODEMAP_DEFAULT_ID 0
 
-/** enums containing the types of ids contained in a nodemap
- * kept so other modules (mgs, mdt, etc) can define the type
- * of search easily
- */
-
-enum nodemap_id_type {
-       NODEMAP_UID,
-       NODEMAP_GID,
-       NODEMAP_PROJID,
-};
-
-enum nodemap_tree_type {
-       NODEMAP_FS_TO_CLIENT,
-       NODEMAP_CLIENT_TO_FS,
-};
-
-enum nodemap_mapping_modes {
-       NODEMAP_MAP_BOTH_LEGACY = 0x0,  /* for compatibility */
-       NODEMAP_MAP_UID         = 0x01,
-       NODEMAP_MAP_GID         = 0x02,
-       NODEMAP_MAP_BOTH        = 0x03, /* for compatibility */
-       NODEMAP_MAP_PROJID      = 0x04,
-       NODEMAP_MAP_ALL         = NODEMAP_MAP_UID |
-                                 NODEMAP_MAP_GID |
-                                 NODEMAP_MAP_PROJID,
+static const struct nodemap_rbac_name {
+       enum nodemap_rbac_roles nrn_mode;
+       const char             *nrn_name;
+} nodemap_rbac_names[] = {
+       { NODEMAP_RBAC_FILE_PERMS, "file_perms" },
+       { NODEMAP_RBAC_DNE_OPS,    "dne_ops"    },
+       { NODEMAP_RBAC_QUOTA_OPS,  "quota_ops"  },
+       { NODEMAP_RBAC_BYFID_OPS,  "byfid_ops"  },
+       { NODEMAP_RBAC_CHLG_OPS,   "chlg_ops"   },
 };
 
 struct nodemap_pde {
@@ -85,8 +69,9 @@ struct lu_nodemap {
                                 nmf_forbid_encryption:1,
                                 nmf_readonly_mount:1;
        /* bitmap for mapping type */
-       enum nodemap_mapping_modes
-                               nmf_map_mode;
+       enum nodemap_mapping_modes nmf_map_mode;
+       /* bitmap for rbac, enum nodemap_rbac_roles */
+       enum nodemap_rbac_roles  nmf_rbac;
        /* unique ID set by MGS */
        unsigned int             nm_id;
        /* nodemap ref counter */
@@ -152,6 +137,7 @@ 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 map_mode);
+int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac);
 int nodemap_set_squash_uid(const char *name, uid_t uid);
 int nodemap_set_squash_gid(const char *name, gid_t gid);
 int nodemap_set_squash_projid(const char *name, projid_t projid);
index ab0dc0b..a82932b 100644 (file)
@@ -141,6 +141,7 @@ enum lcfg_command_type {
        LCFG_NODEMAP_FORBID_ENCRYPT     = 0x00ce05c, /**< forbid encryption */
        LCFG_NODEMAP_SQUASH_PROJID      = 0x00ce05d, /**< default map projid */
        LCFG_NODEMAP_READONLY_MOUNT     = 0x00ce05e, /**< read-only mount */
+       LCFG_NODEMAP_RBAC         = 0x00ce05f, /**< rbac */
 };
 
 struct lustre_cfg_bufs {
index 674abed..6a6f2e9 100644 (file)
@@ -242,6 +242,97 @@ struct lsd_reply_header {
        __u8    lrh_pad[sizeof(struct lsd_reply_data_v1) - 12];
 };
 
+/****************** nodemap *********************/
+
+enum nodemap_idx_type {
+       NODEMAP_EMPTY_IDX = 0,          /* index created with blank record */
+       NODEMAP_CLUSTER_IDX = 1,        /* a nodemap cluster of nodes */
+       NODEMAP_RANGE_IDX = 2,          /* nid range assigned to a nm cluster */
+       NODEMAP_UIDMAP_IDX = 3,         /* uid map assigned to a nm cluster */
+       NODEMAP_GIDMAP_IDX = 4,         /* gid map assigned to a nm cluster */
+       NODEMAP_PROJIDMAP_IDX = 5,      /* projid map assigned to nm cluster */
+       NODEMAP_GLOBAL_IDX = 15,        /* stores nodemap activation status */
+};
+
+/* Nodemap records, uses 32 byte record length.
+ * New nodemap config records can be added into NODEMAP_CLUSTER_IDX
+ * with a new nk_cluster_subid value, as long as the records are
+ * kept at 32 bytes in size.  New global config records can be added
+ * into NODEMAP_GLOBAL_IDX with a new nk_global_subid.  This avoids
+ * breaking compatibility.  Do not change the record size.  If a
+ * new ID type or range is needed, a new IDX type should be used.
+ */
+struct nodemap_cluster_rec {
+       char                    ncr_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+       enum nm_flag_bits       ncr_flags:8;
+       enum nm_flag2_bits      ncr_flags2:8;
+       __u8                    ncr_padding1;
+       __u32                   ncr_squash_projid;
+       __u32                   ncr_squash_uid;
+       __u32                   ncr_squash_gid;
+};
+
+/* lnet_nid_t is 8 bytes */
+struct nodemap_range_rec {
+       lnet_nid_t      nrr_start_nid;
+       lnet_nid_t      nrr_end_nid;
+       __u64           nrr_padding1;
+       __u64           nrr_padding2;
+};
+
+struct nodemap_id_rec {
+       __u32   nir_id_fs;
+       __u32   nir_padding1;
+       __u64   nir_padding2;
+       __u64   nir_padding3;
+       __u64   nir_padding4;
+};
+
+struct nodemap_global_rec {
+       __u8    ngr_is_active;
+       __u8    ngr_padding1;
+       __u16   ngr_padding2;
+       __u32   ngr_padding3;
+       __u64   ngr_padding4;
+       __u64   ngr_padding5;
+       __u64   ngr_padding6;
+};
+
+struct nodemap_cluster_roles_rec {
+       __u64 ncrr_roles;       /* enum nodemap_rbac_roles */
+       __u64 ncrr_unused1;
+       __u64 ncrr_unused2;
+       __u64 ncrr_unused3;
+};
+
+union nodemap_rec {
+       struct nodemap_cluster_rec ncr;
+       struct nodemap_range_rec nrr;
+       struct nodemap_id_rec nir;
+       struct nodemap_global_rec ngr;
+       struct nodemap_cluster_roles_rec ncrr;
+};
+
+/* sub-keys for records of type NODEMAP_CLUSTER_IDX */
+enum nodemap_cluster_rec_subid {
+       NODEMAP_CLUSTER_REC = 0,   /* nodemap_cluster_rec */
+       NODEMAP_CLUSTER_ROLES = 1, /* nodemap_cluster_roles_rec */
+};
+
+/* first 4 bits of the nodemap_id is the index type */
+struct nodemap_key {
+       __u32 nk_nodemap_id;
+       union {
+               __u32 nk_cluster_subid;
+               __u32 nk_range_id;
+               __u32 nk_id_client;
+               __u32 nk_unused;
+       };
+};
+
+#define NM_TYPE_MASK 0x0FFFFFFF
+#define NM_TYPE_SHIFT 28
+
 /** @} disk */
 
 #endif /* _UAPI_LUSTRE_DISK_H */
index 27acb7f..5e17270 100644 (file)
@@ -3670,6 +3670,8 @@ struct llog_update_record {
                                     SELINUX_POLICY_VER_LEN + \
                                     SELINUX_POLICY_HASH_LEN + 3)
 
+#define LUSTRE_NODEMAP_NAME_LENGTH 16
+
 /* lu_nodemap flags */
 enum nm_flag_bits {
        NM_FL_ALLOW_ROOT_ACCESS = 0x1,
@@ -3685,49 +3687,45 @@ enum nm_flag2_bits {
        NM_FL2_READONLY_MOUNT = 0x1,
 };
 
-/* nodemap records, uses 32 byte record length */
-#define LUSTRE_NODEMAP_NAME_LENGTH 16
-struct nodemap_cluster_rec {
-       char                    ncr_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
-       enum nm_flag_bits       ncr_flags:8;
-       enum nm_flag2_bits      ncr_flags2:8;
-       __u8                    ncr_padding1;
-       __u32                   ncr_squash_projid;
-       __u32                   ncr_squash_uid;
-       __u32                   ncr_squash_gid;
-};
-
-/* lnet_nid_t is 8 bytes */
-struct nodemap_range_rec {
-       lnet_nid_t      nrr_start_nid;
-       lnet_nid_t      nrr_end_nid;
-       __u64           nrr_padding1;
-       __u64           nrr_padding2;
-};
-
-struct nodemap_id_rec {
-       __u32   nir_id_fs;
-       __u32   nir_padding1;
-       __u64   nir_padding2;
-       __u64   nir_padding3;
-       __u64   nir_padding4;
-};
-
-struct nodemap_global_rec {
-       __u8    ngr_is_active;
-       __u8    ngr_padding1;
-       __u16   ngr_padding2;
-       __u32   ngr_padding3;
-       __u64   ngr_padding4;
-       __u64   ngr_padding5;
-       __u64   ngr_padding6;
-};
-
-union nodemap_rec {
-       struct nodemap_cluster_rec ncr;
-       struct nodemap_range_rec nrr;
-       struct nodemap_id_rec nir;
-       struct nodemap_global_rec ngr;
+/** enums containing the types of ids contained in a nodemap
+ * kept so other modules (mgs, mdt, etc) can define the type
+ * of search easily
+ */
+
+enum nodemap_id_type {
+       NODEMAP_UID,
+       NODEMAP_GID,
+       NODEMAP_PROJID,
+};
+
+enum nodemap_tree_type {
+       NODEMAP_FS_TO_CLIENT,
+       NODEMAP_CLIENT_TO_FS,
+};
+
+enum nodemap_mapping_modes {
+       NODEMAP_MAP_BOTH_LEGACY = 0x0,  /* for compatibility */
+       NODEMAP_MAP_UID         = 0x01,
+       NODEMAP_MAP_GID         = 0x02,
+       NODEMAP_MAP_BOTH        = 0x03, /* for compatibility */
+       NODEMAP_MAP_PROJID      = 0x04,
+       NODEMAP_MAP_ALL         = NODEMAP_MAP_UID |
+                                 NODEMAP_MAP_GID |
+                                 NODEMAP_MAP_PROJID,
+};
+
+enum nodemap_rbac_roles {
+       NODEMAP_RBAC_FILE_PERMS = 0x00000001,
+       NODEMAP_RBAC_DNE_OPS    = 0x00000002,
+       NODEMAP_RBAC_QUOTA_OPS  = 0x00000004,
+       NODEMAP_RBAC_BYFID_OPS  = 0x00000008,
+       NODEMAP_RBAC_CHLG_OPS   = 0x00000010,
+       NODEMAP_RBAC_NONE       = (__u32)~(NODEMAP_RBAC_FILE_PERMS |
+                                          NODEMAP_RBAC_DNE_OPS    |
+                                          NODEMAP_RBAC_QUOTA_OPS  |
+                                          NODEMAP_RBAC_BYFID_OPS  |
+                                          NODEMAP_RBAC_CHLG_OPS),
+       NODEMAP_RBAC_ALL        = 0xFFFFFFFF, /* future caps ON by default */
 };
 
 /*
index f89d20e..ea88f86 100644 (file)
@@ -866,6 +866,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
        case LCFG_NODEMAP_AUDIT_MODE:
        case LCFG_NODEMAP_FORBID_ENCRYPT:
        case LCFG_NODEMAP_READONLY_MOUNT:
+       case LCFG_NODEMAP_RBAC:
                if (lcfg->lcfg_bufcount != 4)
                        GOTO(out_lcfg, rc = -EINVAL);
                nodemap_name = lustre_cfg_string(lcfg, 1);
index ddb4adc..2acf21c 100644 (file)
@@ -5596,6 +5596,45 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
                rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
                break;
        }
+       case LCFG_NODEMAP_RBAC:
+       {
+               enum nodemap_rbac_roles rbac;
+               char *p;
+
+               if (strcmp(param, "all") == 0) {
+                       rbac = NODEMAP_RBAC_ALL;
+               } else if (strcmp(param, "none") == 0) {
+                       rbac = NODEMAP_RBAC_NONE;
+               } else {
+                       rbac = NODEMAP_RBAC_NONE;
+                       while ((p = strsep(&param, ",")) != NULL) {
+                               int i;
+
+                               if (!*p)
+                                       break;
+
+                               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
+                                    i++) {
+                                       if (strcmp(p,
+                                                nodemap_rbac_names[i].nrn_name)
+                                           == 0) {
+                                               rbac |=
+                                                nodemap_rbac_names[i].nrn_mode;
+                                               break;
+                                       }
+                               }
+                               if (i == ARRAY_SIZE(nodemap_rbac_names))
+                                       break;
+                       }
+                       if (p) {
+                               rc = -EINVAL;
+                               break;
+                       }
+               }
+
+               rc = nodemap_set_rbac(nodemap_name, rbac);
+               break;
+       }
        case LCFG_NODEMAP_TRUSTED:
                rc = kstrtobool(param, &bool_switch);
                if (rc)
index a7355de..a5975f9 100644 (file)
@@ -46,6 +46,7 @@
 #include <lustre_nodemap.h>
 #include <lustre_quota.h>
 #include <lustre_lfsck.h>
+#include <uapi/linux/lustre/lustre_disk.h>
 
 /* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */
 LU_KEY_INIT(dt_global, struct dt_thread_info);
index 58f1046..673b613 100644 (file)
@@ -1184,6 +1184,7 @@ struct lu_nodemap *nodemap_create(const char *name,
                nodemap->nmf_enable_audit = 1;
                nodemap->nmf_forbid_encryption = 0;
                nodemap->nmf_readonly_mount = 0;
+               nodemap->nmf_rbac = NODEMAP_RBAC_ALL;
 
                nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
                nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
@@ -1205,6 +1206,7 @@ struct lu_nodemap *nodemap_create(const char *name,
                        default_nodemap->nmf_forbid_encryption;
                nodemap->nmf_readonly_mount =
                        default_nodemap->nmf_readonly_mount;
+               nodemap->nmf_rbac = default_nodemap->nmf_rbac;
 
                nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
                nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
@@ -1327,6 +1329,49 @@ out:
 }
 EXPORT_SYMBOL(nodemap_set_mapping_mode);
 
+int nodemap_set_rbac(const char *name, enum nodemap_rbac_roles rbac)
+{
+       struct lu_nodemap *nodemap = NULL;
+       enum nodemap_rbac_roles old_rbac;
+       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));
+
+       if (is_default_nodemap(nodemap))
+               GOTO(put, rc = -EINVAL);
+
+       old_rbac = nodemap->nmf_rbac;
+       /* if value does not change, do nothing */
+       if (rbac == old_rbac)
+               GOTO(put, rc = 0);
+
+       nodemap->nmf_rbac = rbac;
+       if (rbac == NODEMAP_RBAC_ALL)
+               /* if new value is ALL (default), just delete
+                * NODEMAP_CLUSTER_ROLES idx
+                */
+               rc = nodemap_idx_cluster_roles_del(nodemap);
+       else if (old_rbac == NODEMAP_RBAC_ALL)
+               /* if old value is ALL (default), need to insert
+                * NODEMAP_CLUSTER_ROLES idx
+                */
+               rc = nodemap_idx_cluster_roles_add(nodemap);
+       else
+               /* otherwise just update existing NODEMAP_CLUSTER_ROLES idx */
+               rc = nodemap_idx_cluster_roles_update(nodemap);
+
+       nm_member_revoke_locks(nodemap);
+put:
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_set_rbac);
+
 /**
  * Update the squash_uid for a nodemap.
  *
index 41c0bb0..b2890a6 100644 (file)
@@ -31,6 +31,7 @@
 #define _NODEMAP_INTERNAL_H
 
 #include <lustre_nodemap.h>
+#include <lustre_disk.h>
 #include <linux/rbtree.h>
 
 #define DEFAULT_NODEMAP "default"
@@ -75,29 +76,6 @@ struct lu_idmap {
        struct rb_node  id_fs_to_client;
 };
 
-/* first 4 bits of the nodemap_id is the index type */
-struct nodemap_key {
-       __u32 nk_nodemap_id;
-       union {
-               __u32 nk_range_id;
-               __u32 nk_id_client;
-               __u32 nk_unused;
-       };
-};
-
-enum nodemap_idx_type {
-       NODEMAP_EMPTY_IDX = 0,          /* index created with blank record */
-       NODEMAP_CLUSTER_IDX = 1,        /* a nodemap cluster of nodes */
-       NODEMAP_RANGE_IDX = 2,          /* nid range assigned to a nm cluster */
-       NODEMAP_UIDMAP_IDX = 3,         /* uid map assigned to a nm cluster */
-       NODEMAP_GIDMAP_IDX = 4,         /* gid map assigned to a nm cluster */
-       NODEMAP_PROJIDMAP_IDX = 5,      /* projid map assigned to nm cluster */
-       NODEMAP_GLOBAL_IDX = 15,        /* stores nodemap activation status */
-};
-
-#define NM_TYPE_MASK 0x0FFFFFFF
-#define NM_TYPE_SHIFT 28
-
 static inline enum nodemap_idx_type nm_idx_get_type(unsigned int id)
 {
        return id >> NM_TYPE_SHIFT;
@@ -191,6 +169,9 @@ int nm_hash_list_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
 int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap);
 int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap);
 int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap);
+int nodemap_idx_cluster_roles_add(const struct lu_nodemap *nodemap);
+int nodemap_idx_cluster_roles_update(const struct lu_nodemap *nodemap);
+int nodemap_idx_cluster_roles_del(const struct lu_nodemap *nodemap);
 int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
                          enum nodemap_id_type id_type,
                          const __u32 map[2]);
index 795d3bb..23d8534 100644 (file)
@@ -630,6 +630,52 @@ static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
 }
 
 /**
+ * Reads and prints the rbac for the given nodemap.
+ *
+ * \param      m               seq file in proc fs
+ * \param      data            unused
+ * \retval     0               success
+ */
+static int nodemap_rbac_seq_show(struct seq_file *m, void *data)
+{
+       struct lu_nodemap *nodemap;
+       char *sep = "";
+       int i, 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_rbac == NODEMAP_RBAC_ALL) {
+               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++)
+                       seq_printf(m, "%s%s", i == 0 ? "" : ",",
+                                  nodemap_rbac_names[i].nrn_name);
+               seq_puts(m, "\n");
+       } else if (nodemap->nmf_rbac == NODEMAP_RBAC_NONE) {
+               seq_puts(m, "none\n");
+       } else {
+               for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++) {
+                       if (nodemap->nmf_rbac &
+                           nodemap_rbac_names[i].nrn_mode) {
+                               seq_printf(m, "%s%s", sep,
+                                          nodemap_rbac_names[i].nrn_name);
+                               sep = ",";
+                       }
+               }
+               seq_puts(m, "\n");
+       }
+
+       nodemap_putref(nodemap);
+       return 0;
+}
+
+/**
  * Reads and prints the deny_unknown flag for the given nodemap.
  *
  * \param      m               seq file in proc fs
@@ -755,6 +801,7 @@ LPROC_SEQ_FOPS_RO(nodemap_squash_projid);
 
 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
+LPROC_SEQ_FOPS_RO(nodemap_rbac);
 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
 LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
 LPROC_SEQ_FOPS_RO(nodemap_readonly_mount);
@@ -781,69 +828,74 @@ static const struct proc_ops nodemap_exports_fops = {
 };
 
 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
-       {
-               .name           = "id",
-               .fops           = &nodemap_id_fops,
-       },
-       {
-               .name           = "trusted_nodemap",
-               .fops           = &nodemap_trusted_fops,
-       },
+       /* in alphabetical order */
        {
                .name           = "admin_nodemap",
                .fops           = &nodemap_admin_fops,
        },
        {
+               .name           = "audit_mode",
+               .fops           = &nodemap_audit_mode_fops,
+       },
+       {
                .name           = "deny_unknown",
                .fops           = &nodemap_deny_unknown_fops,
        },
        {
-               .name           = "map_mode",
-               .fops           = &nodemap_map_mode_fops,
+               .name           = "exports",
+               .fops           = &nodemap_exports_fops,
        },
        {
-               .name           = "audit_mode",
-               .fops           = &nodemap_audit_mode_fops,
+               .name           = "fileset",
+               .fops           = &nodemap_fileset_fops,
        },
        {
                .name           = "forbid_encryption",
                .fops           = &nodemap_forbid_encryption_fops,
        },
        {
-               .name           = "readonly_mount",
-               .fops           = &nodemap_readonly_mount_fops,
-       },
-       {
-               .name           = "squash_uid",
-               .fops           = &nodemap_squash_uid_fops,
+               .name           = "id",
+               .fops           = &nodemap_id_fops,
        },
        {
-               .name           = "squash_gid",
-               .fops           = &nodemap_squash_gid_fops,
+               .name           = "idmap",
+               .fops           = &nodemap_idmap_fops,
        },
        {
-               .name           = "squash_projid",
-               .fops           = &nodemap_squash_projid_fops,
+               .name           = "map_mode",
+               .fops           = &nodemap_map_mode_fops,
        },
        {
                .name           = "ranges",
                .fops           = &nodemap_ranges_fops,
        },
        {
-               .name           = "fileset",
-               .fops           = &nodemap_fileset_fops,
+               .name           = "rbac",
+               .fops           = &nodemap_rbac_fops,
+       },
+       {
+               .name           = "readonly_mount",
+               .fops           = &nodemap_readonly_mount_fops,
        },
        {
                .name           = "sepol",
                .fops           = &nodemap_sepol_fops,
        },
        {
-               .name           = "exports",
-               .fops           = &nodemap_exports_fops,
+               .name           = "squash_gid",
+               .fops           = &nodemap_squash_gid_fops,
        },
        {
-               .name           = "idmap",
-               .fops           = &nodemap_idmap_fops,
+               .name           = "squash_projid",
+               .fops           = &nodemap_squash_projid_fops,
+       },
+       {
+               .name           = "squash_uid",
+               .fops           = &nodemap_squash_uid_fops,
+       },
+       {
+               .name           = "trusted_nodemap",
+               .fops           = &nodemap_trusted_fops,
        },
        {
                NULL
index af9e3a7..73a6f31 100644 (file)
@@ -67,11 +67,12 @@ static DEFINE_MUTEX(ncf_list_lock);
 /* MGS index is different than others, others are listeners to MGS idx */
 static struct nm_config_file *nodemap_mgs_ncf;
 
-static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id)
+static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id,
+                                    enum nodemap_cluster_rec_subid subid)
 {
        nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
                                                        NODEMAP_CLUSTER_IDX));
-       nk->nk_unused = 0;
+       nk->nk_cluster_subid = subid;
 }
 
 static void nodemap_cluster_rec_init(union nodemap_rec *nr,
@@ -105,6 +106,15 @@ static void nodemap_cluster_rec_init(union nodemap_rec *nr,
                        NM_FL2_READONLY_MOUNT : 0);
 }
 
+static void nodemap_cluster_roles_rec_init(union nodemap_rec *nr,
+                                          const struct lu_nodemap *nodemap)
+{
+       struct nodemap_cluster_roles_rec *ncrr = &nr->ncrr;
+
+       memset(ncrr, 0, sizeof(struct nodemap_cluster_roles_rec));
+       ncrr->ncrr_roles = cpu_to_le64(nodemap->nmf_rbac);
+}
+
 static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
                                   enum nodemap_id_type id_type,
                                   u32 id_client)
@@ -380,9 +390,10 @@ enum nm_add_update {
        NM_UPDATE = 1,
 };
 
-static int nodemap_idx_nodemap_add_update(const struct lu_nodemap *nodemap,
+static int nodemap_idx_cluster_add_update(const struct lu_nodemap *nodemap,
                                          struct dt_object *idx,
-                                         enum nm_add_update update)
+                                         enum nm_add_update update,
+                                         enum nodemap_cluster_rec_subid subid)
 {
        struct nodemap_key nk;
        union nodemap_rec nr;
@@ -391,43 +402,51 @@ static int nodemap_idx_nodemap_add_update(const struct lu_nodemap *nodemap,
 
        ENTRY;
 
+       if (idx == NULL) {
+               if (nodemap_mgs_ncf == NULL) {
+                       CERROR("cannot add nodemap config to non-existing MGS.\n");
+                       return -EINVAL;
+               }
+               idx = nodemap_mgs_ncf->ncf_obj;
+       }
+
        rc = lu_env_init(&env, LCT_LOCAL);
        if (rc)
                RETURN(rc);
 
-       nodemap_cluster_key_init(&nk, nodemap->nm_id);
-       nodemap_cluster_rec_init(&nr, nodemap);
+       nodemap_cluster_key_init(&nk, nodemap->nm_id, subid);
+       switch (subid) {
+       case NODEMAP_CLUSTER_REC:
+               nodemap_cluster_rec_init(&nr, nodemap);
+               break;
+       case NODEMAP_CLUSTER_ROLES:
+               nodemap_cluster_roles_rec_init(&nr, nodemap);
+               break;
+       default:
+               CWARN("%s: unknown subtype %u\n", nodemap->nm_name, subid);
+               GOTO(fini, rc = -EINVAL);
+       }
 
        if (update == NM_UPDATE)
                rc = nodemap_idx_update(&env, idx, &nk, &nr);
        else
                rc = nodemap_idx_insert(&env, idx, &nk, &nr);
 
+fini:
        lu_env_fini(&env);
-
        RETURN(rc);
 }
 
 int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap)
 {
-       if (nodemap_mgs_ncf == NULL) {
-               CERROR("cannot add nodemap config to non-existing MGS.\n");
-               return -EINVAL;
-       }
-
-       return nodemap_idx_nodemap_add_update(nodemap, nodemap_mgs_ncf->ncf_obj,
-                                             NM_ADD);
+       return nodemap_idx_cluster_add_update(nodemap, NULL,
+                                             NM_ADD, NODEMAP_CLUSTER_REC);
 }
 
 int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap)
 {
-       if (nodemap_mgs_ncf == NULL) {
-               CERROR("cannot add nodemap config to non-existing MGS.\n");
-               return -EINVAL;
-       }
-
-       return nodemap_idx_nodemap_add_update(nodemap, nodemap_mgs_ncf->ncf_obj,
-                                             NM_UPDATE);
+       return nodemap_idx_cluster_add_update(nodemap, NULL,
+                                             NM_UPDATE, NODEMAP_CLUSTER_REC);
 }
 
 int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
@@ -453,6 +472,11 @@ int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
        if (rc != 0)
                RETURN(rc);
 
+       nodemap_cluster_key_init(&nk, nodemap->nm_id, NODEMAP_CLUSTER_ROLES);
+       rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
+       if (rc2 < 0 && rc2 != -ENOENT)
+               rc = rc2;
+
        root = nodemap->nm_fs_to_client_uidmap;
        nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
                                                id_fs_to_client) {
@@ -495,7 +519,7 @@ int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
                        rc = rc2;
        }
 
-       nodemap_cluster_key_init(&nk, nodemap->nm_id);
+       nodemap_cluster_key_init(&nk, nodemap->nm_id, NODEMAP_CLUSTER_REC);
        rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
        if (rc2 < 0)
                rc = rc2;
@@ -505,6 +529,42 @@ int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
        RETURN(rc);
 }
 
+int nodemap_idx_cluster_roles_add(const struct lu_nodemap *nodemap)
+{
+       return nodemap_idx_cluster_add_update(nodemap, NULL, NM_ADD,
+                                             NODEMAP_CLUSTER_ROLES);
+}
+
+int nodemap_idx_cluster_roles_update(const struct lu_nodemap *nodemap)
+{
+       return nodemap_idx_cluster_add_update(nodemap, NULL, NM_UPDATE,
+                                             NODEMAP_CLUSTER_ROLES);
+}
+
+int nodemap_idx_cluster_roles_del(const struct lu_nodemap *nodemap)
+{
+       struct nodemap_key nk;
+       struct lu_env env;
+       int rc = 0;
+
+       ENTRY;
+
+       if (nodemap_mgs_ncf == NULL) {
+               CERROR("cannot add nodemap config to non-existing MGS.\n");
+               return -EINVAL;
+       }
+
+       rc = lu_env_init(&env, LCT_LOCAL);
+       if (rc != 0)
+               RETURN(rc);
+
+       nodemap_cluster_key_init(&nk, nodemap->nm_id, NODEMAP_CLUSTER_ROLES);
+       rc = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
+
+       lu_env_fini(&env);
+       RETURN(rc);
+}
+
 int nodemap_idx_range_add(const struct lu_nid_range *range,
                          const lnet_nid_t nid[2])
 {
@@ -655,6 +715,93 @@ static enum nodemap_idx_type nodemap_get_key_type(const struct nodemap_key *key)
        return nm_idx_get_type(nodemap_id);
 }
 
+static int nodemap_get_key_subtype(const struct nodemap_key *key)
+{
+       enum nodemap_idx_type type = nodemap_get_key_type(key);
+
+       return type == NODEMAP_CLUSTER_IDX ? key->nk_cluster_subid : -1;
+}
+
+static int nodemap_cluster_rec_helper(struct nodemap_config *config,
+                                     u32 nodemap_id,
+                                     const union nodemap_rec *rec,
+                                     struct lu_nodemap **recent_nodemap)
+{
+       struct lu_nodemap *nodemap, *old_nm;
+       enum nm_flag_bits flags;
+       enum nm_flag2_bits flags2;
+
+       nodemap = cfs_hash_lookup(config->nmc_nodemap_hash, rec->ncr.ncr_name);
+       if (nodemap == NULL) {
+               if (nodemap_id == LUSTRE_NODEMAP_DEFAULT_ID)
+                       nodemap = nodemap_create(rec->ncr.ncr_name, config, 1);
+               else
+                       nodemap = nodemap_create(rec->ncr.ncr_name, config, 0);
+               if (IS_ERR(nodemap))
+                       return PTR_ERR(nodemap);
+
+               /* we need to override the local ID with the saved ID */
+               nodemap->nm_id = nodemap_id;
+               if (nodemap_id > config->nmc_nodemap_highest_id)
+                       config->nmc_nodemap_highest_id = nodemap_id;
+
+       } else if (nodemap->nm_id != nodemap_id) {
+               nodemap_putref(nodemap);
+               return -EINVAL;
+       }
+
+       nodemap->nm_squash_uid = le32_to_cpu(rec->ncr.ncr_squash_uid);
+       nodemap->nm_squash_gid = le32_to_cpu(rec->ncr.ncr_squash_gid);
+       nodemap->nm_squash_projid = le32_to_cpu(rec->ncr.ncr_squash_projid);
+
+       flags = rec->ncr.ncr_flags;
+       nodemap->nmf_allow_root_access = flags & NM_FL_ALLOW_ROOT_ACCESS;
+       nodemap->nmf_trust_client_ids = flags & NM_FL_TRUST_CLIENT_IDS;
+       nodemap->nmf_deny_unknown = flags & NM_FL_DENY_UNKNOWN;
+       nodemap->nmf_map_mode =
+               (flags & NM_FL_MAP_UID ? NODEMAP_MAP_UID : 0) |
+               (flags & NM_FL_MAP_GID ? NODEMAP_MAP_GID : 0) |
+               (flags & NM_FL_MAP_PROJID ? NODEMAP_MAP_PROJID : 0);
+       if (nodemap->nmf_map_mode == NODEMAP_MAP_BOTH_LEGACY)
+               nodemap->nmf_map_mode = NODEMAP_MAP_BOTH;
+       nodemap->nmf_enable_audit = flags & NM_FL_ENABLE_AUDIT;
+       nodemap->nmf_forbid_encryption = flags & NM_FL_FORBID_ENCRYPT;
+       flags2 = rec->ncr.ncr_flags2;
+       nodemap->nmf_readonly_mount = flags2 & NM_FL2_READONLY_MOUNT;
+       /* by default, and in the absence of cluster_roles, grant all roles */
+       nodemap->nmf_rbac = NODEMAP_RBAC_ALL;
+
+       /* The fileset should be saved otherwise it will be empty
+        * every time in case of "NODEMAP_CLUSTER_IDX".
+        */
+       mutex_lock(&active_config_lock);
+       old_nm = nodemap_lookup(rec->ncr.ncr_name);
+       if (!IS_ERR(old_nm) && old_nm->nm_fileset[0] != '\0')
+               strlcpy(nodemap->nm_fileset, old_nm->nm_fileset,
+                       sizeof(nodemap->nm_fileset));
+       mutex_unlock(&active_config_lock);
+       if (!IS_ERR(old_nm))
+               nodemap_putref(old_nm);
+
+       if (*recent_nodemap == NULL) {
+               *recent_nodemap = nodemap;
+               INIT_LIST_HEAD(&nodemap->nm_list);
+       } else {
+               list_add(&nodemap->nm_list, &(*recent_nodemap)->nm_list);
+       }
+       nodemap_putref(nodemap);
+
+       return 0;
+}
+
+static int nodemap_cluster_roles_helper(struct lu_nodemap *nodemap,
+                                       const union nodemap_rec *rec)
+{
+       nodemap->nmf_rbac = le64_to_cpu(rec->ncrr.ncrr_roles);
+
+       return 0;
+}
+
 /**
  * Process a key/rec pair and modify the new configuration.
  *
@@ -676,8 +823,7 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
        struct lu_nodemap *nodemap = NULL;
        enum nodemap_idx_type type;
        enum nodemap_id_type id_type;
-       enum nm_flag_bits flags;
-       enum nm_flag2_bits flags2;
+       int subtype;
        u32 nodemap_id;
        lnet_nid_t nid[2];
        u32 map[2];
@@ -689,14 +835,16 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
 
        nodemap_id = le32_to_cpu(key->nk_nodemap_id);
        type = nodemap_get_key_type(key);
+       subtype = nodemap_get_key_subtype(key);
        nodemap_id = nm_idx_set_type(nodemap_id, 0);
 
-       CDEBUG(D_INFO, "found config entry, nm_id %d type %d\n",
-              nodemap_id, type);
+       CDEBUG(D_INFO, "found config entry, nm_id %d type %d subtype %d\n",
+              nodemap_id, type, subtype);
 
        /* find the correct nodemap in the load list */
        if (type == NODEMAP_RANGE_IDX || type == NODEMAP_UIDMAP_IDX ||
-           type == NODEMAP_GIDMAP_IDX || type == NODEMAP_PROJIDMAP_IDX) {
+           type == NODEMAP_GIDMAP_IDX || type == NODEMAP_PROJIDMAP_IDX ||
+           (type == NODEMAP_CLUSTER_IDX && subtype != NODEMAP_CLUSTER_REC)) {
                struct lu_nodemap *tmp = NULL;
 
                nodemap = *recent_nodemap;
@@ -727,83 +875,26 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
                              " nodemap_id=%d. nodemap config file corrupt?\n",
                              nodemap_id);
                break;
-       case NODEMAP_CLUSTER_IDX: {
-               struct lu_nodemap *old_nm = NULL;
-
-               nodemap = cfs_hash_lookup(config->nmc_nodemap_hash,
-                                         rec->ncr.ncr_name);
-               if (nodemap == NULL) {
-                       if (nodemap_id == LUSTRE_NODEMAP_DEFAULT_ID) {
-                               nodemap = nodemap_create(rec->ncr.ncr_name,
-                                                        config, 1);
-                       } else {
-                               nodemap = nodemap_create(rec->ncr.ncr_name,
-                                                        config, 0);
-                       }
-                       if (IS_ERR(nodemap))
-                               GOTO(out, rc = PTR_ERR(nodemap));
-
-                       /* we need to override the local ID with the saved ID */
-                       nodemap->nm_id = nodemap_id;
-                       if (nodemap_id > config->nmc_nodemap_highest_id)
-                               config->nmc_nodemap_highest_id = nodemap_id;
-
-               } else if (nodemap->nm_id != nodemap_id) {
-                       nodemap_putref(nodemap);
-                       GOTO(out, rc = -EINVAL);
-               }
-
-               nodemap->nm_squash_uid =
-                               le32_to_cpu(rec->ncr.ncr_squash_uid);
-               nodemap->nm_squash_gid =
-                               le32_to_cpu(rec->ncr.ncr_squash_gid);
-               nodemap->nm_squash_projid =
-                       le32_to_cpu(rec->ncr.ncr_squash_projid);
-
-               flags = rec->ncr.ncr_flags;
-               nodemap->nmf_allow_root_access =
-                                       flags & NM_FL_ALLOW_ROOT_ACCESS;
-               nodemap->nmf_trust_client_ids =
-                                       flags & NM_FL_TRUST_CLIENT_IDS;
-               nodemap->nmf_deny_unknown =
-                                       flags & NM_FL_DENY_UNKNOWN;
-               nodemap->nmf_map_mode = (flags & NM_FL_MAP_UID ?
-                                        NODEMAP_MAP_UID : 0) |
-                                       (flags & NM_FL_MAP_GID ?
-                                        NODEMAP_MAP_GID : 0) |
-                                       (flags & NM_FL_MAP_PROJID ?
-                                        NODEMAP_MAP_PROJID : 0);
-               if (nodemap->nmf_map_mode == NODEMAP_MAP_BOTH_LEGACY)
-                       nodemap->nmf_map_mode = NODEMAP_MAP_BOTH;
-               nodemap->nmf_enable_audit =
-                                       flags & NM_FL_ENABLE_AUDIT;
-               nodemap->nmf_forbid_encryption =
-                                       flags & NM_FL_FORBID_ENCRYPT;
-               flags2 = rec->ncr.ncr_flags2;
-               nodemap->nmf_readonly_mount =
-                                       flags2 & NM_FL2_READONLY_MOUNT;
-
-               /* The fileset should be saved otherwise it will be empty
-                * every time in case of "NODEMAP_CLUSTER_IDX". */
-               mutex_lock(&active_config_lock);
-               old_nm = nodemap_lookup(rec->ncr.ncr_name);
-               if (!IS_ERR(old_nm) && old_nm->nm_fileset[0] != '\0')
-                       strlcpy(nodemap->nm_fileset, old_nm->nm_fileset,
-                               sizeof(nodemap->nm_fileset));
-               mutex_unlock(&active_config_lock);
-               if (!IS_ERR(old_nm))
-                       nodemap_putref(old_nm);
-
-               if (*recent_nodemap == NULL) {
-                       *recent_nodemap = nodemap;
-                       INIT_LIST_HEAD(&nodemap->nm_list);
-               } else {
-                       list_add(&nodemap->nm_list,
-                                &(*recent_nodemap)->nm_list);
+       case NODEMAP_CLUSTER_IDX:
+               switch (nodemap_get_key_subtype(key)) {
+               case NODEMAP_CLUSTER_REC:
+                       rc = nodemap_cluster_rec_helper(config, nodemap_id, rec,
+                                                       recent_nodemap);
+                       if (rc != 0)
+                               GOTO(out, rc);
+                       break;
+               case NODEMAP_CLUSTER_ROLES:
+                       rc = nodemap_cluster_roles_helper(nodemap, rec);
+                       if (rc != 0)
+                               GOTO(out, rc);
+                       break;
+               default:
+                       CWARN("%s: ignoring keyrec of type %d with subtype %u\n",
+                             nodemap->nm_name, NODEMAP_CLUSTER_IDX,
+                             nodemap_get_key_subtype(key));
+                       break;
                }
-               nodemap_putref(nodemap);
                break;
-       }
        case NODEMAP_RANGE_IDX:
                nid[0] = le64_to_cpu(rec->nrr.nrr_start_nid);
                nid[1] = le64_to_cpu(rec->nrr.nrr_end_nid);
@@ -833,10 +924,22 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
                        GOTO(out, rc);
                break;
        case NODEMAP_GLOBAL_IDX:
-               config->nmc_nodemap_is_active = rec->ngr.ngr_is_active;
+               switch (key->nk_unused) {
+               case 0:
+                       config->nmc_nodemap_is_active = rec->ngr.ngr_is_active;
+                       break;
+               default:
+                       CWARN("%s: ignoring keyrec of type %d with subtype %u\n",
+                             recent_nodemap ?
+                              (*recent_nodemap)->nm_name : "nodemap",
+                             NODEMAP_GLOBAL_IDX, key->nk_unused);
+                       break;
+               }
                break;
        default:
-               CERROR("got keyrec pair for unknown type %d\n", type);
+               CWARN("%s: ignoring key %u:%u for unknown type %u\n",
+                     recent_nodemap ? (*recent_nodemap)->nm_name : "nodemap",
+                     key->nk_nodemap_id & 0x0FFFFFFF, key->nk_unused, type);
                break;
        }
 
@@ -903,14 +1006,18 @@ static int nodemap_load_entries(const struct lu_env *env,
                struct nodemap_key *key;
                union nodemap_rec rec;
                enum nodemap_idx_type key_type;
+               int sub_type;
 
                key = (struct nodemap_key *)iops->key(env, it);
                key_type = nodemap_get_key_type((struct nodemap_key *)key);
+               sub_type = nodemap_get_key_subtype((struct nodemap_key *)key);
                if ((cur_pass == NM_READ_CLUSTERS &&
-                               key_type == NODEMAP_CLUSTER_IDX) ||
+                    key_type == NODEMAP_CLUSTER_IDX &&
+                    sub_type == NODEMAP_CLUSTER_REC) ||
                    (cur_pass == NM_READ_ATTRIBUTES &&
-                               key_type != NODEMAP_CLUSTER_IDX &&
-                               key_type != NODEMAP_EMPTY_IDX)) {
+                    (key_type != NODEMAP_CLUSTER_IDX ||
+                     sub_type != NODEMAP_CLUSTER_REC) &&
+                    key_type != NODEMAP_EMPTY_IDX)) {
                        rc = iops->rec(env, it, (struct dt_rec *)&rec, 0);
                        if (rc != -ESTALE) {
                                if (rc != 0)
@@ -971,10 +1078,10 @@ out:
                if (IS_ERR(nodemap)) {
                        rc = PTR_ERR(nodemap);
                } else {
-                       rc = nodemap_idx_nodemap_add_update(
+                       rc = nodemap_idx_cluster_add_update(
                                        new_config->nmc_default_nodemap,
                                        nodemap_idx,
-                                       NM_ADD);
+                                       NM_ADD, NODEMAP_CLUSTER_REC);
                        nodemap_putref(new_config->nmc_default_nodemap);
                }
        }
@@ -1031,7 +1138,8 @@ struct dt_object *nodemap_save_config_cache(const struct lu_env *env,
                               nm_hash_list_cb, &nodemap_list_head);
 
        list_for_each_entry_safe(nodemap, nm_tmp, &nodemap_list_head, nm_list) {
-               nodemap_cluster_key_init(&nk, nodemap->nm_id);
+               nodemap_cluster_key_init(&nk, nodemap->nm_id,
+                                        NODEMAP_CLUSTER_REC);
                nodemap_cluster_rec_init(&nr, nodemap);
 
                rc2 = nodemap_idx_insert(env, o, &nk, &nr);
@@ -1040,6 +1148,18 @@ struct dt_object *nodemap_save_config_cache(const struct lu_env *env,
                        continue;
                }
 
+               /* only insert NODEMAP_CLUSTER_ROLES idx in saved config cache
+                * if nmf_rbac is not default value NODEMAP_RBAC_ALL
+                */
+               if (nodemap->nmf_rbac != NODEMAP_RBAC_ALL) {
+                       nodemap_cluster_key_init(&nk, nodemap->nm_id,
+                                                NODEMAP_CLUSTER_ROLES);
+                       nodemap_cluster_roles_rec_init(&nr, nodemap);
+                       rc2 = nodemap_idx_insert(env, o, &nk, &nr);
+                       if (rc2 < 0)
+                               rc = rc2;
+               }
+
                down_read(&active_config->nmc_range_tree_lock);
                list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
                                         rn_list) {
@@ -1377,6 +1497,7 @@ static int nodemap_page_build(const struct lu_env *env, struct dt_object *obj,
                struct dt_key *key;
                __u64 hash;
                enum nodemap_idx_type key_type;
+               int sub_type;
 
                /* fetch 64-bit hash value */
                hash = iops->store(env, it);
@@ -1395,14 +1516,17 @@ static int nodemap_page_build(const struct lu_env *env, struct dt_object *obj,
 
                key = iops->key(env, it);
                key_type = nodemap_get_key_type((struct nodemap_key *)key);
+               sub_type = nodemap_get_key_subtype((struct nodemap_key *)key);
 
                /* on the first pass, get only the cluster types. On second
                 * pass, get all the rest */
                if ((ii->ii_attrs == NM_READ_CLUSTERS &&
-                               key_type == NODEMAP_CLUSTER_IDX) ||
+                    key_type == NODEMAP_CLUSTER_IDX &&
+                    sub_type == NODEMAP_CLUSTER_REC) ||
                    (ii->ii_attrs == NM_READ_ATTRIBUTES &&
-                               key_type != NODEMAP_CLUSTER_IDX &&
-                               key_type != NODEMAP_EMPTY_IDX)) {
+                    (key_type != NODEMAP_CLUSTER_IDX ||
+                     sub_type != NODEMAP_CLUSTER_REC) &&
+                    key_type != NODEMAP_EMPTY_IDX)) {
                        memcpy(tmp_entry, key, ii->ii_keysize);
                        tmp_entry += ii->ii_keysize;
 
index 5ac8e78..3b68448 100644 (file)
@@ -5671,10 +5671,130 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
 
+       /* Checks for struct nodemap_cluster_roles_rec */
+       LASSERTF((int)sizeof(struct nodemap_cluster_roles_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_cluster_roles_rec));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused2) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused2));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused2));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused3) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused3));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused3));
+
        /* Checks for union nodemap_rec */
        LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
                 (long long)(int)sizeof(union nodemap_rec));
 
+       /* Checks for struct nodemap_key */
+       LASSERTF((int)sizeof(struct nodemap_key) == 8, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_key));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_nodemap_id) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_nodemap_id));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_nodemap_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_nodemap_id));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_cluster_subid) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_cluster_subid));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_cluster_subid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_cluster_subid));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_range_id) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_range_id));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_range_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_range_id));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_id_client) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_id_client));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_id_client) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_id_client));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_unused) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_unused));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_unused) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_unused));
+       LASSERTF(NODEMAP_EMPTY_IDX == 0, "found %lld\n",
+                (long long)NODEMAP_EMPTY_IDX);
+       LASSERTF(NODEMAP_CLUSTER_IDX == 1, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_IDX);
+       LASSERTF(NODEMAP_RANGE_IDX == 2, "found %lld\n",
+                (long long)NODEMAP_RANGE_IDX);
+       LASSERTF(NODEMAP_UIDMAP_IDX == 3, "found %lld\n",
+                (long long)NODEMAP_UIDMAP_IDX);
+       LASSERTF(NODEMAP_GIDMAP_IDX == 4, "found %lld\n",
+                (long long)NODEMAP_GIDMAP_IDX);
+       LASSERTF(NODEMAP_PROJIDMAP_IDX == 5, "found %lld\n",
+                (long long)NODEMAP_PROJIDMAP_IDX);
+       LASSERTF(NODEMAP_GLOBAL_IDX == 15, "found %lld\n",
+                (long long)NODEMAP_GLOBAL_IDX);
+       LASSERTF(NODEMAP_CLUSTER_REC == 0, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_REC);
+       LASSERTF(NODEMAP_CLUSTER_ROLES == 1, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_ROLES);
+       LASSERTF(NM_TYPE_MASK == 0x0FFFFFFFUL, "found 0x%.8llxUL\n",
+                (long long)NM_TYPE_MASK);
+       LASSERTF(NM_TYPE_SHIFT == 28, "found %lld\n",
+                (long long)NM_TYPE_SHIFT);
+       LASSERTF(NM_FL_ALLOW_ROOT_ACCESS == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_ALLOW_ROOT_ACCESS);
+       LASSERTF(NM_FL_TRUST_CLIENT_IDS == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_TRUST_CLIENT_IDS);
+       LASSERTF(NM_FL_DENY_UNKNOWN == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_DENY_UNKNOWN);
+       LASSERTF(NM_FL_MAP_UID == 0x00000008UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_UID);
+       LASSERTF(NM_FL_MAP_GID == 0x00000010UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_GID);
+       LASSERTF(NM_FL_ENABLE_AUDIT == 0x00000020UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_ENABLE_AUDIT);
+       LASSERTF(NM_FL_FORBID_ENCRYPT == 0x00000040UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_FORBID_ENCRYPT);
+       LASSERTF(NM_FL_MAP_PROJID == 0x00000080UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_PROJID);
+       LASSERTF(NM_FL2_READONLY_MOUNT == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL2_READONLY_MOUNT);
+       LASSERTF(NODEMAP_UID == 0, "found %lld\n",
+                (long long)NODEMAP_UID);
+       LASSERTF(NODEMAP_GID == 1, "found %lld\n",
+                (long long)NODEMAP_GID);
+       LASSERTF(NODEMAP_PROJID == 2, "found %lld\n",
+                (long long)NODEMAP_PROJID);
+       LASSERTF(NODEMAP_FS_TO_CLIENT == 0, "found %lld\n",
+                (long long)NODEMAP_FS_TO_CLIENT);
+       LASSERTF(NODEMAP_CLIENT_TO_FS == 1, "found %lld\n",
+                (long long)NODEMAP_CLIENT_TO_FS);
+       LASSERTF(NODEMAP_MAP_BOTH_LEGACY == 0x00000000UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_BOTH_LEGACY);
+       LASSERTF(NODEMAP_MAP_UID == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_UID);
+       LASSERTF(NODEMAP_MAP_GID == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_GID);
+       LASSERTF(NODEMAP_MAP_BOTH == 0x00000003UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_BOTH);
+       LASSERTF(NODEMAP_MAP_PROJID == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_PROJID);
+       LASSERTF(NODEMAP_MAP_ALL == 0x00000007UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_ALL);
+       LASSERTF(NODEMAP_RBAC_FILE_PERMS == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_FILE_PERMS);
+       LASSERTF(NODEMAP_RBAC_DNE_OPS == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_DNE_OPS);
+       LASSERTF(NODEMAP_RBAC_QUOTA_OPS == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_QUOTA_OPS);
+       LASSERTF(NODEMAP_RBAC_BYFID_OPS == 0x00000008UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_BYFID_OPS);
+       LASSERTF(NODEMAP_RBAC_CHLG_OPS == 0x00000010UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_CHLG_OPS);
+       LASSERTF(NODEMAP_RBAC_NONE == 0xFFFFFFE0UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_NONE);
+       LASSERTF(NODEMAP_RBAC_ALL == 0xFFFFFFFFUL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_ALL);
+
        LASSERTF(OFD_ACCESS_READ == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)OFD_ACCESS_READ);
        LASSERTF(OFD_ACCESS_WRITE == 0x00000002UL, "found 0x%.8xUL\n",
@@ -6106,6 +6226,8 @@ void lustre_assert_wire_constants(void)
                 (unsigned)LCFG_NODEMAP_SQUASH_PROJID);
        LASSERTF(LCFG_NODEMAP_READONLY_MOUNT == 0x000ce05eUL, "found 0x%.8xUL\n",
                 (unsigned)LCFG_NODEMAP_READONLY_MOUNT);
+       LASSERTF(LCFG_NODEMAP_RBAC == 0x000ce05fUL, "found 0x%.8xUL\n",
+                (unsigned)LCFG_NODEMAP_RBAC);
 #endif /* HAVE_SERVER_SUPPORT */
        LASSERTF(PORTALS_CFG_TYPE == 1, "found %lld\n",
                 (long long)PORTALS_CFG_TYPE);
index f8e9cb6..dd5af9f 100644 (file)
@@ -59,6 +59,7 @@
 #include <getopt.h>
 
 #include <asm/byteorder.h>
+#include <linux/lustre/lustre_idl.h>
 #include <linux/lustre/lustre_disk.h>
 #include <linux/lustre/lustre_ver.h>
 
index 7c130c4..0acbb59 100644 (file)
@@ -56,6 +56,7 @@
 #include <libcfs/util/list.h>
 #include <linux/lustre/lustre_param.h>
 #ifdef HAVE_SERVER_SUPPORT
+#include <linux/lustre/lustre_idl.h>
 #include <linux/lustre/lustre_disk.h>
 #endif
 
index 5d5ae5c..20794fa 100644 (file)
@@ -4589,7 +4589,7 @@ int jt_nodemap_modify(int argc, char **argv)
                fprintf(stderr,
                        "usage: nodemap_modify --name <nodemap_name> --property <property_name> --value <value>\n");
                fprintf(stderr,
-                       "valid properties: admin trusted map_mode squash_uid squash_gid squash_projid deny_unknown audit_mode forbid_encryption readonly_mount\n");
+                       "valid properties: admin trusted map_mode squash_uid squash_gid squash_projid deny_unknown audit_mode forbid_encryption readonly_mount rbac\n");
                return -1;
        }
 
@@ -4613,6 +4613,8 @@ int jt_nodemap_modify(int argc, char **argv)
                cmd = LCFG_NODEMAP_FORBID_ENCRYPT;
        } else if (strcmp("readonly_mount", param) == 0) {
                cmd = LCFG_NODEMAP_READONLY_MOUNT;
+       } else if (strcmp("rbac", param) == 0) {
+               cmd = LCFG_NODEMAP_RBAC;
        } else {
                fprintf(stderr,
                        "error: %s: nodemap_modify invalid subcommand: %s\n",
index 1c962b2..dbb5c2c 100644 (file)
@@ -2687,12 +2687,75 @@ static void check_nodemap_global_rec(void)
        CHECK_MEMBER(nodemap_global_rec, ngr_padding6);
 }
 
+static void check_nodemap_cluster_roles_rec(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_cluster_roles_rec);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_roles);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_unused1);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_unused2);
+       CHECK_MEMBER(nodemap_cluster_roles_rec, ncrr_unused3);
+}
+
 static void check_nodemap_rec(void)
 {
        BLANK_LINE();
        CHECK_UNION(nodemap_rec);
 }
 
+static void check_nodemap_key(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_key);
+       CHECK_MEMBER(nodemap_key, nk_nodemap_id);
+
+       CHECK_VALUE(NODEMAP_EMPTY_IDX);
+       CHECK_VALUE(NODEMAP_CLUSTER_IDX);
+       CHECK_VALUE(NODEMAP_RANGE_IDX);
+       CHECK_VALUE(NODEMAP_UIDMAP_IDX);
+       CHECK_VALUE(NODEMAP_GIDMAP_IDX);
+       CHECK_VALUE(NODEMAP_PROJIDMAP_IDX);
+       CHECK_VALUE(NODEMAP_GLOBAL_IDX);
+
+       CHECK_VALUE(NODEMAP_CLUSTER_REC);
+       CHECK_VALUE(NODEMAP_CLUSTER_ROLES);
+
+       CHECK_VALUE_X(NM_TYPE_MASK);
+       CHECK_VALUE(NM_TYPE_SHIFT);
+
+       CHECK_VALUE_X(NM_FL_ALLOW_ROOT_ACCESS);
+       CHECK_VALUE_X(NM_FL_TRUST_CLIENT_IDS);
+       CHECK_VALUE_X(NM_FL_DENY_UNKNOWN);
+       CHECK_VALUE_X(NM_FL_MAP_UID);
+       CHECK_VALUE_X(NM_FL_MAP_GID);
+       CHECK_VALUE_X(NM_FL_ENABLE_AUDIT);
+       CHECK_VALUE_X(NM_FL_FORBID_ENCRYPT);
+       CHECK_VALUE_X(NM_FL_MAP_PROJID);
+       CHECK_VALUE_X(NM_FL2_READONLY_MOUNT);
+
+       CHECK_VALUE(NODEMAP_UID);
+       CHECK_VALUE(NODEMAP_GID);
+       CHECK_VALUE(NODEMAP_PROJID);
+
+       CHECK_VALUE(NODEMAP_FS_TO_CLIENT);
+       CHECK_VALUE(NODEMAP_CLIENT_TO_FS);
+
+       CHECK_VALUE_X(NODEMAP_MAP_BOTH_LEGACY);
+       CHECK_VALUE_X(NODEMAP_MAP_UID);
+       CHECK_VALUE_X(NODEMAP_MAP_GID);
+       CHECK_VALUE_X(NODEMAP_MAP_BOTH);
+       CHECK_VALUE_X(NODEMAP_MAP_PROJID);
+       CHECK_VALUE_X(NODEMAP_MAP_ALL);
+
+       CHECK_VALUE_X(NODEMAP_RBAC_FILE_PERMS);
+       CHECK_VALUE_X(NODEMAP_RBAC_DNE_OPS);
+       CHECK_VALUE_X(NODEMAP_RBAC_QUOTA_OPS);
+       CHECK_VALUE_X(NODEMAP_RBAC_BYFID_OPS);
+       CHECK_VALUE_X(NODEMAP_RBAC_CHLG_OPS);
+       CHECK_VALUE_X(NODEMAP_RBAC_NONE);
+       CHECK_VALUE_X(NODEMAP_RBAC_ALL);
+}
+
 static void check_ofd_access_entry_v1(void)
 {
        BLANK_LINE();
@@ -2897,6 +2960,7 @@ check_lustre_cfg(void)
        CHECK_VALUE_X(LCFG_NODEMAP_FORBID_ENCRYPT);
        CHECK_VALUE_X(LCFG_NODEMAP_SQUASH_PROJID);
        CHECK_VALUE_X(LCFG_NODEMAP_READONLY_MOUNT);
+       CHECK_VALUE_X(LCFG_NODEMAP_RBAC);
        printf("#endif /* HAVE_SERVER_SUPPORT */\n");
 #endif /* !HAVE_NATIVE_LINUX_CLIENT */
        CHECK_VALUE(PORTALS_CFG_TYPE);
@@ -3300,7 +3364,9 @@ printf("#endif /* HAVE_SERVER_SUPPORT */\n");
        check_nodemap_range_rec();
        check_nodemap_id_rec();
        check_nodemap_global_rec();
+       check_nodemap_cluster_roles_rec();
        check_nodemap_rec();
+       check_nodemap_key();
 
        check_ofd_access_entry_v1();
        check_lustre_access_log_info_v1();
index 4f30dc8..2c7f4be 100644 (file)
@@ -5699,10 +5699,130 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
 
+       /* Checks for struct nodemap_cluster_roles_rec */
+       LASSERTF((int)sizeof(struct nodemap_cluster_roles_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_cluster_roles_rec));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_roles));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_roles));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused1));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused2) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused2));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused2));
+       LASSERTF((int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused3) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_roles_rec, ncrr_unused3));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_unused3));
+
        /* Checks for union nodemap_rec */
        LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
                 (long long)(int)sizeof(union nodemap_rec));
 
+       /* Checks for struct nodemap_key */
+       LASSERTF((int)sizeof(struct nodemap_key) == 8, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_key));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_nodemap_id) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_nodemap_id));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_nodemap_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_nodemap_id));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_cluster_subid) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_cluster_subid));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_cluster_subid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_cluster_subid));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_range_id) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_range_id));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_range_id) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_range_id));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_id_client) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_id_client));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_id_client) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_id_client));
+       LASSERTF((int)offsetof(struct nodemap_key, nk_unused) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_key, nk_unused));
+       LASSERTF((int)sizeof(((struct nodemap_key *)0)->nk_unused) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_key *)0)->nk_unused));
+       LASSERTF(NODEMAP_EMPTY_IDX == 0, "found %lld\n",
+                (long long)NODEMAP_EMPTY_IDX);
+       LASSERTF(NODEMAP_CLUSTER_IDX == 1, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_IDX);
+       LASSERTF(NODEMAP_RANGE_IDX == 2, "found %lld\n",
+                (long long)NODEMAP_RANGE_IDX);
+       LASSERTF(NODEMAP_UIDMAP_IDX == 3, "found %lld\n",
+                (long long)NODEMAP_UIDMAP_IDX);
+       LASSERTF(NODEMAP_GIDMAP_IDX == 4, "found %lld\n",
+                (long long)NODEMAP_GIDMAP_IDX);
+       LASSERTF(NODEMAP_PROJIDMAP_IDX == 5, "found %lld\n",
+                (long long)NODEMAP_PROJIDMAP_IDX);
+       LASSERTF(NODEMAP_GLOBAL_IDX == 15, "found %lld\n",
+                (long long)NODEMAP_GLOBAL_IDX);
+       LASSERTF(NODEMAP_CLUSTER_REC == 0, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_REC);
+       LASSERTF(NODEMAP_CLUSTER_ROLES == 1, "found %lld\n",
+                (long long)NODEMAP_CLUSTER_ROLES);
+       LASSERTF(NM_TYPE_MASK == 0x0FFFFFFFUL, "found 0x%.8llxUL\n",
+                (long long)NM_TYPE_MASK);
+       LASSERTF(NM_TYPE_SHIFT == 28, "found %lld\n",
+                (long long)NM_TYPE_SHIFT);
+       LASSERTF(NM_FL_ALLOW_ROOT_ACCESS == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_ALLOW_ROOT_ACCESS);
+       LASSERTF(NM_FL_TRUST_CLIENT_IDS == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_TRUST_CLIENT_IDS);
+       LASSERTF(NM_FL_DENY_UNKNOWN == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_DENY_UNKNOWN);
+       LASSERTF(NM_FL_MAP_UID == 0x00000008UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_UID);
+       LASSERTF(NM_FL_MAP_GID == 0x00000010UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_GID);
+       LASSERTF(NM_FL_ENABLE_AUDIT == 0x00000020UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_ENABLE_AUDIT);
+       LASSERTF(NM_FL_FORBID_ENCRYPT == 0x00000040UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_FORBID_ENCRYPT);
+       LASSERTF(NM_FL_MAP_PROJID == 0x00000080UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL_MAP_PROJID);
+       LASSERTF(NM_FL2_READONLY_MOUNT == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NM_FL2_READONLY_MOUNT);
+       LASSERTF(NODEMAP_UID == 0, "found %lld\n",
+                (long long)NODEMAP_UID);
+       LASSERTF(NODEMAP_GID == 1, "found %lld\n",
+                (long long)NODEMAP_GID);
+       LASSERTF(NODEMAP_PROJID == 2, "found %lld\n",
+                (long long)NODEMAP_PROJID);
+       LASSERTF(NODEMAP_FS_TO_CLIENT == 0, "found %lld\n",
+                (long long)NODEMAP_FS_TO_CLIENT);
+       LASSERTF(NODEMAP_CLIENT_TO_FS == 1, "found %lld\n",
+                (long long)NODEMAP_CLIENT_TO_FS);
+       LASSERTF(NODEMAP_MAP_BOTH_LEGACY == 0x00000000UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_BOTH_LEGACY);
+       LASSERTF(NODEMAP_MAP_UID == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_UID);
+       LASSERTF(NODEMAP_MAP_GID == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_GID);
+       LASSERTF(NODEMAP_MAP_BOTH == 0x00000003UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_BOTH);
+       LASSERTF(NODEMAP_MAP_PROJID == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_PROJID);
+       LASSERTF(NODEMAP_MAP_ALL == 0x00000007UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_MAP_ALL);
+       LASSERTF(NODEMAP_RBAC_FILE_PERMS == 0x00000001UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_FILE_PERMS);
+       LASSERTF(NODEMAP_RBAC_DNE_OPS == 0x00000002UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_DNE_OPS);
+       LASSERTF(NODEMAP_RBAC_QUOTA_OPS == 0x00000004UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_QUOTA_OPS);
+       LASSERTF(NODEMAP_RBAC_BYFID_OPS == 0x00000008UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_BYFID_OPS);
+       LASSERTF(NODEMAP_RBAC_CHLG_OPS == 0x00000010UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_CHLG_OPS);
+       LASSERTF(NODEMAP_RBAC_NONE == 0xFFFFFFE0UL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_NONE);
+       LASSERTF(NODEMAP_RBAC_ALL == 0xFFFFFFFFUL, "found 0x%.8llxUL\n",
+                (long long)NODEMAP_RBAC_ALL);
+
        LASSERTF(OFD_ACCESS_READ == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)OFD_ACCESS_READ);
        LASSERTF(OFD_ACCESS_WRITE == 0x00000002UL, "found 0x%.8xUL\n",
@@ -6134,6 +6254,8 @@ void lustre_assert_wire_constants(void)
                 (unsigned)LCFG_NODEMAP_SQUASH_PROJID);
        LASSERTF(LCFG_NODEMAP_READONLY_MOUNT == 0x000ce05eUL, "found 0x%.8xUL\n",
                 (unsigned)LCFG_NODEMAP_READONLY_MOUNT);
+       LASSERTF(LCFG_NODEMAP_RBAC == 0x000ce05fUL, "found 0x%.8xUL\n",
+                (unsigned)LCFG_NODEMAP_RBAC);
 #endif /* HAVE_SERVER_SUPPORT */
        LASSERTF(PORTALS_CFG_TYPE == 1, "found %lld\n",
                 (long long)PORTALS_CFG_TYPE);