Whamcloud - gitweb
LU-16503 utils: add --hex-idx option for lfs getstripe 40/50340/4
authorThomas Bertschinger <bertschinger@lanl.gov>
Fri, 17 Mar 2023 20:24:13 +0000 (16:24 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 11 Apr 2023 20:10:52 +0000 (20:10 +0000)
The --hex-idx option for lfs getstripe and getdirstripe makes
them output OST and MDT indexes in hex.

In addition, this commit modifies the YAML parser to treat input
like "0x[0-9a-f]+" as a number so that lfs setstripe --yaml can
accept output produced by lfs getstripe --yaml --hex-idx.

Signed-off-by: Thomas Bertschinger <bertschinger@lanl.gov>
Change-Id: I98eaa9741db787bcf4516648e58e92c7520d8640
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50340
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/utils/lnetconfig/cyaml.c
lustre/doc/lfs-getdirstripe.1
lustre/doc/lfs-getstripe.1
lustre/include/lustre/lustreapi.h
lustre/tests/sanity.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 032bb5a..f11a4f8 100644 (file)
@@ -348,6 +348,23 @@ static bool parse_number(struct cYAML *item, const char *input)
        int subscale = 0, signsubscale = 1;
        const char *num = input;
 
+       if (!strncmp(input, "0x", 2)) {
+               int64_t hex; /* hex input is always an integer */
+               char *invalid = NULL;
+
+               errno = 0;
+               hex = strtoll(input, &invalid, 16);
+               if (errno)
+                       return false;
+               if (*invalid)
+                       return false;
+
+               item->cy_valuedouble = (double) hex;
+               item->cy_valueint = hex;
+               item->cy_type = CYAML_TYPE_NUMBER;
+               return true;
+       }
+
        if (*num == '-') {
                sign = -1;
                num++;
index b3d50aa..ad86f6e 100644 (file)
@@ -23,6 +23,9 @@ Print usage message.
 .BR \-H ", " \-\-mdt-hash
 Only show the hash function being used for this directory.
 .TP
+.BR --hex-idx
+Print MDT indexes in hexademical rather than decimal.
+.TP
 .BR \-i ", " \-m ", " \-\-mdt-index
 Only show the master MDT index of the directory.
 .TP
index 3a9c461..b6b5a52 100644 (file)
@@ -13,6 +13,7 @@ lfs-getstripe \- Lustre client command to print layout parameters of a file
 [\fB--fid\fR|\fB-F\fR]
 [\fB--generation\fR|\fB-g\fR]
 [\fB--help\fR|\fB-h\fR]
+[\fB--hex-idx\fR]
       [\fB--layout\fR|\fB-L\fR]
 [\fB--mdt\fR|\fB--mdt-index\fR|\fB-m\fR]
 [\fB--ost\fR|\fB-O\fR <\fIuuid\fR>]
@@ -160,6 +161,9 @@ Print only the layout generation number.
 .BR --help | -h
 Print usage message.
 .TP
+.BR --hex-idx
+Print OST and MDT indexes in hexademical rather than decimal.
+.TP
 .BR --layout
 Show only the file layout, which is one of:
 .RS 1.2i
index e72d2b2..93ccb4c 100644 (file)
@@ -398,7 +398,8 @@ struct find_param {
 
        unsigned long            fp_got_uuids:1,
                                 fp_obds_printed:1,
-                                fp_no_follow:1;
+                                fp_no_follow:1,
+                                fp_hex_idx:1;
        unsigned int             fp_depth;
        unsigned int             fp_hash_type;
        unsigned int             fp_time_margin; /* time margin in seconds */
index 96ec5be..3772861 100755 (executable)
@@ -8699,6 +8699,32 @@ test_56eb() {
 }
 run_test 56eb "check lfs getstripe on symlink"
 
+test_56ec() {
+       [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
+       local dir=$DIR/$tdir
+       local srcfile=$dir/srcfile
+       local srcyaml=$dir/srcyaml
+       local destfile=$dir/destfile
+
+       test_mkdir -p $dir
+
+       $LFS setstripe -i 1 $srcfile
+       $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
+       # if the setstripe yaml parsing fails for any reason, the command can
+       # randomly assign the correct OST index, leading to an erroneous
+       # success. but the chance of false success is low enough that a
+       # regression should still be quickly caught.
+       $LFS setstripe --yaml=$srcyaml $destfile
+
+       local srcindex=$($LFS getstripe -i $srcfile)
+       local destindex=$($LFS getstripe -i $destfile)
+
+       if [[ ! $srcindex -eq $destindex ]]; then
+               error "setstripe did not set OST index correctly"
+       fi
+}
+run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
+
 test_57a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
        # note test will not do anything if MDS is not local
index dbfbfbb..e8f013a 100644 (file)
@@ -370,7 +370,8 @@ command_t cmdlist[] = {
         "                 [--pool|-p] [--stripe-size|-S] [--directory|-d]\n"
         "                 [--mdt-index|-m] [--recursive|-r] [--raw|-R]\n"
         "                 [--layout|-L] [--generation|-g] [--yaml|-y]\n"
-        "                 [--help|-h] [--component-id|-I[=COMP_ID]]\n"
+        "                 [--help|-h] [--hex-idx]\n"
+        "                 [--component-id|-I[=COMP_ID]]\n"
         "                 [--component-flags[=COMP_FLAGS]]\n"
         "                 [--component-count]\n"
         "                 [--extension-size|--ext-size|-z]\n"
@@ -389,8 +390,8 @@ command_t cmdlist[] = {
         "To list the layout pattern info for a given directory\n"
         "or recursively for all directories in a directory tree.\n"
         "usage: getdirstripe [--mdt-count|-c] [--mdt-index|-m|-i]\n"
-        "                    [--help|-h] [--mdt-hash|-H] [--obd|-O UUID]\n"
-        "                    [--recursive|-r] [--yaml|-y]\n"
+        "                    [--help|-h] [--hex-idx] [--mdt-hash|-H]\n"
+        "                    [--obd|-O UUID] [--recursive|-r] [--yaml|-y]\n"
         "                    [--verbose|-v] [--default|-D]\n"
         "                    [--max-inherit|-X]\n"
         "                    [--max-inherit-rr] <dir> ..."},
@@ -3522,6 +3523,7 @@ enum {
        LFS_FIND_PERM,
        LFS_PRINTF_OPT,
        LFS_NO_FOLLOW_OPT,
+       LFS_HEX_IDX_OPT,
        LFS_STATS_OPT,
        LFS_STATS_INTERVAL_OPT
 };
@@ -5983,12 +5985,6 @@ static int lfs_getstripe_internal(int argc, char **argv,
                        .name = "comp-start",   .has_arg = optional_argument },
        { .val = LFS_COMP_START_OPT,
                .name = "component-start",      .has_arg = optional_argument },
-       { .val = LFS_MIRROR_INDEX_OPT,
-               .name = "mirror-index",         .has_arg = required_argument },
-       { .val = LFS_MIRROR_ID_OPT,
-               .name = "mirror-id",            .has_arg = required_argument },
-       { .val = LFS_NO_FOLLOW_OPT,
-               .name = "no-follow",            .has_arg = no_argument },
        { .val = 'c',   .name = "stripe-count", .has_arg = no_argument },
        { .val = 'c',   .name = "stripe_count", .has_arg = no_argument },
 /* find        { .val = 'C',   .name = "ctime",        .has_arg = required_argument }*/
@@ -6000,6 +5996,8 @@ static int lfs_getstripe_internal(int argc, char **argv,
        { .val = 'g',   .name = "generation",   .has_arg = no_argument },
 /* find        { .val = 'G',   .name = "group",        .has_arg = required_argument }*/
        { .val = 'h',   .name = "help",         .has_arg = no_argument },
+       { .val = LFS_HEX_IDX_OPT,
+                       .name = "hex-idx",      .has_arg = no_argument },
 /* dirstripe { .val = 'H', .name = "mdt-hash", .has_arg = required_argument }*/
        { .val = 'i',   .name = "stripe-index", .has_arg = no_argument },
        { .val = 'i',   .name = "stripe_index", .has_arg = no_argument },
@@ -6013,6 +6011,12 @@ static int lfs_getstripe_internal(int argc, char **argv,
 /* find        { .val = 'M',   .name = "mtime",        .has_arg = required_argument }*/
 /* find        { .val = 'n',   .name = "name",         .has_arg = required_argument }*/
        { .val = 'N',   .name = "mirror-count", .has_arg = no_argument },
+       { .val = LFS_MIRROR_INDEX_OPT,
+                       .name = "mirror-index", .has_arg = required_argument },
+       { .val = LFS_MIRROR_ID_OPT,
+                       .name = "mirror-id",    .has_arg = required_argument },
+       { .val = LFS_NO_FOLLOW_OPT,
+                       .name = "no-follow",    .has_arg = no_argument },
        { .val = 'O',   .name = "obd",          .has_arg = required_argument },
        { .val = 'O',   .name = "ost",          .has_arg = required_argument },
        { .val = 'p',   .name = "pool",         .has_arg = no_argument },
@@ -6187,6 +6191,9 @@ static int lfs_getstripe_internal(int argc, char **argv,
                case LFS_NO_FOLLOW_OPT:
                        param->fp_no_follow = true;
                        break;
+               case LFS_HEX_IDX_OPT:
+                       param->fp_hex_idx = true;
+                       break;
                case 'd':
                        param->fp_max_depth = 0;
                        break;
@@ -6427,6 +6434,8 @@ static int lfs_getdirstripe(int argc, char **argv)
        { .val = 'D',   .name = "default",       .has_arg = no_argument },
        { .val = 'h',   .name = "help",         .has_arg = no_argument },
        { .val = 'H',   .name = "mdt-hash",      .has_arg = no_argument },
+       { .val = LFS_HEX_IDX_OPT,
+                       .name = "hex-idx",       .has_arg = no_argument },
        { .val = 'i',   .name = "mdt-index",     .has_arg = no_argument },
        { .val = 'm',   .name = "mdt-index",     .has_arg = no_argument },
        { .val = 'O',   .name = "obd",           .has_arg = required_argument },
@@ -6434,9 +6443,9 @@ static int lfs_getdirstripe(int argc, char **argv)
        { .val = 'T',   .name = "mdt-count",     .has_arg = no_argument },
        { .val = 'v',   .name = "verbose",       .has_arg = no_argument },
        { .val = 'X',   .name = "max-inherit",   .has_arg = no_argument },
-       { .val = 'y',   .name = "yaml",          .has_arg = no_argument },
        { .val = LFS_INHERIT_RR_OPT,
                        .name = "max-inherit-rr", .has_arg = no_argument },
+       { .val = 'y',   .name = "yaml",          .has_arg = no_argument },
        { .name = NULL } };
        int c, rc = 0;
 
@@ -6461,6 +6470,9 @@ static int lfs_getdirstripe(int argc, char **argv)
                case 'H':
                        param.fp_verbose |= VERBOSE_HASH_TYPE;
                        break;
+               case LFS_HEX_IDX_OPT:
+                       param.fp_hex_idx = 1;
+                       break;
                case 'i':
                        fallthrough;
                case 'm':
index c3831d7..f32a8ef 100644 (file)
@@ -2662,6 +2662,7 @@ enum lov_dump_flags {
        LDF_SKIP_OBJS   = 0x0008,
        LDF_YAML        = 0x0010,
        LDF_EXTENSION   = 0x0020,
+       LDF_HEX_IDX     = 0x0040,
 };
 
 static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
@@ -2679,6 +2680,7 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
        char *prefix = is_dir ? "" : "lmm_";
        char *separator = "";
        char *space = indent ? "      " : "";
+       char *fmt_idx = flags & LDF_HEX_IDX ? "%#x" : "%d";
        int rc;
 
        if (is_dir && lmm_oi_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) {
@@ -2858,14 +2860,16 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                        llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_offset: ",
                                     space, prefix);
                if (is_dir || skip_objs)
-                       llapi_printf(LLAPI_MSG_NORMAL, "%d",
-                                    lum->lmm_stripe_offset ==
-                                    (typeof(lum->lmm_stripe_offset))(-1) ? -1 :
-                                    lum->lmm_stripe_offset);
+                       if (lum->lmm_stripe_offset ==
+                           (typeof(lum->lmm_stripe_offset))(-1))
+                               llapi_printf(LLAPI_MSG_NORMAL, "-1");
+                       else
+                               llapi_printf(LLAPI_MSG_NORMAL, fmt_idx,
+                                            lum->lmm_stripe_offset);
                else if (lov_pattern(lum->lmm_pattern) == LOV_PATTERN_MDT)
                        llapi_printf(LLAPI_MSG_NORMAL, "0");
                else
-                       llapi_printf(LLAPI_MSG_NORMAL, "%u",
+                       llapi_printf(LLAPI_MSG_NORMAL, fmt_idx,
                                     objects[0].l_ost_idx);
                if (!yaml && is_dir)
                        separator = " ";
@@ -2900,6 +2904,7 @@ void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
        bool indent = flags & LDF_INDENT;
        bool skip_objs = flags & LDF_SKIP_OBJS;
        bool yaml = flags & LDF_YAML;
+       bool hex = flags & LDF_HEX_IDX;
        bool obdstripe = obdindex == OBD_NOT_FOUND;
        int i;
 
@@ -2942,10 +2947,11 @@ void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
 
                        if (yaml) {
                                struct lu_fid fid = { 0 };
-
                                ostid_to_fid(&fid, &objects[i].l_ost_oi, idx);
                                llapi_printf(LLAPI_MSG_NORMAL,
-                                   "%sl_ost_idx: %d\n", space, idx);
+                                            hex ? "%sl_ost_idx: %#x\n"
+                                                : "%sl_ost_idx: %d\n",
+                                            space, idx);
                                llapi_printf(LLAPI_MSG_NORMAL,
                                    "%8sl_fid:     "DFID_NOBRACE"\n",
                                    " ", PFID(&fid));
@@ -2953,14 +2959,16 @@ void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
                                struct lu_fid fid = { 0 };
 
                                ostid_to_fid(&fid, &objects[i].l_ost_oi, idx);
-                               llapi_printf(LLAPI_MSG_NORMAL,
-                                   "%s%d: { l_ost_idx: %d, l_fid: "DFID" }\n",
+                               llapi_printf(LLAPI_MSG_NORMAL, hex ?
+                                   "%s%3d: { l_ost_idx: %#5x, l_fid: "DFID" }\n" :
+                                   "%s%3d: { l_ost_idx: %3d, l_fid: "DFID" }\n",
                                    space, i, idx, PFID(&fid));
                        } else {
-                               char fmt[48];
+                               char fmt[48] = { 0 };
 
                                sprintf(fmt, "%s%s%s\n",
-                                       "\t%6u\t%14llu\t%#13llx\t",
+                                       hex ? "\t%#6x\t%14llu\t%#13llx\t"
+                                           : "\t%6u\t%14llu\t%#13llx\t",
                                        (fid_seq_is_rsvd(gr) ||
                                         fid_seq_is_mdt0(gr)) ?
                                         "%14llu" : "%#14llx", "%s");
@@ -2982,6 +2990,7 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
        char *prefix = lum->lum_magic == LMV_USER_MAGIC ? "(Default)" : "";
        char *separator = "";
        bool yaml = flags & LDF_YAML;
+       bool hex = flags & LDF_HEX_IDX;
        bool obdstripe = false;
        int i;
 
@@ -3035,7 +3044,7 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
                if (verbose & ~VERBOSE_STRIPE_OFFSET)
                        llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_offset: ");
-               llapi_printf(LLAPI_MSG_NORMAL, "%d",
+               llapi_printf(LLAPI_MSG_NORMAL, hex ? "%#x" : "%d",
                             (int)lum->lum_stripe_offset);
                if (verbose & VERBOSE_HASH_TYPE && !yaml)
                        separator = " ";
@@ -3116,13 +3125,16 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name,
                if (lum->lum_stripe_count > 0)
                        llapi_printf(LLAPI_MSG_NORMAL,
                                     "mdtidx\t\t FID[seq:oid:ver]\n");
+
+               char fmt[48] = { 0 };
+               sprintf(fmt, "%s%s", hex ? "%#6x" : "%6u",
+                       "\t\t "DFID"\t\t%s\n");
                for (i = 0; i < lum->lum_stripe_count; i++) {
                        int idx = objects[i].lum_mds;
                        struct lu_fid *fid = &objects[i].lum_fid;
 
                        if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
-                               llapi_printf(LLAPI_MSG_NORMAL,
-                                            "%6u\t\t "DFID"\t\t%s\n",
+                               llapi_printf(LLAPI_MSG_NORMAL, fmt,
                                            idx, PFID(fid),
                                            obdindex == idx ? " *" : "");
                }
@@ -3862,6 +3874,8 @@ static void llapi_lov_dump_user_lmm(struct find_param *param, char *path,
                flags |= LDF_IS_RAW;
        if (param->fp_yaml)
                flags |= LDF_YAML;
+       if (param->fp_hex_idx)
+               flags |= LDF_HEX_IDX;
 
        switch (magic) {
        case LOV_USER_MAGIC_V1:
@@ -6035,6 +6049,7 @@ static int cb_get_mdt_index(char *path, int p, int *dp, void *data,
        int d = dp == NULL ? -1 : *dp;
        int ret;
        int mdtidx;
+       bool hex = param->fp_hex_idx;
 
        if (p == -1 && d == -1)
                return -EINVAL;
@@ -6077,9 +6092,10 @@ static int cb_get_mdt_index(char *path, int p, int *dp, void *data,
        }
 
        if (param->fp_quiet || !(param->fp_verbose & VERBOSE_DETAIL))
-               llapi_printf(LLAPI_MSG_NORMAL, "%d\n", mdtidx);
+               llapi_printf(LLAPI_MSG_NORMAL, hex ? "%#x\n" : "%d\n", mdtidx);
        else
-               llapi_printf(LLAPI_MSG_NORMAL, "%s\nmdt_index:\t%d\n",
+               llapi_printf(LLAPI_MSG_NORMAL, hex ? "%s\nmdt_index:\t%#x\n"
+                                                  : "%s\nmdt_index:\t%d\n",
                             path, mdtidx);
 
 out: