void nodemap_del_member(struct obd_export *exp);
int nodemap_parse_range(const char *range_string, struct lnet_nid range[2],
u8 *netmask);
-int nodemap_parse_idmap(char *idmap_string, __u32 idmap[2]);
+int nodemap_parse_idmap(const char *nodemap_name, char *idmap_str,
+ __u32 idmap[2], u32 *range_count);
int nodemap_add_range(const char *name, const struct lnet_nid nid[2],
u8 netmask);
int nodemap_del_range(const char *name, const struct lnet_nid nid[2],
int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption);
int nodemap_set_readonly_mount(const char *name, bool readonly_mount);
bool nodemap_can_setquota(struct lu_nodemap *nodemap, __u32 qc_type, __u32 id);
-int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
+int nodemap_add_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
const __u32 map[2]);
-int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
+int nodemap_del_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
const __u32 map[2]);
int nodemap_set_fileset(const char *name, const char *fileset);
char *nodemap_get_fileset(const struct lu_nodemap *nodemap);
* parse a string containing an id map of form "client_id:filesystem_id"
* into an array of __u32 * for use in mapping functions
*
+ * the string can also be a range of "ci_start-ci_end:fs_start[-fs_end]"
+ *
+ * \param nodemap_name nodemap name string
* \param idmap_str map string
* \param idmap array[2] of __u32
+ * \param range_count potential idmap range u32
*
* \retval 0 on success
* \retval -EINVAL if idmap cannot be parsed
*/
-int nodemap_parse_idmap(char *idmap_str, __u32 idmap[2])
+int nodemap_parse_idmap(const char *nodemap_name, char *idmap_str,
+ __u32 idmap[2], u32 *range_count)
{
- char *sep;
- long unsigned int idmap_buf;
- int rc;
+ char *sep;
+ char *sep_range;
+ char *potential_range;
+ unsigned long id;
+ int rc;
+ int range = 1;
if (idmap_str == NULL)
return -EINVAL;
*sep = '\0';
sep++;
- rc = kstrtoul(idmap_str, 10, &idmap_buf);
- if (rc != 0)
+ /* see if range is passed in idmap_str */
+ sep_range = strchr(idmap_str, '-');
+ if (sep_range)
+ *sep_range++ = '\0';
+
+ rc = kstrtoul(idmap_str, 10, &id);
+ if (rc)
return -EINVAL;
- idmap[0] = idmap_buf;
+ idmap[0] = id;
- rc = kstrtoul(sep, 10, &idmap_buf);
- if (rc != 0)
+ /* parse cid range end if it is supplied */
+ if (sep_range) {
+ rc = kstrtoul(sep_range, 10, &id);
+ if (rc)
+ return -EINVAL;
+
+ range = id - idmap[0] + 1;
+ if (range <= 0)
+ return -ERANGE;
+ }
+
+ potential_range = strchr(sep, '-');
+ if (potential_range)
+ *potential_range++ = '\0';
+
+ rc = kstrtoul(sep, 10, &id);
+ if (rc)
return -EINVAL;
- idmap[1] = idmap_buf;
+ idmap[1] = id;
+
+ /* parse fsid range end if it is supplied */
+ if (potential_range) {
+ rc = kstrtoul(potential_range, 10, &id);
+ if (rc)
+ return -ERANGE;
+
+ /* make sure fsid range is equal to cid range */
+ if (id - idmap[1] + 1 != range) {
+ rc = -EINVAL;
+ CERROR("%s: range length mismatch between client id %s-%s and fs id %s-%s: rc = %d\n",
+ nodemap_name, idmap_str, sep_range, sep,
+ potential_range, rc);
+ return rc;
+ }
+ }
+ *range_count = range;
return 0;
}
return rc;
}
-int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
+int nodemap_add_idmap_range(const char *nodemap_name, enum nodemap_id_type id_type,
+ const __u32 map[2], const u32 range_count)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < range_count && !rc; i++) {
+ rc = nodemap_add_idmap(nodemap_name, id_type,
+ (int[2]){map[0] + i, map[1] + i});
+ }
+
+ return rc;
+}
+
+int nodemap_add_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
const __u32 map[2])
{
struct lu_nodemap *nodemap = NULL;
ENTRY;
mutex_lock(&active_config_lock);
- nodemap = nodemap_lookup(name);
+ nodemap = nodemap_lookup(nodemap_name);
if (IS_ERR(nodemap)) {
mutex_unlock(&active_config_lock);
GOTO(out, rc = PTR_ERR(nodemap));
*
* \retval 0 on success
*/
-int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
+int nodemap_del_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
const __u32 map[2])
{
struct lu_nodemap *nodemap = NULL;
ENTRY;
mutex_lock(&active_config_lock);
- nodemap = nodemap_lookup(name);
+ nodemap = nodemap_lookup(nodemap_name);
if (IS_ERR(nodemap)) {
mutex_unlock(&active_config_lock);
GOTO(out, rc = PTR_ERR(nodemap));
}
EXPORT_SYMBOL(nodemap_del_idmap);
+int nodemap_del_idmap_range(const char *nodemap_name, enum nodemap_id_type id_type,
+ const __u32 map[2], const u32 range_count)
+{
+ int rc = 0;
+ int i;
+
+ for (i = 0; i < range_count && !rc; i++) {
+ rc = nodemap_del_idmap(nodemap_name, id_type,
+ (int[2]) {map[0] + i, map[1] + i});
+ }
+
+ return rc;
+}
+
/**
* Get nodemap assigned to given export. Takes a reference on the nodemap.
*
bool bool_switch;
u8 netmask = 0;
u32 idmap[2];
+ u32 range_count;
u32 int_id;
int rc = 0;
case LCFG_NODEMAP_ADD_UIDMAP:
case LCFG_NODEMAP_ADD_GIDMAP:
case LCFG_NODEMAP_ADD_PROJIDMAP:
- rc = nodemap_parse_idmap(param, idmap);
+ rc = nodemap_parse_idmap(nodemap_name, param, idmap, &range_count);
if (rc != 0)
break;
if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
- rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
- idmap);
+ rc = nodemap_add_idmap_range(nodemap_name, NODEMAP_UID,
+ idmap, range_count);
else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
- rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
- idmap);
+ rc = nodemap_add_idmap_range(nodemap_name, NODEMAP_GID,
+ idmap, range_count);
else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
- rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
- idmap);
+ rc = nodemap_add_idmap_range(nodemap_name, NODEMAP_PROJID,
+ idmap, range_count);
else
rc = -EINVAL;
break;
case LCFG_NODEMAP_DEL_UIDMAP:
case LCFG_NODEMAP_DEL_GIDMAP:
case LCFG_NODEMAP_DEL_PROJIDMAP:
- rc = nodemap_parse_idmap(param, idmap);
+ rc = nodemap_parse_idmap(nodemap_name, param, idmap, &range_count);
if (rc != 0)
break;
if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
- rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
- idmap);
+ rc = nodemap_del_idmap_range(nodemap_name, NODEMAP_UID,
+ idmap, range_count);
else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
- rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
- idmap);
+ rc = nodemap_del_idmap_range(nodemap_name, NODEMAP_GID,
+ idmap, range_count);
else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
- rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
- idmap);
+ rc = nodemap_del_idmap_range(nodemap_name, NODEMAP_PROJID,
+ idmap, range_count);
else
rc = -EINVAL;
break;
}
run_test 27a "test fileset in various nodemaps"
+test_27aa() { #LU-17922
+ local idmap
+ local id=500
+
+ do_facet mgs $LCTL nodemap_add Test17922 ||
+ error "unable to add Test17922 as nodemap"
+ stack_trap "do_facet mgs $LCTL nodemap_del Test17922 || true"
+
+ do_facet mgs $LCTL nodemap_add_idmap --name Test17922 \
+ --idtype uid --idmap 500-509:10000-10009 ||
+ error "unable to add idmap range 500-509:10000-10009"
+
+ idmap=$(do_facet mgs $LCTL get_param nodemap.Test17922.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 Test17922 \
+ --idtype uid --idmap 505-509:10005 ||
+ error "cannot delete idmap range 505-509:10005"
+
+ id=500
+ idmap=$(do_facet mgs $LCTL get_param nodemap.Test17922.idmap | grep idtype)
+ while IFS= read -r idmap; do
+ if (( $id <= 504 )); then
+ [[ "$idmap" == *"client_id: $id"* ]] ||
+ error "could not find 'client_id: ${id}' inside of ${idmap}"
+ else
+ [[ "$idmap" =~ "client_id: $id" ]] &&
+ error "found 'client_id: $id' in $idmap"
+ fi
+ ((id++))
+ done < <(echo "$idmap")
+
+ do_facet mgs $LCTL nodemap_del_idmap --name Test17922 \
+ --idtype uid --idmap 500-504:10000
+
+ #expected error, invalid secondary range supplied
+ do_facet mgs $LCTL nodemap_add --name Test17922 \
+ --idtype uid --idmap 500-509:10000-10010 &&
+ error "Invalid range 10000-10010 was added"
+
+ (( $(do_facet mgs $LCTL get_param nodemap.Test17922.idmap |
+ grep -c idtype) == 0 )) ||
+ error "invalid range 10000-10010 supplied and passed"
+
+ do_facet mgs $LCTL nodemap_del Test17922 ||
+ error "failed to remove nodemap Test17922"
+}
+run_test 27aa "test nodemap idmap range"
+
test_27b() { #LU-10703
[ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
skip "Need MDS >= 2.11.50"