Whamcloud - gitweb
LU-11138 lfs: getstripe display certain mirror(s) 04/32804/5
authorBobi Jam <bobijam@whamcloud.com>
Tue, 10 Jul 2018 18:07:01 +0000 (12:07 -0600)
committerOleg Drokin <green@whamcloud.com>
Tue, 24 Jul 2018 16:01:19 +0000 (16:01 +0000)
Add [!] --mirror-index=[+-]<index> | [!] --mirror-id=[+-]<id>
option for lfs getstripe to print the components of mirror(s)
relative to <index>-th mirror or components of mirror(s) relative
to the one with mirror ID of <id>.

Change-Id: I9ab8fd5faaea07b7567f88665e06ca71157cca67
Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/32804
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@gmail.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-getstripe.1
lustre/include/lustre/lustreapi.h
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 98c1156..e8a18cc 100644 (file)
@@ -21,6 +21,7 @@ lfs getstripe \- Lustre client command to print layout parameters of a file
 [\fB--stripe-count\fR|\fB-c\fR]
 [\fB--stripe-index\fR|\fB-i\fR]
       [\fB--stripe-size\fR|\fB-S\fR]
+[[\fB!\fR] \fB--mirror-index\fR=[\fB+-\fR]\fI<index>\fR | [\fB!\fR] \fB--mirror-id\fR=[\fB+-\fR]\fI<id>\fR]
 [\fB--verbose\fR|\fB-v\fR]
 [\fB--yaml\fR|\fB-y\fR]
       <\fIdirname\fR|\fIfilename\fR> ...
@@ -41,18 +42,24 @@ specific layout information to be printed, then the
 .BR --component-count ,
 .BR --component-start ,
 .BR --component-end ,
-or
 .BR --pool
+or
+.BR --mirror-index
+or
+.BR --mirror-id
 options, or equivalent single-character options, can be used without an
 argument to return only the specified field(s).
 .PP
-You can limit the displayed content to one or more specific components of
-a composite file layout by specifying the matching parameter(s) for the
+You can limit the displayed content to one or more specific components or
+mirror of a composite file layout by specifying the matching
+parameter(s) for the
 .BR --component-id ,
 .BR --component-flags ,
 .BR --component-start ,
-and
 .BR --component-end ,
+.BR --mirror-index ,
+or
+.BR --mirror-id ,
 or their single-character options. For single-character options, the
 argument must follow the option without a space, and for long options an
 .RB ' = '
@@ -131,6 +138,43 @@ is used, print components with respectively a larger or smaller
 .I start
 offset.
 .TP
+.BR --mirror-index = [\fB+-\fR]\fR<\fIindex\fR>
+Print only the components of \fI<index>\fR-th mirror, based on the order
+that the mirror components are stored in the file layout, The \fIindex\fR
+starts at 1. If
+.BI + index
+or
+.BI - index
+is used, print components of mirror(s) respectively a later or earlier
+\fIindex\fR-th mirror.
+.RS 1.2i
+.TP
+.B !
+Negates the meaning. Using + before \fIindex\fR means mirror appears 'later
+than \fIindex\fR',
+- before \fIindex\fR means mirror appears 'earlier than \fIindex\fR'. If
+neither is used, it means 'equal to \fIindex\fR'.
+.RE
+.TP
+.BR --mirror-id = [\fB+-\fR]\fR<\fIid\fR>
+Print only the component s of the mirror with ID of \fIid\fR. The mirror IDs
+are assigned to new mirrors as they are created, but may not be sequential if
+some mirrors are removed. If
+.BI + id
+or
+.BI - id
+is used, print components of mirror(s) with respectively a larger or smaller
+mirror ID of
+.I id
+.
+.RS 1.2i
+.TP
+.B !
+Negates the meaning. Using + before \fIid\fR means mirror with ID 'larger
+than \fIid\fR', - before \fIid\fR means mirror with ID 'smaller than \fIid\fR'.
+If neither is used, it means 'equal to \fIid\fR'.
+.RE
+.TP
 .BR --directory | -d
 Get striping information for only the specified directory, like
 .RB ' "ls -d" '.
@@ -202,11 +246,17 @@ List the detailed object allocation of the given file.
 .B $ lfs getstripe -v -I2 /mnt/lustre/file1
 List the detailed information of only component with ID 2 of the given file.
 .TP
+.B $ lfs getstripe --mirror-index=+1 /mnt/lustre/file1
+Print the mirror(s) appearing later than the first mirror in the the file.
+.TP
+.B $ lfs getstripe ! --mirror-id=2 /mnt/lustre/file1
+Print the mirror(s) with mirror ID other than 2 in the file.
+.TP
 .B $ lfs getstripe --component-flags=^init -I /mnt/lustre/file1
 Print only the component IDs for all the uninitialized components.
 .TP
 .B $ lfs getstripe --component-flags=init,^stale -I /mnt/lustre/file1
