Whamcloud - gitweb
LU-13307 nodemap: have nodemap_add_member support large NIDs 35/53135/12
authorJames Simmons <jsimmons@infradead.org>
Sun, 7 Jan 2024 15:13:38 +0000 (08:13 -0700)
committerOleg Drokin <green@whamcloud.com>
Sat, 20 Jan 2024 03:40:32 +0000 (03:40 +0000)
Currently when mounting lustre using IPv6 address fails with

Lustre: 27361:0:(nodemap_handler.c:395:nodemap_add_member())
  lustre-MDT0000: error adding to nodemap, no valid NIDs found
LustreError: 11-0: lustre-MDT0000-osp-MDT0003:
  operation mds_connect to node 0@lo failed: rc = -22

This was due to no nodemap being set so the ptlrpc layer was not
seeing any new peers. Adding minimal support to nodemap allows
mounting.

Change-Id: If9cfe88ec92afc3f14788f3f3ded8387a1b5d8c7
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53135
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
18 files changed:
lustre/include/lustre_nodemap.h
lustre/include/uapi/linux/lustre/lustre_disk.h
lustre/mdt/mdt_handler.c
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/ofd/ofd_obd.c
lustre/ptlrpc/gss/gss_svc_upcall.c
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_internal.h
lustre/ptlrpc/nodemap_lproc.c
lustre/ptlrpc/nodemap_member.c
lustre/ptlrpc/nodemap_range.c
lustre/ptlrpc/nodemap_storage.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanity-sec.sh
lustre/utils/obd.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 8ff20e6..26a550a 100644 (file)
@@ -127,12 +127,15 @@ struct nm_config_file {
 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);
@@ -160,12 +163,12 @@ __u32 nodemap_map_id(struct lu_nodemap *nodemap,
 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,
@@ -198,6 +201,9 @@ struct nodemap_config {
        /* 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.
         */
index e264f27..6d23d3d 100644 (file)
@@ -252,6 +252,7 @@ enum nodemap_idx_type {
        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 */
 };
 
@@ -302,6 +303,15 @@ struct nodemap_range_rec {
        __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;
@@ -330,6 +340,7 @@ struct nodemap_cluster_roles_rec {
 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;
index 1feb91a..1d33c99 100644 (file)
@@ -7087,11 +7087,9 @@ static int mdt_obd_connect(const struct lu_env *env,
        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) {
@@ -7135,11 +7133,9 @@ static int mdt_obd_reconnect(const struct lu_env *env,
        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);
index 2c1ed34..c5d68e1 100644 (file)
@@ -772,7 +772,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
 {
        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;
@@ -827,8 +827,11 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                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)));
@@ -842,7 +845,10 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                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)
@@ -856,7 +862,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                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);
 
index 41f08c6..f2db9dc 100644 (file)
@@ -5605,9 +5605,10 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
                    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;
 
@@ -5620,16 +5621,16 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
                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);
index e70b375..f935898 100644 (file)
@@ -309,11 +309,9 @@ static int ofd_obd_reconnect(const struct lu_env *env, struct obd_export *exp,
        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);
 
@@ -367,8 +365,8 @@ static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp,
        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 {
index 4074f22..441afa3 100644 (file)
@@ -802,7 +802,7 @@ int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
         */
        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. */
index 10fc259..403ff50 100644 (file)
@@ -257,30 +257,29 @@ struct lu_nodemap *nodemap_lookup(const char *name)
  * \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
@@ -307,7 +306,8 @@ static bool is_default_nodemap(const struct lu_nodemap *nodemap)
  * \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;
@@ -317,15 +317,32 @@ int nodemap_parse_range(const char *range_str, lnet_nid_t range[2])
 
        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;
 
@@ -380,20 +397,19 @@ EXPORT_SYMBOL(nodemap_parse_idmap);
  * \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);
@@ -802,21 +818,21 @@ EXPORT_SYMBOL(nodemap_map_acl);
  */
 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",
