/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2014, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#include <utime.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"
} 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. */
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;
- strcpy(p->pc_log.pcl_pfid, pfid);
- strcpy(p->pc_log.pcl_tfid, tfid);
- strcpy(p->pc_log.pcl_name, name);
-
- p->pc_next = parents;
- parents = p;
- return 0;
+ 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;
+ 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;
+ 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;
+
+ p->pc_next = parents;
+ parents = p;
+ return 0;
+
+out_err:
+ free(p);
+ return -E2BIG;
}
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;
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],
/* 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);
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;
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;
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)
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)
* 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);
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_source_fs, status->ls_last_recno);
if (rc < 0) {
fprintf(stderr, "Error opening changelog file for fs %s.\n",
status->ls_source_fs);
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;
}
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;
- }
+ case CL_CLOSE:
+ case CL_EXT:
+ case CL_OPEN:
+ case CL_LAYOUT:
+ case CL_MARK:
+ /* Nothing needs to be done for these entries */
+ /* fallthrough */
+ default:
+ break;
+ }
DEBUG_EXIT(info, rc);
if (rc && rc != -ENOENT) {
lr_print_failure(info, rc);
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++;
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;
break;
case 'D':
/* Undocumented option debug log file */
+ if (debug_log != NULL)
+ fclose(debug_log);
debug_log = fopen(optarg, "a");
if (debug_log == NULL) {
printf("Cannot open %s for debug log\n",