Whamcloud - gitweb
LU-8009 utils: Lustre_rsync does not sync files on MDT1
[fs/lustre-release.git] / lustre / utils / lustre_rsync.c
index dee27b0..3e196d5 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <getopt.h>
 #include <stdarg.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <errno.h>
 #include <limits.h>
 #include <utime.h>
+#include <time.h>
 #include <sys/xattr.h>
 
-#include <libcfs/libcfsutil.h>
+#include <libcfs/util/string.h>
+#include <libcfs/util/parser.h>
 #include <lustre/lustreapi.h>
 #include <lustre/lustre_idl.h>
 #include "lustre_rsync.h"
@@ -389,31 +392,39 @@ int lr_copy_data(struct lr_info *info)
                 info->bufsize = bufsize;
         }
 
-        while (1) {
-                rsize = read(fd_src, info->buf, bufsize);
-                if (rsize == 0) {
-                        break;
-                } else if (rsize < 0) {
-                        rc = -errno;
-                        goto out;
-                }
-                errno = 0;
-                if (write(fd_dest, info->buf, rsize) != rsize) {
-                        if (errno != 0)
-                                rc = -errno;
-                        else
-                                rc = -EINTR;
-                }
-        }
-        fsync(fd_dest);
+       while (1) {
+               char *buf;
+               int wsize;
+
+               buf = info->buf;
+               rsize = read(fd_src, buf, bufsize);
+               if (rsize == 0) {
+                       rc = 0;
+                       break;
+               }
+               if (rsize < 0) {
+                       rc = -errno;
+                       break;
+               }
+               do {
+                       wsize = write(fd_dest, buf, rsize);
+                       if (wsize <= 0) {
+                               rc = -errno;
+                               break;
+                       }
+                       rsize -= wsize;
+                       buf += wsize;
+               } while (rsize > 0);
+       }
+       fsync(fd_dest);
 
 out:
-        if (fd_src != -1)
-                close(fd_src);
-        if (fd_dest != -1)
-                close(fd_dest);
+       if (fd_src != -1)
+               close(fd_src);
+       if (fd_dest != -1)
+               close(fd_dest);
 
-        return rc;
+       return rc;
 }
 
 /* Copy data from source to destination */
@@ -674,11 +685,11 @@ void lr_cascade_move(const char *fid, const char *dest, struct lr_info *info)
                                         info->src, d, errno);
                                 errors++;
                         }
-                        lr_cascade_move(curr->pc_log.pcl_tfid, d, info);
                         if (curr == parents)
                                 parents = curr->pc_next;
                         else
                                 prev->pc_next = curr->pc_next;
+                       lr_cascade_move(curr->pc_log.pcl_tfid, d, info);
                         free(curr);
                         prev = curr = parents;
 
@@ -958,12 +969,12 @@ int lr_move(struct lr_info *info)
                        lr_debug(DINFO, "rename returns %d\n", rc1);
                 }
 
