Whamcloud - gitweb
LU-5092 nodemap: save id maps to targets in new index file 13/11813/31
authorKit Westneat <kit.westneat@gmail.com>
Sat, 19 Sep 2015 13:20:04 +0000 (09:20 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 20 Feb 2016 05:40:20 +0000 (05:40 +0000)
Creates a new nodemap index file on registered targets and modifies
it on changes to the nodemaps. On init, the nodemap/idmaps are
loaded into memory from the index file. Currently only the MGS
registers itself.

Signed-off-by: Kit Westneat <kit.westneat@gmail.com>
Change-Id: Ie2b84e25ecc02d5d3daebf268d2f72ffaf142758
Reviewed-on: http://review.whamcloud.com/11813
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
15 files changed:
lustre/include/dt_object.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre_nodemap.h
lustre/include/obd_target.h
lustre/mgs/mgs_fs.c
lustre/obdclass/dt_object.c
lustre/ptlrpc/Makefile.in
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_internal.h
lustre/ptlrpc/nodemap_range.c
lustre/ptlrpc/nodemap_storage.c [new file with mode: 0644]
lustre/ptlrpc/wiretest.c
lustre/tests/sanity-sec.sh
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 7c5aae7..a37e6c1 100644 (file)
@@ -358,6 +358,9 @@ extern const struct dt_index_features dt_quota_glb_features;
 /* index features supported by the quota slave indexes */
 extern const struct dt_index_features dt_quota_slv_features;
 
+/* index features supported by the nodemap index */
+extern const struct dt_index_features dt_nodemap_features;
+
 /**
  * This is a general purpose dt allocation hint.
  * It now contains the parent object.
index ed1c0d3..24077ae 100644 (file)
@@ -4088,6 +4088,49 @@ struct llog_update_record {
        */
 };
 
+/* nodemap records, uses 32 byte record length */
+#define LUSTRE_NODEMAP_NAME_LENGTH 16
+struct nodemap_cluster_rec {
+       char    ncr_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+       __u8    ncr_flags;
+       __u16   ncr_padding1;
+       __u32   ncr_padding2;
+       __u32   ncr_squash_uid;
+       __u32   ncr_squash_gid;
+};
+
+/* lnet_nid_t is 8 bytes */
+struct nodemap_range_rec {
+       lnet_nid_t      nrr_start_nid;
+       lnet_nid_t      nrr_end_nid;
+       __u64           nrr_padding1;
+       __u64           nrr_padding2;
+};
+
+struct nodemap_id_rec {
+       __u32   nir_id_fs;
+       __u32   nir_padding1;
+       __u64   nir_padding2;
+       __u64   nir_padding3;
+       __u64   nir_padding4;
+};
+
+struct nodemap_global_rec {
+       __u8    ngr_is_active;
+       __u8    ngr_padding1;
+       __u16   ngr_padding2;
+       __u32   ngr_padding3;
+       __u64   ngr_padding4;
+       __u64   ngr_padding5;
+       __u64   ngr_padding6;
+};
+
+union nodemap_rec {
+       struct nodemap_cluster_rec ncr;
+       struct nodemap_range_rec nrr;
+       struct nodemap_id_rec nir;
+       struct nodemap_global_rec ngr;
+};
 
 #endif
 /** @} lustreidl */
index 375154d..e5b26f7 100644 (file)
@@ -27,8 +27,9 @@
 #ifndef _LUSTRE_NODEMAP_H
 #define _LUSTRE_NODEMAP_H
 
+#include <lustre/lustre_idl.h>
+
 #define LUSTRE_NODEMAP_NAME "nodemap"
-#define LUSTRE_NODEMAP_NAME_LENGTH 16
 
 #define LUSTRE_NODEMAP_DEFAULT_ID 0
 
