From: Bobi Jam Date: Tue, 25 Apr 2017 01:18:44 +0000 (+0800) Subject: LU-9324 lfs: add setstripe --yaml=template parameter X-Git-Tag: 2.10.59~61 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F60%2F26860%2F34;p=fs%2Flustre-release.git LU-9324 lfs: add setstripe --yaml=template parameter Add a "lfs setstripe --yaml= " usage to set stripe using stripe info from a YAML template file. The YAML template file can be get from $ lfs getstripe --yaml and user can manually edit it to tweak stripe options. This patch fixes two cyaml issues: 1. a YAML_BLOCK_ENTRY_TOKEN can follow a YAML_VALUE_TOKEN. 2. free_node() has memory leak, it needs to free cYAML::cy_valuestring and cYAML::cy_string if possible. Test-Parameters: testlist=sanity-pfl,sanity-flr Signed-off-by: Bobi Jam Change-Id: I78149bb011fbc03387cbe3d057eb030550dd75ae Reviewed-on: https://review.whamcloud.com/26860 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Emoly Liu Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- diff --git a/lnet/utils/lnetconfig/cyaml.c b/lnet/utils/lnetconfig/cyaml.c index 0293be5..7c0ae4e 100644 --- a/lnet/utils/lnetconfig/cyaml.c +++ b/lnet/utils/lnetconfig/cyaml.c @@ -590,7 +590,8 @@ static enum cYAML_handler_error yaml_entry_token(yaml_token_t *token, struct cYAML *obj; if (tree->state != TREE_STATE_SEQ_START && - tree->state != TREE_STATE_BLK_STARTED) + tree->state != TREE_STATE_BLK_STARTED && + tree->state != TREE_STATE_VALUE) return CYAML_ERROR_UNEXPECTED_STATE; if (tree->state == TREE_STATE_SEQ_START) { @@ -678,6 +679,10 @@ static bool clean_usr_data(struct cYAML *node, void *usr_data, void **out) static bool free_node(struct cYAML *node, void *user_data, void **out) { + if (node->cy_type == CYAML_TYPE_STRING) + free(node->cy_valuestring); + if (node->cy_string) + free(node->cy_string); if (node) free(node); diff --git a/lustre/doc/lfs-getstripe.1 b/lustre/doc/lfs-getstripe.1 index 46d3e6b..22d8ea8 100644 --- a/lustre/doc/lfs-getstripe.1 +++ b/lustre/doc/lfs-getstripe.1 @@ -213,6 +213,9 @@ List information of components in a file with extent end less than 64MiB. .TP .B $ lfs getstripe -I3 --component-start /mnt/lustre/file1 Print only the component start for the component with ID of 3 +.TP +.B $ lfs getstripe --yaml /mnt/lustre/file1 +Lists the information of the components of a file in YAML format. .SH AUTHOR The lfs command is part of the Lustre filesystem. .SH SEE ALSO diff --git a/lustre/doc/lfs-setstripe.1 b/lustre/doc/lfs-setstripe.1 index 98abce4..12b904b 100644 --- a/lustre/doc/lfs-setstripe.1 +++ b/lustre/doc/lfs-setstripe.1 @@ -19,6 +19,8 @@ lfs setstripe \- set striping pattern of a file or directory default .br .B lfs setstripe -d \fR<\fIdirectory\fR> .br +.B lfs setstripe --yaml= +.br .SH DESCRIPTION .TP .B lfs setstripe \fR[\fISTRIPE_OPTIONS\fR] <\fIdirectory\fR|\fIfilename\fR> @@ -111,6 +113,13 @@ Delete the default layout on the specified directory. It is not necessary to delete the default layout on a directory before replacing it. This is only needed if the directory should revert from a directory-specific layout to using the global filesystem default layout stored on the root directory. +.TP +.B lfs setstripe --yaml= +.br +Create a file with layout information specified by a YAML format template +file, the template file can be obtained using the +.B lfs getstripe --yaml +command. .SH STRIPE_OPTIONS The various stripe related options are listed and explained below: .TP @@ -260,6 +269,11 @@ component with ID 1. .B $ lfs setstripe -E 1M -L mdt -E -1 /mnt/lustre/file1 This created file with Data-on-MDT layout. The first 1M is placed on MDT and \ rest of file is placed on OST with default striping. +.TP +.B $ lfs setstripe --yaml=/tmp/layout_yaml /mnt/lustre/file2 +This creates a file with layout specified by a layout template which can be \ +obtained with \fBlfs getstripe --yaml\fR command. + .SH SEE ALSO .BR lfs (1), .BR lfs-migrate (1), diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1 index 2c72790..29cd139 100644 --- a/lustre/doc/lfs.1 +++ b/lustre/doc/lfs.1 @@ -126,6 +126,8 @@ lfs \- client utility for Lustre-specific file layout and other attributes .B lfs setstripe --component-del {--component-id|-I id | \fB--component-flags } .br +.B lfs setstripe --yaml= +.br .B lfs --version .br .B lfs --list-commands diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index 617ffcd..c6a15f3 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -873,6 +873,10 @@ int llapi_layout_mirror_id_get(const struct llapi_layout *layout, uint32_t *id); */ int llapi_layout_comp_add(struct llapi_layout *layout); /** + * Adds a first component of a mirror to the existing composite layout. + */ +int llapi_layout_add_first_comp(struct llapi_layout *layout); +/** * Deletes the current layout component from the composite layout. */ int llapi_layout_comp_del(struct llapi_layout *layout); diff --git a/lustre/tests/sanity-flr.sh b/lustre/tests/sanity-flr.sh index 3d87ba5..bdcb3bf 100644 --- a/lustre/tests/sanity-flr.sh +++ b/lustre/tests/sanity-flr.sh @@ -1763,6 +1763,31 @@ test_44() { } run_test 44 "lfs mirror split check" +test_45() { + [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return + + local file=$DIR/$tdir/$tfile + local dir=$DIR/$tdir/$dir + local temp=$DIR/$tdir/template + rm -rf $DIR/$tdir + test_mkdir $DIR/$tdir + + $LFS setstripe -N -E1m -c2 -o0,1 -E2m -Eeof -N -E4m -Eeof \ + -N -E3m -Eeof -N -E8m -Eeof $file || error "Create $file failed" + + echo "getstripe --yaml $file" + $LFS getstripe --yaml $file > $temp || error "getstripe $file failed" + echo "setstripe --yaml=$temp $file.2" + $LFS setstripe --yaml=$temp $file.2 || error "setstripe $file.2 failed" + + echo "compare layout" + local layout1=$(get_layout_param $file) + local layout2=$(get_layout_param $file.2) + [ "$layout1" == "$layout2" ] || + error "FLR file $file/$file.2 layouts are not equal" +} +run_test 45 "Verify setstripe/getstripe with YAML with FLR file" + ctrl_file=$(mktemp /tmp/CTRL.XXXXXX) lock_file=$(mktemp /var/lock/FLR.XXXXXX) diff --git a/lustre/tests/sanity-pfl.sh b/lustre/tests/sanity-pfl.sh index 3f9083b..ca63b90 100644 --- a/lustre/tests/sanity-pfl.sh +++ b/lustre/tests/sanity-pfl.sh @@ -636,6 +636,74 @@ test_15() { } run_test 15 "Verify component options for lfs find" +verify_16() { + local src=$1 + local dst=$2 + local temp=$3 + local msg_prefix=$4 + + echo "getstripe --yaml $src" + $LFS getstripe --yaml $src > $temp || error "getstripe $src failed" + echo "setstripe --yaml=$temp $dst" + $LFS setstripe --yaml=$temp $dst|| error "setstripe $dst failed" + + echo "compare" + local layout1=$(get_layout_param $src) + local layout2=$(get_layout_param $dst) + # compare their layout info + [ "$layout1" == "$layout2" ] || + error "$msg_prefix $src/$dst layouts are not equal" +} + +test_16() { + [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return + + local file=$DIR/$tdir/$tfile + local dir=$DIR/$tdir/dir + local temp=$DIR/$tdir/template + rm -rf $DIR/$tdir + test_mkdir $DIR/$tdir + + ##################################################################### + # 1. PFL file + # set stripe for source file + $LFS setstripe -E1m -c2 -o0,1 -E2m -c2 -E3m -o1,0 -E4m -c1 -E-1 $file || + error "Create $file failed" + + echo "1. PFL file" + verify_16 $file $file.copy $temp "1. PFL file" + + ##################################################################### + # 2. plain file + # set stripe for source file + rm -f $file + $LFS setstripe -c2 -o0,1 -i1 $file || error "Create $file failed" + + rm -f $file.copy + echo "2. plain file" + verify_16 $file $file.copy $temp "2. plain file" + + ##################################################################### + # 3. PFL dir + # set stripe for source dir + test_mkdir $dir + $LFS setstripe -E1m -c2 -E2m -c1 -E-1 $dir || + error "setstripe $dir failed" + + test_mkdir $dir.copy + echo "3. PFL dir" + verify_16 $dir $dir.copy $temp.dir "3. PFL dir" + + ##################################################################### + # 4. plain dir + # set stripe for source dir + $LFS setstripe -c2 -i-1 $dir || error "setstripe $dir failed" + + echo "4. plain dir" + verify_16 $dir $dir.copy $temp.dir "4. plain dir" +} +run_test 16 "Verify setstripe/getstripe with YAML config file" + test_17() { [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return local file=$DIR/$tdir/$tfile diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 43ca575..2f1a301 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -2,7 +2,6 @@ AM_CFLAGS := -fPIC -D_GNU_SOURCE \ -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DLUSTRE_UTILS=1 -AM_LDFLAGS := -L$(top_builddir)/lnet/utils if TESTS EXTRA_PROGRAMS = wirecheck @@ -61,6 +60,7 @@ lctl_DEPENDENCIES := liblustreapi.la lfs_SOURCES = lfs.c lfs_project.c lfs_project.h lfs_LDADD := liblustreapi.la -lz +lfs_LDADD += $(top_builddir)/lnet/utils/lnetconfig/liblnetconfig.la lfs_DEPENDENCIES := liblustreapi.la lustre_rsync_SOURCES = lustre_rsync.c lustre_rsync.h callvpe.c callvpe.h diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 1020567..fbddb03 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -73,6 +73,7 @@ #include #include #include +#include #ifndef ARRAY_SIZE # define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0]))) @@ -160,7 +161,8 @@ static inline int lfs_mirror_split(int argc, char **argv) " [--stripe-size|-S ]\n" \ " [--layout|-L ]\n" \ " [--pool|-p ]\n" \ - " [--ost|-o ]\n" + " [--ost|-o ]\n" \ + " [--yaml|-y ]\n" #define SSM_HELP_COMMON \ "\tstripe_count: Number of OSTs to stripe over (0=fs default, -1 all)\n" \ @@ -180,7 +182,10 @@ static inline int lfs_mirror_split(int argc, char **argv) "\tcomp_end: Extent end of component, start after previous end.\n"\ "\t Can be specified with K, M or G (for KB, MB, GB\n" \ "\t respectively, -1 for EOF). Must be a multiple of\n"\ - "\t stripe_size.\n" + "\t stripe_size.\n" \ + "\tyaml_template_file:\n" \ + "\t YAML layout template file, can't be used with -c,\n" \ + "\t -i, -S, -p, -o, or -E arguments.\n" #define MIRROR_CREATE_HELP \ "\tmirror_count: Number of mirrors to be created with the upcoming\n" \ @@ -1915,13 +1920,18 @@ struct lfs_setstripe_args { __u32 lsa_comp_flags; __u32 lsa_comp_neg_flags; unsigned long long lsa_pattern; + unsigned int lsa_mirror_count; int lsa_nr_tgts; + bool lsa_first_comp; __u32 *lsa_tgts; char *lsa_pool_name; }; static inline void setstripe_args_init(struct lfs_setstripe_args *lsa) { + unsigned int mirror_count = lsa->lsa_mirror_count; + bool first_comp = lsa->lsa_first_comp; + memset(lsa, 0, sizeof(*lsa)); lsa->lsa_stripe_size = LLAPI_LAYOUT_DEFAULT; @@ -1929,6 +1939,9 @@ static inline void setstripe_args_init(struct lfs_setstripe_args *lsa) lsa->lsa_stripe_off = LLAPI_LAYOUT_DEFAULT; lsa->lsa_pattern = LLAPI_LAYOUT_RAID0; lsa->lsa_pool_name = NULL; + + lsa->lsa_mirror_count = mirror_count; + lsa->lsa_first_comp = first_comp; } /** @@ -1978,7 +1991,8 @@ static inline bool setstripe_args_specified(struct lfs_setstripe_args *lsa) * Return: 0 on success or an error code on failure. */ static int comp_args_to_layout(struct llapi_layout **composite, - struct lfs_setstripe_args *lsa) + struct lfs_setstripe_args *lsa, + bool set_extent) { struct llapi_layout *layout = *composite; uint64_t prev_end = 0; @@ -2004,19 +2018,30 @@ static int comp_args_to_layout(struct llapi_layout **composite, return rc; } - rc = llapi_layout_comp_add(layout); + if (lsa->lsa_first_comp) + prev_end = 0; + + if (lsa->lsa_first_comp) + rc = llapi_layout_add_first_comp(layout); + else + rc = llapi_layout_comp_add(layout); if (rc) { fprintf(stderr, "Add component failed. %s\n", strerror(errno)); return rc; } } + /* reset lsa_first_comp */ + lsa->lsa_first_comp = false; - rc = llapi_layout_comp_extent_set(layout, prev_end, lsa->lsa_comp_end); - if (rc) { - fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n", - prev_end, lsa->lsa_comp_end, strerror(errno)); - return rc; + if (set_extent) { + rc = llapi_layout_comp_extent_set(layout, prev_end, + lsa->lsa_comp_end); + if (rc) { + fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n", + prev_end, lsa->lsa_comp_end, strerror(errno)); + return rc; + } } /* Data-on-MDT component setting */ @@ -2106,7 +2131,7 @@ static int comp_args_to_layout(struct llapi_layout **composite, lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT && lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE && lsa->lsa_nr_tgts != lsa->lsa_stripe_count) { - fprintf(stderr, "stripe_count(%lld) != nr_osts(%d)\n", + fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n", lsa->lsa_stripe_count, lsa->lsa_nr_tgts); return -EINVAL; } @@ -2116,7 +2141,8 @@ static int comp_args_to_layout(struct llapi_layout **composite, if (rc) break; } - } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT) { + } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT && + lsa->lsa_stripe_off != -1) { rc = llapi_layout_ost_index_set(layout, 0, lsa->lsa_stripe_off); } if (rc) { @@ -2128,6 +2154,140 @@ static int comp_args_to_layout(struct llapi_layout **composite, return 0; } +static int build_component(struct llapi_layout **layout, + struct lfs_setstripe_args *lsa, bool set_extent) +{ + int rc; + + rc = comp_args_to_layout(layout, lsa, set_extent); + if (rc) + return rc; + + if (lsa->lsa_mirror_count > 0) { + rc = llapi_layout_mirror_count_set(*layout, + lsa->lsa_mirror_count); + if (rc) + return rc; + + rc = llapi_layout_flags_set(*layout, LCM_FL_RDONLY); + if (rc) + return rc; + lsa->lsa_mirror_count = 0; + } + + return rc; +} + +static int build_layout_from_yaml_node(struct cYAML *node, + struct llapi_layout **layout, + struct lfs_setstripe_args *lsa, + __u32 *osts) +{ + char *string; + int rc = 0; + + while (node) { + string = node->cy_string; + /* skip leading lmm_ if present, to simplify parsing */ + if (string != NULL && strncmp(string, "lmm_", 4) == 0) + string += 4; + + if (node->cy_type == CYAML_TYPE_STRING) { + if (!strcmp(string, "lcme_extent.e_end")) { + if (!strcmp(node->cy_valuestring, "EOF") || + !strcmp(node->cy_valuestring, "eof")) + lsa->lsa_comp_end = LUSTRE_EOF; + } else if (!strcmp(string, "pool")) { + lsa->lsa_pool_name = node->cy_valuestring; + } else if (!strcmp(string, "pattern")) { + if (!strcmp(node->cy_valuestring, "mdt")) + lsa->lsa_pattern = LLAPI_LAYOUT_MDT; + } + } else if (node->cy_type == CYAML_TYPE_NUMBER) { + if (!strcmp(string, "lcm_mirror_count")) { + lsa->lsa_mirror_count = node->cy_valueint; + } else if (!strcmp(string, "lcme_extent.e_start")) { + if (node->cy_valueint != 0 || *layout != NULL) { + rc = build_component(layout, lsa, true); + if (rc) + return rc; + } + + if (node->cy_valueint == 0) + lsa->lsa_first_comp = true; + + /* initialize lsa */ + setstripe_args_init(lsa); + lsa->lsa_tgts = osts; + } else if (!strcmp(string, "lcme_extent.e_end")) { + if (node->cy_valueint == -1) + lsa->lsa_comp_end = LUSTRE_EOF; + else + lsa->lsa_comp_end = node->cy_valueint; + } else if (!strcmp(string, "stripe_count")) { + lsa->lsa_stripe_count = node->cy_valueint; + } else if (!strcmp(string, "stripe_size")) { + lsa->lsa_stripe_size = node->cy_valueint; + } else if (!strcmp(string, "stripe_offset")) { + lsa->lsa_stripe_off = node->cy_valueint; + } else if (!strcmp(string, "l_ost_idx")) { + osts[lsa->lsa_nr_tgts] = node->cy_valueint; + lsa->lsa_nr_tgts++; + } + } else if (node->cy_type == CYAML_TYPE_OBJECT) { + /* go deep to sub blocks */ + rc = build_layout_from_yaml_node(node->cy_child, layout, + lsa, osts); + if (rc) + return rc; + } + node = node->cy_next; + } + + return rc; +} + +static int lfs_comp_create_from_yaml(char *template, + struct llapi_layout **layout, + struct lfs_setstripe_args *lsa, + __u32 *osts) +{ + struct cYAML *tree = NULL, *err_rc = NULL; + int rc = 0; + + tree = cYAML_build_tree(template, NULL, 0, &err_rc, false); + if (!tree) { + fprintf(stderr, "%s: cannot parse YAML file %s\n", + progname, template); + cYAML_build_error(-EINVAL, -1, "yaml", "from comp yaml", + "can't parse", &err_rc); + cYAML_print_tree2file(stderr, err_rc); + cYAML_free_tree(err_rc); + rc = -EINVAL; + goto err; + } + + /* initialize lsa for plain file */ + setstripe_args_init(lsa); + lsa->lsa_tgts = osts; + + rc = build_layout_from_yaml_node(tree, layout, lsa, osts); + if (rc) { + fprintf(stderr, "%s: cannot build layout from YAML file %s.\n", + progname, template); + goto err; + } else { + rc = build_component(layout, lsa, *layout != NULL); + } + /* clean clean lsa */ + setstripe_args_init(lsa); + +err: + if (tree) + cYAML_free_tree(tree); + return rc; +} + /* In 'lfs setstripe --component-add' mode, we need to fetch the extent * end of the last component in the existing file, and adjust the * first extent start of the components to be added accordingly. */ @@ -2305,14 +2465,14 @@ enum { static int lfs_setstripe_internal(int argc, char **argv, enum setstripe_origin opc) { - struct lfs_setstripe_args lsa; + struct lfs_setstripe_args lsa = { 0 }; struct llapi_stripe_param *param = NULL; struct find_param migrate_mdt_param = { .fp_max_depth = -1, .fp_mdt_index = -1, }; char *fname; - int result; + int result = 0; int result2 = 0; char *end; int c; @@ -2337,6 +2497,8 @@ static int lfs_setstripe_internal(int argc, char **argv, struct mirror_args *last_mirror = NULL; __u16 mirror_id = 0; char cmd[PATH_MAX]; + bool from_yaml = false; + char *template = NULL; struct option long_opts[] = { /* find { .val = 'A', .name = "atime", .has_arg = required_argument }*/ @@ -2410,7 +2572,7 @@ static int lfs_setstripe_internal(int argc, char **argv, /* find { .val = 'U', .name = "user", .has_arg = required_argument }*/ /* --verbose is only valid in migrate mode */ { .val = 'v', .name = "verbose", .has_arg = no_argument}, -/* getstripe { .val = 'y', .name = "yaml", .has_arg = no_argument }, */ + { .val = 'y', .name = "yaml", .has_arg = required_argument }, { .name = NULL } }; setstripe_args_init(&lsa); @@ -2420,7 +2582,7 @@ static int lfs_setstripe_internal(int argc, char **argv, snprintf(cmd, sizeof(cmd), "%s %s", progname, argv[0]); progname = cmd; - while ((c = getopt_long(argc, argv, "bc:dDE:f:i:I:m:N::no:p:L:s:S:v", + while ((c = getopt_long(argc, argv, "bc:dDE:f:i:I:m:N::no:p:L:s:S:vy:", long_opts, NULL)) >= 0) { switch (c) { case 0: @@ -2541,7 +2703,7 @@ static int lfs_setstripe_internal(int argc, char **argv, break; case 'E': if (lsa.lsa_comp_end != 0) { - result = comp_args_to_layout(lpp, &lsa); + result = comp_args_to_layout(lpp, &lsa, true); if (result) { fprintf(stderr, "%s %s: invalid layout\n", @@ -2681,7 +2843,7 @@ static int lfs_setstripe_internal(int argc, char **argv, if (lsa.lsa_comp_end == 0) lsa.lsa_comp_end = LUSTRE_EOF; - result = comp_args_to_layout(lpp, &lsa); + result = comp_args_to_layout(lpp, &lsa, true); if (result) { lfs_mirror_free(new_mirror); goto error; @@ -2744,6 +2906,10 @@ static int lfs_setstripe_internal(int argc, char **argv, } migrate_mdt_param.fp_verbose = VERBOSE_DETAIL; break; + case 'y': + from_yaml = true; + template = optarg; + break; default: fprintf(stderr, "%s %s: unrecognized option '%s'\n", progname, argv[0], argv[optind - 1]); @@ -2773,7 +2939,7 @@ static int lfs_setstripe_internal(int argc, char **argv, } if (lsa.lsa_comp_end != 0) { - result = comp_args_to_layout(lpp, &lsa); + result = comp_args_to_layout(lpp, &lsa, true); if (result) goto error; } @@ -2867,6 +3033,13 @@ static int lfs_setstripe_internal(int argc, char **argv, goto error; } + if (from_yaml && (setstripe_args_specified(&lsa) || layout != NULL)) { + fprintf(stderr, "error: %s: can't specify --yaml with " + "-c, -S, -i, -o, -p or -E options.\n", + argv[0]); + goto error; + } + if (mdt_idx_arg != NULL && optind > 3) { fprintf(stderr, "%s %s: option -m cannot be used with other options\n", @@ -2943,6 +3116,18 @@ static int lfs_setstripe_internal(int argc, char **argv, } } + if (from_yaml) { + /* generate a layout from a YAML template */ + result = lfs_comp_create_from_yaml(template, &layout, + &lsa, osts); + if (result) { + fprintf(stderr, "error: %s: can't create composite " + "layout from template file %s\n", + argv[0], template); + goto error; + } + } + for (fname = argv[optind]; fname != NULL; fname = argv[++optind]) { if (mdt_idx_arg != NULL) { result = llapi_migrate_mdt(fname, &migrate_mdt_param); @@ -4404,7 +4589,7 @@ static int lfs_setdirstripe(int argc, char **argv) { char *dname; int result; - struct lfs_setstripe_args lsa; + struct lfs_setstripe_args lsa = { 0 }; struct llapi_stripe_param *param = NULL; __u32 mdts[LMV_MAX_STRIPE_COUNT] = { 0 }; char *end; @@ -4434,6 +4619,7 @@ static int lfs_setdirstripe(int argc, char **argv) { .val = 't', .name = "hash-type", .has_arg = required_argument }, #endif { .val = 'T', .name = "mdt-count", .has_arg = required_argument }, +/* setstripe { .val = 'y', .name = "yaml", .has_arg = no_argument }, */ { .name = NULL } }; setstripe_args_init(&lsa); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index b3dd226..2c23a1a 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -2580,7 +2580,7 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, layout2name(lum->lmm_pattern)); else llapi_printf(LLAPI_MSG_NORMAL, "%x", lum->lmm_pattern); - separator = is_dir ? " " : "\n"; + separator = (!yaml && is_dir) ? " " : "\n"; } if ((verbose & VERBOSE_GENERATION) && !is_dir) { @@ -2589,7 +2589,7 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, llapi_printf(LLAPI_MSG_NORMAL, "%s%slayout_gen: ", space, prefix); llapi_printf(LLAPI_MSG_NORMAL, "%u", - (int)lum->lmm_layout_gen); + skip_objs ? 0 : (int)lum->lmm_layout_gen); separator = "\n"; } diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index 4b0adbd..d179a09 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -1687,7 +1687,7 @@ int llapi_layout_comp_extent_set(struct llapi_layout *layout, if (comp->llc_list.prev != &layout->llot_comp_list) { prev = list_entry(comp->llc_list.prev, typeof(*prev), llc_list); - if (start != prev->llc_extent.e_end) { + if (start != 0 && start != prev->llc_extent.e_end) { errno = EINVAL; return -1; } @@ -1696,7 +1696,8 @@ int llapi_layout_comp_extent_set(struct llapi_layout *layout, if (comp->llc_list.next != &layout->llot_comp_list) { next = list_entry(comp->llc_list.next, typeof(*next), llc_list); - if (end != next->llc_extent.e_start) { + if (next->llc_extent.e_start != 0 && + end != next->llc_extent.e_start) { errno = EINVAL; return -1; } @@ -1875,6 +1876,37 @@ int llapi_layout_comp_add(struct llapi_layout *layout) return 0; } +/** + * Adds a first component of a mirror to \a layout. + * The \a layout will change it's current component pointer to + * the newly added component, and it'll be turned into a composite + * layout if it was not before the adding. + * + * \param[in] layout existing composite or plain layout + * + * \retval 0 on success + * \retval <0 if error occurs + */ +int llapi_layout_add_first_comp(struct llapi_layout *layout) +{ + struct llapi_layout_comp *comp, *new; + + comp = __llapi_layout_cur_comp(layout); + if (comp == NULL) + return -1; + + new = __llapi_comp_alloc(0); + if (new == NULL) + return -1; + + new->llc_extent.e_start = 0; + + list_add_tail(&new->llc_list, &layout->llot_comp_list); + layout->llot_cur_comp = new; + layout->llot_is_composite = true; + + return 0; +} /** * Deletes current component from the composite layout. The component