-Print only the component(s) that are instantiated but not stale
+Print only the component(s) that are instantiated but not stale.
 .TP
 .B $ lfs getstripe -E-64M /mnt/lustre/file1
 List information of components in a file with extent end less than 64MiB.
index 5df3050..59f7129 100644 (file)
@@ -198,6 +198,8 @@ struct find_param {
                                 fp_comp_end_sign:2,
                                 fp_comp_count_sign:2,
                                 fp_mirror_count_sign:2,
+                                fp_mirror_index_sign:2,
+                                fp_mirror_id_sign:2,
                                 fp_mdt_count_sign:2,
                                 fp_blocks_sign:2;
        unsigned long long       fp_size;
@@ -244,6 +246,10 @@ struct find_param {
                                 fp_exclude_comp_end:1,
                                 fp_check_comp_id:1,
                                 fp_exclude_comp_id:1,
+                                fp_check_mirror_id:1,
+                                fp_exclude_mirror_id:1,
+                                fp_check_mirror_index:1,
+                                fp_exclude_mirror_index:1,
                                 fp_check_mdt_count:1,
                                 fp_exclude_mdt_count:1,
                                 fp_check_hash_type:1,
@@ -291,6 +297,8 @@ struct find_param {
        __u16                    fp_mirror_state;
        __u16                    fp_mirror_neg_state;
        __u32                    fp_comp_id;
+       __u16                    fp_mirror_id;
+       __u16                    fp_mirror_index;
        unsigned long long       fp_comp_start;
        unsigned long long       fp_comp_start_units;
        unsigned long long       fp_comp_end;
index 9a5ecdf..37855f1 100644 (file)
@@ -335,6 +335,8 @@ command_t cmdlist[] = {
         "                 [--component-count]\n"
         "                 [--component-start[=[+-]comp_start]]\n"
         "                 [--component-end[=[+-]comp_end]|-E[[+-]comp_end]]\n"
+        "                 [[!] --mirror-index=[+-]<index> |\n"
+        "                  [!] --mirror-id=[+-]<id>]\n"
         "                 <directory|filename> ..."},
        {"setdirstripe", lfs_setdirstripe, 0,
         "To create a striped directory on a specified MDT. This can only\n"
@@ -2503,6 +2505,7 @@ enum {
        LFS_MIRROR_ID_OPT,
        LFS_MIRROR_STATE_OPT,
        LFS_LAYOUT_COPY,
+       LFS_MIRROR_INDEX_OPT,
 };
 
 /* functions */
@@ -4002,6 +4005,10 @@ 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 = '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 }*/
@@ -4040,11 +4047,36 @@ static int lfs_getstripe_internal(int argc, char **argv,
        { .val = 'y',   .name = "yaml",         .has_arg = no_argument },
        { .name = NULL } };
        int c, rc;
+       int neg_opt = 0;
+       int pathstart = -1, pathend = -1;
+       int isoption;
        char *end, *tmp;
 
-       while ((c = getopt_long(argc, argv, "cdDE::FghiI::LmMoO:pqrRsSvy",
-                               long_opts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv,
+                       "-cdDE::FghiI::LmMoO:pqrRsSvy",
+                       long_opts, NULL)) != -1) {
+               if (neg_opt)
+                       --neg_opt;
+
+               /* '!' is part of option */
+               isoption = (c != 1) || (strcmp(optarg, "!") == 0);
+               if (!isoption && pathend != -1) {
+                       fprintf(stderr,
+                               "error: %s: filename|dirname must either precede options or follow options\n",
+                               argv[0]);
+                       return CMD_HELP;
+               }
+               if (!isoption && pathstart == -1)
+                       pathstart = optind - 1;
+               if (isoption && pathstart != -1 && pathend == -1)
+                       pathend = optind - 2;
+
                switch (c) {
+               case 1:
+                       /* unknown: opt is "!" */
+                       if (strcmp(optarg, "!") == 0)
+                               neg_opt = 2;
+                       break;
                case 'c':
                        if (!(param->fp_verbose & VERBOSE_DETAIL)) {
                                param->fp_verbose |= VERBOSE_COUNT;
@@ -4098,6 +4130,58 @@ static int lfs_getstripe_internal(int argc, char **argv,
                                param->fp_max_depth = 0;
                        }
                        break;
+               case LFS_MIRROR_INDEX_OPT:
+                       if (optarg[0] == '+') {
+                               param->fp_mirror_index_sign = -1;
+                               optarg++;
+                       } else if (optarg[0] == '-') {
+                               param->fp_mirror_index_sign = 1;
+                               optarg++;
+                       }
+
+                       param->fp_mirror_index = strtoul(optarg, &end, 0);
+                       if (*end != '\0' || (param->fp_mirror_index == 0 &&
+                           param->fp_mirror_index_sign == 0 && neg_opt == 0)) {
+                               fprintf(stderr,
+                                       "%s %s: invalid mirror index '%s'\n",
+                                       progname, argv[0], optarg);
+                               return CMD_HELP;
+                       }
+                       if (param->fp_mirror_id != 0) {
+                               fprintf(stderr,
+                                       "%s %s: can't specify both mirror index and mirror ID\n",
+                                       progname, argv[0]);
+                               return CMD_HELP;
+                       }
+                       param->fp_check_mirror_index = 1;
+                       param->fp_exclude_mirror_index = !!neg_opt;
+                       break;
+               case LFS_MIRROR_ID_OPT:
+                       if (optarg[0] == '+') {
+                               param->fp_mirror_id_sign = -1;
+                               optarg++;
+                       } else if (optarg[0] == '-') {
+                               param->fp_mirror_id_sign = 1;
+                               optarg++;
+                       }
+
+                       param->fp_mirror_id = strtoul(optarg, &end, 0);
+                       if (*end != '\0' || (param->fp_mirror_id == 0 &&
+                           param->fp_mirror_id_sign == 0 && neg_opt == 0)) {
+                               fprintf(stderr,
+                                       "%s %s: invalid mirror ID '%s'\n",
+                                       progname, argv[0], optarg);
+                               return CMD_HELP;
+                       }
+                       if (param->fp_mirror_index != 0) {
+                               fprintf(stderr,
+                                       "%s %s: can't specify both mirror index and mirror ID\n",
+                                       progname, argv[0]);
+                               return CMD_HELP;
+                       }
+                       param->fp_check_mirror_id = 1;
+                       param->fp_exclude_mirror_id = !!neg_opt;
+                       break;
                case 'd':
                        param->fp_max_depth = 0;
                        break;
@@ -4228,7 +4312,16 @@ static int lfs_getstripe_internal(int argc, char **argv,
                }
        }
 
-       if (optind >= argc)
+       if (pathstart == -1) {
+               fprintf(stderr, "error: %s: no filename|pathname\n",
+                               argv[0]);
+               return CMD_HELP;
+       } else if (pathend == -1) {
+               /* no options */
+               pathend = argc;
+       }
+
+       if (pathend > argc)
                return CMD_HELP;
 
        if (param->fp_recursive)
@@ -4242,8 +4335,8 @@ static int lfs_getstripe_internal(int argc, char **argv,
                param->fp_verbose = VERBOSE_OBJID;
 
        do {
-               rc = llapi_getstripe(argv[optind], param);
-       } while (++optind < argc && !rc);
+               rc = llapi_getstripe(argv[pathstart], param);
+       } while (++pathstart < pathend && !rc);
 
        if (rc)
                fprintf(stderr, "error: %s failed for %s.\n",
index 40c6c65..01bd95e 100644 (file)
@@ -3110,7 +3110,8 @@ print_last_init_comp(struct find_param *param)
 
        /* print specific component info */
        if (param->fp_check_comp_id || param->fp_check_comp_flags ||
-           param->fp_check_comp_start || param->fp_check_comp_end)
+           param->fp_check_comp_start || param->fp_check_comp_end ||
+           param->fp_check_mirror_id || param->fp_check_mirror_index)
                return false;
 
        return true;
@@ -3201,6 +3202,8 @@ static void lov_dump_comp_v1(struct find_param *param, char *path,
        int obdindex = param->fp_obd_index;
        int i, j, match;
        bool obdstripe = false;
+       __u16 mirror_index = 0;
+       __u16 mirror_id = 0;
 
        if (obdindex != OBD_NOT_FOUND) {
                for (i = 0; !(flags & LDF_IS_DIR) && !obdstripe &&
@@ -3261,6 +3264,32 @@ static void lov_dump_comp_v1(struct find_param *param, char *path,
                                continue;
                }
 
+               if (param->fp_check_mirror_index) {
+                       if (mirror_id != mirror_id_of(entry->lcme_id)) {
+                               mirror_index++;
+                               mirror_id = mirror_id_of(entry->lcme_id);
+                       }
+
+                       match = find_value_cmp(mirror_index,
+                                              param->fp_mirror_index,
+                                              param->fp_mirror_index_sign,
+                                              param->fp_exclude_mirror_index,
+                                              1, 0);
+                       if (match == -1)
+                               continue;
+               } else if (param->fp_check_mirror_id) {
+                       if (mirror_id != mirror_id_of(entry->lcme_id))
+                               mirror_id = mirror_id_of(entry->lcme_id);
+
+                       match = find_value_cmp(mirror_id,
+                                              param->fp_mirror_id,
+                                              param->fp_mirror_id_sign,
+                                              param->fp_exclude_mirror_id,
+                                              1, 0);
+                       if (match == -1)
+                               continue;
+               }
+
                if (print_last_init_comp(param)) {
                        /**
                         * if part of stripe info is needed, we'd print only