@@ -63,10 +64,7 @@ struct lu_nodemap {
        char                     nm_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
        /* flags to govern nodemap behavior */
        bool                     nmf_trust_client_ids:1,
-                                nmf_allow_root_access:1,
-                                nmf_block_lookups:1,
-                                nmf_hmac_required:1,
-                                nmf_encryption_required:1;
+                                nmf_allow_root_access:1;
        /* unique ID set by MGS */
        unsigned int             nm_id;
        /* nodemap ref counter */
@@ -94,10 +92,19 @@ struct lu_nodemap {
        struct hlist_node        nm_hash;
        struct nodemap_pde      *nm_pde_data;
 
-       /* used when unloading nodemaps */
+       /* used when loading/unloading nodemaps */
        struct list_head         nm_list;
 };
 
+/* Store handles to local MGC storage to save config locally. In future
+ * versions of nodemap, mgc will receive the config directly and so this might
+ * not be needed.
+ */
+struct nm_config_file {
+       struct dt_object        *ncf_obj;
+       struct list_head        ncf_list;
+};
+
 void nodemap_activate(const bool value);
 int nodemap_add(const char *nodemap_name);
 int nodemap_del(const char *nodemap_name);
@@ -124,4 +131,8 @@ ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size,
 void nodemap_test_nid(lnet_nid_t nid, char *name_buf, size_t name_len);
 __u32 nodemap_test_id(lnet_nid_t nid, enum nodemap_id_type idtype,
                      __u32 client_id);
+struct nm_config_file *nm_config_file_register(const struct lu_env *env,
+                                              struct dt_object *obj);
+void nm_config_file_deregister(const struct lu_env *env,
+                              struct nm_config_file *ncf);
 #endif /* _LUSTRE_NODEMAP_H */
index ed8ec98..fb2cb6e 100644 (file)
@@ -46,6 +46,7 @@ struct obd_device_target {
        struct lu_target       *obt_lut;
        __u64                   obt_mount_count;
        struct obd_job_stats    obt_jobstats;
+       struct nm_config_file   *obt_nodemap_config_file;
 };
 
 #define OBJ_SUBDIR_COUNT 32 /* set to zero for no subdirs */
index 064a7f1..a3ce58f 100644 (file)
@@ -119,6 +119,8 @@ int mgs_fs_setup(const struct lu_env *env, struct mgs_device *mgs)
        struct dt_object        *o;
        struct lu_fid            rfid;
        struct dt_object        *root;
+       struct dt_object        *nm_config_file_obj;
+       struct nm_config_file   *nm_config_file;
        int                      rc;
 
        ENTRY;
@@ -161,17 +163,52 @@ int mgs_fs_setup(const struct lu_env *env, struct mgs_device *mgs)
 
        mgs->mgs_configs_dir = o;
 
+       nm_config_file_obj = local_index_find_or_create(env, mgs->mgs_los,
+                                                       mgs->mgs_configs_dir,
+                                                       LUSTRE_NODEMAP_NAME,
+                                                       S_IFREG | S_IRUGO |
+                                                                 S_IWUSR,
+                                                       &dt_nodemap_features);
+       if (IS_ERR(nm_config_file_obj))
+               GOTO(out_configs, rc = PTR_ERR(nm_config_file_obj));
+
+       if (nm_config_file_obj->do_index_ops == NULL) {
+               rc = nm_config_file_obj->do_ops->do_index_try(env,
+                                                       nm_config_file_obj,
+                                                       &dt_nodemap_features);
+               if (rc < 0) {
+                       lu_object_put(env, &nm_config_file_obj->do_lu);
+                       GOTO(out_configs, rc);
+               }
+       }
+       nm_config_file = nm_config_file_register(env, nm_config_file_obj);
+       if (IS_ERR(nm_config_file)) {
+               lu_object_put(env, &nm_config_file_obj->do_lu);
+               CERROR("%s: error loading nodemap config file, file must be "
+                      "removed via ldiskfs: rc = %ld\n",
+                      mgs->mgs_obd->obd_name, PTR_ERR(nm_config_file));
+               GOTO(out_configs, rc = PTR_ERR(nm_config_file));
+       }
+       mgs->mgs_obd->u.obt.obt_nodemap_config_file = nm_config_file;
+
        /* create directory to store nid table versions */
        o = local_file_find_or_create(env, mgs->mgs_los, root, MGS_NIDTBL_DIR,
                                      S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
-       if (IS_ERR(o)) {
-               lu_object_put(env, &mgs->mgs_configs_dir->do_lu);
-               mgs->mgs_configs_dir = NULL;
-               GOTO(out_root, rc = PTR_ERR(o));
-       }
+       if (IS_ERR(o))
+               GOTO(out_nm, rc = PTR_ERR(o));
 
        mgs->mgs_nidtbl_dir = o;
 
+out_nm:
+       if (rc < 0) {
+               nm_config_file_deregister(env, nm_config_file);
+               mgs->mgs_obd->u.obt.obt_nodemap_config_file = NULL;
+       }
+out_configs:
+       if (rc < 0) {
+               lu_object_put(env, &mgs->mgs_configs_dir->do_lu);
+               mgs->mgs_configs_dir = NULL;
+       }
 out_root:
        lu_object_put(env, &root->do_lu);
 out_los:
@@ -195,6 +232,12 @@ int mgs_fs_cleanup(const struct lu_env *env, struct mgs_device *mgs)
                lu_object_put(env, &mgs->mgs_nidtbl_dir->do_lu);
                mgs->mgs_nidtbl_dir = NULL;
        }
+       if (mgs->mgs_obd->u.obt.obt_nodemap_config_file != NULL) {
+               nm_config_file_deregister(env,
+                               mgs->mgs_obd->u.obt.obt_nodemap_config_file);
+               mgs->mgs_obd->u.obt.obt_nodemap_config_file = NULL;
+       }
+
        if (mgs->mgs_los) {
                local_oid_storage_fini(env, mgs->mgs_los);
                mgs->mgs_los = NULL;
index 65649be..2c13a3c 100644 (file)
@@ -48,7 +48,7 @@
 #include <libcfs/list.h>
 /* fid_be_to_cpu() */
 #include <lustre_fid.h>
-
+#include <lustre_nodemap.h>
 #include <lustre_quota.h>
 
 /* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */
@@ -636,6 +636,17 @@ const struct dt_index_features dt_quota_slv_features = {
 };
 EXPORT_SYMBOL(dt_quota_slv_features);
 
+/* nodemap files, nodemap_rec size asserted in nodemap_storage.c */
+const struct dt_index_features dt_nodemap_features = {
+       .dif_flags              = DT_IND_UPDATE,
+       .dif_keysize_min        = sizeof(__u64), /* 64-bit nodemap/record id */
+       .dif_keysize_max        = sizeof(__u64), /* 64-bit nodemap/record id */
+       .dif_recsize_min        = sizeof(union nodemap_rec), /* 32 bytes */
+       .dif_recsize_max        = sizeof(union nodemap_rec), /* 32 bytes */
+       .dif_ptrsize            = 4
+};
+EXPORT_SYMBOL(dt_nodemap_features);
+
 /* helper function returning what dt_index_features structure should be used
  * based on the FID sequence. This is used by OBD_IDX_READ RPC */
 static inline const struct dt_index_features *dt_index_feat_select(__u64 seq,
index 7521a98..488f757 100644 (file)
@@ -26,6 +26,7 @@ ptlrpc_objs += nrs_tbf.o errno.o
 
 nodemap_objs := nodemap_handler.o nodemap_lproc.o nodemap_range.o
 nodemap_objs += nodemap_idmap.o nodemap_rbtree.o nodemap_member.o
+nodemap_objs += nodemap_storage.o
 
 ptlrpc-objs := $(ldlm_objs) $(ptlrpc_objs)
 @SERVER_TRUE@ptlrpc-objs += $(target_objs) $(nodemap_objs)
index 5bf4932..ec7dda2 100644 (file)
@@ -61,6 +61,8 @@ struct nodemap_config *active_config;
  */
 static void nodemap_destroy(struct lu_nodemap *nodemap)
 {
+       ENTRY;
+
        if (nodemap->nm_pde_data != NULL)
                lprocfs_nodemap_remove(nodemap->nm_pde_data);
 
@@ -80,6 +82,8 @@ static void nodemap_destroy(struct lu_nodemap *nodemap)
        nm_member_delete_list(nodemap);
 
        OBD_FREE_PTR(nodemap);
+
+       EXIT;
 }
 
 /**
@@ -389,9 +393,9 @@ EXPORT_SYMBOL(nodemap_del_member);
  *
  * \retval     0 on success
  */
-static int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
-                                   enum nodemap_id_type id_type,
-                                   const __u32 map[2])
+int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
+                            enum nodemap_id_type id_type,
+                            const __u32 map[2])
 {
        struct lu_idmap         *idmap;
        int                     rc = 0;
@@ -408,6 +412,7 @@ static int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
 out:
        return rc;
 }
+
 int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
                      const __u32 map[2])
 {
@@ -421,13 +426,14 @@ int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
                GOTO(out, rc = PTR_ERR(nodemap));
        }
 
-       if (is_default_nodemap(nodemap))
+       if (is_default_nodemap(nodemap)) {
                rc = -EINVAL;
-       else
+       } else {
                rc = nodemap_add_idmap_helper(nodemap, id_type, map);
-
+               if (rc == 0)
+                       rc = nodemap_idx_idmap_add(nodemap, id_type, map);
+       }
        mutex_unlock(&active_config_lock);
-
        nodemap_putref(nodemap);
 
 out:
@@ -466,10 +472,12 @@ int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
        write_lock(&nodemap->nm_idmap_lock);
        idmap = idmap_search(nodemap, NODEMAP_CLIENT_TO_FS, id_type,
                             map[0]);
-       if (idmap == NULL)
+       if (idmap == NULL) {
                rc = -EINVAL;
-       else
+       } else {
                idmap_delete(id_type, idmap, nodemap);
+               rc = nodemap_idx_idmap_del(nodemap, id_type, map);
+       }
        write_unlock(&nodemap->nm_idmap_lock);
 
 out_putref:
@@ -623,23 +631,27 @@ ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size,
 EXPORT_SYMBOL(nodemap_map_acl);
 
 /*
- * add nid range to nodemap
+ * Add nid range to given nodemap
+ *
+ * \param      config          nodemap config to work on
  * \param      nodemap         nodemap to add range to
- * \param      range_st        string containing nid range
- * \retval     0 on success
+ * \param      nid             nid range to add
+ * \param      range_id        should be 0 unless loading from disk
+ * \retval     0               success
+ * \retval     -ENOMEM
  *
- * add an range to the global range tree and attached the
- * range to the named nodemap.
  */
