From: Kit Westneat Date: Sat, 19 Sep 2015 13:20:04 +0000 (-0400) Subject: LU-5092 nodemap: save id maps to targets in new index file X-Git-Tag: 2.8.51~68 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=928714dddabb2dbc4fc93101f23eaa671099dbea LU-5092 nodemap: save id maps to targets in new index file 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 Change-Id: Ie2b84e25ecc02d5d3daebf268d2f72ffaf142758 Reviewed-on: http://review.whamcloud.com/11813 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 7c5aae7..a37e6c1 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -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. diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index ed1c0d3..24077ae 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -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 */ diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index 375154d..e5b26f7 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -27,8 +27,9 @@ #ifndef _LUSTRE_NODEMAP_H #define _LUSTRE_NODEMAP_H +#include + #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 */ diff --git a/lustre/include/obd_target.h b/lustre/include/obd_target.h index ed8ec98..fb2cb6e 100644 --- a/lustre/include/obd_target.h +++ b/lustre/include/obd_target.h @@ -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 */ diff --git a/lustre/mgs/mgs_fs.c b/lustre/mgs/mgs_fs.c index 064a7f1..a3ce58fc 100644 --- a/lustre/mgs/mgs_fs.c +++ b/lustre/mgs/mgs_fs.c @@ -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; diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c index 65649be..2c13a3c 100644 --- a/lustre/obdclass/dt_object.c +++ b/lustre/obdclass/dt_object.c @@ -48,7 +48,7 @@ #include /* fid_be_to_cpu() */ #include - +#include #include /* 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, diff --git a/lustre/ptlrpc/Makefile.in b/lustre/ptlrpc/Makefile.in index 7521a98..488f757 100644 --- a/lustre/ptlrpc/Makefile.in +++ b/lustre/ptlrpc/Makefile.in @@ -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) diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index 5bf4932..ec7dda2 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -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(); } diff --git a/lustre/ptlrpc/nodemap_internal.h b/lustre/ptlrpc/nodemap_internal.h index 86c55b0..991564f 100644 --- a/lustre/ptlrpc/nodemap_internal.h +++ b/lustre/ptlrpc/nodemap_internal.h @@ -33,7 +33,7 @@ #include #include -#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 */ diff --git a/lustre/ptlrpc/nodemap_range.c b/lustre/ptlrpc/nodemap_range.c index e8b5a24..56da8ea 100644 --- a/lustre/ptlrpc/nodemap_range.c +++ b/lustre/ptlrpc/nodemap_range.c @@ -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 index 0000000..dc956a8 --- /dev/null +++ b/lustre/ptlrpc/nodemap_storage.c @@ -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 + * Author: Kit Westneat + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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); diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 6fbc0e1..e2405ec 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -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)); diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 612cba1..2a8eb9a 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -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 diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 41a8ae3..bb654cc 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -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(); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 79f3ea7..841d706 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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));