@@ -837,7 +853,7 @@ int nodemap_add_range_helper(struct nodemap_config *config,
 
        /* 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);
@@ -848,7 +864,8 @@ out:
        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;
@@ -863,7 +880,8 @@ int nodemap_add_range(const char *name, const lnet_nid_t nid[2])
        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:
@@ -880,7 +898,8 @@ EXPORT_SYMBOL(nodemap_add_range);
  * 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;
@@ -897,7 +916,7 @@ int nodemap_del_range(const char *name, const lnet_nid_t nid[2])
                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);
@@ -907,7 +926,7 @@ int nodemap_del_range(const char *name, const lnet_nid_t nid[2])
                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);
 
@@ -1660,7 +1679,7 @@ int nodemap_del(const char *nodemap_name)
                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);
 
@@ -1749,6 +1768,7 @@ struct nodemap_config *nodemap_config_alloc(void)
 
        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;
@@ -1782,7 +1802,7 @@ void nodemap_config_dealloc(struct nodemap_config *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);
 
@@ -1940,9 +1960,9 @@ void nm_member_revoke_all(void)
  * \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);
@@ -1973,10 +1993,10 @@ EXPORT_SYMBOL(nodemap_test_nid);
  * \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);
index b2890a6..009f72e 100644 (file)
@@ -58,10 +58,14 @@ struct lu_nid_range {
        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;
 };
 
@@ -98,23 +102,20 @@ void nodemap_procfs_exit(void);
 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,
@@ -130,7 +131,7 @@ struct lu_idmap *idmap_search(struct lu_nodemap *nodemap,
 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);
@@ -141,8 +142,8 @@ int nodemap_add_idmap_helper(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);
@@ -178,8 +179,7 @@ int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
 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 */
index 824fa95..4f151fc 100644 (file)
@@ -150,8 +150,8 @@ static int nodemap_ranges_show(struct seq_file *m, void *data)
                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);
        }
index e049799..2227e66 100644 (file)
@@ -176,12 +176,12 @@ void nm_member_reclassify_nodemap(struct lu_nodemap *nodemap)
 
        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;
index ca08d11..35ed82f 100644 (file)
@@ -40,8 +40,8 @@
  * 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)
@@ -54,16 +54,31 @@ INTERVAL_TREE_DEFINE(struct lu_nid_range, rn_rb, lnet_nid_t, rn_subtree_last,
  * \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",
@@ -72,6 +87,7 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
        }
 
        /* 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;
@@ -82,8 +98,9 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
        }
        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);
 
@@ -97,17 +114,44 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
  * \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;
 }
 
@@ -131,16 +175,22 @@ void range_destroy(struct lu_nid_range *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;
 }
 
@@ -150,11 +200,18 @@ int range_insert(struct nodemap_range_tree *nm_range_tree,
  *
  * \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);
 }
 
@@ -163,9 +220,32 @@ void range_delete(struct nodemap_range_tree *nm_range_tree,
  *
  * \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;
 }
index ba95da5..048c4a2 100644 (file)
@@ -140,19 +140,38 @@ static void nodemap_idmap_rec_init(union nodemap_rec *nr, u32 id_fs)
        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)
@@ -463,7 +482,6 @@ int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
        int                      rc2 = 0;
 
        ENTRY;
-
        if (nodemap_mgs_ncf == NULL) {
                CERROR("cannot add nodemap config to non-existing MGS.\n");
                return -EINVAL;
@@ -513,7 +531,11 @@ int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
 
        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)
@@ -566,15 +588,14 @@ int nodemap_idx_cluster_roles_del(const struct lu_nodemap *nodemap)
        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;
@@ -584,10 +605,15 @@ int nodemap_idx_range_add(const struct lu_nid_range *range,
        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);
@@ -609,8 +635,9 @@ int nodemap_idx_range_del(const struct lu_nid_range *range)
        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);
 
@@ -824,9 +851,9 @@ 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;
+       struct lnet_nid nid[2];
        int subtype;
        u32 nodemap_id;
-       lnet_nid_t nid[2];
        u32 map[2];
        int rc;
 
@@ -843,8 +870,9 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
               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;
 
@@ -897,11 +925,19 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
                }
                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;
@@ -1165,13 +1201,17 @@ nodemap_save_config_cache(const struct lu_env *env,
                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;
index ca536d3..2a9cb20 100644 (file)
@@ -6131,6 +6131,34 @@ void lustre_assert_wire_constants(void)
        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));
index 0d19845..4f1b8ba 100755 (executable)
@@ -1118,9 +1118,13 @@ create_fops_nodemaps() {
        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
@@ -5226,9 +5230,13 @@ setup_61() {
 
        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 \
index 9a39c6a..ebf1cee 100644 (file)
@@ -4319,10 +4319,29 @@ int jt_nodemap_test_id(int argc, char **argv)
  */
 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);
 
index 22cb0c2..2fde5cf 100644 (file)
@@ -2909,6 +2909,18 @@ static void check_nodemap_range_rec(void)
        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();
index 5c85588..0cc6acc 100644 (file)
@@ -6192,6 +6192,34 @@ void lustre_assert_wire_constants(void)
        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));