From: Alexander Boyko Date: Sat, 21 Oct 2023 08:30:12 +0000 (-0400) Subject: LU-17225 utils: check_iam print records X-Git-Tag: 2.15.59~34 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;ds=sidebyside;h=6ad9ef1fec11e1d7ae03d661b69684ffa60e9b75;p=fs%2Flustre-release.git LU-17225 utils: check_iam print records Fix adds ability to print records with -r option. Format is FID ino/igen. [0x200000001:0x3:0x0] 88/2116153859 [0x200000001:0x4:0x0] 89/182164966 If a root block has wrong sizes, stop processing. Also fixing a test. Test-Parameters: trivial testlist=conf-sanity env=ONLY=134 HPE-bug-id: LUS-11905 Signed-off-by: Alexander Boyko Change-Id: I2e11d1a8d675e6be9ea79023348a18370a0bb5a0 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52815 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Artem Blagodarenko Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/lustre/libiam.h b/lustre/include/lustre/libiam.h index 3e400ec..6ccd52f 100644 --- a/lustre/include/lustre/libiam.h +++ b/lustre/include/lustre/libiam.h @@ -124,6 +124,12 @@ struct lvar_leaf_entry { u_int8_t vle_key[0]; } __attribute__((packed)); +struct osd_inode_id { + __u32 oii_ino; + __u32 oii_gen; +} __attribute__ ((packed)); + + enum { LVAR_PAD = 4, LVAR_ROUND = LVAR_PAD - 1 diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index e83a681..c6c3513 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -10557,7 +10557,7 @@ test_134() { $DEBUGFS -c -R 'dump $f $tmp_dir/$f' $mdt_dev 2>&1; \ $CHECK_IAM -v $tmp_dir/$f 2>&1; \ echo $cmd; eval $cmd 2>/dev/null; - $CHECK_IAM -v $tmp_dir/$f 2>&1; echo \\\$?" >> $out + $CHECK_IAM -v $tmp_dir/$f 2>&1; echo \\\$?" >> $out 2>&1 done tail -n50 $out diff --git a/lustre/utils/check_iam.c b/lustre/utils/check_iam.c index 0888dbf..bee3c8c 100644 --- a/lustre/utils/check_iam.c +++ b/lustre/utils/check_iam.c @@ -36,10 +36,12 @@ #include #include +#include #include #include static int verbose; +static bool print_records; enum { ROOT_NODE, @@ -56,7 +58,7 @@ struct node_info { void usage(char *str) { - printf("usage: %s [-h] [-v] iam_file\n", str); + printf("Usage: %s [-hrv] iam_file\n", str); } struct iam_params { @@ -119,7 +121,7 @@ int check_idle_blocks(char *buf, struct iam_params *params) } static int check_entries(unsigned char *entries, size_t size, int count, - struct iam_params *params) + struct iam_params *params, int block_type) { unsigned int ptr; int i, j, rc; @@ -135,32 +137,85 @@ static int check_entries(unsigned char *entries, size_t size, int count, return -1; } - if (verbose) - printf("key:"); + if (block_type == INDEX_NODE) { - for (j = 0; j < params->keysize; j++, entries++) if (verbose) - printf("%02x", *entries); + printf("key:"); - ptr = __le32_to_cpu(*((__le32 *)entries)); + for (j = 0; j < params->keysize; j++, entries++) + if (verbose) + printf("%02x", *entries); - if (ptr >= params->blocks_count) { - params->rc = -1; - rc = -1; - } - if (verbose) - printf(", ptr: %u%s\n", ptr, rc ? " wrong" : ""); + ptr = __le32_to_cpu(*((__le32 *)entries)); - entries += params->ptrsize; + if (ptr >= params->blocks_count) { + params->rc = -1; + rc = -1; + } + if (verbose) + printf(", ptr: %u%s\n", ptr, + rc ? " wrong" : ""); - if (rc) - continue; + entries += params->ptrsize; - if (params->node_info[ptr].recycled && verbose) { - printf("Reference to recycled node (%u) from node %lu\n", - ptr, params->current_block); + if (rc) + continue; + + if (params->node_info[ptr].recycled && verbose) { + printf("Reference to recycled node (%u) from node %lu\n", + ptr, params->current_block); + } + params->node_info[ptr].referenced = 1; + } else if (block_type == LEAF_NODE) { + struct lu_fid fid; + struct osd_inode_id *inode; + + fid_be_to_cpu(&fid, (struct lu_fid *)entries); + inode = (struct osd_inode_id *)(entries + sizeof(fid)); + entries += params->keysize + params->recsize; + + if (print_records) + printf(DFID" %u/%u\n", PFID(&fid), + __be32_to_cpu(inode->oii_ino), + __be32_to_cpu(inode->oii_gen)); } - params->node_info[ptr].referenced = 1; + + } + + return 0; +} + +static int check_leaf(char *buf, struct iam_params *params) +{ + struct iam_leaf_head *leaf; + int counted_limit; + int leaf_count; + + leaf = (struct iam_leaf_head *)buf; + + params->node_info[params->current_block].node_type = LEAF_NODE; + + counted_limit = node_limit(sizeof(struct iam_leaf_head), + params->blocksize, + params->keysize + params->recsize); + leaf_count = __le16_to_cpu(leaf->ill_count); + + if (verbose) + printf("Leaf block, count %i, limit %i\n", leaf_count, + counted_limit); + + if (leaf_count > counted_limit) { + printf("More elements (%i) then limit (%i)\n", leaf_count, + counted_limit); + return -1; + } + + if (check_entries((unsigned char *)(buf + sizeof(struct iam_leaf_head)), + params->blocksize - sizeof(struct iam_leaf_head), + counted_limit < leaf_count ? + counted_limit : leaf_count, params, LEAF_NODE)) { + printf("Broken entries\n"); + return -1; } return 0; @@ -171,15 +226,16 @@ static int check_index(char *buf, struct iam_params *params) struct iam_index_head *index; int counted_limit; struct dx_countlimit *limit; + int limit_count; index = (struct iam_index_head *)buf; limit = &index->limit; params->node_info[params->current_block].node_type = INDEX_NODE; + limit_count = __le16_to_cpu(limit->count); if (verbose) - printf("Index block, count %i, limit %i\n", - __le16_to_cpu(limit->count), + printf("Index block, count %i, limit %i\n", limit_count, __le16_to_cpu(limit->limit)); counted_limit = node_limit(params->node_gap, params->blocksize, @@ -192,9 +248,8 @@ static int check_index(char *buf, struct iam_params *params) } - if (__le16_to_cpu(limit->count) > __le16_to_cpu(limit->limit)) { - printf("More elements (%i) then limit (%i)\n", - __le16_to_cpu(limit->count), + if (limit_count > __le16_to_cpu(limit->limit)) { + printf("More elements (%i) then limit (%i)\n", limit_count, __le16_to_cpu(limit->limit)); return -1; } @@ -203,7 +258,7 @@ static int check_index(char *buf, struct iam_params *params) if (check_entries(index->entries, params->blocksize - offsetof(struct iam_index_head, entries), - __le16_to_cpu(limit->count) - 1, params)) { + limit_count - 1, params, INDEX_NODE)) { printf("Broken entries\n"); return -1; } @@ -232,7 +287,7 @@ static int check_root(char *buf, size_t size, struct iam_params *params) printf("LVAR,"); } else { printf("Bad magic %llu\n", __le64_to_cpu(root->ilr_magic)); - return -1; + params->rc = -1; } limit = &root->limit; @@ -316,7 +371,7 @@ static int check_root(char *buf, size_t size, struct iam_params *params) /* cound - 1, because limit is entry itself */ if (check_entries(root->entries, size - offsetof(struct iam_lfix_root, entries), - min - 1, params)) { + min - 1, params, INDEX_NODE)) { printf("Broken entries\n"); return -1; } @@ -337,8 +392,10 @@ static int check_block(char *buf, struct iam_params *params) case __cpu_to_le16(IAM_LEAF_HEADER_MAGIC): if (verbose) printf("FIX leaf,"); - params->node_info[params->current_block].node_type = - LEAF_NODE; + if (check_leaf(buf, params)) { + printf("Broken leaf block\n"); + params->rc = -1; + } break; case __cpu_to_le16(IAM_LVAR_ROOT_MAGIC): if (verbose) @@ -419,17 +476,20 @@ int main(int argc, char **argv) struct stat sb; params.rc = 0; + print_records = false; do { - opt = getopt(argc, argv, "hv"); + opt = getopt(argc, argv, "hvr"); switch (opt) { case 'v': verbose++; + break; + case 'r': + print_records = true; case -1: break; default: fprintf(stderr, "Unable to parse options."); case 'h': - printf("HERE\n"); usage(argv[0]); return 0; } @@ -486,7 +546,7 @@ int main(int argc, char **argv) rc = check_root(buf, params.blocksize, ¶ms); if (rc) { printf("Root node is insane\n"); - params.rc = rc; + goto err; } params.current_block++;