-static int nodemap_add_range_helper(struct nodemap_config *config,
-                                   struct lu_nodemap *nodemap,
-                                   const lnet_nid_t nid[2])
+int nodemap_add_range_helper(struct nodemap_config *config,
+                            struct lu_nodemap *nodemap,
+                            const lnet_nid_t nid[2],
+                            unsigned int range_id)
 {
        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 = range_create(&config->nmc_range_tree, nid[0], nid[1],
+                            nodemap, range_id);
        if (range == NULL) {
                up_write(&config->nmc_range_tree_lock);
                GOTO(out, rc = -ENOMEM);
@@ -659,6 +671,10 @@ static int nodemap_add_range_helper(struct nodemap_config *config,
        nm_member_reclassify_nodemap(config->nmc_default_nodemap);
        up_write(&config->nmc_range_tree_lock);
 
+       /* if range_id is non-zero, we are loading from disk */
+       if (range_id == 0)
+               rc = nodemap_idx_range_add(range, nid);
+
        nm_member_revoke_locks(config->nmc_default_nodemap);
        nm_member_revoke_locks(nodemap);
 
@@ -680,9 +696,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);
+               rc = nodemap_add_range_helper(active_config, nodemap, nid, 0);
        mutex_unlock(&active_config_lock);
-
        nodemap_putref(nodemap);
 out:
        return rc;
@@ -720,6 +735,7 @@ int nodemap_del_range(const char *name, const lnet_nid_t nid[2])
                up_write(&active_config->nmc_range_tree_lock);
                GOTO(out_putref, rc = -EINVAL);
        }
+       rc = nodemap_idx_range_del(range);
        range_delete(&active_config->nmc_range_tree, range);
        nm_member_reclassify_nodemap(nodemap);
        up_write(&active_config->nmc_range_tree_lock);
@@ -758,9 +774,12 @@ struct lu_nodemap *nodemap_create(const char *name,
                                  bool is_default)
 {
        struct lu_nodemap       *nodemap = NULL;
+       struct lu_nodemap       *default_nodemap;
        struct cfs_hash         *hash = config->nmc_nodemap_hash;
        int                      rc = 0;
 
+       default_nodemap = config->nmc_default_nodemap;
+
        if (!nodemap_name_is_valid(name))
                GOTO(out, rc = -EINVAL);
 
@@ -802,26 +821,26 @@ struct lu_nodemap *nodemap_create(const char *name,
 
        if (is_default) {
                nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
+               config->nmc_default_nodemap = nodemap;
+       } else {
+               config->nmc_nodemap_highest_id++;
+               nodemap->nm_id = config->nmc_nodemap_highest_id;
+       }
+
+       if (is_default || default_nodemap == NULL) {
                nodemap->nmf_trust_client_ids = 0;
                nodemap->nmf_allow_root_access = 0;
-               nodemap->nmf_block_lookups = 0;
 
                nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
                nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
-
-               config->nmc_default_nodemap = nodemap;
+               if (!is_default)
+                       CWARN("adding nodemap '%s' to config without"
+                             " default nodemap\n", nodemap->nm_name);
        } else {
-               struct lu_nodemap *default_nodemap =
-                                       config->nmc_default_nodemap;
-
-               config->nmc_nodemap_highest_id++;
-               nodemap->nm_id = config->nmc_nodemap_highest_id;
                nodemap->nmf_trust_client_ids =
                                default_nodemap->nmf_trust_client_ids;
                nodemap->nmf_allow_root_access =
                                default_nodemap->nmf_allow_root_access;
-               nodemap->nmf_block_lookups =
-                               default_nodemap->nmf_block_lookups;
 
                nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
                nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
@@ -854,6 +873,7 @@ int nodemap_set_allow_root(const char *name, bool allow_root)
                GOTO(out, rc = PTR_ERR(nodemap));
 
        nodemap->nmf_allow_root_access = allow_root;
+       rc = nodemap_idx_nodemap_update(nodemap);
 
        nm_member_revoke_locks(nodemap);
        nodemap_putref(nodemap);
@@ -883,6 +903,7 @@ int nodemap_set_trust_client_ids(const char *name, bool trust_client_ids)
                GOTO(out, rc = PTR_ERR(nodemap));
 
        nodemap->nmf_trust_client_ids = trust_client_ids;
+       rc = nodemap_idx_nodemap_update(nodemap);
 
        nm_member_revoke_locks(nodemap);
        nodemap_putref(nodemap);
@@ -915,6 +936,7 @@ int nodemap_set_squash_uid(const char *name, uid_t uid)
                GOTO(out, rc = PTR_ERR(nodemap));
 
        nodemap->nm_squash_uid = uid;
+       rc = nodemap_idx_nodemap_update(nodemap);
 
        nm_member_revoke_locks(nodemap);
        nodemap_putref(nodemap);
@@ -947,6 +969,7 @@ int nodemap_set_squash_gid(const char *name, gid_t gid)
                GOTO(out, rc = PTR_ERR(nodemap));
 
        nodemap->nm_squash_gid = gid;
+       rc = nodemap_idx_nodemap_update(nodemap);
 
        nm_member_revoke_locks(nodemap);
        nodemap_putref(nodemap);
@@ -988,7 +1011,10 @@ int nodemap_add(const char *nodemap_name)
                return PTR_ERR(nodemap);
        }
 
-       rc = lprocfs_nodemap_register(nodemap, 0);
+       rc = nodemap_idx_nodemap_add(nodemap);
+       if (rc == 0)
+               rc = lprocfs_nodemap_register(nodemap, 0);
+
        mutex_unlock(&active_config_lock);
        nodemap_putref(nodemap);
 
@@ -1010,6 +1036,7 @@ int nodemap_del(const char *nodemap_name)
        struct lu_nid_range     *range;
        struct lu_nid_range     *range_temp;
        int                      rc = 0;
+       int                      rc2 = 0;
 
        if (strcmp(nodemap_name, DEFAULT_NODEMAP) == 0)
                RETURN(-EINVAL);
@@ -1025,10 +1052,19 @@ int nodemap_del(const char *nodemap_name)
        /* erase nodemap from active ranges to prevent client assignment */
        down_write(&active_config->nmc_range_tree_lock);
        list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
-                                rn_list)
+                                rn_list) {
+               rc2 = nodemap_idx_range_del(range);
+               if (rc2 < 0)
+                       rc = rc2;
+
                range_delete(&active_config->nmc_range_tree, range);
+       }
        up_write(&active_config->nmc_range_tree_lock);
 
+       rc2 = nodemap_idx_nodemap_del(nodemap);
+       if (rc2 < 0)
+               rc = rc2;
+
        /*
         * remove procfs here in case nodemap_create called with same name
         * before nodemap_destroy is run.
@@ -1056,6 +1092,7 @@ void nodemap_activate(const bool value)
 
        /* copy active value to global to avoid locking in map functions */
        nodemap_active = value;
+       nodemap_idx_nodemap_activate(value);
        mutex_unlock(&active_config_lock);
        nm_member_revoke_all();
 }
index 86c55b0..991564f 100644 (file)
@@ -33,7 +33,7 @@
 #include <lustre_nodemap.h>
 #include <interval_tree.h>
 
-#define MODULE_STRING "nodemap"
+#define DEFAULT_NODEMAP "default"
 
 /* Default nobody uid and gid values */
 
@@ -100,6 +100,38 @@ struct nodemap_config {
        struct cfs_hash *nmc_nodemap_hash;
 };
 
+/* first 4 bits of the nodemap_id is the index type */
+struct nodemap_key {
+       __u32 nk_nodemap_id;
+       union {
+               __u32 nk_range_id;
+               __u32 nk_id_client;
+               __u32 nk_unused;
+       };
+};
+
+enum nodemap_idx_type {
+       NODEMAP_EMPTY_IDX = 0,          /* index created with blank record */
+       NODEMAP_CLUSTER_IDX = 1,        /* a nodemap cluster of nodes */
+       NODEMAP_RANGE_IDX = 2,          /* nid range assigned to a nm cluster */
+       NODEMAP_UIDMAP_IDX = 3,         /* uid map assigned to a nm cluster */
+       NODEMAP_GIDMAP_IDX = 4,         /* gid map assigned to a nm cluster */
+       NODEMAP_GLOBAL_IDX = 15,        /* stores nodemap activation status */
+};
+
+#define NM_TYPE_MASK 0x0FFFFFFF
+#define NM_TYPE_SHIFT 28
+
+static inline enum nodemap_idx_type nm_idx_get_type(unsigned int id)
+{
+       return id >> NM_TYPE_SHIFT;
+}
+
+static inline __u32 nm_idx_set_type(unsigned int id, enum nodemap_idx_type t)
+{
+       return (id & NM_TYPE_MASK) | (t << NM_TYPE_SHIFT);
+}
+
 struct nodemap_config *nodemap_config_alloc(void);
 void nodemap_config_dealloc(struct nodemap_config *config);
 void nodemap_config_set_active(struct nodemap_config *config);
