X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flustre_rsync.c;h=c3eab0fb4e1d628750ee52892edc6dda26f7166a;hp=113dc04f09104c61347b6b7b647d37d1ae4f1305;hb=449186a71320e3406f6f06cc8cc89be71c016e9f;hpb=e0d2bfe3b93d5179c9aee4a65e1695fa4c7779ed diff --git a/lustre/utils/lustre_rsync.c b/lustre/utils/lustre_rsync.c index 113dc04..c3eab0f 100644 --- a/lustre/utils/lustre_rsync.c +++ b/lustre/utils/lustre_rsync.c @@ -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/ @@ -114,14 +114,17 @@ #include #include #include +#include #include #include #include #include #include +#include #include -#include +#include +#include #include #include #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 */ @@ -569,10 +580,9 @@ int lr_get_symlink(struct lr_info *info) } else { link = info->linktmp; } - strncpy(info->link, link, PATH_MAX); - info->link[PATH_MAX] = '\0'; + strlcpy(info->link, link, sizeof(info->link)); - return rc; + return rc; } /* Create file/directory/device file/symlink. */ @@ -628,24 +638,25 @@ int lr_mkfile(struct lr_info *info) int lr_add_pc(const char *pfid, const char *tfid, const char *name) { - struct lr_parent_child_list *p; - - p = calloc(1, sizeof(*p)); - if (!p) - return -ENOMEM; - if (strlen(pfid) > sizeof(p->pc_log.pcl_pfid)-1) + struct lr_parent_child_list *p; + size_t len; + + p = calloc(1, sizeof(*p)); + if (p == NULL) + return -ENOMEM; + len = strlcpy(p->pc_log.pcl_pfid, pfid, sizeof(p->pc_log.pcl_pfid)); + if (len >= sizeof(p->pc_log.pcl_pfid)) goto out_err; - strncpy(p->pc_log.pcl_pfid, pfid, sizeof(p->pc_log.pcl_pfid)); - if (strlen(tfid) > sizeof(p->pc_log.pcl_tfid)-1) + len = strlcpy(p->pc_log.pcl_tfid, tfid, sizeof(p->pc_log.pcl_tfid)); + if (len >= sizeof(p->pc_log.pcl_tfid)) goto out_err; - strncpy(p->pc_log.pcl_tfid, tfid, sizeof(p->pc_log.pcl_tfid)); - if (strlen(name) > sizeof(p->pc_log.pcl_name)-1) + len = strlcpy(p->pc_log.pcl_name, name, sizeof(p->pc_log.pcl_name)); + if (len >= sizeof(p->pc_log.pcl_name)) goto out_err; - strncpy(p->pc_log.pcl_name, name, sizeof(p->pc_log.pcl_name)); - p->pc_next = parents; - parents = p; - return 0; + p->pc_next = parents; + parents = p; + return 0; out_err: free(p); @@ -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", @@ -978,7 +989,6 @@ int lr_move(struct lr_info *info) int lr_link(struct lr_info *info) { int i; - int len; int rc; int rc1; struct stat st; @@ -991,42 +1001,57 @@ int lr_link(struct lr_info *info) for (info->target_no = 0; info->target_no < status->ls_num_targets; info->target_no++) { - info->src[0] = 0; - info->dest[0] = 0; - rc1 = 0; + info->src[0] = 0; + info->dest[0] = 0; + rc1 = 0; + + /* + * The changelog record has the new parent directory FID and + * name of the target file. So info->dest can be constructed + * by getting the path of the new parent directory and + * appending the target file name. + */ + rc1 = lr_get_path(info, info->pfid); + lr_debug(rc1 ? 0 : DTRACE, "\tparent fid2path %s, %s, rc=%d\n", + info->path, info->name, rc1); + + if (rc1 == 0) { + snprintf(info->dest, sizeof(info->dest), "%s/%s/%s", + status->ls_targets[info->target_no], + info->path, info->name); + lr_debug(DINFO, "link destination is %s\n", info->dest); + } - /* Search through the hardlinks to get the src and dest */ - for (i = 0; i < st.st_nlink && (info->src[0] == 0 || - info->dest[0] == 0); i++) { + /* Search through the hardlinks to get the src */ + for (i = 0; i < st.st_nlink && info->src[0] == 0; i++) { rc1 = lr_get_path_ln(info, info->tfid, i); lr_debug(rc1 ? 0:DTRACE, "\tfid2path %s, %s, %d rc=%d\n", info->path, info->name, i, rc1); if (rc1) break; - len = strlen(info->path) - strlen(info->name); - if (len > 0 && strcmp(info->path + len, - info->name) == 0) - snprintf(info->dest, PATH_MAX, "%s/%s", - status->ls_targets[info->target_no], - info->path); - else if (info->src[0] == 0) - snprintf(info->src, PATH_MAX, "%s/%s", - status->ls_targets[info->target_no], - info->path); - } + /* + * Compare the path of target FID with info->dest + * to find out info->src. + */ + char srcpath[PATH_MAX]; + + snprintf(srcpath, sizeof(srcpath), "%s/%s", + status->ls_targets[info->target_no], + info->path); + + if (strcmp(srcpath, info->dest) != 0) { + strlcpy(info->src, srcpath, sizeof(info->src)); + lr_debug(DINFO, "link source is %s\n", + info->src); + } + } if (rc1) { rc = rc1; continue; } - if (info->src[0] == 0 || info->dest[0] == 0) - /* Could not find the source or destination. - This can happen when some links don't exist - anymore. */ - return -EINVAL; - if (info->src[0] == 0) snprintf(info->src, PATH_MAX, "%s/%s/%s", status->ls_targets[info->target_no], @@ -1036,9 +1061,10 @@ int lr_link(struct lr_info *info) status->ls_targets[info->target_no], SPECIAL_DIR, info->tfid); - rc1 = link(info->src, info->dest); - lr_debug(rc1?0:DINFO, "link: %s [to] %s; rc1=%d %s\n", - info->src, info->dest, rc1, strerror(errno)); + rc1 = link(info->src, info->dest); + lr_debug(DINFO, "link: %s [to] %s; rc1=%d %s\n", + info->src, info->dest, rc1, + strerror(rc1 ? errno : 0)); if (rc1) rc = rc1; @@ -1111,31 +1137,43 @@ 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); - - 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, info->name, info->sname); } else { - info->name[rec->cr_namelen] = '\0'; - if (verbose > 1) printf("Rec %lld: %d %s\n", info->recno, info->type, info->name); @@ -1236,31 +1274,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; @@ -1270,8 +1327,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; @@ -1281,20 +1341,21 @@ int lr_read_log() if (status->ls_last_recno == -1) status->ls_last_recno = s->ls_last_recno; - if (status->ls_registration[0] == '\0') - strncpy(status->ls_registration, s->ls_registration, - LR_NAME_MAXLEN); + if (status->ls_registration[0] == '\0') + strlcpy(status->ls_registration, s->ls_registration, + sizeof(status->ls_registration)); - if (status->ls_mdt_device[0] == '\0') - strncpy(status->ls_mdt_device, s->ls_mdt_device, - LR_NAME_MAXLEN); + if (status->ls_mdt_device[0] == '\0') + strlcpy(status->ls_mdt_device, s->ls_mdt_device, + sizeof(status->ls_mdt_device)); - if (status->ls_source_fs[0] == '\0') - strncpy(status->ls_source_fs, s->ls_source_fs, - LR_NAME_MAXLEN); + if (status->ls_source_fs[0] == '\0') + strlcpy(status->ls_source_fs, s->ls_source_fs, + sizeof(status->ls_source_fs)); - if (status->ls_source[0] == '\0') - strncpy(status->ls_source, s->ls_source, PATH_MAX); + if (status->ls_source[0] == '\0') + strlcpy(status->ls_source, s->ls_source, + sizeof(status->ls_source)); out: if (fd != -1) @@ -1308,9 +1369,9 @@ int lr_read_log() processing. */ int lr_clear_cl(struct lr_info *info, int force) { - char mdt_device[LR_NAME_MAXLEN + 1]; - long long rec; - int rc = 0; + char mdt_device[LR_NAME_MAXLEN + 1]; + long long rec; + int rc = 0; if (force || info->recno > status->ls_last_recno + CLEAR_INTERVAL) { if (info->type == CL_RENAME) @@ -1322,8 +1383,8 @@ int lr_clear_cl(struct lr_info *info, int force) * device name so make a copy of it until this * is fixed. */ - strncpy(mdt_device, status->ls_mdt_device, - LR_NAME_MAXLEN); + strlcpy(mdt_device, status->ls_mdt_device, + sizeof(mdt_device)); rc = llapi_changelog_clear(mdt_device, status->ls_registration, rec); @@ -1400,7 +1461,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 +1535,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); @@ -1495,8 +1558,8 @@ int lr_replicate() memcpy(info->spfid, info->pfid, sizeof(info->spfid)); memcpy(info->tfid, ext->tfid, sizeof(info->tfid)); memcpy(info->pfid, ext->pfid, sizeof(info->pfid)); - strncpy(info->sname, info->name, sizeof(info->sname)); - strncpy(info->name, ext->name, sizeof(info->name)); + strlcpy(info->sname, info->name, sizeof(info->sname)); + strlcpy(info->name, ext->name, sizeof(info->name)); info->is_extended = 1; } @@ -1603,7 +1666,8 @@ int main(int argc, char *argv[]) break; case 's': /* Assume absolute paths */ - strncpy(status->ls_source, optarg, PATH_MAX); + strlcpy(status->ls_source, optarg, + sizeof(status->ls_source)); break; case 't': status->ls_num_targets++; @@ -1624,16 +1688,16 @@ int main(int argc, char *argv[]) if (status == NULL) return -ENOMEM; } - strncpy(status->ls_targets[status->ls_num_targets - 1], - optarg, - PATH_MAX); - break; - case 'm': - strncpy(status->ls_mdt_device, optarg, LR_NAME_MAXLEN); - break; - case 'u': - strncpy(status->ls_registration, optarg, - LR_NAME_MAXLEN); + strlcpy(status->ls_targets[status->ls_num_targets - 1], + optarg, sizeof(status->ls_targets[0])); + break; + case 'm': + strlcpy(status->ls_mdt_device, optarg, + sizeof(status->ls_mdt_device)); + break; + case 'u': + strlcpy(status->ls_registration, optarg, + sizeof(status->ls_registration)); break; case 'l': statuslog = optarg;