Whamcloud - gitweb
LU-9771 flr: mirror resync multiple files 42/30242/4
authorBobi Jam <bobijam.xu@intel.com>
Fri, 24 Nov 2017 04:41:59 +0000 (12:41 +0800)
committerJinshan Xiong <jinshan.xiong@intel.com>
Tue, 28 Nov 2017 16:54:47 +0000 (16:54 +0000)
mirror resync multiple files in one command line.

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: I4e301070f678fbad2dd8663d52ded7294ad5dad5
Reviewed-on: https://review.whamcloud.com/30242
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
lustre/doc/lfs-mirror-resync.1
lustre/tests/sanity-flr.sh
lustre/utils/lfs.c

index 11eea0f..8ae9ba9 100644 (file)
@@ -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
index 29f3b99..abf81d5 100644 (file)
@@ -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
 }
index 2136201..0f8d866 100644 (file)
@@ -244,9 +244,9 @@ command_t mirror_cmdlist[] = {
                "[setstripe options|--parent|-f <victim_file>] ... <filename>\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 <mirror_id[,...]>] "
-               "<mirrored file>\n"},
+               "<mirrored file> [<mirrored file2>...]\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.