@@ -118,7 +150,8 @@ 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_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);
@@ -149,6 +182,14 @@ void nm_member_reclassify_nodemap(struct lu_nodemap *nodemap);
 void nm_member_revoke_locks(struct lu_nodemap *nodemap);
 void nm_member_revoke_all(void);
 
+int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
+                            enum nodemap_id_type id_type,
+                            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);
+
 struct rb_node *nm_rb_next_postorder(const struct rb_node *node);
 struct rb_node *nm_rb_first_postorder(const struct rb_root *root);
 void nodemap_putref(struct lu_nodemap *nodemap);
@@ -166,4 +207,18 @@ void nodemap_putref(struct lu_nodemap *nodemap);
                n = (pos && nm_rb_next_postorder(&pos->field)) ?        \
                rb_entry(nm_rb_next_postorder(&pos->field),             \
                typeof(*pos), field) : NULL)
+
+int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap);
+int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap);
+int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap);
+int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
+                         enum nodemap_id_type id_type,
+                         const __u32 map[2]);
+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_del(const struct lu_nid_range *range);
+int nodemap_idx_nodemap_activate(bool value);
 #endif  /* _NODEMAP_INTERNAL_H */
index e8b5a24..56da8ea 100644 (file)
@@ -71,7 +71,7 @@ static enum interval_iter range_cb(struct interval_node *n, void *data)
  */
 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_nodemap *nodemap, unsigned range_id)
 {
        struct lu_nid_range *range;
 
@@ -86,8 +86,15 @@ struct lu_nid_range *range_create(struct nodemap_range_tree *nm_range_tree,
                return NULL;
        }
 
-       nm_range_tree->nmrt_range_highest_id++;
-       range->rn_id = nm_range_tree->nmrt_range_highest_id;
+       /* if we are loading from save, use on disk id num */
+       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_id = range_id;
+       } else {
+               nm_range_tree->nmrt_range_highest_id++;
+               range->rn_id = nm_range_tree->nmrt_range_highest_id;
+       }
        range->rn_nodemap = nodemap;
        interval_set(&range->rn_node, start_nid, end_nid);
        INIT_LIST_HEAD(&range->rn_list);
