- void *changelog_priv;
- struct lr_info *info;
- struct lr_info *ext;
- time_t start;
- int xattr_not_supp;
- int i;
- int rc;
-
- start = time(NULL);
-
- info = calloc(1, sizeof(struct lr_info));
- if (info == NULL)
- return -ENOMEM;
-
- rc = llapi_search_fsname(status->ls_source, status->ls_source_fs);
- if (rc) {
- fprintf(stderr, "Source path is not a valid Lustre client "
- "mountpoint.\n");
- return rc;
- }
- if (status->ls_mdt_device[0] == '\0')
- snprintf(status->ls_mdt_device, LR_NAME_MAXLEN, "%s%s",
- status->ls_source_fs, DEFAULT_MDT);
-
- ext = calloc(1, sizeof(struct lr_info));
- if (ext == NULL)
- return -ENOMEM;
- memcpy(ext, info, sizeof(struct lr_info));
-
- for (i = 0, xattr_not_supp = 0; i < status->ls_num_targets; i++) {
- snprintf(info->dest, PATH_MAX, "%s/%s", status->ls_targets[i],
- SPECIAL_DIR);
- rc = mkdir(info->dest, 0777);
- if (rc == -1 && errno != EEXIST) {
- fprintf(stderr, "Error writing to target path %s.\n",
- status->ls_targets[i]);
- return -errno;
- }
- rc = llistxattr(info->src, info->xlist, info->xsize);
- if (rc == -1 && errno == ENOTSUP) {
- fprintf(stderr, "xattrs not supported on %s\n",
- status->ls_targets[i]);
- xattr_not_supp++;
- }
- }
- if (xattr_not_supp == status->ls_num_targets)
- /* None of the targets support xattrs. */
- noxattr = 1;
-
- 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);
- if (rc < 0) {
- fprintf(stderr, "Error opening changelog file for fs %s.\n",
- status->ls_source_fs);
- return rc;
- }
-
- while (!quit && lr_parse_line(changelog_priv, info) == 0) {
- rc = 0;
- if (info->type == CL_RENAME)
- /* Rename operations have an additional changelog
- record of information. */
- lr_parse_line(changelog_priv, ext);
-
- if (dryrun)
- continue;
-
- switch(info->type) {
- case CL_CREATE:
- case CL_MKDIR:
- case CL_MKNOD:
- case CL_SOFTLINK:
- rc = lr_create(info);
- break;
- case CL_RMDIR:
- case CL_UNLINK:
- rc = lr_remove(info);
- break;
- case CL_RENAME:
- rc = lr_move(info, ext);
- break;
- case CL_HARDLINK:
- rc = lr_link(info);
- break;
- case CL_TRUNC:
- case CL_SETATTR:
- rc = lr_setattr(info);
- break;
- case CL_XATTR:
- rc = lr_setxattr(info);
- break;
- case CL_CLOSE:
- case CL_EXT:
- case CL_OPEN:
- case CL_IOCTL:
- case CL_MARK:
- /* Nothing needs to be done for these entries */
- default:
- break;
- }
- if (rc && rc != -ENOENT) {
- lr_print_failure(info, rc);
- errors++;
- if (abort_on_err)
- break;
- }
- lr_clear_cl(info, 0);
- if (debug) {
- bzero(info, sizeof(struct lr_info));
- bzero(ext, sizeof(struct lr_info));
- }
- }
-
- llapi_changelog_fini(&changelog_priv);
-
- if (errors || verbose)
- printf("Errors: %d\n", errors);
-
- /* Clear changelog records used so far */
- lr_clear_cl(info, 1);
-
- if (verbose) {
- printf("lustre_rsync took %ld seconds\n", time(NULL) - start);
- printf("Changelog records consumed: %lld\n", rec_count);
- }
-
- return 0;
+ void *changelog_priv;
+ struct lr_info *info;
+ struct lr_info *ext = NULL;
+ time_t start;
+ int xattr_not_supp;
+ int i;
+ int rc;
+
+ start = time(NULL);
+
+ info = calloc(1, sizeof(struct lr_info));
+ if (!info)
+ return -ENOMEM;
+
+ rc = llapi_search_fsname(status->ls_source, status->ls_source_fs);
+ if (rc) {
+ fprintf(stderr, "Source path is not a valid Lustre client mountpoint.\n");
+ goto out;
+ }
+
+ if (status->ls_mdt_device[0] == '\0') {
+ int len;
+
+ len = snprintf(status->ls_mdt_device,
+ sizeof(status->ls_mdt_device), "%s%s",
+ status->ls_source_fs, DEFAULT_MDT);
+ if (len >= sizeof(status->ls_mdt_device)) {
+ rc = -E2BIG;
+ goto out;
+ }
+ }
+
+ ext = calloc(1, sizeof(struct lr_info));
+ if (!ext) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0, xattr_not_supp = 0; i < status->ls_num_targets; i++) {
+ snprintf(info->dest, sizeof(info->dest), "%s/%s",
+ status->ls_targets[i], SPECIAL_DIR);
+ rc = mkdir(info->dest, 0777);
+ if (rc == -1 && errno != EEXIST) {
+ fprintf(stderr, "Error writing to target path %s.\n",
+ status->ls_targets[i]);
+ rc = -errno;
+ goto out;
+ }
+ rc = llistxattr(info->src, info->xlist, info->xsize);
+ if (rc == -1 && errno == ENOTSUP) {
+ fprintf(stderr, "xattrs not supported on %s\n",
+ status->ls_targets[i]);
+ xattr_not_supp++;
+ }
+ }
+ if (xattr_not_supp == status->ls_num_targets)
+ /* None of the targets support xattrs. */
+ noxattr = 1;
+
+ lr_print_status(info);
+
+ /* Open changelogs for consumption*/
+ rc = llapi_changelog_start(&changelog_priv,
+ CHANGELOG_FLAG_BLOCK |
+ CHANGELOG_FLAG_JOBID |
+ CHANGELOG_FLAG_EXTRA_FLAGS,
+ 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);
+ goto out;
+ }
+
+ rc = llapi_changelog_set_xflags(changelog_priv,
+ CHANGELOG_EXTRA_FLAG_UIDGID |
+ CHANGELOG_EXTRA_FLAG_NID |
+ CHANGELOG_EXTRA_FLAG_OMODE |
+ CHANGELOG_EXTRA_FLAG_XATTR);
+ if (rc < 0) {
+ fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
+ status->ls_source_fs);
+ goto out;
+ }
+
+ while (!quit && lr_parse_line(changelog_priv, info) == 0) {
+ rc = 0;
+
+ if (info->type == CL_RENAME && !info->is_extended) {
+ /*
+ * Newer rename operations extends changelog to store
+ * source file information, but old changelog has
+ * another record.
+ */
+ if (lr_parse_line(changelog_priv, ext) != 0)
+ break;
+ memcpy(info->sfid, info->tfid, sizeof(info->sfid));
+ memcpy(info->spfid, info->pfid, sizeof(info->spfid));
+ memcpy(info->tfid, ext->tfid, sizeof(info->tfid));
+ memcpy(info->pfid, ext->pfid, sizeof(info->pfid));
+ snprintf(info->sname, sizeof(info->sname), "%s",
+ info->name);
+ snprintf(info->name, sizeof(info->name), "%s",
+ ext->name);
+ info->is_extended = 1;
+ info->recno = ext->recno; /* For lr_clear_cl(). */
+ }
+
+ if (dryrun)
+ continue;
+
+ lr_debug(DTRACE, "***** Start %lld %s (%d) %s %s %s *****\n",
+ info->recno, changelog_type2str(info->type),
+ info->type, info->tfid, info->pfid, info->name);
+
+ switch (info->type) {
+ case CL_CREATE:
+ case CL_MKDIR:
+ case CL_MKNOD:
+ case CL_SOFTLINK:
+ rc = lr_create(info);
+ break;
+ case CL_RMDIR:
+ case CL_UNLINK:
+ rc = lr_remove(info);
+ break;
+ case CL_RENAME:
+ rc = lr_move(info);
+ break;
+ case CL_HARDLINK:
+ rc = lr_link(info);
+ break;
+ case CL_TRUNC:
+ case CL_SETATTR:
+ rc = lr_setattr(info);
+ break;
+ case CL_SETXATTR:
+ rc = lr_setxattr(info);
+ break;
+ case CL_CLOSE:
+ case CL_EXT:
+ case CL_OPEN:
+ case CL_GETXATTR:
+ case CL_DN_OPEN:
+ case CL_LAYOUT:
+ case CL_MARK:
+ /*
+ * Nothing needs to be done for these entries
+ * fallthrough
+ */
+ default:
+ break;
+ }
+
+ lr_debug(DTRACE, "##### End %lld %s (%d) %s %s %s rc=%d #####\n",
+ info->recno, changelog_type2str(info->type),
+ info->type, info->tfid, info->pfid, info->name, rc);
+
+ if (rc && rc != -ENOENT) {
+ lr_print_failure(info, rc);
+ errors++;
+ if (abort_on_err)
+ break;
+ }
+ lr_clear_cl(info, 0);
+ }
+
+ llapi_changelog_fini(&changelog_priv);
+
+ if (errors || verbose)
+ printf("Errors: %d\n", errors);
+
+ /* Clear changelog records used so far */
+ lr_clear_cl(info, 1);
+
+ if (verbose) {
+ printf("lustre_rsync took %ld seconds\n", time(NULL) - start);
+ printf("Changelog records consumed: %lld\n", rec_count);
+ }
+
+ rc = 0;
+
+out:
+ if (info)
+ free(info);
+ if (ext)
+ free(ext);
+
+ return rc;