nodemap offset: the ability to add an offset range to nodemaps.
When an offset is defined, idmaps can only be set inside of their
given range. This is defined as:
lctl nodemap_add_offset --name nodemap --offset 100000 --limit 99999
And removed as:
lctl nodemap_del_offset --name nodemap
Test sanity-sec 27ab is added to exercise this new feature.
Signed-off-by: Maximilian Dilger <mdilger@whamcloud.com>
Change-Id: Iba2116d21bc7de1ba03111b0313427301e4b0b50
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55943
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lctl-nodemap-modify.8 \
lctl-nodemap-set-fileset.8 \
lctl-nodemap-set-sepol.8 \
+ lctl-nodemap-add-offset.8 \
+ lctl-nodemap-del-offset.8 \
lctl-snapshot-create.8 \
lctl-snapshot-destroy.8 \
lctl-snapshot-list.8 \
--- /dev/null
+.TH LCTL-NODEMAP_ADD_OFFSET 8 2024-08-21 Lustre "Lustre Configuration Utilities"
+.SH NAME
+lctl-nodemap_add_offset \- define ID mapping offset for a nodemap
+.SH SYNOPSIS
+.SY "lctl nodemap_add_offset"
+.BI --name " NAME"
+.BI --offset " OFFSET"
+.BI --limit " FSID_COUNT"
+.YS
+.SH DESCRIPTION
+.B nodemap_add_offset
+adds an identity mapping offset to a nodemap for the UID, GID and PROJID types.
+This command allows admins to create offset ranges for client systems to avoid
+overlapping assignments in multi-tenant systems. The
+.I FSID_COUNT
+is used to specify the number of IDs mapped by the range, starting with the
+.BR root (0)
+user/group/project ID and extending through
+.BR FSID_COUNT-1 .
+.PP
+An offset range cannot overlap into another's offset range.
+.PP
+A nodemap can only have one offset defined. To modify the offset already
+defined, remove it first and recreate it with new values.
+Any existing files will
+.B not
+automatically be remapped to the new
+.I OFFSET
+range. IDs must be manually changed on all files for that nodemap with
+.BR chown (1)
+and
+.BR lfs-project (1)
+on a trusted client that has access to the unmapped, canonical file system IDs.
+So modifying a nodemap offset should be avoided if possible.
+.SH OPTIONS
+.TP
+.BI --name " NAME"
+The name of the nodemap that the offset will be applied to.
+.TP
+.BI --offset " OFFSET"
+The given start value for the offset.
+.TP
+.BI --limit " FSID_COUNT"
+The number of IDs in the offset range.
+.SH EXAMPLES
+Map the client UID, GID, and PROJID values from the range 0-99999 to the
+filesystem UID, GID, and PROJID values to the range 100000-199999:
+.RS
+.EX
+.B # lctl nodemap_add_offset --name remotesite --offset 100000 --limit 100000
+.EE
+.RE
+.PP
+This map the "-2" user ID used by some systems for the
+.B nobody
+user to the user ID 65534, which will then be offset by OFFSET to a final UID of
+165534 in this example:
+.RS
+.EX
+.B # lctl nodemap_add_idmap --name remotesite --idtype uid --idmap 4294967294:65534
+.EE
+.RE
+.SH AVAILABILITY
+.B lctl nodemap_add_offset
+is part of the
+.BR lustre (7)
+filesystem package since release 2.16.0
+.\" Added in commit v2.15.99~
+.SH SEE ALSO
+.BR lustre (7),
+.BR lctl-nodemap-del-offset (8),
+.BR lctl-nodemap-activate (8),
+.BR lctl-nodemap-add (8),
+.BR lctl-nodemap-add-idmap (8),
+.BR lctl-nodemap-add-range (8),
+.BR lctl-nodemap-del (8),
+.BR lctl-nodemap-del-idmap (8),
+.BR lctl-nodemap-del-range (8),
+.BR lctl-nodemap-modify (8)
--- /dev/null
+.TH LCTL-NODEMAP_DEL_OFFSET 8 2024-08-21 Lustre "Lustre Configuration Utilities"
+.SH NAME
+lctl-nodemap_del_offset \- remove ID mapping offset from a nodemap
+.SH SYNOPSIS
+.SY "lctl nodemap_del_offset"
+.BI --name " NAME"
+.YS
+.SH DESCRIPTION
+.B nodemap_del_offset
+removes an identity mapping offset from a nodemap for the UID, GID and PROJID types.
+.SH OPTIONS
+.TP
+.BI --name " NAME"
+The name of the nodemap to remove the offset from.
+.SH NOTES
+Removing an offset from a nodemap does
+.B not
+affect the UID, GID, or PROJID of any files that were previously created under
+this nodemap. If these files are mapped into a different nodemap, then their
+UID, GID, and PROJID must be changed on a trusted client with access to the
+unmapped, canonical file system IDs using
+.BR chown (1),
+.BR chgrp (1),
+and
+.BR "lfs project" (1)
+from the old offset range to the new offset. As such, removing an offset from a
+nodemap should be avoided whenever possible.
+.SH EXAMPLES
+Remove the already existing offset from nodemap remotesite:
+.RS
+.EX
+.B # lctl nodemap_del_offset --name remotesite
+.EE
+.RE
+.SH AVAILABILITY
+.B lctl nodemap_del_offset
+is part of the
+.BR lustre (7)
+filesystem package since release 2.16.0
+.\" Added in commit v2.15.99~
+.SH SEE ALSO
+.BR lustre (7),
+.BR lctl-nodemap-add-offset (8),
+.BR lctl-nodemap-activate (8),
+.BR lctl-nodemap-add (8),
+.BR lctl-nodemap-add-idmap (8),
+.BR lctl-nodemap-add-range (8),
+.BR lctl-nodemap-del (8),
+.BR lctl-nodemap-del-idmap (8),
+.BR lctl-nodemap-del-range (8),
+.BR lctl-nodemap-modify (8)
.BR lctl-nodemap-modify (8)
Modify a nodemap property.
.TP
-.BR lctl-nodemap-set-fileset(8)
+.BR lctl-nodemap-set-fileset (8)
Add a fileset to a nodemap.
.TP
+.BR lctl-nodemap-add-offset (8)
+Set a UID/GID/PROJID offset value
+.TP
+.BR lctl-nodemap-del-offset (8)
+Remove a UID/GID/PROJID offset from a nodemap.
+.TP
.BR lctl-nodemap-set-sepol (8)
Set SELinux policy info on a nodemap.
.SS Configuration logs
.BR lctl-nodemap-del-idmap (8),
.BR lctl-nodemap-del-range (8),
.BR lctl-nodemap-modify (8),
+.BR lctl-nodemap-add-offset (8),
+.BR lctl-nodemap-del-offset (8),
.BR lctl-pcc (8),
.BR lctl-set_param (8),
.BR lctl-snapshot-create (8),
struct list_head nm_list;
/* is a dynamic nodemap */
bool nm_dyn;
+ /* value to start UID offset */
+ unsigned int nm_offset_start_uid;
+ /* number of values allocated to UID offset */
+ unsigned int nm_offset_limit_uid;
+ /* value to start GID offset */
+ unsigned int nm_offset_start_gid;
+ /* number of values allocated to GID offset */
+ unsigned int nm_offset_limit_gid;
+ /* value to start PROJID offset */
+ unsigned int nm_offset_start_projid;
+ /* number of values allocated to PROJID offset */
+ unsigned int nm_offset_limit_projid;
};
/* Store handles to local MGC storage to save config locally. In future
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_add_offset(const char *nodemap_name, char *offset);
+int nodemap_del_offset(const char *nodemap_name);
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);
LCFG_NODEMAP_ADMIN = 0x00ce049, /**< allow cluster to use id 0 */
LCFG_NODEMAP_ADD_PROJIDMAP = 0x00ce04a, /**< add a projidmap */
LCFG_NODEMAP_DEL_PROJIDMAP = 0x00ce04b, /**< delete projidmap */
+ LCFG_NODEMAP_ADD_OFFSET = 0x00ce04c, /**< UID/GID/PROJID add offset */
+ LCFG_NODEMAP_DEL_OFFSET = 0x00ce04d, /**< UID/GID/PROJID del offset */
LCFG_NODEMAP_TRUSTED = 0x00ce050, /**< trust a clusters ids */
LCFG_NODEMAP_SQUASH_UID = 0x00ce051, /**< default map uid */
LCFG_NODEMAP_SQUASH_GID = 0x00ce052, /**< default map gid */
__u64 ncrr_padding3; /* zeroed since 2.16 (always) */
};
+struct nodemap_offset_rec {
+ __u32 nor_start_uid;
+ __u32 nor_limit_uid;
+ __u32 nor_start_gid;
+ __u32 nor_limit_gid;
+ __u32 nor_start_projid;
+ __u32 nor_limit_projid;
+ __u32 nor_padding1;
+ __u32 nor_padding2;
+};
+
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;
+ struct nodemap_offset_rec nor;
};
/* 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 */
+ NODEMAP_CLUSTER_OFFSET = 2, /* UID/GID/PROJID offset for a nm cluster */
};
/* first 4 bits of the nodemap_id is the index type */
* of search easily
*/
enum nodemap_id_type {
- NODEMAP_UID,
- NODEMAP_GID,
- NODEMAP_PROJID,
+ NODEMAP_UID = 0,
+ NODEMAP_GID = 1,
+ NODEMAP_PROJID = 2,
};
enum nodemap_tree_type {
- NODEMAP_FS_TO_CLIENT,
- NODEMAP_CLIENT_TO_FS,
+ NODEMAP_FS_TO_CLIENT = 0,
+ NODEMAP_CLIENT_TO_FS = 1,
};
enum nodemap_mapping_modes {
*
* Author: Joshua Walgenbach <jjw@iu.edu>
*/
+
#include <linux/module.h>
#include <linux/sort.h>
#include <uapi/linux/lnet/nidstr.h>
enum nodemap_id_type id_type,
enum nodemap_tree_type tree_type, __u32 id)
{
- struct lu_idmap *idmap = NULL;
- __u32 found_id;
+ struct lu_idmap *idmap = NULL;
+ __u32 offset_start;
+ __u32 offset_limit;
+ __u32 found_id = id;
+ bool attempted_squash = false;
ENTRY;
if (id_type == NODEMAP_UID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_UID))
- goto out;
+ goto offset;
if (id_type == NODEMAP_GID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_GID))
- goto out;
+ goto offset;
if (id_type == NODEMAP_PROJID &&
!(nodemap->nmf_map_mode & NODEMAP_MAP_PROJID))
- goto out;
+ goto offset;
if (nodemap->nmf_trust_client_ids)
- goto out;
+ goto offset;
map:
if (is_default_nodemap(nodemap))
else
found_id = idmap->id_fs;
up_read(&nodemap->nm_idmap_lock);
- RETURN(found_id);
+ GOTO(offset, found_id);
squash:
if (id_type == NODEMAP_UID)
- RETURN(nodemap->nm_squash_uid);
- if (id_type == NODEMAP_GID)
- RETURN(nodemap->nm_squash_gid);
- if (id_type == NODEMAP_PROJID)
- RETURN(nodemap->nm_squash_projid);
+ found_id = nodemap->nm_squash_uid;
+ else if (id_type == NODEMAP_GID)
+ found_id = nodemap->nm_squash_gid;
+ else if (id_type == NODEMAP_PROJID)
+ found_id = nodemap->nm_squash_projid;
+ attempted_squash = true;
+offset:
+ if (id_type == NODEMAP_UID) {
+ offset_start = nodemap->nm_offset_start_uid;
+ offset_limit = nodemap->nm_offset_limit_uid;
+ } else if (id_type == NODEMAP_GID) {
+ offset_start = nodemap->nm_offset_start_uid;
+ offset_limit = nodemap->nm_offset_limit_gid;
+ } else if (id_type == NODEMAP_PROJID) {
+ offset_start = nodemap->nm_offset_start_projid;
+ offset_limit = nodemap->nm_offset_limit_projid;
+ } else {
+ CERROR("%s: nodemap invalid id_type provided\n",
+ nodemap->nm_name);
+ GOTO(out, id);
+ }
+
+ if (offset_start == 0 && offset_limit == 0)
+ GOTO(out, found_id);
+
+ if (tree_type == NODEMAP_FS_TO_CLIENT) {
+ found_id -= offset_start;
+ } else {
+ if (found_id >= offset_limit && !attempted_squash)
+ GOTO(squash, found_id);
+
+ if (attempted_squash) {
+ CERROR("%s: squash_id for type %u is outside nodemap limit %u, use unmapped value %u\n",
+ nodemap->nm_name, id_type, offset_limit,
+ found_id);
+ GOTO(out, found_id);
+ }
+ found_id += offset_start;
+ }
out:
- RETURN(id);
+ RETURN(found_id);
}
EXPORT_SYMBOL(nodemap_map_id);
nodemap->nm_squash_projid = NODEMAP_NOBODY_PROJID;
nodemap->nm_fileset[0] = '\0';
nodemap->nm_sepol[0] = '\0';
+ nodemap->nm_offset_start_uid = 0;
+ nodemap->nm_offset_limit_uid = 0;
+ nodemap->nm_offset_start_gid = 0;
+ nodemap->nm_offset_limit_gid = 0;
+ nodemap->nm_offset_start_projid = 0;
+ nodemap->nm_offset_limit_projid = 0;
if (!is_default)
CWARN("adding nodemap '%s' to config without"
" default nodemap\n", nodemap->nm_name);
nodemap->nm_squash_projid = default_nodemap->nm_squash_projid;
nodemap->nm_fileset[0] = '\0';
nodemap->nm_sepol[0] = '\0';
+ nodemap->nm_offset_start_uid = 0;
+ nodemap->nm_offset_limit_uid = 0;
+ nodemap->nm_offset_start_gid = 0;
+ nodemap->nm_offset_limit_gid = 0;
+ nodemap->nm_offset_start_projid = 0;
+ nodemap->nm_offset_limit_projid = 0;
}
RETURN(nodemap);
}
EXPORT_SYMBOL(nodemap_del);
+/* Do not call this method directly unless the ranges and nodemap have been
+ * previously verified.
+ * Store separate offset+limit in case this needs to be changed
+ * in the future, but for now there is no good reason to expose
+ * this complexity to userspace.
+ * TODO allow individual setting of values
+ */
+int nodemap_add_offset_helper(struct lu_nodemap *nodemap, __u32 offset_start,
+ __u32 offset_limit)
+{
+ if (IS_ERR_OR_NULL(nodemap))
+ return -ENOENT;
+
+ nodemap->nm_offset_start_uid = offset_start;
+ nodemap->nm_offset_limit_uid = offset_limit;
+ nodemap->nm_offset_start_gid = offset_start;
+ nodemap->nm_offset_limit_gid = offset_limit;
+ nodemap->nm_offset_start_projid = offset_start;
+ nodemap->nm_offset_limit_projid = offset_limit;
+ return 0;
+}
+
+/**
+ * The nodemap offset shifts client UID/GID/PROJIDs from the range [0,limit)
+ * to a new range [offset,offset+limit). This is useful for clusters that share
+ * a single filesystem among several tenants that administer their IDs
+ * independently. The offsets provide non-overlapping spaces with "limit"
+ * IDs each without having to configure individual idmaps for each ID.
+ *
+ * \param name name of nodemmap
+ * \param offset offset+limit
+ * \retval 0 success
+ * \retval -EINVAL invalid input
+ * \retval -ENOENT no existing nodemap
+ */
+int nodemap_add_offset(const char *nodemap_name, char *offset)
+{
+ struct lu_nodemap *nodemap;
+ struct lu_nodemap *nm_iterating;
+ struct lu_nodemap *nm_tmp;
+ unsigned long offset_start, offset_limit;
+ unsigned long min, max;
+ bool overlap = false;
+ LIST_HEAD(nodemap_list_head);
+ char *offset_max;
+ int rc = 0;
+
+ offset_max = strchr(offset, '+');
+ if (offset_max == NULL)
+ GOTO(out, rc = -EINVAL);
+ *offset_max = '\0';
+ offset_max++;
+
+ rc = kstrtoul(offset, 10, &offset_start);
+ if (rc) {
+ CERROR("%s: nodemap offset_start '%lu' not valid: rc = %d\n",
+ nodemap_name, offset_start, rc);
+ GOTO(out, rc);
+ }
+ rc = kstrtoul(offset_max, 10, &offset_limit);
+ if (rc) {
+ CERROR("%s: nodemap offset_limit '%lu' not valid: rc = %d\n",
+ nodemap_name, offset_limit, rc);
+ GOTO(out, rc);
+ }
+ if (offset_start == 0 || offset_start >= UINT_MAX) {
+ rc = -EINVAL;
+ CERROR("%s: nodemap offset_start '%lu' is invalid: rc = %d\n",
+ nodemap_name, offset_start, rc);
+ GOTO(out, rc);
+ }
+ if (offset_limit == 0 || offset_limit >= UINT_MAX) {
+ rc = -EINVAL;
+ CERROR("%s: nodemap offset_limit '%lu' is invalid: rc = %d\n",
+ nodemap_name, offset_limit, rc);
+ GOTO(out, rc);
+ }
+ if (offset_start + offset_limit >= UINT_MAX) {
+ rc = -EINVAL;
+ CERROR("%s: nodemap offset_start+offset_limit '%s+%s' would overflow: rc = %d\n",
+ nodemap_name, offset, offset_max, rc);
+ GOTO(out, rc);
+ }
+
+ mutex_lock(&active_config_lock);
+ nodemap = nodemap_lookup(nodemap_name);
+ if (IS_ERR(nodemap)) {
+ mutex_unlock(&active_config_lock);
+ GOTO(out, rc = -ENOENT);
+ }
+
+ if (is_default_nodemap(nodemap))
+ GOTO(out_putref, rc = -EINVAL);
+
+ if (nodemap->nm_offset_start_uid) {
+ /* nodemap has already offset */
+ nm_iterating = nodemap;
+ GOTO(overlap, rc = -ERANGE);
+ }
+
+ cfs_hash_for_each_safe(active_config->nmc_nodemap_hash,
+ nm_hash_list_cb, &nodemap_list_head);
+
+ list_for_each_entry_safe(nm_iterating, nm_tmp, &nodemap_list_head,
+ nm_list) {
+ if (nodemap_name == nm_iterating->nm_name)
+ continue;
+ min = nm_iterating->nm_offset_start_uid;
+ max = nm_iterating->nm_offset_start_uid +
+ nm_iterating->nm_offset_limit_uid;
+ if (min == 0 && max == 0) /* nodemaps with no set offset */
+ continue;
+ /* seeing if new offset / offset_max overlaps with other
+ * existing nodemap offsets
+ */
+ if (offset_start <= max - 1 &&
+ offset_start + offset_limit - 1 >= min) {
+ overlap = true;
+ break;
+ }
+ }
+
+ if (overlap) {
+overlap:
+ rc = -ERANGE;
+ CERROR("%s: new offset %lu+%lu overlaps with existing nodemap %s offset %u+%u: rc = %d\n",
+ nodemap_name, offset_start, offset_limit,
+ nm_iterating->nm_name, nm_iterating->nm_offset_start_uid,
+ nm_iterating->nm_offset_limit_uid, rc);
+ GOTO(out_putref, rc);
+ }
+
+ rc = nodemap_add_offset_helper(nodemap, offset_start, offset_limit);
+ if (rc == 0)
+ rc = nodemap_idx_offset_add(nodemap);
+ if (rc == 0)
+ nm_member_revoke_locks(nodemap);
+
+out_putref:
+ mutex_unlock(&active_config_lock);
+ nodemap_putref(nodemap);
+out:
+ return rc;
+}
+
+int nodemap_del_offset_helper(struct lu_nodemap *nodemap)
+{
+ if (IS_ERR_OR_NULL(nodemap))
+ return -ENOENT;
+
+ nodemap->nm_offset_start_uid = 0;
+ nodemap->nm_offset_limit_uid = 0;
+ nodemap->nm_offset_start_gid = 0;
+ nodemap->nm_offset_limit_gid = 0;
+ nodemap->nm_offset_start_projid = 0;
+ nodemap->nm_offset_limit_projid = 0;
+ return 0;
+}
+
+/**
+ * Delete mapping offset.
+ *
+ * \param name name of nodemmap
+ * \retval 0 success
+ * \retval -EINVAL invalid input
+ * \retval -ENOENT no existing nodemap
+ */
+int nodemap_del_offset(const char *nodemap_name)
+{
+ struct lu_nodemap *nodemap;
+ int rc = 0;
+
+ mutex_lock(&active_config_lock);
+ nodemap = nodemap_lookup(nodemap_name);
+ if (IS_ERR(nodemap)) {
+ mutex_unlock(&active_config_lock);
+ GOTO(out, rc = -ENOENT);
+ }
+
+ if (is_default_nodemap(nodemap))
+ GOTO(out_putref, rc = -EINVAL);
+
+ rc = nodemap_del_offset_helper(nodemap);
+ if (rc == 0)
+ rc = nodemap_idx_offset_del(nodemap);
+ if (rc == 0)
+ nm_member_revoke_locks(nodemap);
+
+out_putref:
+ mutex_unlock(&active_config_lock);
+ nodemap_putref(nodemap);
+out:
+ return rc;
+}
+
/**
* activate nodemap functions
*
break;
rc = nodemap_set_squash_projid(nodemap_name, int_id);
break;
+ case LCFG_NODEMAP_ADD_OFFSET:
+ rc = nodemap_add_offset(nodemap_name, param);
+ break;
+ case LCFG_NODEMAP_DEL_OFFSET:
+ rc = nodemap_del_offset(nodemap_name);
+ break;
case LCFG_NODEMAP_ADD_UIDMAP:
case LCFG_NODEMAP_ADD_GIDMAP:
case LCFG_NODEMAP_ADD_PROJIDMAP:
break;
case LCFG_NODEMAP_ADD:
case LCFG_NODEMAP_DEL:
+ case LCFG_NODEMAP_DEL_OFFSET:
if (lcfg->lcfg_bufcount != 2)
GOTO(out_lcfg, rc = -EINVAL);
nodemap_name = lustre_cfg_string(lcfg, 1);
sizeof(fs_idstr)) != 0)
GOTO(out_lcfg, rc = -EINVAL);
break;
+ case LCFG_NODEMAP_ADD_OFFSET:
case LCFG_NODEMAP_ADD_RANGE:
case LCFG_NODEMAP_DEL_RANGE:
case LCFG_NODEMAP_ADD_UIDMAP:
struct lu_nodemap *nodemap,
const struct lnet_nid nid[2],
u8 netmask, unsigned int range_id);
+int nodemap_add_offset_helper(struct lu_nodemap *nodemap, __u32 offset_start,
+ __u32 offset_limit);
+int nodemap_del_offset_helper(struct lu_nodemap *nodemap);
void nodemap_getref(struct lu_nodemap *nodemap);
void nodemap_putref(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_offset_add(const struct lu_nodemap *nodemap);
+int nodemap_idx_offset_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]);
}
/**
+ * Reads and prints the UID/GID/PROJID offsets for the given nodemap.
+ *
+ * \param m seq file in proc fs
+ * \param data unused
+ * \retval 0 success
+ */
+static int nodemap_offset_seq_show(struct seq_file *m, void *data)
+{
+ struct lu_nodemap *nodemap;
+ int rc;
+
+ mutex_lock(&active_config_lock);
+ nodemap = nodemap_lookup(m->private);
+ mutex_unlock(&active_config_lock);
+ if (IS_ERR(nodemap)) {
+ rc = PTR_ERR(nodemap);
+ CERROR("%s: nodemap not found: rc = %d\n",
+ (char *)m->private, rc);
+ return rc;
+ }
+
+ seq_printf(m, "start_uid: %u\n", nodemap->nm_offset_start_uid);
+ seq_printf(m, "limit_uid: %u\n", nodemap->nm_offset_limit_uid);
+ seq_printf(m, "start_gid: %u\n", nodemap->nm_offset_start_gid);
+ seq_printf(m, "limit_gid: %u\n", nodemap->nm_offset_limit_gid);
+ seq_printf(m, "start_projid: %u\n", nodemap->nm_offset_start_projid);
+ seq_printf(m, "limit_projid: %u\n", nodemap->nm_offset_limit_projid);
+
+ nodemap_putref(nodemap);
+ return 0;
+}
+
+/**
* Reads and prints the NID ranges for the given nodemap.
*
* \param m seq file in proc fs
LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
LPROC_SEQ_FOPS_RO(nodemap_map_mode);
+LPROC_SEQ_FOPS_RO(nodemap_offset);
LPROC_SEQ_FOPS_RO(nodemap_rbac);
LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
.fops = &nodemap_idmap_fops,
},
{
+ .name = "offset",
+ .fops = &nodemap_offset_fops,
+ },
+ {
.name = "map_mode",
.fops = &nodemap_map_mode_fops,
},
ncrr->ncrr_padding3 = 0;
}
+static void nodemap_offset_rec_init(union nodemap_rec *nr,
+ const struct lu_nodemap *nodemap)
+{
+ struct nodemap_offset_rec *nor = &nr->nor;
+
+ memset(nor, 0, sizeof(struct nodemap_offset_rec));
+ nor->nor_start_uid = cpu_to_le32(nodemap->nm_offset_start_uid);
+ nor->nor_limit_uid = cpu_to_le32(nodemap->nm_offset_limit_uid);
+ nor->nor_start_gid = cpu_to_le32(nodemap->nm_offset_start_gid);
+ nor->nor_limit_gid = cpu_to_le32(nodemap->nm_offset_limit_gid);
+ nor->nor_start_projid = cpu_to_le32(nodemap->nm_offset_start_projid);
+ nor->nor_limit_projid = cpu_to_le32(nodemap->nm_offset_limit_projid);
+}
+
static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
enum nodemap_id_type id_type,
u32 id_client)
case NODEMAP_CLUSTER_ROLES:
nodemap_cluster_roles_rec_init(&nr, nodemap);
break;
+ case NODEMAP_CLUSTER_OFFSET:
+ nodemap_offset_rec_init(&nr, nodemap);
+ break;
default:
CWARN("%s: unknown subtype %u\n", nodemap->nm_name, subid);
GOTO(fini, rc = -EINVAL);
if (rc2 < 0 && rc2 != -ENOENT)
rc = rc2;
+ nodemap_cluster_key_init(&nk, nodemap->nm_id, NODEMAP_CLUSTER_OFFSET);
+ 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;
rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
id_fs_to_client) {
RETURN(rc);
}
+int nodemap_idx_offset_add(const struct lu_nodemap *nodemap)
+{
+ return nodemap_idx_cluster_add_update(nodemap, NULL, NM_ADD,
+ NODEMAP_CLUSTER_OFFSET);
+}
+
+int nodemap_idx_offset_del(const struct lu_nodemap *nodemap)
+{
+ struct nodemap_key nk;
+ struct lu_env env;
+ int rc = 0;
+
+ ENTRY;
+
+ if (!nodemap_mgs()) {
+ 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_OFFSET);
+ 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)
{
struct nodemap_key nk;
switch (type) {
case NODEMAP_EMPTY_IDX:
if (nodemap_id != 0)
- CWARN("Found nodemap config record without type field, "
- " nodemap_id=%d. nodemap config file corrupt?\n",
- nodemap_id);
+ CWARN("%s: Found nodemap config record without type field, nodemap_id=%d. nodemap config file corrupt?\n",
+ nodemap->nm_name, nodemap_id);
break;
case NODEMAP_CLUSTER_IDX:
switch (nodemap_get_key_subtype(key)) {
if (rc != 0)
GOTO(out, rc);
break;
+ case NODEMAP_CLUSTER_OFFSET:
+ /* only works for offset UID = GID = PROJID */
+ rc = nodemap_add_offset_helper(nodemap,
+ le32_to_cpu(rec->nor.nor_start_uid),
+ le32_to_cpu(rec->nor.nor_limit_uid));
+ 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,
rc = rc2;
}
+ nodemap_cluster_key_init(&nk, nodemap->nm_id,
+ NODEMAP_CLUSTER_OFFSET);
+ nodemap_offset_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) {
LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3) == 8, "found %lld\n",
(long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3));
+ /* Checks for struct nodemap_offset_rec */
+ LASSERTF((int)sizeof(struct nodemap_offset_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_offset_rec));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_uid) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_uid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_uid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_uid) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_uid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_uid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_gid) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_gid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_gid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_gid) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_gid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_gid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_projid) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_projid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_projid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_projid) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_projid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_projid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_padding1) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding1));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_padding2) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding2));
+
/* Checks for union nodemap_rec */
LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
(long long)(int)sizeof(union nodemap_rec));
(long long)NODEMAP_CLUSTER_REC);
LASSERTF(NODEMAP_CLUSTER_ROLES == 1, "found %lld\n",
(long long)NODEMAP_CLUSTER_ROLES);
+ LASSERTF(NODEMAP_CLUSTER_OFFSET == 2, "found %lld\n",
+ (long long)NODEMAP_CLUSTER_OFFSET);
LASSERTF(NM_TYPE_MASK == 0x0fffffffUL, "found 0x%.8xUL\n",
(unsigned)NM_TYPE_MASK);
LASSERTF(NM_TYPE_SHIFT == 28, "found %lld\n",
(unsigned)LCFG_NODEMAP_ADD_PROJIDMAP);
LASSERTF(LCFG_NODEMAP_DEL_PROJIDMAP == 0x000ce04bUL, "found 0x%.8xUL\n",
(unsigned)LCFG_NODEMAP_DEL_PROJIDMAP);
+ LASSERTF(LCFG_NODEMAP_ADD_OFFSET == 0x000ce04cUL, "found 0x%.8xUL\n",
+ (unsigned)LCFG_NODEMAP_ADD_OFFSET);
+ LASSERTF(LCFG_NODEMAP_DEL_OFFSET == 0x000ce04dUL, "found 0x%.8xUL\n",
+ (unsigned)LCFG_NODEMAP_DEL_OFFSET);
LASSERTF(LCFG_NODEMAP_TRUSTED == 0x000ce050UL, "found 0x%.8xUL\n",
(unsigned)LCFG_NODEMAP_TRUSTED);
LASSERTF(LCFG_NODEMAP_SQUASH_UID == 0x000ce051UL, "found 0x%.8xUL\n",
}
run_test 27aa "test nodemap idmap range"
+test_27ab() { #LU-18109
+ local idmap
+ local id=500
+ local offset
+
+ do_facet mgs $LCTL nodemap_add Test18109 ||
+ error "unable to add Test18109 as nodemap"
+ stack_trap "do_facet mgs $LCTL nodemap_del Test18109 || true"
+
+ do_facet mgs $LCTL nodemap_add OffsetTest ||
+ error "unable to add OffsetTest as nodemap"
+ stack_trap "do_facet mgs $LCTL nodemap_del OffsetTest || true"
+
+ do_facet mgs $LCTL nodemap_add_offset --name Test18109 \
+ --offset 100000 --limit 200000 ||
+ error "cannot set offset 100000-299999 for Test18109"
+
+ #expected error, invalid offset range supplied
+ do_facet mgs $LCTL nodemap_add_offset --name OffsetTest \
+ --offset 150000 --limit 100000 &&
+ error "cannot set offset 150000-249999 for OffsetTest"
+
+ do_facet mgs $LCTL nodemap_add_idmap --name Test18109 \
+ --idtype uid --idmap 500-509:0-9 ||
+ error "unable to add idmap range 500-509:0-9"
+
+ idmap=$(do_facet mgs $LCTL get_param nodemap.Test18109.idmap |
+ grep idtype)
+ while IFS= read -r idmap; do
+ if (( $id <= 509 )); then
+ [[ "$idmap" == *"client_id: $id"* ]] ||
+ error "could not find 'client_id: ${id}' inside of ${idmap}"
+ fi
+ ((id++))
+ done < <(echo "$idmap")
+
+ do_facet mgs $LCTL nodemap_del_idmap --name Test18109 \
+ --idtype uid --idmap 500-509:0 ||
+ error "cannot delete idmap range 500-509:0"
+
+ #expected error, invalid secondary range supplied
+ do_facet mgs $LCTL nodemap_add --name Test18109 \
+ --idtype uid --idmap 500-509:200000-200010 &&
+ error "Invalid range 200000-200010 was supplied"
+
+ (( $(do_facet mgs $LCTL get_param nodemap.Test18109.idmap |
+ grep -c idtype) == 0 )) ||
+ error "invalid range 200000-200010 supplied and passed"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep start_uid)
+ [[ "$offset" == *"start_uid: 100000"* ]] ||
+ error "expected start_uid of 100000 not found before remounting"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep limit_uid)
+ [[ "$offset" == *"limit_uid: 200000"* ]] ||
+ error "expected limit_uid of 200000 not found before remounting"
+
+ stopall || error "failed to unmount servers"
+ setupall || error "failed to remount servers"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep start_uid)
+ [[ "$offset" == *"start_uid: 100000"* ]] ||
+ error "expected start_uid of 100000 not found after remounting"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep limit_uid)
+ [[ "$offset" == *"limit_uid: 200000"* ]] ||
+ error "expected limit_uid of 200000 not found after remounting"
+
+ do_facet mgs $LCTL nodemap_del_offset --name Test18109 ||
+ error "cannot del offset from Test18109"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep start_uid)
+ [[ "$offset" == *"start_uid: 0"* ]] ||
+ error "expected start_uid 0, found $offset"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep limit_uid)
+ [[ "$offset" == *"limit_uid: 0"* ]] ||
+ error "expected limit_uid 0, found $offset"
+
+ stopall || error "failed to unmount servers"
+ setupall || error "failed to remount servers"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep start_uid)
+ [[ "$offset" == *"start_uid: 0"* ]] ||
+ error "expected start_uid 0, found $offset after remounting"
+
+ offset=$(do_facet mgs $LCTL get_param nodemap.Test18109.offset |
+ grep limit_uid)
+ [[ "$offset" == *"limit_uid: 0"* ]] ||
+ error "expected limit_uid 0, found $offset after remounting"
+
+ do_facet mgs $LCTL nodemap_del Test18109 ||
+ error "failed to remove nodemap Test18109"
+
+ do_facet mgs $LCTL nodemap_del OffsetTest ||
+ error "failed to remove nodemap OffsetTest"
+}
+run_test 27ab "test nodemap idmap offset"
+
test_27b() { #LU-10703
[ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
skip "Need MDS >= 2.11.50"
{"nodemap_modify", jt_nodemap_modify, 0,
"modify a nodemap parameters\n"
"usage: nodemap_modify nodemap_name param value"},
+ {"nodemap_add_offset", jt_nodemap_add_offset, 0,
+ "add an offset for UID/GID/PROJID mappings\n"
+ "usage: nodemap_add_offset --name NODEMAP_NAME --offset OFFSET --limit LIMIT\n"},
+ {"nodemap_del_offset", jt_nodemap_del_offset, 0,
+ "delete an offset for UID/GID/PROJID mappings\n"
+ "usage: nodemap_del_offset --name NODEMAP_NAME --offset OFFSET\n"},
{"nodemap_add_idmap", jt_nodemap_add_idmap, 0,
"add a UID or GID mapping to a nodemap"},
{"nodemap_del_idmap", jt_nodemap_del_idmap, 0,
return rc;
}
+/**
+ * Add a nodemap's UID/GID/PROJID offset
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * --name nodemap name
+ * --offset UID/GID/PROJID offset
+ * --limit number of maximum entries
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_add_offset(int argc, char **argv)
+{
+ char *nodemap_name = NULL;
+ __u32 offset = 0;
+ __u32 limit = 0;
+ char param[24];
+ int rc = 0;
+ int c;
+
+ static struct option long_opts[] = {
+ { .val = 'l', .name = "limit", .has_arg = required_argument },
+ { .val = 'n', .name = "name", .has_arg = required_argument },
+ { .val = 'o', .name = "offset", .has_arg = required_argument },
+ { .name = NULL } };
+
+ while ((c = getopt_long(argc, argv, "l:n:o:",
+ long_opts, NULL)) != -1) {
+ switch (c) {
+ case 'l':
+ limit = strtol(optarg, NULL, 10);
+ if (errno == ERANGE) {
+ fprintf(stderr,
+ "Invalid limit value input: %u\n",
+ limit);
+ return -1;
+ }
+ break;
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'o':
+ offset = strtol(optarg, NULL, 10);
+ if (errno == ERANGE) {
+ fprintf(stderr,
+ "Invalid offset value input: %u\n",
+ offset);
+ return -1;
+ }
+ break;
+ }
+ }
+
+ if (!nodemap_name || !offset || !limit ||
+ offset <= 0 || offset >= UINT_MAX || errno != 0) {
+ fprintf(stderr, "%s: invalid nodemap '%s' offset '%s'\n",
+ jt_cmdname(argv[0]), nodemap_name, optarg);
+ return CMD_HELP;
+ }
+
+ /* user warnings for setting offset to 0 or less than 65536 */
+ if (offset < 65536)
+ fprintf(stderr,
+ "It is not recomended to have an offset before 65536 as the nobody/squash id's will not be mapped properly.\n");
+
+ snprintf(param, sizeof(param), "%u+%u", offset, limit);
+
+ rc = nodemap_cmd(LCFG_NODEMAP_ADD_OFFSET, false, NULL, 0,
+ argv[0], nodemap_name, param, NULL);
+
+ if (rc == -ERANGE) {
+ fprintf(stderr,
+ "%s: cannot set offset %s to nodemap '%s' because it overlaps with existing offset: %s\n",
+ *argv, param, nodemap_name, strerror(-rc));
+ } else if (rc != 0) {
+ fprintf(stderr,
+ "%s: cannot set offset %s to nodemap '%s': %s\n",
+ *argv, param, nodemap_name, strerror(-rc));
+ }
+
+ return rc;
+}
+
+/**
+ * Delete a nodemap's UID/GID/PROJID offset
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * --name nodemap name
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_del_offset(int argc, char **argv)
+{
+ char *nodemap_name = NULL;
+ int rc = 0;
+ int c;
+
+ static struct option long_opts[] = {
+ { .val = 'n', .name = "name", .has_arg = required_argument },
+ { .name = NULL } };
+
+ while ((c = getopt_long(argc, argv, "n:",
+ long_opts, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ }
+ }
+
+ if (!nodemap_name || errno != 0) {
+ fprintf(stderr, "%s: invalid nodemap '%s' offset '%s'\n",
+ jt_cmdname(argv[0]), nodemap_name, optarg);
+ return CMD_HELP;
+ }
+
+ rc = nodemap_cmd(LCFG_NODEMAP_DEL_OFFSET, false, NULL, 0,
+ argv[0], nodemap_name, NULL);
+
+ if (rc != 0) {
+ fprintf(stderr,
+ "%s: cannot del offset from nodemap '%s': %s\n",
+ *argv, nodemap_name, strerror(-rc));
+ }
+
+ return rc;
+}
+
int jt_nodemap_add_idmap(int argc, char **argv)
{
int c;
return -EOPNOTSUPP;
}
+int jt_nodemap_add_offset(int argc, char **argv)
+{
+ fprintf(stderr, "error: %s: invalid ioctl\n",
+ jt_cmdname(argv[0]));
+ return -EOPNOTSUPP;
+}
+
+int jt_nodemap_del_offset(int argc, char **argv)
+{
+ fprintf(stderr, "error: %s: invalid ioctl\n",
+ jt_cmdname(argv[0]));
+ return -EOPNOTSUPP;
+}
+
int jt_nodemap_add_range(int argc, char **argv)
{
fprintf(stderr, "error: %s: invalid ioctl\n",
int jt_nodemap_add(int argc, char **argv);
int jt_nodemap_del(int argc, char **argv);
int jt_nodemap_modify(int argc, char **argv);
+int jt_nodemap_add_offset(int argc, char **argv);
+int jt_nodemap_del_offset(int argc, char **argv);
int jt_nodemap_add_range(int argc, char **argv);
int jt_nodemap_test_nid(int argc, char **argv);
int jt_nodemap_del_range(int argc, char **argv);
CHECK_MEMBER(nodemap_id_rec, nir_padding4);
}
+static void check_nodemap_offset_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_offset_rec);
+ CHECK_MEMBER(nodemap_offset_rec, nor_start_uid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_limit_uid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_start_gid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_limit_gid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_start_projid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_limit_projid);
+ CHECK_MEMBER(nodemap_offset_rec, nor_padding1);
+ CHECK_MEMBER(nodemap_offset_rec, nor_padding2);
+}
+
static void check_nodemap_global_rec(void)
{
BLANK_LINE();
CHECK_VALUE(NODEMAP_CLUSTER_REC);
CHECK_VALUE(NODEMAP_CLUSTER_ROLES);
+ CHECK_VALUE(NODEMAP_CLUSTER_OFFSET);
CHECK_VALUE_X(NM_TYPE_MASK);
CHECK_VALUE(NM_TYPE_SHIFT);
CHECK_VALUE_X(LCFG_NODEMAP_ADMIN);
CHECK_VALUE_X(LCFG_NODEMAP_ADD_PROJIDMAP);
CHECK_VALUE_X(LCFG_NODEMAP_DEL_PROJIDMAP);
+ CHECK_VALUE_X(LCFG_NODEMAP_ADD_OFFSET);
+ CHECK_VALUE_X(LCFG_NODEMAP_DEL_OFFSET);
CHECK_VALUE_X(LCFG_NODEMAP_TRUSTED);
CHECK_VALUE_X(LCFG_NODEMAP_SQUASH_UID);
CHECK_VALUE_X(LCFG_NODEMAP_SQUASH_GID);
check_nodemap_range_rec();
check_nodemap_range2_rec();
check_nodemap_id_rec();
+ check_nodemap_offset_rec();
check_nodemap_global_rec();
check_nodemap_cluster_roles_rec();
check_nodemap_rec();
LASSERTF((int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3) == 8, "found %lld\n",
(long long)(int)sizeof(((struct nodemap_cluster_roles_rec *)0)->ncrr_padding3));
+ /* Checks for struct nodemap_offset_rec */
+ LASSERTF((int)sizeof(struct nodemap_offset_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_offset_rec));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_uid) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_uid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_uid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_uid) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_uid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_uid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_gid) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_gid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_gid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_gid) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_gid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_gid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_start_projid) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_start_projid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_start_projid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_limit_projid) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_limit_projid));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_limit_projid));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_padding1) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding1));
+ LASSERTF((int)offsetof(struct nodemap_offset_rec, nor_padding2) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_offset_rec, nor_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_offset_rec *)0)->nor_padding2));
+
/* Checks for union nodemap_rec */
LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
(long long)(int)sizeof(union nodemap_rec));
(long long)NODEMAP_CLUSTER_REC);
LASSERTF(NODEMAP_CLUSTER_ROLES == 1, "found %lld\n",
(long long)NODEMAP_CLUSTER_ROLES);
+ LASSERTF(NODEMAP_CLUSTER_OFFSET == 2, "found %lld\n",
+ (long long)NODEMAP_CLUSTER_OFFSET);
LASSERTF(NM_TYPE_MASK == 0x0fffffffUL, "found 0x%.8xUL\n",
(unsigned)NM_TYPE_MASK);
LASSERTF(NM_TYPE_SHIFT == 28, "found %lld\n",
(unsigned)LCFG_NODEMAP_ADD_PROJIDMAP);
LASSERTF(LCFG_NODEMAP_DEL_PROJIDMAP == 0x000ce04bUL, "found 0x%.8xUL\n",
(unsigned)LCFG_NODEMAP_DEL_PROJIDMAP);
+ LASSERTF(LCFG_NODEMAP_ADD_OFFSET == 0x000ce04cUL, "found 0x%.8xUL\n",
+ (unsigned)LCFG_NODEMAP_ADD_OFFSET);
+ LASSERTF(LCFG_NODEMAP_DEL_OFFSET == 0x000ce04dUL, "found 0x%.8xUL\n",
+ (unsigned)LCFG_NODEMAP_DEL_OFFSET);
LASSERTF(LCFG_NODEMAP_TRUSTED == 0x000ce050UL, "found 0x%.8xUL\n",
(unsigned)LCFG_NODEMAP_TRUSTED);
LASSERTF(LCFG_NODEMAP_SQUASH_UID == 0x000ce051UL, "found 0x%.8xUL\n",