.B nodemap_add_idmap
adds an identity mapping to a nodemap. Clients that are members of the given
nodemap will have the identities of their users mapped accordingly.
+.PP
+When offsets are defined on the nodemap, any explicit identity mapping should
+map to an
+.I FSID
+in the offset range [ 0, offset_limit-1 ], otherwise the mapped ID would escape
+offsetting.
.SH OPTIONS
.TP
.BI --name " NODEMAP_NAME"
.BR lustre (7),
.BR lctl-nodemap-activate (8),
.BR lctl-nodemap-add (8),
+.BR lctl-nodemap-add-offset (8),
.BR lctl-nodemap-add-range (8),
.BR lctl-nodemap-del (8),
.BR lctl-nodemap-del-idmap (8),
+.BR lctl-nodemap-del-offset (8),
.BR lctl-nodemap-del-range (8),
.BR lctl-nodemap-modify (8)
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 .
+.IR 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.
+defined, just assign a new value.
Any existing files will
.B not
automatically be remapped to the new
.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.
+.PP
+Once an offset is set on a nodemap, please make sure the explicit mappings are
+defined so that they do not escape the offset range. This means an explicit
+mapping should not map a client id to a file system id greater than
+.IR FSID_COUNT-1 "."
+Similarly, the
+.BR squash_uid ", " squash_gid " and " squash_projid
+values should not be set to a value greater than
+.IR FSID_COUNT-1 "."
+Otherwise this would produce file system IDs outside of the offset range.
+Finally, the offset limit
+.I FSID_COUNT
+should be defined so that the
+.B nobody
+user (65534) is included in the offset range.
.SH OPTIONS
.TP
.BI --name " NAME"
if not specified, which is 65534 to match the standard Linux
.B nobody
user ID.
-The user ID that unknown users (if not trusted)
-and root (if not admin) should be mapped to.
+The user ID that unknown users (if not
+.BR trusted " ) and "
+.BR root " (if not " admin )
+should be mapped to.
+When offsets are defined on the nodemap, the squash value should be in the
+offset range [ 0, offset_limit-1 ], otherwise squashed UIDs would escape
+offsetting.
.TP
.B squash_gid
Defaults to
user ID.
The group ID that unknown groups (if not trusted)
and root (if not admin) should be mapped to.
+When offsets are defined on the nodemap, the squash value should be in the
+offset range [ 0, offset_limit-1 ], otherwise squashed GIDs would escape
+offsetting.
.TP
.B squash_projid
Defaults to
.B nobody
user ID.
The project ID that unknown projects (if not trusted) should be mapped to.
+When offsets are defined on the nodemap, the squash value should be in the
+offset range [ 0, offset_limit-1 ], otherwise squashed PROJIDs would escape
+offsetting.
.TP
.B deny_unknown
Defaults to 0. If set to 1 then unknown (squashed) users will be denied
.BR lctl-nodemap-activate (8),
.BR lctl-nodemap-add (8),
.BR lctl-nodemap-add-idmap (8),
+.BR lctl-nodemap-add-offset (8),
.BR lctl-nodemap-add-range (8),
.BR lctl-nodemap-del (8),
.BR lctl-nodemap-del-idmap (8),
+.BR lctl-nodemap-del-offset (8),
.BR lctl-nodemap-del-range (8)
return rc;
}
+int yaml_get_limit_uid(const char *config)
+{
+ yaml_parser_t parser;
+ yaml_event_t event;
+ bool done = false;
+ int rc;
+
+ /* Initialize parser */
+ if (!yaml_parser_initialize(&parser))
+ return -EOPNOTSUPP;
+
+ /* Set input string */
+ yaml_parser_set_input_string(&parser, (const unsigned char *)config,
+ strlen(config));
+
+ while (!done) {
+ if (!yaml_parser_parse(&parser, &event)) {
+ yaml_parser_log_error(&parser, stderr, "lctl: ");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ if (event.type == YAML_SCALAR_EVENT) {
+ char *value = (char *)event.data.scalar.value;
+
+ if (strcmp(value, "limit_uid") == 0) {
+ yaml_event_delete(&event);
+ if (!yaml_parser_parse(&parser, &event)) {
+ rc = -EINVAL;
+ goto error;
+ }
+ value = (char *)event.data.scalar.value;
+ errno = 0;
+ rc = strtoul(value, NULL, 10);
+ if (errno)
+ rc = -errno;
+ yaml_event_delete(&event);
+ goto out;
+ }
+ }
+
+ done = (event.type == YAML_STREAM_END_EVENT);
+ yaml_event_delete(&event);
+ }
+
+ rc = -ENOENT; /* Key not found */
+
+out:
+ yaml_parser_delete(&parser);
+ return rc;
+
+error:
+ yaml_parser_delete(&parser);
+ return rc;
+}
+
/* get device list by netlink or debugfs */
int jt_device_list(int argc, char **argv)
{
return obd_abort_recovery(argv[0], OBD_FLG_ABORT_RECOV_MDT);
}
-#else /* ! HAVE_SERVER_SUPPROT */
+
+static int lcfg_get_nm_offset_limit(char *nodemap)
+{
+ /* buffer to contain nodemap/<nodemap name>/offset */
+ char param[LUSTRE_NODEMAP_NAME_LENGTH + 16 + 1];
+ char *buf = NULL;
+ size_t buflen;
+ glob_t paths;
+ int rc;
+
+ snprintf(param, sizeof(param), "nodemap/%s/offset", nodemap);
+ rc = llapi_param_get_paths(param, &paths);
+ if (rc)
+ return -errno;
+
+ rc = llapi_param_get_value(paths.gl_pathv[0], &buf, &buflen);
+ if (rc)
+ goto free_all;
+
+ rc = yaml_get_limit_uid(buf);
+
+free_all:
+ free(buf);
+ llapi_param_paths_free(&paths);
+ return rc;
+}
+#else /* ! HAVE_SERVER_SUPPORT */
int jt_obd_no_transno(int argc, char **argv)
{
if (argc != 1)
return CMD_HELP;
}
+ if (cmd == LCFG_NODEMAP_SQUASH_UID ||
+ cmd == LCFG_NODEMAP_SQUASH_GID ||
+ cmd == LCFG_NODEMAP_SQUASH_PROJID) {
+ int offset_limit;
+ int squash;
+
+ offset_limit = lcfg_get_nm_offset_limit(nodemap_name);
+ squash = strtol(value, NULL, 10);
+ if (errno == ERANGE)
+ squash = -1;
+
+ if (offset_limit && squash >= offset_limit)
+ fprintf(stderr,
+ "Warning: it is not recommended to have a squash value outside of the offset range [ 0, %d ] as it will not be mapped properly.\n",
+ offset_limit - 1);
+ }
+
rc = nodemap_cmd(cmd, false, NULL, 0, argv[0], nodemap_name, param,
value, NULL);
if (rc != 0) {
/* 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");
+ "Warning: it is not recommended to have an offset before 65536 as the nobody/squash ids will not be mapped properly.\n");
+
+ /* user warning for setting limit to less than 65536 */
+ if (limit < 65536)
+ fprintf(stderr,
+ "Warning: it is not recommended to have a limit below 65536 as the nobody/squash ids will not be mapped properly.\n");
snprintf(param, sizeof(param), "%u+%u", offset, limit);
char *nodemap_name = NULL;
char *idtype = NULL;
char *idmap = NULL;
+ char *fsid = NULL;
+ int fsid_val = -1;
int c, rc = 0;
static struct option long_opts[] = {
goto add_idmap_usage;
}
+ fsid = strchr(idmap, ':');
+ if (fsid) {
+ fsid_val = strtol(fsid + 1, NULL, 10);
+ if (errno == ERANGE)
+ fsid_val = -1;
+ }
+ if (fsid_val != -1) {
+ int offset_limit;
+
+ offset_limit = lcfg_get_nm_offset_limit(nodemap_name);
+ if (offset_limit && fsid_val >= offset_limit)
+ fprintf(stderr,
+ "Warning: it is not recommended to map an id outside of the offset range [ 0, %d ] as it will not be mapped properly.\n",
+ offset_limit - 1);
+ }
+
rc = nodemap_cmd(cmd, false, NULL, 0,
argv[0], nodemap_name, idmap, NULL);
if (rc != 0) {
int jt_lcfg_confparam(int argc, char **argv);
int jt_lcfg_applyyaml(int argc, char **argv);
int jt_lcfg_setparam_perm(int argc, char **argv, struct param_opts *popt);
+int yaml_get_limit_uid(const char *config);
int jt_pool_cmd(int argc, char **argv);
int jt_del_ost(int argc, char **argv);