diff --git a/lustre/ptlrpc/nodemap_storage.c b/lustre/ptlrpc/nodemap_storage.c
new file mode 100644 (file)
index 0000000..dc956a8
--- /dev/null
@@ -0,0 +1,796 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (C) 2015, Trustees of Indiana University
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ * Author: Kit Westneat <cwestnea@iu.edu>
+ *
+ * Implements the storage functionality for the nodemap configuration. Functions
+ * in this file prepare, store, and load nodemap configuration data. Targets
+ * using nodemap services should register a configuration file object. Nodemap
+ * configuration changes that need to persist should call the appropriate
+ * storage function for the data being modified.
+ *
+ * There are several index types as defined in enum nodemap_idx_type:
+ *     NODEMAP_CLUSTER_IDX     stores the data found on the lu_nodemap struct,
+ *                             like root squash and config flags, as well as
+ *                             the name.
+ *     NODEMAP_RANGE_IDX       stores NID range information for a nodemap
+ *     NODEMAP_UIDMAP_IDX      stores a fs/client UID mapping pair
+ *     NODEMAP_GIDMAP_IDX      stores a fs/client GID mapping pair
+ *     NODEMAP_GLOBAL_IDX      stores whether or not nodemaps are active
+ */
+
+#include <libcfs/libcfs.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <lnet/types.h>
+#include <lustre/lustre_idl.h>
+#include <dt_object.h>
+#include <lu_object.h>
+#include <lustre_net.h>
+#include <lustre_nodemap.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include "nodemap_internal.h"
+
+/* list of registered nodemap index files */
+static LIST_HEAD(ncf_list_head);
+static DEFINE_MUTEX(ncf_list_lock);
+
+/* lu_nodemap flags */
+enum nm_flag_shifts {
+       NM_FL_ALLOW_ROOT_ACCESS = 0x1,
+       NM_FL_TRUST_CLIENT_IDS = 0x2,
+};
+
+static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id)
+{
+       nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
+                                                       NODEMAP_CLUSTER_IDX));
+       nk->nk_unused = 0;
+}
+
+static void nodemap_cluster_rec_init(union nodemap_rec *nr,
+                                    const struct lu_nodemap *nodemap)
+{
+       CLASSERT(sizeof(nr->ncr.ncr_name) == sizeof(nodemap->nm_name));
+
+       strncpy(nr->ncr.ncr_name, nodemap->nm_name, sizeof(nodemap->nm_name));
+       nr->ncr.ncr_squash_uid = cpu_to_le32(nodemap->nm_squash_uid);
+       nr->ncr.ncr_squash_gid = cpu_to_le32(nodemap->nm_squash_gid);
+       nr->ncr.ncr_flags = cpu_to_le32(
+               (nodemap->nmf_trust_client_ids ? NM_FL_TRUST_CLIENT_IDS : 0) |
+               (nodemap->nmf_allow_root_access ? NM_FL_ALLOW_ROOT_ACCESS : 0));
+}
+
+static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
+                                  enum nodemap_id_type id_type,
+                                  u32 id_client)
+{
+       enum nodemap_idx_type idx_type;
+
+       if (id_type == NODEMAP_UID)
+               idx_type = NODEMAP_UIDMAP_IDX;
+       else
+               idx_type = NODEMAP_GIDMAP_IDX;
+
+       nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id, idx_type));
+       nk->nk_id_client = cpu_to_le32(id_client);
+}
+
+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)
+{
+       nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(nm_id,
+                                                       NODEMAP_RANGE_IDX));
+       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])
+{
+       nr->nrr.nrr_start_nid = cpu_to_le64(nid[0]);
+       nr->nrr.nrr_end_nid = cpu_to_le64(nid[1]);
+}
+
+static void nodemap_global_key_init(struct nodemap_key *nk)
+{
+       nk->nk_nodemap_id = cpu_to_le32(nm_idx_set_type(0, NODEMAP_GLOBAL_IDX));
+       nk->nk_unused = 0;
+}
+
+static void nodemap_global_rec_init(union nodemap_rec *nr, bool active)
+{
+       nr->ngr.ngr_is_active = active;
+}
+
+/* should be called with dt_write lock */
+static void nodemap_inc_version(const struct lu_env *env,
+                               struct dt_object *nodemap_idx,
+                               struct thandle *th)
+{
+       u64 ver = dt_version_get(env, nodemap_idx);
+       dt_version_set(env, nodemap_idx, ver + 1, th);
+}
+
+static int nodemap_idx_insert(struct lu_env *env,
+                             struct dt_object *idx,
+                             const struct nodemap_key *nk,
+                             const union nodemap_rec *nr)
+{
+       struct thandle          *th;
+       struct dt_device        *dev = lu2dt_dev(idx->do_lu.lo_dev);
+       int                      rc;
+
+       CLASSERT(sizeof(union nodemap_rec) == 32);
+
+       th = dt_trans_create(env, dev);
+
+       if (IS_ERR(th))
+               GOTO(out, rc = PTR_ERR(th));
+
+       rc = dt_declare_insert(env, idx,
+                              (const struct dt_rec *)nr,
+                              (const struct dt_key *)nk, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_declare_version_set(env, idx, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_trans_start_local(env, dev, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       dt_write_lock(env, idx, 0);
+
+       rc = dt_insert(env, idx, (const struct dt_rec *)nr,
+                      (const struct dt_key *)nk, th, 1);
+
+       nodemap_inc_version(env, idx, th);
+       dt_write_unlock(env, idx);
+out:
+       dt_trans_stop(env, dev, th);
+
+       return rc;
+}
+
+static int nodemap_idx_update(struct lu_env *env,
+                             struct dt_object *idx,
+                             const struct nodemap_key *nk,
+                             const union nodemap_rec *nr)
+{
+       struct thandle          *th;
+       struct dt_device        *dev = lu2dt_dev(idx->do_lu.lo_dev);
+       int                      rc = 0;
+
+       th = dt_trans_create(env, dev);
+
+       if (IS_ERR(th))
+               GOTO(out, rc = PTR_ERR(th));
+
+       rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_declare_insert(env, idx, (const struct dt_rec *)nr,
+                              (const struct dt_key *)nk, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_declare_version_set(env, idx, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_trans_start_local(env, dev, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       dt_write_lock(env, idx, 0);
+
+       rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
+       if (rc != 0)
+               GOTO(out_lock, rc);
+
+       rc = dt_insert(env, idx, (const struct dt_rec *)nr,
+                      (const struct dt_key *)nk, th, 1);
+       if (rc != 0)
+               GOTO(out_lock, rc);
+
+       nodemap_inc_version(env, idx, th);
+out_lock:
+       dt_write_unlock(env, idx);
+out:
+       dt_trans_stop(env, dev, th);
+
+       return rc;
+}
+
+static int nodemap_idx_delete(struct lu_env *env,
+                             struct dt_object *idx,
+                             const struct nodemap_key *nk,
+                             const union nodemap_rec *unused)
+{
+       struct thandle          *th;
+       struct dt_device        *dev = lu2dt_dev(idx->do_lu.lo_dev);
+       int                      rc = 0;
+
+       th = dt_trans_create(env, dev);
+
+       if (IS_ERR(th))
+               GOTO(out, rc = PTR_ERR(th));
+
+       rc = dt_declare_delete(env, idx, (const struct dt_key *)nk, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_declare_version_set(env, idx, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = dt_trans_start_local(env, dev, th);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       dt_write_lock(env, idx, 0);
+
+       rc = dt_delete(env, idx, (const struct dt_key *)nk, th);
+
+       nodemap_inc_version(env, idx, th);
+
+       dt_write_unlock(env, idx);
+out:
+       dt_trans_stop(env, dev, th);
+
+       return rc;
+}
+
+typedef int (*nm_idx_cb_t)(struct lu_env *env,
+                          struct dt_object *idx,
+                          const struct nodemap_key *nk,
+                          const union nodemap_rec *nr);
+
+/**
+ * Iterates through all the registered nodemap_config_files and calls the
+ * given callback with the ncf as a parameter, as well as the given key and rec.
+ *
+ * \param      cb_f            callback function to call
+ * \param      nk              key of the record to act upon
+ * \param      nr              record to act upon, NULL for the delete action
+ */
+static int nodemap_idx_action(nm_idx_cb_t cb_f, struct nodemap_key *nk,
+                             union nodemap_rec *nr)
+{
+       struct nm_config_file   *ncf;
+       struct lu_env            env;
+       int                      rc = 0;
+       int                      rc2 = 0;
+
+       rc = lu_env_init(&env, LCT_LOCAL);
+       if (rc != 0)
+               return rc;
+
+       mutex_lock(&ncf_list_lock);
+       list_for_each_entry(ncf, &ncf_list_head, ncf_list) {
+               rc2 = cb_f(&env, ncf->ncf_obj, nk, nr);
+               if (rc2 < 0) {
+                       CWARN("%s: error writing to nodemap config: rc = %d\n",
+                             ncf->ncf_obj->do_lu.lo_dev->ld_obd->obd_name, rc);
+                       rc = rc2;
+               }
+       }
+       mutex_unlock(&ncf_list_lock);
+       lu_env_fini(&env);
+
+       return 0;
+}
+
+enum nm_add_update {
+       NM_ADD = 0,
+       NM_UPDATE = 1,
+};
+
+static int nodemap_idx_nodemap_add_update(const struct lu_nodemap *nodemap,
+                                         enum nm_add_update update)
+{
+       struct nodemap_key       nk;
+       union nodemap_rec        nr;
+       int rc = 0;
+
+       ENTRY;
+
+       nodemap_cluster_key_init(&nk, nodemap->nm_id);
+       nodemap_cluster_rec_init(&nr, nodemap);
+
+       if (update == NM_UPDATE)
+               rc = nodemap_idx_action(nodemap_idx_update, &nk, &nr);
+       else
+               rc = nodemap_idx_action(nodemap_idx_insert, &nk, &nr);
+
+       RETURN(rc);
+}
+
+int nodemap_idx_nodemap_add(const struct lu_nodemap *nodemap)
+{
+       return nodemap_idx_nodemap_add_update(nodemap, NM_ADD);
+}
+
+int nodemap_idx_nodemap_update(const struct lu_nodemap *nodemap)
+{
+       return nodemap_idx_nodemap_add_update(nodemap, NM_UPDATE);
+}
+
+int nodemap_idx_nodemap_del(const struct lu_nodemap *nodemap)
+{
+       struct rb_root           root;
+       struct lu_idmap         *idmap;
+       struct lu_idmap         *temp;
+       struct lu_nid_range     *range;
+       struct lu_nid_range     *range_temp;
+       struct nodemap_key       nk;
+       int                      rc = 0;
+       int                      rc2 = 0;
+
+       ENTRY;
+
+       root = nodemap->nm_fs_to_client_uidmap;
+       nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
+                                               id_fs_to_client) {
+               nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_UID,
+                                      idmap->id_client);
+               rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+               if (rc2 < 0)
+                       rc = rc2;
+       }
+
+       root = nodemap->nm_client_to_fs_gidmap;
+       nm_rbtree_postorder_for_each_entry_safe(idmap, temp, &root,
+                                               id_client_to_fs) {
+               nodemap_idmap_key_init(&nk, nodemap->nm_id, NODEMAP_GID,
+                                      idmap->id_client);
+               rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+               if (rc2 < 0)
+                       rc = rc2;
+       }
+
+       list_for_each_entry_safe(range, range_temp, &nodemap->nm_ranges,
+                                rn_list) {
+               nodemap_range_key_init(&nk, nodemap->nm_id, range->rn_id);
+               rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+               if (rc2 < 0)
+                       rc = rc2;
+       }
+
+       nodemap_cluster_key_init(&nk, nodemap->nm_id);
+       rc2 = nodemap_idx_action(nodemap_idx_delete, &nk, NULL);
+       if (rc2 < 0)
+               rc = rc2;
+
+       RETURN(rc);
+}
+
+int nodemap_idx_range_add(const struct lu_nid_range *range,
+                         const lnet_nid_t nid[2])
+{
+       struct nodemap_key       nk;
+       union nodemap_rec        nr;
+       ENTRY;
+
+       nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
+       nodemap_range_rec_init(&nr, nid);
+
+       RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_range_del(const struct lu_nid_range *range)
+{
+       struct nodemap_key       nk;
+       ENTRY;
+
+       nodemap_range_key_init(&nk, range->rn_nodemap->nm_id, range->rn_id);
+
+       RETURN(nodemap_idx_action(nodemap_idx_delete, &nk, NULL));
+}
+
+int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
+                         enum nodemap_id_type id_type,
+                         const u32 map[2])
+{
+       struct nodemap_key       nk;
+       union nodemap_rec        nr;
+       ENTRY;
+
+       nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
+       nodemap_idmap_rec_init(&nr, map[1]);
+
+       RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
+                         enum nodemap_id_type id_type,
+                         const u32 map[2])
+{
+       struct nodemap_key       nk;
+       ENTRY;
+
+       nodemap_idmap_key_init(&nk, nodemap->nm_id, id_type, map[0]);
+
+       RETURN(nodemap_idx_action(nodemap_idx_delete, &nk, NULL));
+}
+
+static int nodemap_idx_global_add_update(bool value, enum nm_add_update update)
+{
+       struct nodemap_key       nk;
+       union nodemap_rec        nr;
+       ENTRY;
+
+       nodemap_global_key_init(&nk);
+       nodemap_global_rec_init(&nr, value);
+
+       if (update == NM_UPDATE)
+               RETURN(nodemap_idx_action(nodemap_idx_update, &nk, &nr));
+       else
+               RETURN(nodemap_idx_action(nodemap_idx_insert, &nk, &nr));
+}
+
+int nodemap_idx_nodemap_activate(bool value)
+{
+       return nodemap_idx_global_add_update(value, NM_UPDATE);
+}
+
+/**
+ * Process a key/rec pair and modify the new configuration.
+ *
+ * \param      config          configuration to update with this key/rec data
+ * \param      key             key of the record that was loaded
+ * \param      rec             record that was loaded
+ * \param      recent_nodemap  last referenced nodemap
+ * \retval     type of record processed, see enum #nodemap_idx_type
+ * \retval     -ENOENT         range or map loaded before nodemap record
+ * \retval     -EINVAL         duplicate nodemap cluster records found with
+ *                             different IDs, or nodemap has invalid name
+ * \retval     -ENOMEM
+ */
+static int nodemap_process_keyrec(struct nodemap_config *config,
+                                 const struct nodemap_key *key,
+                                 const union nodemap_rec *rec,
+                                 struct lu_nodemap **recent_nodemap)
+{
+       struct lu_nodemap       *nodemap = NULL;
+       enum nodemap_idx_type    type;
+       enum nodemap_id_type     id_type;
+       u8                       flags;
+       u32                      nodemap_id;
+       lnet_nid_t               nid[2];
+       u32                      map[2];
+       int                      rc;
+
+       CLASSERT(sizeof(union nodemap_rec) == 32);
+
+       nodemap_id = le32_to_cpu(key->nk_nodemap_id);
+       type = nm_idx_get_type(nodemap_id);
+       nodemap_id = nm_idx_set_type(nodemap_id, 0);
+
+       /* find the correct nodemap in the load list */
+       if (type == NODEMAP_RANGE_IDX || type == NODEMAP_UIDMAP_IDX ||
+           type == NODEMAP_GIDMAP_IDX) {
+               struct lu_nodemap *tmp = NULL;
+
+               nodemap = *recent_nodemap;
+
+               if (nodemap == NULL)
+                       GOTO(out, rc = -ENOENT);
+
+               if (nodemap->nm_id != nodemap_id) {
+                       list_for_each_entry(tmp, &nodemap->nm_list, nm_list)
+                               if (tmp->nm_id == nodemap_id) {
+                                       nodemap = tmp;
+                                       break;
+                               }
+
+                       if (nodemap->nm_id != nodemap_id)
+                               GOTO(out, rc = -ENOENT);
+               }
+
+               /* update most recently used nodemap if necessay */
+               if (nodemap != *recent_nodemap)
+                       *recent_nodemap = nodemap;
+       }
+
+       switch (type) {
+       case NODEMAP_EMPTY_IDX:
+               if (nodemap_id != 0)
+                       CWARN("Found nodemap config record without type field, "
+                             " nodemap_id=%d. nodemap config file corrupt?\n",
+                             nodemap_id);
+               break;
+       case NODEMAP_CLUSTER_IDX:
+               nodemap = cfs_hash_lookup(config->nmc_nodemap_hash,
+                                         rec->ncr.ncr_name);
+               if (nodemap == NULL) {
+                       if (nodemap_id == LUSTRE_NODEMAP_DEFAULT_ID) {
+                               nodemap = nodemap_create(rec->ncr.ncr_name,
+                                                        config, 1);
+                               config->nmc_default_nodemap = nodemap;
+                       } else {
+                               nodemap = nodemap_create(rec->ncr.ncr_name,
+                                                        config, 0);
+                       }
+                       if (IS_ERR(nodemap))
+                               GOTO(out, rc = PTR_ERR(nodemap));
+
+                       /* we need to override the local ID with the saved ID */
+                       nodemap->nm_id = nodemap_id;
+                       if (nodemap_id > config->nmc_nodemap_highest_id)
+                               config->nmc_nodemap_highest_id = nodemap_id;
+
+               } else if (nodemap->nm_id != nodemap_id) {
+                       nodemap_putref(nodemap);
+                       GOTO(out, rc = -EINVAL);
+               }
+
+               nodemap->nm_squash_uid =
+                               le32_to_cpu(rec->ncr.ncr_squash_uid);
+               nodemap->nm_squash_gid =
+                               le32_to_cpu(rec->ncr.ncr_squash_gid);
+
+               flags = le32_to_cpu(rec->ncr.ncr_flags);
+               nodemap->nmf_allow_root_access =
+                                       flags & NM_FL_ALLOW_ROOT_ACCESS;
+               nodemap->nmf_trust_client_ids =
+                                       flags & NM_FL_TRUST_CLIENT_IDS;
+
+               if (*recent_nodemap == NULL) {
+                       *recent_nodemap = nodemap;
+                       INIT_LIST_HEAD(&nodemap->nm_list);
+               } else {
+                       list_add(&nodemap->nm_list,
+                                &(*recent_nodemap)->nm_list);
+               }
+               nodemap_putref(nodemap);
+               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);
+
+               rc = nodemap_add_range_helper(config, nodemap, nid,
+                                       le32_to_cpu(key->nk_range_id));
+               if (rc != 0)
+                       GOTO(out, rc);
+               break;
+       case NODEMAP_UIDMAP_IDX:
+       case NODEMAP_GIDMAP_IDX:
+               map[0] = le32_to_cpu(key->nk_id_client);
+               map[1] = le32_to_cpu(rec->nir.nir_id_fs);
+
+               if (type == NODEMAP_UIDMAP_IDX)
+                       id_type = NODEMAP_UID;
+               else
+                       id_type = NODEMAP_GID;
+
+               rc = nodemap_add_idmap_helper(nodemap, id_type, map);
+               if (rc != 0)
+                       GOTO(out, rc);
+               break;
+       case NODEMAP_GLOBAL_IDX:
+               config->nmc_nodemap_is_active = rec->ngr.ngr_is_active;
+               break;
+       default:
+               CERROR("got keyrec pair for unknown type %d\n", type);
+               break;
+       }
+       rc = type;
+
+out:
+       return rc;
+}
+
+static int nodemap_load_entries(const struct lu_env *env,
+                               struct dt_object *nodemap_idx)
+{
+       const struct dt_it_ops  *iops;
+       struct dt_it            *it;
+       struct lu_nodemap       *recent_nodemap = NULL;
+       struct nodemap_config   *new_config = NULL;
+       u64                      hash = 0;
+       bool                     activate_nodemap = false;
+       bool                     loaded_global_idx = false;
+       int                      rc = 0;
+
+       ENTRY;
+
+       iops = &nodemap_idx->do_index_ops->dio_it;
+
+       dt_read_lock(env, nodemap_idx, 0);
+       it = iops->init(env, nodemap_idx, 0);
+       if (IS_ERR(it))
+               GOTO(out, rc = PTR_ERR(it));
+
+       rc = iops->load(env, it, hash);
+       if (rc == 0) {
+               rc = iops->next(env, it);
+               if (rc != 0)
+                       GOTO(out_iops, rc = 0);
+       }
+
+       /* acquires active config lock */
+       new_config = nodemap_config_alloc();
+
+       if (IS_ERR(new_config)) {
+               rc = PTR_ERR(new_config);
+               new_config = NULL;
+               GOTO(out_lock, rc);
+       }
+
+       do {
+               struct nodemap_key *key;
+               union nodemap_rec rec;
+
+               key = (struct nodemap_key *)iops->key(env, it);
+               rc = iops->rec(env, it, (struct dt_rec *)&rec, 0);
+               if (rc != -ESTALE) {
+                       if (rc != 0)
+                               GOTO(out_lock, rc);
+                       rc = nodemap_process_keyrec(new_config, key, &rec,
+                                                   &recent_nodemap);
+                       if (rc < 0)
+                               GOTO(out_lock, rc);
+                       if (rc == NODEMAP_GLOBAL_IDX)
+                               loaded_global_idx = true;
+               }
+
+               do
+                       rc = iops->next(env, it);
+               while (rc == -ESTALE);
+       } while (rc == 0);
+
+       if (rc > 0)
+               rc = 0;
+
+out_lock:
+       if (rc != 0)
+               nodemap_config_dealloc(new_config);
+       else
+               /* creating new default needs to be done outside dt read lock */
+               activate_nodemap = true;
+out_iops:
+       iops->put(env, it);
+       iops->fini(env, it);
+out:
+       dt_read_unlock(env, nodemap_idx);
+
+       if (rc != 0)
+               CWARN("%s: failed to load nodemap configuration: rc = %d\n",
+                     nodemap_idx->do_lu.lo_dev->ld_obd->obd_name, rc);
+
+       if (!activate_nodemap)
+               RETURN(rc);
+
+       if (new_config->nmc_default_nodemap == NULL) {
+               /* new MGS won't have a default nm on disk, so create it here */
+               new_config->nmc_default_nodemap =
+                       nodemap_create(DEFAULT_NODEMAP, new_config, 1);
+               if (IS_ERR(new_config->nmc_default_nodemap)) {
+                       rc = PTR_ERR(new_config->nmc_default_nodemap);
+               } else {
+                       rc = nodemap_idx_nodemap_add_update(
+                                       new_config->nmc_default_nodemap, 0);
+                       nodemap_putref(new_config->nmc_default_nodemap);
+               }
+       }
+
+       /* new nodemap config won't have an active/inactive record */
+       if (rc == 0 && loaded_global_idx == false)
+               rc = nodemap_idx_global_add_update(false, NM_ADD);
+
+       if (rc == 0)
+               nodemap_config_set_active(new_config);
+       else
+               nodemap_config_dealloc(new_config);
+
+       RETURN(rc);
+}
+
+/**
+ * Register a dt_object representing the config index file. This should be
+ * called by targets in order to load the nodemap configuration from disk. The
+ * dt_object should be created with local_index_find_or_create and the index
+ * features should be enabled with do_index_try.
+ *
+ * \param obj  dt_object returned by local_index_find_or_create
+ *
+ * \retval     on success: nm_config_file handle for later deregistration
+ * \retval     -ENOMEM         memory allocation failure
+ * \retval     -ENOENT         error loading nodemap config
+ * \retval     -EINVAL         error loading nodemap config
+ */
+struct nm_config_file *nm_config_file_register(const struct lu_env *env,
+                                              struct dt_object *obj)
+{
+       struct nm_config_file *ncf;
+       bool load_entries = false;
+       int rc;
+       ENTRY;
+
+       OBD_ALLOC_PTR(ncf);
+       if (ncf == NULL)
+               RETURN(ERR_PTR(-ENOMEM));
+
+       ncf->ncf_obj = obj;
+       mutex_lock(&ncf_list_lock);
+
+       /* if this is first config file, we load it from disk */
+       if (list_empty(&ncf_list_head))
+               load_entries = true;
+
+       list_add(&ncf->ncf_list, &ncf_list_head);
+       mutex_unlock(&ncf_list_lock);
+
+       if (load_entries) {
+               rc = nodemap_load_entries(env, obj);
+               if (rc < 0) {
+                       mutex_lock(&ncf_list_lock);
+                       list_del(&ncf->ncf_list);
+                       mutex_unlock(&ncf_list_lock);
+                       OBD_FREE_PTR(ncf);
+                       RETURN(ERR_PTR(rc));
+               }
+       }
+
+       RETURN(ncf);
+}
+EXPORT_SYMBOL(nm_config_file_register);
+
+/**
+ * Deregister a nm_config_file. Should be called by targets during cleanup.
+ *
+ * \param ncf  config file to deregister
+ */
+void nm_config_file_deregister(const struct lu_env *env,
+                              struct nm_config_file *ncf)
+{
+       ENTRY;
+
+       lu_object_put(env, &ncf->ncf_obj->do_lu);
+
+       mutex_lock(&ncf_list_lock);
+       list_del(&ncf->ncf_list);
+       mutex_unlock(&ncf_list_lock);
+       OBD_FREE_PTR(ncf);
+
+       EXIT;
+}
+EXPORT_SYMBOL(nm_config_file_deregister);
index 6fbc0e1..e2405ec 100644 (file)
@@ -4710,6 +4710,114 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct out_update_buffer *)0)->oub_padding) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct out_update_buffer *)0)->oub_padding));
 
