void nodemap_activate(const bool value);
int nodemap_add(const char *nodemap_name);
int nodemap_del(const char *nodemap_name);
-int nodemap_add_member(lnet_nid_t nid, struct obd_export *exp);
+int nodemap_add_member(struct lnet_nid *nid, struct obd_export *exp);
void nodemap_del_member(struct obd_export *exp);
-int nodemap_parse_range(const char *range_string, lnet_nid_t range[2]);
+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_add_range(const char *name, const lnet_nid_t nid[2]);
-int nodemap_del_range(const char *name, const lnet_nid_t nid[2]);
+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],
+ u8 netmask);
int nodemap_set_allow_root(const char *name, bool allow_root);
int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids);
int nodemap_set_deny_unknown(const char *name, bool deny_unknown);
ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size,
enum nodemap_tree_type tree_type);
#ifdef HAVE_SERVER_SUPPORT
-void nodemap_test_nid(lnet_nid_t nid, char *name_buf, size_t name_len);
+void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len);
#else
#define nodemap_test_nid(nid, name_buf, name_len) do {} while(0)
#endif
-int nodemap_test_id(lnet_nid_t nid, enum nodemap_id_type idtype,
- __u32 client_id, __u32 *fs_id);
+int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
+ u32 client_id, u32 *fs_id);
struct nm_config_file *nm_config_file_register_mgs(const struct lu_env *env,
struct dt_object *obj,
/* Pointer to default nodemap as it is needed more often */
struct lu_nodemap *nmc_default_nodemap;
+ /* list of netmask + address prefix */
+ struct list_head nmc_netmask_setup;
+
/**
* Lock required to access the range tree.
*/
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_NID_MASK_IDX = 6, /* large NID setup for a nm cluster */
NODEMAP_GLOBAL_IDX = 15, /* stores nodemap activation status */
};
__u64 nrr_padding2;
};
+struct nodemap_range2_rec {
+ struct lnet_nid nrr_nid_prefix;
+ __u32 nrr_padding1; /* these fields may be used if */
+ __u32 nrr_padding2; /* nrr_nid_prefix.nid_size > 12 */
+ __u16 nrr_padding3;
+ __u8 nrr_padding4;
+ __u8 nrr_netmask;
+};
+
struct nodemap_id_rec {
__u32 nir_id_fs;
__u32 nir_padding1;
union nodemap_rec {
struct nodemap_cluster_rec ncr;
struct nodemap_range_rec nrr;
+ struct nodemap_range2_rec nrr2;
struct nodemap_id_rec nir;
struct nodemap_global_rec ngr;
struct nodemap_cluster_roles_rec ncrr;
lexp = class_conn2export(&conn);
LASSERT(lexp != NULL);
- if (nid_is_nid4(client_nid)) {
- rc = nodemap_add_member(lnet_nid_to_nid4(client_nid), lexp);
- if (rc != 0 && rc != -EEXIST)
- GOTO(out, rc);
- }
+ rc = nodemap_add_member(client_nid, lexp);
+ if (rc != 0 && rc != -EEXIST)
+ GOTO(out, rc);
rc = mdt_connect_internal(env, lexp, mdt, data, false);
if (rc == 0) {
if (exp == NULL || obd == NULL || cluuid == NULL)
RETURN(-EINVAL);
- if (nid_is_nid4(client_nid)) {
- rc = nodemap_add_member(lnet_nid_to_nid4(client_nid), exp);
- if (rc != 0 && rc != -EEXIST)
- RETURN(rc);
- }
+ rc = nodemap_add_member(client_nid, exp);
+ if (rc != 0 && rc != -EEXIST)
+ RETURN(rc);
rc = mdt_connect_internal(env, exp, mdt_dev(obd->obd_lu_dev), data,
true);
{
struct lustre_cfg *lcfg = NULL;
struct fs_db *fsdb;
- lnet_nid_t nid;
+ struct lnet_nid nid;
const char *nodemap_name = NULL;
const char *nidstr = NULL;
const char *client_idstr = NULL;
if (lcfg->lcfg_bufcount != 2)
GOTO(out_lcfg, rc = -EINVAL);
nidstr = lustre_cfg_string(lcfg, 1);
- nid = libcfs_str2nid(nidstr);
- nodemap_test_nid(nid, name_buf, sizeof(name_buf));
+ rc = libcfs_strnid(&nid, nidstr);
+ if (rc < 0)
+ GOTO(out_lcfg, rc);
+
+ nodemap_test_nid(&nid, name_buf, sizeof(name_buf));
rc = copy_to_user(data->ioc_pbuf1, name_buf,
min_t(size_t, data->ioc_plen1,
sizeof(name_buf)));
idtype_str = lustre_cfg_string(lcfg, 2);
client_idstr = lustre_cfg_string(lcfg, 3);
- nid = libcfs_str2nid(nidstr);
+ rc = libcfs_strnid(&nid, nidstr);
+ if (rc < 0)
+ GOTO(out_lcfg, rc);
+
if (strcmp(idtype_str, "uid") == 0)
idtype = NODEMAP_UID;
else if (strcmp(idtype_str, "gid") == 0)
if (rc != 0)
GOTO(out_lcfg, rc = -EINVAL);
- rc = nodemap_test_id(nid, idtype, client_id, &fs_id);
+ rc = nodemap_test_id(&nid, idtype, client_id, &fs_id);
if (rc < 0)
GOTO(out_lcfg, rc = -EINVAL);
enum lcfg_command_type cmd, const char *nodemap_name,
char *param)
{
- lnet_nid_t nid[2];
+ struct lnet_nid nid[2];
u32 idmap[2];
bool bool_switch;
+ u8 netmask = 0;
u32 int_id;
int rc = 0;
rc = nodemap_del(nodemap_name);
break;
case LCFG_NODEMAP_ADD_RANGE:
- rc = nodemap_parse_range(param, nid);
+ rc = nodemap_parse_range(param, nid, &netmask);
if (rc != 0)
break;
- rc = nodemap_add_range(nodemap_name, nid);
+ rc = nodemap_add_range(nodemap_name, nid, netmask);
break;
case LCFG_NODEMAP_DEL_RANGE:
- rc = nodemap_parse_range(param, nid);
+ rc = nodemap_parse_range(param, nid, &netmask);
if (rc != 0)
break;
- rc = nodemap_del_range(nodemap_name, nid);
+ rc = nodemap_del_range(nodemap_name, nid, netmask);
break;
case LCFG_NODEMAP_ADMIN:
rc = kstrtobool(param, &bool_switch);
if (!exp || !obd || !cluuid)
RETURN(-EINVAL);
- if (nid_is_nid4(client_nid)) {
- rc = nodemap_add_member(lnet_nid_to_nid4(client_nid), exp);
- if (rc != 0 && rc != -EEXIST)
- RETURN(rc);
- }
+ rc = nodemap_add_member(client_nid, exp);
+ if (rc != 0 && rc != -EEXIST)
+ RETURN(rc);
ofd = ofd_dev(obd->obd_lu_dev);
exp = class_conn2export(&conn);
LASSERT(exp != NULL);
- if (client_nid && nid_is_nid4(client_nid)) {
- rc = nodemap_add_member(lnet_nid_to_nid4(client_nid), exp);
+ if (client_nid) {
+ rc = nodemap_add_member(client_nid, exp);
if (rc != 0 && rc != -EEXIST)
GOTO(out, rc);
} else {
*/
LNetPrimaryNID(&req->rq_source.nid);
rsi.si_nid4 = lnet_nid_to_nid4(&req->rq_source.nid);
- nodemap_test_nid(lnet_nid_to_nid4(&req->rq_peer.nid), rsi.si_nm_name,
+ nodemap_test_nid(&req->rq_peer.nid, rsi.si_nm_name,
sizeof(rsi.si_nm_name));
/* Note that context handle is always 0 for for INIT. */
* \retval default_nodemap default nodemap
* \retval -EINVAL LO nid given without other local nid
*/
-struct lu_nodemap *nodemap_classify_nid(lnet_nid_t nid)
+struct lu_nodemap *nodemap_classify_nid(struct lnet_nid *nid)
{
struct lu_nid_range *range;
struct lu_nodemap *nodemap;
int rc;
ENTRY;
-
/* don't use 0@lo, use the first non-lo local NID instead */
- if (nid == LNET_NID_LO_0) {
+ if (nid_is_lo0(nid)) {
struct lnet_processid id;
int i = 0;
do {
- rc = LNetGetId(i++, &id, false);
+ rc = LNetGetId(i++, &id, true);
if (rc < 0)
RETURN(ERR_PTR(-EINVAL));
} while (nid_is_lo0(&id.nid));
- nid = lnet_nid_to_nid4(&id.nid);
- CDEBUG(D_INFO, "found nid %s\n", libcfs_nid2str(nid));
+ nid = &id.nid;
+ CDEBUG(D_INFO, "found nid %s\n", libcfs_nidstr(nid));
}
- range = range_search(&active_config->nmc_range_tree, nid);
+ range = range_search(active_config, nid);
if (range != NULL)
nodemap = range->rn_nodemap;
else
* \param range[2] array of two nids
* \reyval 0 on success
*/
-int nodemap_parse_range(const char *range_str, lnet_nid_t range[2])
+int nodemap_parse_range(const char *range_str, struct lnet_nid range[2],
+ u8 *netmask)
{
char buf[LNET_NIDSTR_SIZE * 2 + 2];
char *ptr = NULL;
snprintf(buf, sizeof(buf), "%s", range_str);
ptr = buf;
- start_nidstr = strsep(&ptr, ":");
- end_nidstr = strsep(&ptr, ":");
+
+ /* For large NID we use netmasks. Currently we only
+ * support /128 which is a single NID.
+ */
+ if (strchr(ptr, '/')) {
+ start_nidstr = strsep(&ptr, "/");
+
+ rc = kstrtou8(ptr, 10, netmask);
+ if (rc < 0)
+ GOTO(out, rc);
+ if (*netmask != 128)
+ GOTO(out, rc = -ERANGE);
+ end_nidstr = start_nidstr;
+ } else {
+ start_nidstr = strsep(&ptr, ":");
+ end_nidstr = strsep(&ptr, ":");
+ }
if (start_nidstr == NULL || end_nidstr == NULL)
GOTO(out, rc = -EINVAL);
- range[0] = libcfs_str2nid(start_nidstr);
- range[1] = libcfs_str2nid(end_nidstr);
+ rc = libcfs_strnid(&range[0], start_nidstr);
+ if (rc < 0)
+ GOTO(out, rc);
+ rc = libcfs_strnid(&range[1], end_nidstr);
out:
return rc;
* \retval -EINVAL export is NULL, or has invalid NID
* \retval -EEXIST export is already member of a nodemap
*/
-int nodemap_add_member(lnet_nid_t nid, struct obd_export *exp)
+int nodemap_add_member(struct lnet_nid *nid, struct obd_export *exp)
{
struct lu_nodemap *nodemap;
int rc = 0;
- ENTRY;
+ ENTRY;
mutex_lock(&active_config_lock);
down_read(&active_config->nmc_range_tree_lock);
nodemap = nodemap_classify_nid(nid);
-
if (IS_ERR(nodemap)) {
CWARN("%s: error adding to nodemap, no valid NIDs found\n",
- exp->exp_obd->obd_name);
+ exp->exp_obd->obd_name);
rc = -EINVAL;
} else {
rc = nm_member_add(nodemap, exp);
*/
int nodemap_add_range_helper(struct nodemap_config *config,
struct lu_nodemap *nodemap,
- const lnet_nid_t nid[2],
- unsigned int range_id)
+ const struct lnet_nid nid[2],
+ u8 netmask, unsigned int range_id)
{
- struct lu_nid_range *range;
+ struct lu_nid_range *range;
int rc;
down_write(&config->nmc_range_tree_lock);
- range = range_create(&config->nmc_range_tree, nid[0], nid[1],
- nodemap, range_id);
+ range = range_create(config, &nid[0], &nid[1], netmask, nodemap,
+ range_id);
if (range == NULL) {
up_write(&config->nmc_range_tree_lock);
GOTO(out, rc = -ENOMEM);
}
- rc = range_insert(&config->nmc_range_tree, range);
+ rc = range_insert(config, range);
if (rc) {
CDEBUG_LIMIT(rc == -EEXIST ? D_INFO : D_ERROR,
"cannot insert nodemap range into '%s': rc = %d\n",
/* if range_id is non-zero, we are loading from disk */
if (range_id == 0)
- rc = nodemap_idx_range_add(range, nid);
+ rc = nodemap_idx_range_add(range);
if (config == active_config) {
nm_member_revoke_locks(config->nmc_default_nodemap);
return rc;
}
-int nodemap_add_range(const char *name, const lnet_nid_t nid[2])
+int nodemap_add_range(const char *name, const struct lnet_nid nid[2],
+ u8 netmask)
{
struct lu_nodemap *nodemap = NULL;
int rc;
if (is_default_nodemap(nodemap))
rc = -EINVAL;
else
- rc = nodemap_add_range_helper(active_config, nodemap, nid, 0);
+ rc = nodemap_add_range_helper(active_config, nodemap, nid,
+ netmask, 0);
mutex_unlock(&active_config_lock);
nodemap_putref(nodemap);
out:
* Delete range from global range tree, and remove it
* from the list in the associated nodemap.
*/
-int nodemap_del_range(const char *name, const lnet_nid_t nid[2])
+int nodemap_del_range(const char *name, const struct lnet_nid nid[2],
+ u8 netmask)
{
struct lu_nodemap *nodemap;
struct lu_nid_range *range;
GOTO(out_putref, rc = -EINVAL);
down_write(&active_config->nmc_range_tree_lock);
- range = range_find(&active_config->nmc_range_tree, nid[0], nid[1]);
+ range = range_find(active_config, &nid[0], &nid[1], netmask);
if (range == NULL) {
up_write(&active_config->nmc_range_tree_lock);
GOTO(out_putref, rc = -EINVAL);
GOTO(out_putref, rc = -EINVAL);
}
rc = nodemap_idx_range_del(range);
- range_delete(&active_config->nmc_range_tree, range);
+ range_delete(active_config, range);
nm_member_reclassify_nodemap(nodemap);
up_write(&active_config->nmc_range_tree_lock);
if (rc2 < 0)
rc = rc2;
- range_delete(&active_config->nmc_range_tree, range);
+ range_delete(active_config, range);
}
up_write(&active_config->nmc_range_tree_lock);
init_rwsem(&config->nmc_range_tree_lock);
+ INIT_LIST_HEAD(&config->nmc_netmask_setup);
config->nmc_range_tree.nmrt_range_interval_root = INTERVAL_TREE_ROOT;
return config;
nm_member_reclassify_nodemap(nodemap);
list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
rn_list)
- range_delete(&config->nmc_range_tree, range);
+ range_delete(config, range);
up_write(&config->nmc_range_tree_lock);
mutex_unlock(&active_config_lock);
* \param[out] name_buf buffer to write the nodemap name to
* \param name_len length of buffer
*/
-void nodemap_test_nid(lnet_nid_t nid, char *name_buf, size_t name_len)
+void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len)
{
- struct lu_nodemap *nodemap;
+ struct lu_nodemap *nodemap;
mutex_lock(&active_config_lock);
down_read(&active_config->nmc_range_tree_lock);
* \retval 0 success
* \retval -EINVAL invalid NID
*/
-int nodemap_test_id(lnet_nid_t nid, enum nodemap_id_type idtype,
- __u32 client_id, __u32 *fs_id)
+int nodemap_test_id(struct lnet_nid *nid, enum nodemap_id_type idtype,
+ u32 client_id, u32 *fs_id)
{
- struct lu_nodemap *nodemap;
+ struct lu_nodemap *nodemap;
mutex_lock(&active_config_lock);
down_read(&active_config->nmc_range_tree_lock);
struct lu_nodemap *rn_nodemap;
/* list for nodemap */
struct list_head rn_list;
+ /* list for nodemap config */
+ struct list_head rn_collect;
/* nid interval tree */
- lnet_nid_t rn_start,
- rn_end,
- rn_subtree_last;
+ struct lnet_nid rn_start,
+ rn_end;
+ lnet_nid_t rn_subtree_last;
+ /* Large NID netmask */
+ u8 rn_netmask;
struct rb_node rn_rb;
};
int lprocfs_nodemap_register(struct lu_nodemap *nodemap,
bool is_default_nodemap);
void lprocfs_nodemap_remove(struct nodemap_pde *nodemap_pde);
-struct lu_nid_range *nodemap_range_find(lnet_nid_t start_nid,
- lnet_nid_t end_nid);
-struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t start_nid, lnet_nid_t end_nid,
- struct lu_nodemap *nodemap,
+struct lu_nid_range *range_create(struct nodemap_config *config,
+ const struct lnet_nid *start_nid,
+ const struct lnet_nid *end_nid,
+ u8 netmask, struct lu_nodemap *nodemap,
unsigned int range_id);
void range_destroy(struct lu_nid_range *range);
-int range_insert(struct nodemap_range_tree *nm_range_tree,
- struct lu_nid_range *data);
-void range_delete(struct nodemap_range_tree *nm_range_tree,
- struct lu_nid_range *data);
-struct lu_nid_range *range_search(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t nid);
-struct lu_nid_range *range_find(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t start_nid, lnet_nid_t end_nid);
-int range_parse_nidstring(char *range_string, lnet_nid_t *start_nid,
- lnet_nid_t *end_nid);
+int range_insert(struct nodemap_config *config, struct lu_nid_range *data);
+void range_delete(struct nodemap_config *config, struct lu_nid_range *data);
+struct lu_nid_range *range_search(struct nodemap_config *config,
+ struct lnet_nid *nid);
+struct lu_nid_range *range_find(struct nodemap_config *config,
+ const struct lnet_nid *start_nid,
+ const struct lnet_nid *end_nid,
+ u8 netmask);
void range_init_tree(void);
struct lu_idmap *idmap_create(__u32 client_id, __u32 fs_id);
struct lu_idmap *idmap_insert(enum nodemap_id_type id_type,
int nm_member_add(struct lu_nodemap *nodemap, struct obd_export *exp);
void nm_member_del(struct lu_nodemap *nodemap, struct obd_export *exp);
void nm_member_delete_list(struct lu_nodemap *nodemap);
-struct lu_nodemap *nodemap_classify_nid(lnet_nid_t nid);
+struct lu_nodemap *nodemap_classify_nid(struct lnet_nid *nid);
void nm_member_reclassify_nodemap(struct lu_nodemap *nodemap);
void nm_member_revoke_locks(struct lu_nodemap *nodemap);
void nm_member_revoke_locks_always(struct lu_nodemap *nodemap);
const __u32 map[2]);
int nodemap_add_range_helper(struct nodemap_config *config,
struct lu_nodemap *nodemap,
- const lnet_nid_t nid[2],
- unsigned int range_id);
+ const struct lnet_nid nid[2],
+ u8 netmask, unsigned int range_id);
struct rb_node *nm_rb_next_postorder(const struct rb_node *node);
struct rb_node *nm_rb_first_postorder(const struct rb_root *root);
int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
enum nodemap_id_type id_type,
const __u32 map[2]);
-int nodemap_idx_range_add(const struct lu_nid_range *range,
- const lnet_nid_t nid[2]);
+int nodemap_idx_range_add(const struct lu_nid_range *range);
int nodemap_idx_range_del(const struct lu_nid_range *range);
int nodemap_idx_nodemap_activate(bool value);
#endif /* _NODEMAP_INTERNAL_H */
if (cont)
seq_printf(m, ",\n");
cont = 1;
- libcfs_nid2str_r(range->rn_start, start_nidstr, sizeof(start_nidstr));
- libcfs_nid2str_r(range->rn_end, end_nidstr, sizeof(end_nidstr));
+ libcfs_nidstr_r(&range->rn_start, start_nidstr, sizeof(start_nidstr));
+ libcfs_nidstr_r(&range->rn_end, end_nidstr, sizeof(end_nidstr));
seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
range->rn_id, start_nidstr, end_nidstr);
}
list_for_each_entry_safe(exp, tmp, &nodemap->nm_member_list,
exp_target_data.ted_nodemap_member) {
- lnet_nid_t nid;
+ struct lnet_nid *nid;
/* if no conn assigned to this exp, reconnect will reclassify */
spin_lock(&exp->exp_lock);
if (exp->exp_connection) {
- nid = lnet_nid_to_nid4(&exp->exp_connection->c_peer.nid);
+ nid = &exp->exp_connection->c_peer.nid;
} else {
spin_unlock(&exp->exp_lock);
continue;
* controlled to prevent read access during update operations.
*/
-#define START(node) ((node)->rn_start)
-#define LAST(node) ((node)->rn_end)
+#define START(node) (lnet_nid_to_nid4(&((node)->rn_start)))
+#define LAST(node) (lnet_nid_to_nid4(&((node)->rn_end)))
INTERVAL_TREE_DEFINE(struct lu_nid_range, rn_rb, lnet_nid_t, rn_subtree_last,
START, LAST, static, nm_range)
* \param nodemap nodemap that contains this range
* \retval lu_nid_range on success, NULL on failure
*/
-struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t start_nid, lnet_nid_t end_nid,
- struct lu_nodemap *nodemap, unsigned range_id)
+struct lu_nid_range *range_create(struct nodemap_config *config,
+ const struct lnet_nid *start_nid,
+ const struct lnet_nid *end_nid,
+ u8 netmask, struct lu_nodemap *nodemap,
+ unsigned int range_id)
{
+ struct nodemap_range_tree *nm_range_tree;
struct lu_nid_range *range;
- if (LNET_NIDNET(start_nid) != LNET_NIDNET(end_nid) ||
- LNET_NIDADDR(start_nid) > LNET_NIDADDR(end_nid))
+ if (LNET_NID_NET(start_nid) != LNET_NID_NET(end_nid))
return NULL;
+ if (!netmask) {
+ lnet_nid_t nid4[2] = {
+ lnet_nid_to_nid4(start_nid),
+ lnet_nid_to_nid4(end_nid)
+ };
+
+ if (LNET_NIDADDR(nid4[0]) > LNET_NIDADDR(nid4[1]))
+ return NULL;
+ } else if (!nid_same(start_nid, end_nid)) {
+ /* FIXME Currently we only support one large NID per nodemap */
+ return NULL;
+ }
+
OBD_ALLOC_PTR(range);
if (range == NULL) {
CERROR("cannot allocate lu_nid_range of size %zu bytes\n",
}
/* if we are loading from save, use on disk id num */
+ nm_range_tree = &config->nmc_range_tree;
if (range_id != 0) {
if (nm_range_tree->nmrt_range_highest_id < range_id)
nm_range_tree->nmrt_range_highest_id = range_id;
}
range->rn_nodemap = nodemap;
- range->rn_start = start_nid;
- range->rn_end = end_nid;
+ range->rn_netmask = netmask;
+ range->rn_start = *start_nid;
+ range->rn_end = *end_nid;
INIT_LIST_HEAD(&range->rn_list);
* \param end_nid ending nid
* \retval matching range or NULL
*/
-struct lu_nid_range *range_find(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t start_nid, lnet_nid_t end_nid)
+struct lu_nid_range *range_find(struct nodemap_config *config,
+ const struct lnet_nid *start_nid,
+ const struct lnet_nid *end_nid,
+ u8 netmask)
{
- struct lu_nid_range *range;
-
- range = nm_range_iter_first(
- &nm_range_tree->nmrt_range_interval_root, start_nid, end_nid);
- while (range &&
- (range->rn_start != start_nid || range->rn_end != end_nid))
- range = nm_range_iter_next(range, start_nid, end_nid);
-
+ struct lu_nid_range *range = NULL;
+
+ if (!netmask) {
+ struct nodemap_range_tree *nm_range_tree;
+ lnet_nid_t nid4[2];
+
+ if (!nid_is_nid4(start_nid) || !nid_is_nid4(end_nid))
+ return NULL;
+
+ nid4[0] = lnet_nid_to_nid4(start_nid);
+ nid4[1] = lnet_nid_to_nid4(end_nid);
+ nm_range_tree = &config->nmc_range_tree;
+ range = nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+ nid4[0], nid4[1]);
+ while (range &&
+ (!nid_same(&range->rn_start, start_nid) ||
+ !nid_same(&range->rn_end, end_nid)))
+ range = nm_range_iter_next(range, nid4[0], nid4[1]);
+ } else if (!list_empty(&config->nmc_netmask_setup)) {
+ struct lu_nid_range *range_temp;
+
+ /* FIXME. We scan the config for large NIDs. Each range
+ * only contains one large NID for now.
+ */
+ list_for_each_entry_safe(range, range_temp,
+ &config->nmc_netmask_setup,
+ rn_collect) {
+ if (nid_same(&range->rn_start, start_nid) &&
+ range->rn_netmask == netmask)
+ break;
+ range = NULL;
+ }
+ }
return range;
}
* does not overlap so that each nid can belong
* to exactly one range
*/
-int range_insert(struct nodemap_range_tree *nm_range_tree,
- struct lu_nid_range *range)
+int range_insert(struct nodemap_config *config, struct lu_nid_range *range)
{
- if (nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
- range->rn_start,
- range->rn_end))
- return -EEXIST;
+ if (!range->rn_netmask) {
+ struct nodemap_range_tree *nm_range_tree;
- nm_range_insert(range, &nm_range_tree->nmrt_range_interval_root);
+ nm_range_tree = &config->nmc_range_tree;
+ if (nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+ lnet_nid_to_nid4(&range->rn_start),
+ lnet_nid_to_nid4(&range->rn_end)))
+ return -EEXIST;
+ nm_range_insert(range,
+ &nm_range_tree->nmrt_range_interval_root);
+ } else {
+ list_add(&range->rn_collect, &config->nmc_netmask_setup);
+ }
return 0;
}
*
* \param range range to remove
*/
-void range_delete(struct nodemap_range_tree *nm_range_tree,
- struct lu_nid_range *range)
+void range_delete(struct nodemap_config *config, struct lu_nid_range *range)
{
list_del(&range->rn_list);
- nm_range_remove(range, &nm_range_tree->nmrt_range_interval_root);
+ if (!range->rn_netmask) {
+ struct nodemap_range_tree *nm_range_tree;
+
+ nm_range_tree = &config->nmc_range_tree;
+ nm_range_remove(range,
+ &nm_range_tree->nmrt_range_interval_root);
+ } else {
+ list_del(&range->rn_collect);
+ }
range_destroy(range);
}
*
* \param nid nid to search for
*/
-struct lu_nid_range *range_search(struct nodemap_range_tree *nm_range_tree,
- lnet_nid_t nid)
+struct lu_nid_range *range_search(struct nodemap_config *config,
+ struct lnet_nid *nid)
{
- return nm_range_iter_first(
- &nm_range_tree->nmrt_range_interval_root, nid, nid);
+ struct lu_nid_range *range = NULL;
+
+ if (nid_is_nid4(nid)) {
+ struct nodemap_range_tree *nm_range_tree;
+
+ nm_range_tree = &config->nmc_range_tree;
+ range = nm_range_iter_first(&nm_range_tree->nmrt_range_interval_root,
+ lnet_nid_to_nid4(nid),
+ lnet_nid_to_nid4(nid));
+ } else if (!list_empty(&config->nmc_netmask_setup)) {
+ struct lu_nid_range *range_temp;
+
+ /* FIXME. We scan the config for the large NIDs. Each range
+ * only contains one large NID for now.
+ */
+ list_for_each_entry_safe(range, range_temp,
+ &config->nmc_netmask_setup,
+ rn_collect) {
+ if (nid_same(&range->rn_start, nid))
+ break;
+ range = NULL;
+ }
+ }
+
+ return range;
}
nr->nir.nir_id_fs = cpu_to_le32(id_fs);
}
-static void nodemap_range_key_init(struct nodemap_key *nk, unsigned int nm_id,
- unsigned int rn_id)
+static void nodemap_range_key_init(struct nodemap_key *nk,
+ enum nodemap_idx_type type,
+ unsigned int nm_id, unsigned int rn_id)
{
- nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
- NODEMAP_RANGE_IDX));
+ nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id, type));
nk->nk_range_id = cpu_to_le32(rn_id);
}
-static void nodemap_range_rec_init(union nodemap_rec *nr,
- const lnet_nid_t nid[2])
+static int nodemap_range_rec_init(union nodemap_rec *nr,
+ const struct lu_nid_range *range)
{
- nr->nrr.nrr_start_nid = cpu_to_le64(nid[0]);
- nr->nrr.nrr_end_nid = cpu_to_le64(nid[1]);
+ if (range->rn_netmask) {
+ nr->nrr2.nrr_nid_prefix = range->rn_start;
+ nr->nrr2.nrr_netmask = range->rn_netmask;
+
+ if (NID_BYTES(&nr->nrr2.nrr_nid_prefix) >
+ sizeof(struct lnet_nid))
+ return -E2BIG;
+ } else {
+ lnet_nid_t nid4[2];
+
+ if (!nid_is_nid4(&range->rn_start) ||
+ !nid_is_nid4(&range->rn_end))
+ return -EINVAL;
+
+ nid4[0] = lnet_nid_to_nid4(&range->rn_start);
+ nid4[1] = lnet_nid_to_nid4(&range->rn_end);
+ nr->nrr.nrr_start_nid = cpu_to_le64(nid4[0]);
+ nr->nrr.nrr_end_nid = cpu_to_le64(nid4[1]);
+ }
+
+ return 0;
}
static void nodemap_global_key_init(struct nodemap_key *nk)
int rc2 = 0;
ENTRY;
-
if (nodemap_mgs_ncf == NULL) {
CERROR("cannot add nodemap config to non-existing MGS.\n");
return -EINVAL;
list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
rn_list) {
- nodemap_range_key_init(&nk, nodemap->nm_id, range->rn_id);
+ enum nodemap_idx_type type;
+
+ type = range->rn_netmask ? NODEMAP_NID_MASK_IDX :
+ NODEMAP_RANGE_IDX;
+ nodemap_range_key_init(&nk, type, nodemap->nm_id, range->rn_id);
rc2 = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj,
&nk, NULL);
if (rc2 < 0)
RETURN(rc);
}
-int nodemap_idx_range_add(const struct lu_nid_range *range,
- const lnet_nid_t nid[2])
+int nodemap_idx_range_add(const struct lu_nid_range *range)
{
- struct nodemap_key nk;
- union nodemap_rec nr;
- struct lu_env env;
- int rc = 0;
- ENTRY;
+ struct nodemap_key nk;
+ union nodemap_rec nr;
+ 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;
if (rc != 0)
RETURN(rc);
- nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
- nodemap_range_rec_init(&nr, nid);
+ nodemap_range_key_init(&nk, range->rn_netmask ? NODEMAP_NID_MASK_IDX :
+ NODEMAP_RANGE_IDX,
+ range->rn_nodemap->nm_id, range->rn_id);
+ rc = nodemap_range_rec_init(&nr, range);
+ if (rc < 0)
+ goto free_env;
rc = nodemap_idx_insert(&env, nodemap_mgs_ncf->ncf_obj, &nk, &nr);
+free_env:
lu_env_fini(&env);
RETURN(rc);
if (rc != 0)
RETURN(rc);
- nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
-
+ nodemap_range_key_init(&nk, range->rn_netmask ? NODEMAP_NID_MASK_IDX :
+ NODEMAP_RANGE_IDX,
+ range->rn_nodemap->nm_id, range->rn_id);
rc = nodemap_idx_delete(&env, nodemap_mgs_ncf->ncf_obj, &nk, NULL);
lu_env_fini(&env);
struct lu_nodemap *nodemap = NULL;
enum nodemap_idx_type type;
enum nodemap_id_type id_type;
+ struct lnet_nid nid[2];
int subtype;
u32 nodemap_id;
- lnet_nid_t nid[2];
u32 map[2];
int rc;
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 ||
+ if (type == NODEMAP_RANGE_IDX || type == NODEMAP_NID_MASK_IDX ||
+ type == NODEMAP_UIDMAP_IDX || type == NODEMAP_GIDMAP_IDX ||
+ type == NODEMAP_PROJIDMAP_IDX ||
(type == NODEMAP_CLUSTER_IDX && subtype != NODEMAP_CLUSTER_REC)) {
struct lu_nodemap *tmp = NULL;
}
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);
-
+ lnet_nid4_to_nid(le64_to_cpu(rec->nrr.nrr_start_nid), &nid[0]);
+ lnet_nid4_to_nid(le64_to_cpu(rec->nrr.nrr_end_nid), &nid[1]);
+ rc = nodemap_add_range_helper(config, nodemap, nid, 0,
+ le32_to_cpu(key->nk_range_id));
+ if (rc != 0)
+ GOTO(out, rc);
+ break;
+ case NODEMAP_NID_MASK_IDX:
+ nid[0] = rec->nrr2.nrr_nid_prefix;
+ nid[1] = rec->nrr2.nrr_nid_prefix;
rc = nodemap_add_range_helper(config, nodemap, nid,
- le32_to_cpu(key->nk_range_id));
+ rec->nrr2.nrr_netmask,
+ le32_to_cpu(key->nk_range_id));
if (rc != 0)
GOTO(out, rc);
break;
down_read(&active_config->nmc_range_tree_lock);
list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
rn_list) {
- lnet_nid_t nid[2] = {
- range->rn_start,
- range->rn_end
- };
- nodemap_range_key_init(&nk, nodemap->nm_id,
+ enum nodemap_idx_type type;
+
+ type = range->rn_netmask ? NODEMAP_NID_MASK_IDX :
+ NODEMAP_RANGE_IDX;
+ nodemap_range_key_init(&nk, type, nodemap->nm_id,
range->rn_id);
- nodemap_range_rec_init(&nr, nid);
+ rc2 = nodemap_range_rec_init(&nr, range);
+ if (rc2 < 0) {
+ rc = rc2;
+ continue;
+ }
rc2 = nodemap_idx_insert(env, o, &nk, &nr);
if (rc2 < 0)
rc = rc2;
LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2) == 8, "found %lld\n",
(long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2));
+ /* Checks for struct nodemap_range2_rec */
+ LASSERTF((int)sizeof(struct nodemap_range2_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_range2_rec));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_nid_prefix) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_nid_prefix));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_nid_prefix) == 20, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_nid_prefix));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding1) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding2) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding3) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding3) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding3));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding4) == 30, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding4) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding4));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_netmask) == 31, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_netmask));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_netmask) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_netmask));
+
/* Checks for struct nodemap_id_rec */
LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
(long long)(int)sizeof(struct nodemap_id_rec));
for client in $clients; do
local client_ip=$(host_nids_address $client $NETTYPE)
local client_nid=$(h2nettype $client_ip)
+ [[ "$client_nid" =~ ":" ]] && client_nid+="/128"
do_facet mgs $LCTL nodemap_add c${i} || return 1
do_facet mgs $LCTL nodemap_add_range \
- --name c${i} --range $client_nid || return 1
+ --name c${i} --range $client_nid || {
+ do_facet mgs $LCTL nodemap_del c${i}
+ return 1
+ }
for map in ${FOPS_IDMAPS[i]}; do
do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
--idtype uid --idmap ${map} || return 1
client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
client_nid=$(h2nettype $client_ip)
+ [[ "$client_nid" =~ ":" ]] && client_nid+="/128"
do_facet mgs $LCTL nodemap_add c0
do_facet mgs $LCTL nodemap_add_range \
- --name c0 --range $client_nid
+ --name c0 --range $client_nid || {
+ do_facet mgs $LCTL nodemap_del c0
+ return 1
+ }
do_facet mgs $LCTL nodemap_modify --name c0 \
--property admin --value 1
do_facet mgs $LCTL nodemap_modify --name c0 \
*/
static int parse_nid_range(char *nodemap_range, char *nid_range, int range_len)
{
- char min_nid[LNET_NIDSTR_SIZE + 1];
- char max_nid[LNET_NIDSTR_SIZE + 1];
- struct list_head nidlist;
- int rc = 0;
+ char min_nid[LNET_NIDSTR_SIZE + 1];
+ char max_nid[LNET_NIDSTR_SIZE + 1];
+ struct list_head nidlist;
+ char *netmask = NULL;
+ int rc = 0;
+
+ netmask = strchr(nodemap_range, '/');
+ if (netmask) {
+ unsigned long mask;
+
+ /* FIXME !!! Only 128 netmask is supported. This means
+ * nodemap will only support one large NID.
+ */
+ mask = strtoul(++netmask, NULL, 10);
+ if (mask < 0)
+ return -errno;
+
+ if (mask != 128)
+ return -ERANGE;
+
+ strncpy(nid_range, nodemap_range, range_len);
+ return rc;
+ }
INIT_LIST_HEAD(&nidlist);
CHECK_MEMBER(nodemap_range_rec, nrr_padding2);
}
+static void check_nodemap_range2_rec(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(nodemap_range2_rec);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_nid_prefix);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_padding1);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_padding2);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_padding3);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_padding4);
+ CHECK_MEMBER(nodemap_range2_rec, nrr_netmask);
+}
+
static void check_nodemap_id_rec(void)
{
BLANK_LINE();
LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2) == 8, "found %lld\n",
(long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding2));
+ /* Checks for struct nodemap_range2_rec */
+ LASSERTF((int)sizeof(struct nodemap_range2_rec) == 32, "found %lld\n",
+ (long long)(int)sizeof(struct nodemap_range2_rec));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_nid_prefix) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_nid_prefix));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_nid_prefix) == 20, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_nid_prefix));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding1) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding1));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding1));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding2) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding2));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding2));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding3) == 28, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding3));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding3) == 2, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding3));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_padding4) == 30, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_padding4));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding4) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_padding4));
+ LASSERTF((int)offsetof(struct nodemap_range2_rec, nrr_netmask) == 31, "found %lld\n",
+ (long long)(int)offsetof(struct nodemap_range2_rec, nrr_netmask));
+ LASSERTF((int)sizeof(((struct nodemap_range2_rec *)0)->nrr_netmask) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct nodemap_range2_rec *)0)->nrr_netmask));
+
/* Checks for struct nodemap_id_rec */
LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
(long long)(int)sizeof(struct nodemap_id_rec));