-               if (special_src) {
+               if (special_src)
                        rc1 = lr_remove_pc(info->spfid, info->sfid);
-                       if (!special_dest)
-                               lr_cascade_move(info->sfid, info->dest, info);
-                }
-               if (special_dest)
+
+               if (!special_dest)
+                       lr_cascade_move(info->sfid, info->dest, info);
+               else
                        rc1 = lr_add_pc(info->pfid, info->sfid, info->name);
 
                 lr_debug(DINFO, "move: %s [to] %s rc1=%d, errno=%d\n",
@@ -1005,7 +1016,7 @@ int lr_link(struct lr_info *info)
                                 break;
 
                         len = strlen(info->path) - strlen(info->name);
-                        if (len > 0 && strcmp(info->path + len,
+                       if (len >= 0 && strcmp(info->path + len,
                                               info->name) == 0)
                                 snprintf(info->dest, PATH_MAX, "%s/%s",
                                         status->ls_targets[info->target_no],
@@ -1111,25 +1122,38 @@ int lr_setxattr(struct lr_info *info)
 /* Parse a line of changelog entry */
 int lr_parse_line(void *priv, struct lr_info *info)
 {
-       struct changelog_ext_rec *rec;
-
-        if (llapi_changelog_recv(priv, &rec) != 0)
-                return -1;
-
-       info->is_extended = CHANGELOG_REC_EXTENDED(rec);
-        info->recno = rec->cr_index;
-        info->type = rec->cr_type;
-        sprintf(info->tfid, DFID, PFID(&rec->cr_tfid));
-        sprintf(info->pfid, DFID, PFID(&rec->cr_pfid));
-       strncpy(info->name, rec->cr_name, rec->cr_namelen);
-       info->name[rec->cr_namelen] = '\0';
-
-       if (fid_is_sane(&rec->cr_sfid)) {
-               sprintf(info->sfid, DFID, PFID(&rec->cr_sfid));
-               sprintf(info->spfid, DFID, PFID(&rec->cr_spfid));
-               strncpy(info->sname, changelog_rec_sname(rec),
-                       changelog_rec_snamelen(rec));
-               info->sname[changelog_rec_snamelen(rec)] = '\0';
+       struct changelog_rec            *rec;
+       struct changelog_ext_rename     *rnm;
+       size_t                           namelen;
+       size_t                           copylen = sizeof(info->name);
+
+       if (llapi_changelog_recv(priv, &rec) != 0)
+               return -1;
+
+       info->is_extended = !!(rec->cr_flags & CLF_RENAME);
+       info->recno = rec->cr_index;
+       info->type = rec->cr_type;
+       snprintf(info->tfid, sizeof(info->tfid), DFID, PFID(&rec->cr_tfid));
+       snprintf(info->pfid, sizeof(info->pfid), DFID, PFID(&rec->cr_pfid));
+
+       namelen = strnlen(changelog_rec_name(rec), rec->cr_namelen);
+       if (copylen > namelen + 1)
+               copylen = namelen + 1;
+       strlcpy(info->name, changelog_rec_name(rec), copylen);
+
+       /* Don't use rnm if CLF_RENAME isn't set */
+       rnm = changelog_rec_rename(rec);
+       if (rec->cr_flags & CLF_RENAME && !fid_is_zero(&rnm->cr_sfid)) {
+               copylen = sizeof(info->sname);
+
+               snprintf(info->sfid, sizeof(info->sfid), DFID,
+                        PFID(&rnm->cr_sfid));
+               snprintf(info->spfid, sizeof(info->spfid), DFID,
+                        PFID(&rnm->cr_spfid));
+               namelen = changelog_rec_snamelen(rec);
+               if (copylen > namelen + 1)
+                       copylen = namelen + 1;
+               strlcpy(info->sname, changelog_rec_sname(rec), copylen);
 
                if (verbose > 1)
                        printf("Rec %lld: %d %s %s\n", info->recno, info->type,
@@ -1235,31 +1259,50 @@ int lr_read_log()
                 return 0;
 
         s = calloc(1, read_size);
-        if (s == NULL)
-                GOTO(out, rc = -ENOMEM);
-
-        fd = open(statuslog, O_RDONLY);
-        if (fd == -1)
-                GOTO(out, rc = -errno);
-        size = read(fd, s, read_size);
-        if (size != read_size)
-                GOTO(out, rc = -EINVAL);
-        if (read_size < s->ls_size) {
-                read_size = s->ls_size;
-                s = lr_grow_buf(s, read_size);
-                if (s == NULL)
-                        GOTO(out, rc = -ENOMEM);
-                if (lseek(fd, 0, SEEK_SET) == -1)
-                        GOTO(out, rc = -errno);
-                size = read(fd, s, read_size);
-                if (size != read_size)
-                        GOTO(out, rc = -EINVAL);
-        }
+       if (s == NULL) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       fd = open(statuslog, O_RDONLY);
+       if (fd == -1) {
+               rc = -errno;
+               goto out;
+       }
+
+       size = read(fd, s, read_size);
+       if (size != read_size) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       if (read_size < s->ls_size) {
+               read_size = s->ls_size;
+               s = lr_grow_buf(s, read_size);
+               if (s == NULL) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
+
+               if (lseek(fd, 0, SEEK_SET) == -1) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
+
+               size = read(fd, s, read_size);
+               if (size != read_size) {
+                       rc = -EINVAL;
+                       goto out;
+               }
+       }
+
+       while (read(fd, &rec, sizeof(rec)) != 0) {
+               tmp = calloc(1, sizeof(*tmp));
+               if (!tmp) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
 
-        while (read(fd, &rec, sizeof(rec)) != 0) {
-                tmp = calloc(1, sizeof(*tmp));
-                if (!tmp)
-                        GOTO(out, rc = -ENOMEM);
                 tmp->pc_log = rec;
                 tmp->pc_next = parents;
                 parents = tmp;
@@ -1269,8 +1312,11 @@ int lr_read_log()
         if (status->ls_num_targets == 0) {
                 if (status->ls_size != s->ls_size) {
                         status = lr_grow_buf(status, s->ls_size);
-                        if (status == NULL)
-                                GOTO(out, rc = -ENOMEM);
+                       if (status == NULL) {
+                               rc = -ENOMEM;
+                               goto out;
+                       }
+
                         status->ls_size = s->ls_size;
                 }
                 status->ls_num_targets = s->ls_num_targets;
@@ -1400,7 +1446,8 @@ void lr_print_status(struct lr_info *info)
         if (statuslog != NULL)
                 printf("Statuslog: %s\n", statuslog);
         printf("Changelog registration: %s\n", status->ls_registration);
-        printf("Starting changelog record: "LPD64"\n", status->ls_last_recno);
+       printf("Starting changelog record: %jd\n",
+              (uintmax_t)status->ls_last_recno);
         if (noxattr)
                 printf("Replicate xattrs: no\n");
         if (noclear)
@@ -1473,9 +1520,10 @@ int lr_replicate()
 
         lr_print_status(info);
 
-        /* Open changelogs for consumption*/
-        rc = llapi_changelog_start(&changelog_priv, CHANGELOG_FLAG_BLOCK,
-                                   status->ls_source_fs, status->ls_last_recno);
+       /* Open changelogs for consumption*/
+       rc = llapi_changelog_start(&changelog_priv,
+                               CHANGELOG_FLAG_BLOCK | CHANGELOG_FLAG_JOBID,
+                               status->ls_mdt_device, status->ls_last_recno);
         if (rc < 0) {
                 fprintf(stderr, "Error opening changelog file for fs %s.\n",
                         status->ls_source_fs);