+       /* Checks for struct nodemap_cluster_rec */
+       LASSERTF((int)sizeof(struct nodemap_cluster_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_cluster_rec));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_name) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_name));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name) == 17, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_flags) == 17, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_flags));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding1) == 18, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1) == 2, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding2) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid) == 28, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid));
+
+       /* Checks for struct nodemap_range_rec */
+       LASSERTF((int)sizeof(struct nodemap_range_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_range_rec));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_start_nid) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_start_nid));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_end_nid) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_end_nid));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding1) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding2) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding2));
+       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_id_rec */
+       LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_id_rec));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_id_fs) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_id_fs));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding1) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding2) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding3) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding3));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding4) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding4));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4));
+
+       /* Checks for struct nodemap_global_rec */
+       LASSERTF((int)sizeof(struct nodemap_global_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_global_rec));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_is_active) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_is_active));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding1) == 1, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding2) == 2, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2) == 2, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding3) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding3));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding4) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding4));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding5) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding5));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding6) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding6));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
+
+       /* Checks for union nodemap_rec */
+       LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(union nodemap_rec));
+
        /* Checks for struct lfsck_request */
        LASSERTF((int)sizeof(struct lfsck_request) == 96, "found %lld\n",
                 (long long)(int)sizeof(struct lfsck_request));
