From 311a3bb4ca735a73afc8c9086ed4cbde85f8fcda Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Fri, 24 Nov 2017 12:41:59 +0800 Subject: [PATCH] LU-9771 flr: mirror resync multiple files mirror resync multiple files in one command line. Signed-off-by: Bobi Jam Change-Id: I4e301070f678fbad2dd8663d52ded7294ad5dad5 Reviewed-on: https://review.whamcloud.com/30242 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jinshan Xiong --- lustre/doc/lfs-mirror-resync.1 | 14 +-- lustre/tests/sanity-flr.sh | 15 ++- lustre/utils/lfs.c | 209 +++++++++++++++++++++++------------------ 3 files changed, 140 insertions(+), 98 deletions(-) diff --git a/lustre/doc/lfs-mirror-resync.1 b/lustre/doc/lfs-mirror-resync.1 index 11eea0f..8ae9ba9 100644 --- a/lustre/doc/lfs-mirror-resync.1 +++ b/lustre/doc/lfs-mirror-resync.1 @@ -4,26 +4,28 @@ lfs mirror resync \- resynchronize an out-of-sync mirrored file .SH SYNOPSIS .B lfs mirror resync [\fB\-\-only\fR <\fImirror_id\fR[,...]>] -<\fImirrored_file\fR> +<\fImirrored_file\fR> [<\fImirrored_file2\fR>...] .SH DESCRIPTION -This command resynchronizes an out-of-sync mirrored file specified by the path +This command resynchronizes out-of-sync mirrored file(s) specified by the path name \fImirrored_file\fR. .br -If there is no stale mirror for the \fImirrored_file\fR, then the command does +If there is no stale mirror for the \fImirrored_file(s)\fR, then the command does nothing. Otherwise, it will copy data from synced mirror to stale mirror(s), and mark all successfully copied mirror(s) as SYNC. If \fB\-\-only\fR <\fImirror_id\fR[,...]> option is specified, then the command will resynchronize the mirror(s) specified by the \fImirror_id\fR(s). +This option cannot be used when multiple mirrored files are specified. .SH OPTIONS .TP .BR \-\-only\fR\ <\fImirror_id\fR[,...]> This option indicates which mirror(s) specified by \fImirror_id\fR(s) needs to be resynchronized. The \fImirror_id\fR is the numerical unique identifier for -a mirror. Multiple \fImirror_id\fRs are separated by comma. +a mirror. Multiple \fImirror_id\fRs are separated by comma. This option cannot +be used when multiple mirrored files are specified. .SH EXAMPLES .TP -.B lfs mirror resync /mnt/lustre/file1 -Resynchronize all of the stale mirror(s) for /mnt/lustre/file1. +.B lfs mirror resync /mnt/lustre/file1 /mnt/lustre/file2 +Resynchronize all of the stale mirror(s) for /mnt/lustre/file1 and /mnt/lustre/file2. .TP .B lfs mirror resync --only 4,5 /mnt/lustre/file1 Resynchronize mirrors with mirror ID 4 and 5 for /mnt/lustre/file1 even if they diff --git a/lustre/tests/sanity-flr.sh b/lustre/tests/sanity-flr.sh index 29f3b99..abf81d5 100644 --- a/lustre/tests/sanity-flr.sh +++ b/lustre/tests/sanity-flr.sh @@ -1301,30 +1301,41 @@ run_test 40 "PFLR rdonly state instantiation check" test_41() { local tf=$DIR/$tfile - rm -f $tf + rm -f $tf $tf-1 $LFS mirror create -N -E2m -E4m -E-1 -N -E1m -E2m -E3m -E-1 $tf || error "create PFLR file $tf failed" + $LFS mirror create -N -E4m -E-1 -N -E2m -E3m -E-1 $tf-1 || + error "create PFLR file $tf-1 failed" # file should be in ro status verify_flr_state $tf "ro" + verify_flr_state $tf-1 "ro" # write data in [0, 2M) dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc || error "writing $tf failed" + dd if=/dev/zero of=$tf-1 bs=1M count=4 conv=notrunc || + error "writing $tf-1 failed" verify_flr_state $tf "wp" + verify_flr_state $tf-1 "wp" # file should have stale component $LFS getstripe $tf | grep lcme_flags | grep stale > /dev/null || error "after writing $tf, it does not contain stale component" + $LFS getstripe $tf-1 | grep lcme_flags | grep stale > /dev/null || + error "after writing $tf-1, it does not contain stale component" - $LFS mirror resync $tf || error "mirror resync $tf failed" + $LFS mirror resync $tf $tf-1 || error "mirror resync $tf $tf-1 failed" verify_flr_state $tf "ro" + verify_flr_state $tf-1 "ro" # file should not have stale component $LFS getstripe $tf | grep lcme_flags | grep stale && error "after resyncing $tf, it contains stale component" + $LFS getstripe $tf-1 | grep lcme_flags | grep stale && + error "after resyncing $tf, it contains stale component" return 0 } diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 2136201..0f8d866 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -244,9 +244,9 @@ command_t mirror_cmdlist[] = { "[setstripe options|--parent|-f ] ... \n" MIRROR_EXTEND_HELP }, { .pc_name = "resync", .pc_func = lfs_mirror_resync, - .pc_help = "Resynchronizes an out-of-sync mirrored file.\n" + .pc_help = "Resynchronizes out-of-sync mirrored file(s).\n" "usage: lfs mirror resync [--only ] " - "\n"}, + " [...]\n"}, { .pc_name = "--list-commands", .pc_func = lfs_mirror_list_commands, .pc_help = "list commands supported by lfs mirror"}, { .pc_name = "help", .pc_func = Parser_help, .pc_help = "help" }, @@ -6254,70 +6254,29 @@ static int parse_mirror_ids(__u16 *ids, int size, char *arg) return rc < 0 ? rc : nr; } -static inline int lfs_mirror_resync(int argc, char **argv) +static inline +int lfs_mirror_resync_file(const char *fname, struct ll_ioc_lease *ioc, + __u16 *mirror_ids, int ids_nr) { - const char *fname; + const char *progname = "lfs mirror resync"; + struct llapi_resync_comp comp_array[1024] = { { 0 } }; + struct llapi_layout *layout; struct stat stbuf; + uint32_t flr_state; + int comp_size = 0; + int idx; int fd; - int c; int rc; - int idx; - - struct llapi_layout *layout; - struct ll_ioc_lease *ioc = NULL; - struct llapi_resync_comp comp_array[1024] = { { 0 } }; - __u16 mirror_ids[128] = { 0 }; - int ids_nr = 0; - int comp_size = 0; - uint32_t flr_state; - struct option long_opts[] = { - { .val = 'o', .name = "only", .has_arg = required_argument }, - { .name = NULL } }; - - while ((c = getopt_long(argc, argv, "o:", long_opts, NULL)) >= 0) { - switch (c) { - case 'o': - rc = parse_mirror_ids(mirror_ids, - sizeof(mirror_ids) / sizeof(__u16), - optarg); - if (rc < 0) { - fprintf(stderr, - "%s: bad mirror ids '%s'.\n", - argv[0], optarg); - goto error; - } - ids_nr = rc; - break; - default: - fprintf(stderr, "%s: options '%s' unrecognized.\n", - argv[0], argv[optind - 1]); - rc = -EINVAL; - goto error; - } - } - - if (argc > optind + 1) { - fprintf(stderr, "%s: too many files.\n", argv[0]); - rc = CMD_HELP; - goto error; - } - if (argc == optind) { - fprintf(stderr, "%s: no file name given.\n", argv[0]); - rc = CMD_HELP; - goto error; - } - - fname = argv[optind]; if (stat(fname, &stbuf) < 0) { fprintf(stderr, "%s: cannot stat file '%s': %s.\n", - argv[0], fname, strerror(errno)); + progname, fname, strerror(errno)); rc = -errno; goto error; } if (!S_ISREG(stbuf.st_mode)) { fprintf(stderr, "%s: '%s' is not a regular file.\n", - argv[0], fname); + progname, fname); rc = -EINVAL; goto error; } @@ -6325,52 +6284,46 @@ static inline int lfs_mirror_resync(int argc, char **argv) fd = open(fname, O_DIRECT | O_RDWR); if (fd < 0) { fprintf(stderr, "%s: cannot open '%s': %s.\n", - argv[0], fname, strerror(errno)); + progname, fname, strerror(errno)); rc = -errno; goto error; } - /* set the lease on the file */ - ioc = calloc(sizeof(*ioc) + sizeof(__u32) * 4096, 1); - if (ioc == NULL) { - fprintf(stderr, "%s: cannot alloc id array for ioc: %s.\n", - argv[0], strerror(errno)); - rc = -errno; - goto close_fd; - } - ioc->lil_mode = LL_LEASE_WRLCK; ioc->lil_flags = LL_LEASE_RESYNC; rc = llapi_lease_get_ext(fd, ioc); if (rc < 0) { - fprintf(stderr, "%s: llapi_lease_get_ext resync failed: %s.\n", - argv[0], strerror(errno)); - goto free_ioc; + fprintf(stderr, "%s: '%s' llapi_lease_get_ext resync failed: " + "%s.\n", progname, fname, strerror(errno)); + goto close_fd; } layout = llapi_layout_get_by_fd(fd, 0); if (layout == NULL) { - fprintf(stderr, "%s: llapi_layout_get_by_fd failed: %s.\n", - argv[0], strerror(errno)); + fprintf(stderr, "%s: '%s' llapi_layout_get_by_fd failed: %s.\n", + progname, fname, strerror(errno)); rc = -errno; - goto free_ioc; + goto close_fd; } rc = llapi_layout_flags_get(layout, &flr_state); if (rc) { - fprintf(stderr, "%s: llapi_layout_flags_get failed: %s.\n", - argv[0], strerror(errno)); + fprintf(stderr, "%s: '%s' llapi_layout_flags_get failed: %s.\n", + progname, fname, strerror(errno)); rc = -errno; - goto free_ioc; + goto close_fd; } flr_state &= LCM_FL_FLR_MASK; - if (flr_state != LCM_FL_WRITE_PENDING && - flr_state != LCM_FL_SYNC_PENDING) { - fprintf(stderr, "%s: file state error: %s.\n", - argv[0], lcm_flags_string(flr_state)); - rc = 1; - goto free_ioc; + switch (flr_state) { + case LCM_FL_NOT_FLR: + rc = -EINVAL; + case LCM_FL_RDONLY: + fprintf(stderr, "%s: '%s' file state error: %s.\n", + progname, fname, lcm_flags_string(flr_state)); + goto close_fd; + default: + break; } /* get stale component info */ @@ -6379,7 +6332,7 @@ static inline int lfs_mirror_resync(int argc, char **argv) mirror_ids, ids_nr); if (comp_size < 0) { rc = comp_size; - goto free_ioc; + goto close_fd; } idx = 0; @@ -6391,8 +6344,9 @@ static inline int lfs_mirror_resync(int argc, char **argv) rc = llapi_lease_check(fd); if (rc != LL_LEASE_WRLCK) { - fprintf(stderr, "lost lease lock.\n"); - goto free_ioc; + fprintf(stderr, "%s: '%s' lost lease lock.\n", + progname, fname); + goto close_fd; } mirror_id = comp_array[idx].lrc_mirror_id; @@ -6410,10 +6364,10 @@ static inline int lfs_mirror_resync(int argc, char **argv) comp_array[idx].lrc_start, end); if (result < 0) { - fprintf(stderr, "llapi_mirror_resync_one: %ld.\n", - result); + fprintf(stderr, "%s: '%s' llapi_mirror_resync_one: " + "%ld.\n", progname, fname, result); rc = result; - goto free_ioc; + goto close_fd; } else if (result > 0) { int j; @@ -6443,20 +6397,95 @@ static inline int lfs_mirror_resync(int argc, char **argv) if (rc == 0) /* lost lease lock */ rc = -EBUSY; fprintf(stderr, "%s: resync file '%s' failed: %s.\n", - argv[0], fname, strerror(errno)); - goto free_ioc; + progname, fname, strerror(errno)); + goto close_fd; } + /** + * llapi_lease_get_ext returns lease mode when it request to unlock + * the lease lock + */ rc = 0; -free_ioc: - if (ioc) - free(ioc); close_fd: close(fd); error: return rc; } +static inline int lfs_mirror_resync(int argc, char **argv) +{ + struct ll_ioc_lease *ioc = NULL; + __u16 mirror_ids[128] = { 0 }; + int ids_nr = 0; + int c; + int rc = 0; + + struct option long_opts[] = { + { .val = 'o', .name = "only", .has_arg = required_argument }, + { .name = NULL } }; + + while ((c = getopt_long(argc, argv, "o:", long_opts, NULL)) >= 0) { + switch (c) { + case 'o': + rc = parse_mirror_ids(mirror_ids, + sizeof(mirror_ids) / sizeof(__u16), + optarg); + if (rc < 0) { + fprintf(stderr, + "%s: bad mirror ids '%s'.\n", + argv[0], optarg); + goto error; + } + ids_nr = rc; + break; + default: + fprintf(stderr, "%s: options '%s' unrecognized.\n", + argv[0], argv[optind - 1]); + rc = -EINVAL; + goto error; + } + } + + if (argc == optind) { + fprintf(stderr, "%s: no file name given.\n", argv[0]); + rc = CMD_HELP; + goto error; + } + + if (ids_nr > 0 && argc > optind + 1) { + fprintf(stderr, "%s: option '--only' cannot be used upon " + "multiple files.\n", argv[0]); + rc = CMD_HELP; + goto error; + + } + + /* set the lease on the file */ + ioc = calloc(sizeof(*ioc) + sizeof(__u32) * 4096, 1); + if (ioc == NULL) { + fprintf(stderr, "%s: cannot alloc id array for ioc: %s.\n", + argv[0], strerror(errno)); + rc = -errno; + goto error; + } + + for (; optind < argc; optind++) { + rc = lfs_mirror_resync_file(argv[optind], ioc, + mirror_ids, ids_nr); + if (rc) + fprintf(stderr, "%s: resync file '%s' failed: %d\n", + argv[0], argv[optind], rc); + /* ignore previous file's error, continue with next file */ + + /* reset ioc */ + memset(ioc, 0, sizeof(__u32) * 4096); + } + + free(ioc); +error: + return rc; +} + /** * lfs_mirror() - Parse and execute lfs mirror commands. * @argc: The count of lfs mirror command line arguments. -- 1.8.3.1