X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flustre_rsync.c;h=550ffddbf33aa63b500b395258f1cdbb2733a712;hb=refs%2Fchanges%2F15%2F35815%2F2;hp=20a1c144b64df87c3cbea36ac17a5ec3ec5408cb;hpb=d2629cfcabfa3a22ddf4a6c474364d0012d80390;p=fs%2Flustre-release.git diff --git a/lustre/utils/lustre_rsync.c b/lustre/utils/lustre_rsync.c index 20a1c14..550ffdd 100644 --- a/lustre/utils/lustre_rsync.c +++ b/lustre/utils/lustre_rsync.c @@ -124,6 +124,7 @@ #include #include #include "lustre_rsync.h" +#include "callvpe.h" #define REPLICATE_STATUS_VER 1 #define CLEAR_INTERVAL 100 @@ -160,7 +161,6 @@ struct lr_info { char savedpath[PATH_MAX + 1]; char link[PATH_MAX + 1]; char linktmp[PATH_MAX + 1]; - char cmd[PATH_MAX * 10]; int bufsize; char *buf; @@ -192,8 +192,8 @@ int quit; /* Flag to stop processing the changelog; set on the receipt of a signal */ int abort_on_err = 0; -char rsync[PATH_MAX]; -char rsync_ver[PATH_MAX]; +char rsync[PATH_MAX + 128]; +char rsync_ver[PATH_MAX * 2]; struct lr_parent_child_list *parents; FILE *debug_log; @@ -289,22 +289,28 @@ int lr_rsync_data(struct lr_info *info) if (st_src.st_mtime != st_dest.st_mtime || st_src.st_size != st_dest.st_size) { - /* XXX spawning off an rsync for every data sync and - * waiting synchronously is bad for performance. - * librsync could possibly used here. But it does not - * seem to be of production grade. Multi-threaded - * replication is also to be considered. - */ - int status; - - if (snprintf(info->cmd, sizeof(info->cmd), "%s --inplace %s %s", - rsync, info->src, info->dest) >= sizeof(info->cmd)) { - rc = -E2BIG; - goto err; - } - lr_debug(DTRACE, "\t%s %s\n", info->cmd, info->tfid); - status = system(info->cmd); - if (status == -1) { + /* XXX spawning off an rsync for every data sync and + * waiting synchronously is bad for performance. + * librsync could possibly used here. But it does not + * seem to be of production grade. Multi-threaded + * replication is also to be considered. + */ + char *args[] = { + rsync, + "--inplace", + "--", + info->src, + info->dest, + NULL, + }; + extern char **environ; + int status; + + lr_debug(DTRACE, "\t%s %s %s %s %s %s\n", args[0], args[1], + args[2], args[3], args[4], info->tfid); + + status = callvpe(rsync, args, environ); + if (status < 0) { rc = -errno; } else if (WIFEXITED(status)) { status = WEXITSTATUS(status); @@ -326,7 +332,7 @@ int lr_rsync_data(struct lr_info *info) lr_debug(DTRACE, "Not syncing %s and %s %s\n", info->src, info->dest, info->tfid); } -err: + return rc; } @@ -422,7 +428,7 @@ int lr_sync_data(struct lr_info *info) } /* Copy all attributes from file src to file dest */ -int lr_copy_attr(char *src, char *dest) +int lr_copy_attr(const char *src, const char *dest) { struct stat st; struct utimbuf time; @@ -492,9 +498,10 @@ int lr_copy_xattr(struct lr_info *info) rc, errno); if (rc == -1) { if (errno != ENOTSUP) { - fprintf(stderr, "Error replicating " - " xattr for %s: %d\n", - info->dest, errno); + fprintf(stderr, + "cannot replicate xattrs from '%s' to '%s': %s\n", + info->src, info->dest, + strerror(errno)); errors++; } rc = 0; @@ -565,8 +572,9 @@ int lr_get_symlink(struct lr_info *info) } else { link = info->linktmp; } - strlcpy(info->link, link, sizeof(info->link)); - + rc = snprintf(info->link, sizeof(info->link), "%s", link); + if (rc >= sizeof(info->link)) + rc = -E2BIG; return rc; } @@ -634,13 +642,16 @@ int lr_add_pc(const char *pfid, const char *tfid, const char *name) p = calloc(1, sizeof(*p)); if (p == NULL) return -ENOMEM; - len = strlcpy(p->pc_log.pcl_pfid, pfid, sizeof(p->pc_log.pcl_pfid)); + len = snprintf(p->pc_log.pcl_pfid, sizeof(p->pc_log.pcl_pfid), + "%s", pfid); if (len >= sizeof(p->pc_log.pcl_pfid)) goto out_err; - len = strlcpy(p->pc_log.pcl_tfid, tfid, sizeof(p->pc_log.pcl_tfid)); + len = snprintf(p->pc_log.pcl_tfid, sizeof(p->pc_log.pcl_tfid), + "%s", tfid); if (len >= sizeof(p->pc_log.pcl_tfid)) goto out_err; - len = strlcpy(p->pc_log.pcl_name, name, sizeof(p->pc_log.pcl_name)); + len = snprintf(p->pc_log.pcl_name, sizeof(p->pc_log.pcl_name), + "%s", name); if (len >= sizeof(p->pc_log.pcl_name)) goto out_err; @@ -747,15 +758,26 @@ int lr_rmfile(struct lr_info *info) /* Recursively remove directory and its contents */ int lr_rm_recursive(struct lr_info *info) { + char *args[] = { + "rm", + "-rf", + "--", + info->dest, + NULL, + }; + extern char **environ; + int status; int rc; - snprintf(info->cmd, sizeof(info->cmd), "rm -rf %s", - info->dest); - rc = system(info->cmd); - if (rc == -1) - rc = -errno; + status = callvpe("/bin/rm", args, environ); + if (status < 0) + rc = -errno; + else if (WIFEXITED(status)) + rc = WEXITSTATUS(status) == 0 ? 0 : -EINVAL; + else + rc = -EINTR; - return rc; + return rc; } /* Remove a file under SPECIAL_DIR with its tfid as its name. */ @@ -1041,7 +1063,8 @@ int lr_link(struct lr_info *info) info->path); if (strcmp(srcpath, info->dest) != 0) { - strlcpy(info->src, srcpath, sizeof(info->src)); + snprintf(info->src, sizeof(info->src), "%s", + srcpath); lr_debug(DINFO, "link source is %s\n", info->src); } @@ -1072,6 +1095,30 @@ int lr_link(struct lr_info *info) return rc; } +int lr_set_dest_for_attr(struct lr_info *info) +{ + int rc; + + snprintf(info->dest, sizeof(info->dest), "%s/%s", + status->ls_targets[info->target_no], info->path); + rc = access(info->dest, F_OK); + if (rc < 0) + rc = -errno; + + if (rc != -ENOENT) + return rc; + + snprintf(info->dest, sizeof(info->dest), "%s/%s/%s", + status->ls_targets[info->target_no], SPECIAL_DIR, + info->tfid); + + rc = access(info->dest, F_OK); + if (rc < 0) + return -errno; + + return 0; +} + /* Replicate file attributes */ int lr_setattr(struct lr_info *info) { @@ -1089,9 +1136,10 @@ int lr_setattr(struct lr_info *info) for (info->target_no = 0; info->target_no < status->ls_num_targets; info->target_no++) { + rc = lr_set_dest_for_attr(info); + if (rc < 0) + continue; - snprintf(info->dest, sizeof(info->dest), "%s/%s", - status->ls_targets[info->target_no], info->path); lr_debug(DINFO, "setattr: %s %s %s", info->src, info->dest, info->tfid); @@ -1120,9 +1168,10 @@ int lr_setxattr(struct lr_info *info) for (info->target_no = 0; info->target_no < status->ls_num_targets; info->target_no++) { + rc = lr_set_dest_for_attr(info); + if (rc < 0) + continue; - snprintf(info->dest, sizeof(info->dest), "%s/%s", - status->ls_targets[info->target_no], info->path); lr_debug(DINFO, "setxattr: %s %s %s\n", info->src, info->dest, info->tfid); @@ -1154,7 +1203,7 @@ int lr_parse_line(void *priv, struct lr_info *info) namelen = strnlen(changelog_rec_name(rec), rec->cr_namelen); if (copylen > namelen + 1) copylen = namelen + 1; - strlcpy(info->name, changelog_rec_name(rec), copylen); + snprintf(info->name, copylen, "%s", changelog_rec_name(rec)); /* Don't use rnm if CLF_RENAME isn't set */ rnm = changelog_rec_rename(rec); @@ -1168,7 +1217,7 @@ int lr_parse_line(void *priv, struct lr_info *info) namelen = changelog_rec_snamelen(rec); if (copylen > namelen + 1) copylen = namelen + 1; - strlcpy(info->sname, changelog_rec_sname(rec), copylen); + snprintf(info->sname, copylen, "%s", changelog_rec_sname(rec)); if (verbose > 1) printf("Rec %lld: %d %s %s\n", info->recno, info->type, @@ -1342,20 +1391,24 @@ int lr_read_log() status->ls_last_recno = s->ls_last_recno; if (status->ls_registration[0] == '\0') - strlcpy(status->ls_registration, s->ls_registration, - sizeof(status->ls_registration)); + snprintf(status->ls_registration, + sizeof(status->ls_registration), "%s", + s->ls_registration); if (status->ls_mdt_device[0] == '\0') - strlcpy(status->ls_mdt_device, s->ls_mdt_device, - sizeof(status->ls_mdt_device)); + snprintf(status->ls_mdt_device, + sizeof(status->ls_mdt_device), "%s", + s->ls_mdt_device); if (status->ls_source_fs[0] == '\0') - strlcpy(status->ls_source_fs, s->ls_source_fs, - sizeof(status->ls_source_fs)); + snprintf(status->ls_source_fs, + sizeof(status->ls_source_fs), "%s", + s->ls_source_fs); if (status->ls_source[0] == '\0') - strlcpy(status->ls_source, s->ls_source, - sizeof(status->ls_source)); + snprintf(status->ls_source, + sizeof(status->ls_source), "%s", + s->ls_source); out: if (fd != -1) @@ -1370,37 +1423,33 @@ int lr_read_log() int lr_clear_cl(struct lr_info *info, int force) { 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) - rec = info->recno + 1; - else - rec = info->recno; if (!noclear && !dryrun) { /* llapi_changelog_clear modifies the mdt * device name so make a copy of it until this * is fixed. - */ - strlcpy(mdt_device, status->ls_mdt_device, - sizeof(mdt_device)); + */ + snprintf(mdt_device, sizeof(mdt_device), "%s", + status->ls_mdt_device); rc = llapi_changelog_clear(mdt_device, status->ls_registration, - rec); + info->recno); if (rc) - printf("Changelog clear (%s, %s, %lld) " - "returned %d\n", status->ls_mdt_device, - status->ls_registration, rec, rc); - } - if (!rc && !dryrun) { - status->ls_last_recno = rec; - lr_write_log(); + printf("Changelog clear (%s, %s, %lld) " + "returned %d\n", status->ls_mdt_device, + status->ls_registration, info->recno, + rc); + } - } - } + if (!rc && !dryrun) { + status->ls_last_recno = info->recno; + lr_write_log(); + } + } - return rc; + return rc; } /* Locate a usable version of rsync. At this point we'll use any @@ -1558,7 +1607,9 @@ int lr_replicate() rc = llapi_changelog_set_xflags(changelog_priv, CHANGELOG_EXTRA_FLAG_UIDGID | - CHANGELOG_EXTRA_FLAG_NID); + 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); @@ -1578,9 +1629,12 @@ 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)); - strlcpy(info->sname, info->name, sizeof(info->sname)); - strlcpy(info->name, ext->name, sizeof(info->name)); + 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) @@ -1611,12 +1665,14 @@ int lr_replicate() case CL_SETATTR: rc = lr_setattr(info); break; - case CL_XATTR: + 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 */ @@ -1636,10 +1692,6 @@ int lr_replicate() 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); @@ -1692,8 +1744,8 @@ int main(int argc, char *argv[]) break; case 's': /* Assume absolute paths */ - strlcpy(status->ls_source, optarg, - sizeof(status->ls_source)); + snprintf(status->ls_source, sizeof(status->ls_source), + "%s", optarg); break; case 't': status->ls_num_targets++; @@ -1714,16 +1766,18 @@ int main(int argc, char *argv[]) if (status == NULL) return -ENOMEM; } - strlcpy(status->ls_targets[status->ls_num_targets - 1], - optarg, sizeof(status->ls_targets[0])); + snprintf(status->ls_targets[status->ls_num_targets - 1], + sizeof(status->ls_targets[0]), "%s", optarg); break; case 'm': - strlcpy(status->ls_mdt_device, optarg, - sizeof(status->ls_mdt_device)); + snprintf(status->ls_mdt_device, + sizeof(status->ls_mdt_device), + "%s", optarg); break; case 'u': - strlcpy(status->ls_registration, optarg, - sizeof(status->ls_registration)); + snprintf(status->ls_registration, + sizeof(status->ls_registration), + "%s", optarg); break; case 'l': statuslog = optarg;