index 612cba1..2a8eb9a 100755 (executable)
@@ -11,8 +11,6 @@ ONLY=${ONLY:-"$*"}
 ALWAYS_EXCEPT="                2     5     6    $SANITY_SEC_EXCEPT"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
-[ "$ALWAYS_EXCEPT$EXCEPT" ] && echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT"
-
 SRCDIR=$(dirname $0)
 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
 export NAME=${NAME:-local}
@@ -23,6 +21,11 @@ init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
 init_logging
 
+[ "$SLOW" = "no" ] && EXCEPT_SLOW="26"
+
+[ "$ALWAYS_EXCEPT$EXCEPT$EXCEPT_SLOW" ] &&
+       echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT $EXCEPT_SLOW"
+
 RUNAS_CMD=${RUNAS_CMD:-runas}
 
 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
@@ -501,7 +504,7 @@ test_idmap() {
        local rc=0
 
        ## nodemap deactivated
-       if ! do_facet mgs lctl nodemap_activate 0; then
+       if ! do_facet mgs $LCTL nodemap_activate 0; then
                return 1
        fi
        for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
@@ -519,7 +522,7 @@ test_idmap() {
        done
 
        ## nodemap activated
-       if ! do_facet mgs lctl nodemap_activate 1; then
+       if ! do_facet mgs $LCTL nodemap_activate 1; then
                return 2
        fi
 
@@ -1037,7 +1040,7 @@ fops_test_setup() {
        do_servers_not_mgs $LCTL set_param nodemap.c0.trusted_nodemap=$trust
 
        # flush MDT locks to make sure they are reacquired before test
-       do_node ${clients_arr[0]} lctl set_param \
+       do_node ${clients_arr[0]} $LCTL set_param \
                ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
 }
 
@@ -1521,11 +1524,46 @@ test_24() {
 }
 run_test 24 "check nodemap proc files for LBUGs and Oopses"
 
+test_25() {
+       nodemap_version_check || return 0
+       nodemap_test_setup
+
+       trap nodemap_test_cleanup EXIT
+       local tmpfile=$(mktemp)
+       do_facet mgs $LCTL nodemap_info > $tmpfile
+       cleanup_and_setup_lustre
+       diff -q <(do_facet mgs $LCTL nodemap_info) $tmpfile >& /dev/null ||
+               error "nodemap_info diff after remount"
+
+       nodemap_test_cleanup
+       rm -f $tmpfile
+}
+run_test 25 "test save and reload nodemap config"
+
+test_26() {
+       nodemap_version_check || return 0
+
+       local large_i=13000
+
+       for ((i = 0; i < large_i; i++)); do
+               ((i % 1000 == 0)) && echo $i
+               do_facet mgs $LCTL nodemap_add c$i ||
+                       error "cannot add nodemap $i to config"
+       done
+
+       for ((i = 0; i < large_i; i++)); do
+               ((i % 1000 == 0)) && echo $i
+               do_facet mgs $LCTL nodemap_del c$i ||
+                       error "cannot delete nodemap $i from config"
+       done
+}
+run_test 26 "test transferring very large nodemap"
+
 log "cleanup: ======================================================"
 
 sec_unsetup() {
        ## nodemap deactivated
-       do_facet mgs lctl nodemap_activate 0
+       do_facet mgs $LCTL nodemap_activate 0
 
        for num in $(seq $MDSCOUNT); do
                if [ "${identity_old[$num]}" = 1 ]; then
index 41a8ae3..bb654cc 100644 (file)
@@ -2158,6 +2158,58 @@ static void check_out_update_buffer(void)
        CHECK_MEMBER(out_update_buffer, oub_padding);
 }
 
+static void check_nodemap_cluster_rec(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_cluster_rec);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_name);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_flags);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_padding1);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_padding2);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_squash_uid);
+       CHECK_MEMBER(nodemap_cluster_rec, ncr_squash_gid);
+}
+
+static void check_nodemap_range_rec(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_range_rec);
+       CHECK_MEMBER(nodemap_range_rec, nrr_start_nid);
+       CHECK_MEMBER(nodemap_range_rec, nrr_end_nid);
+       CHECK_MEMBER(nodemap_range_rec, nrr_padding1);
+       CHECK_MEMBER(nodemap_range_rec, nrr_padding2);
+}
+
+static void check_nodemap_id_rec(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_id_rec);
+       CHECK_MEMBER(nodemap_id_rec, nir_id_fs);
+       CHECK_MEMBER(nodemap_id_rec, nir_padding1);
+       CHECK_MEMBER(nodemap_id_rec, nir_padding2);
+       CHECK_MEMBER(nodemap_id_rec, nir_padding3);
+       CHECK_MEMBER(nodemap_id_rec, nir_padding4);
+}
+
+static void check_nodemap_global_rec(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(nodemap_global_rec);
+       CHECK_MEMBER(nodemap_global_rec, ngr_is_active);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding1);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding2);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding3);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding4);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding5);
+       CHECK_MEMBER(nodemap_global_rec, ngr_padding6);
+}
+
+static void check_nodemap_rec(void)
+{
+       BLANK_LINE();
+       CHECK_UNION(nodemap_rec);
+}
+
 static void check_lfsck_request(void)
 {
        BLANK_LINE();
@@ -2652,6 +2704,12 @@ main(int argc, char **argv)
        check_out_update_header();
        check_out_update_buffer();
 
+       check_nodemap_cluster_rec();
+       check_nodemap_range_rec();
+       check_nodemap_id_rec();
+       check_nodemap_global_rec();
+       check_nodemap_rec();
+
        check_lfsck_request();
        check_lfsck_reply();
 
index 79f3ea7..841d706 100644 (file)
@@ -4724,6 +4724,114 @@ void lustre_assert_wire_constants(void)
        LASSERTF((int)sizeof(((struct out_update_buffer *)0)->oub_padding) == 4, "found %lld\n",
                 (long long)(int)sizeof(((struct out_update_buffer *)0)->oub_padding));
 
+       /* Checks for struct nodemap_cluster_rec */
+       LASSERTF((int)sizeof(struct nodemap_cluster_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_cluster_rec));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_name) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_name));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name) == 17, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_name));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_flags) == 17, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_flags));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_flags));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding1) == 18, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1) == 2, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_padding2) == 20, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_padding2));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_uid));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_uid));
+       LASSERTF((int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid) == 28, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_cluster_rec, ncr_squash_gid));
+       LASSERTF((int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_cluster_rec *)0)->ncr_squash_gid));
+
+       /* Checks for struct nodemap_range_rec */
+       LASSERTF((int)sizeof(struct nodemap_range_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_range_rec));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_start_nid) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_start_nid));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_start_nid));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_end_nid) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_end_nid));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_end_nid));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding1) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_range_rec *)0)->nrr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_range_rec, nrr_padding2) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_range_rec, nrr_padding2));
+       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_id_rec */
+       LASSERTF((int)sizeof(struct nodemap_id_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_id_rec));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_id_fs) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_id_fs));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_id_fs));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding1) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding1));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding2) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding2));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding3) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding3));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding3));
+       LASSERTF((int)offsetof(struct nodemap_id_rec, nir_padding4) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_id_rec, nir_padding4));
+       LASSERTF((int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_id_rec *)0)->nir_padding4));
+
+       /* Checks for struct nodemap_global_rec */
+       LASSERTF((int)sizeof(struct nodemap_global_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct nodemap_global_rec));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_is_active) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_is_active));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_is_active));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding1) == 1, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding1));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1) == 1, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding1));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding2) == 2, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding2));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2) == 2, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding2));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding3) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding3));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding3));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding4) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding4));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding4));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding5) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding5));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding5));
+       LASSERTF((int)offsetof(struct nodemap_global_rec, ngr_padding6) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct nodemap_global_rec, ngr_padding6));
+       LASSERTF((int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct nodemap_global_rec *)0)->ngr_padding6));
+
+       /* Checks for union nodemap_rec */
+       LASSERTF((int)sizeof(union nodemap_rec) == 32, "found %lld\n",
+                (long long)(int)sizeof(union nodemap_rec));
+
        /* Checks for struct lfsck_request */
        LASSERTF((int)sizeof(struct lfsck_request) == 96, "found %lld\n",
                 (long long)(int)sizeof(struct lfsck_request));