[\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> ...
.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 ' = '
.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" '.
.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.
" [--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"
LFS_MIRROR_ID_OPT,
LFS_MIRROR_STATE_OPT,
LFS_LAYOUT_COPY,
+ LFS_MIRROR_INDEX_OPT,
};
/* functions */
.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 }*/
{ .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;
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;
}
}
- 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)
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",
/* 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;
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 &&
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