int o_shadow_tree;
int o_verbose;
int o_copy_xattrs;
- int o_archive_cnt;
- int o_archive_id[LL_HSM_MAX_ARCHIVE + 1];
+ int o_archive_id_used;
+ int o_archive_id_cnt;
+ int *o_archive_id;
int o_report_int;
unsigned long long o_bandwidth;
size_t o_chunk_size;
.has_arg = required_argument },
{ .val = 'v', .name = "verbose", .has_arg = no_argument },
{ .name = NULL } };
- int c, rc;
- unsigned long long value;
- unsigned long long unit;
+ unsigned long long value;
+ unsigned long long unit;
+ bool all_id = false;
+ int c, rc;
+ int i;
optind = 0;
+
+ opt.o_archive_id_cnt = LL_HSM_ORIGIN_MAX_ARCHIVE;
+ opt.o_archive_id = malloc(opt.o_archive_id_cnt *
+ sizeof(*opt.o_archive_id));
+ if (opt.o_archive_id == NULL)
+ return -ENOMEM;
+repeat:
while ((c = getopt_long(argc, argv, "A:b:c:f:hiMp:qru:v",
long_opts, NULL)) != -1) {
switch (c) {
optarg);
return rc;
}
+ /* if archiveID is zero, any archiveID is accepted */
+ if (all_id == true)
+ goto repeat;
+
+ if (val == 0) {
+ free(opt.o_archive_id);
+ opt.o_archive_id = NULL;
+ opt.o_archive_id_cnt = 0;
+ opt.o_archive_id_used = 0;
+ all_id = true;
+ CT_WARN("archive-id = 0 is found, any backend will be served\n");
+ goto repeat;
+ }
- if (opt.o_archive_cnt > LL_HSM_MAX_ARCHIVE ||
- val > LL_HSM_MAX_ARCHIVE) {
- rc = -EINVAL;
- CT_ERROR(rc, "archive number must be less"
- " than %zu", LL_HSM_MAX_ARCHIVE + 1);
- return rc;
+ /* skip the duplicated id */
+ for (i = 0; i < opt.o_archive_id_used; i++) {
+ if (opt.o_archive_id[i] == val)
+ goto repeat;
}
- opt.o_archive_id[opt.o_archive_cnt] = val;
- opt.o_archive_cnt++;
+ /* extend the space */
+ if (opt.o_archive_id_used >= opt.o_archive_id_cnt) {
+ int *tmp;
+
+ opt.o_archive_id_cnt *= 2;
+ tmp = realloc(opt.o_archive_id,
+ sizeof(*opt.o_archive_id) *
+ opt.o_archive_id_cnt);
+ if (tmp == NULL)
+ return -ENOMEM;
+
+ opt.o_archive_id = tmp;
+ }
+
+ opt.o_archive_id[opt.o_archive_id_used++] = val;
break;
}
case 'b': /* -b and -c have both a number with unit as arg */
static int ct_save_stripe(int src_fd, const char *src, const char *dst)
{
- char lov_file[PATH_MAX];
+ char lov_file[PATH_MAX + 8];
char lov_buf[XATTR_SIZE_MAX];
struct lov_user_md *lum;
int rc;
static int ct_load_stripe(const char *src, void *lovea, size_t *lovea_size)
{
- char lov_file[PATH_MAX];
+ char lov_file[PATH_MAX + 4];
int rc;
int fd;
CT_TRACE("bandwith control: %lluB/s "
"excess=%llu sleep for "
"%lld.%09lds",
- opt.o_bandwidth, excess,
+ (unsigned long long)opt.o_bandwidth,
+ (unsigned long long)excess,
(long long)delay.tv_sec,
delay.tv_nsec);
last_bw_print = now;
}
if (rename_needed == true) {
- char tmp_src[PATH_MAX];
- char tmp_dst[PATH_MAX];
+ char tmp_src[PATH_MAX + 8];
+ char tmp_dst[PATH_MAX + 8];
/* atomically replace old archived file */
ct_path_archive(src, sizeof(src), opt.o_hsm_root,
src);
rcf = rcf ? rcf : -errno;
goto fini_minor;
+ }
/* unlink old symlink done */
CT_TRACE("remove old symlink '%s' pointing"
" to '%s'", src, buf);
- }
} else {
/* symlink already ok */
CT_TRACE("symlink '%s' already pointing"
rc = -errno;
CT_ERROR(rc, "cannot unlink '%s'", attr);
err_minor++;
- goto fini;
+
+ /* ignore the error when lov file does not exist. */
+ if (rc == -ENOENT)
+ rc = 0;
+ else
+ goto fini;
}
fini:
return 0;
rc = llapi_hsm_import(dst,
- opt.o_archive_cnt ? opt.o_archive_id[0] : 0,
+ opt.o_archive_id_used ?
+ opt.o_archive_id[0] : 0,
&st, 0, 0, 0, 0, NULL, &fid);
if (rc < 0) {
CT_ERROR(rc, "cannot import '%s' from '%s'", dst, src);
if (relpath == NULL)
return -EINVAL;
- /* Is relpath a FID? In which case SFID should expand to three
- * elements. */
- rc = sscanf(relpath, SFID, RFID(&import_fid));
- if (rc == 3)
+ /* Is relpath a FID? */
+ rc = llapi_fid_parse(relpath, &import_fid, NULL);
+ if (!rc)
return ct_import_fid(&import_fid);
srcpath = path_concat(opt.o_hsm_root, relpath);
/* each line consists of 2 FID */
while ((r = getline(&line, &line_size, filp)) != -1) {
- struct lu_fid old_fid;
- struct lu_fid new_fid;
+ struct lu_fid old_fid;
+ struct lu_fid new_fid;
+ char *next_fid;
/* Ignore empty and commented out ('#...') lines. */
if (should_ignore_line(line))
nl++;
- rc = sscanf(line, SFID" "SFID, RFID(&old_fid), RFID(&new_fid));
- if (rc != 6 || !fid_is_file(&old_fid) ||
- !fid_is_file(&new_fid)) {
- CT_ERROR(EINVAL,
- "'%s' FID expected near '%s', line %u",
- list, line, nl);
+ rc = llapi_fid_parse(line, &old_fid, &next_fid);
+ if (rc)
+ goto error;
+ rc = llapi_fid_parse(next_fid, &new_fid, NULL);
+ if (rc)
+ goto error;
+ if (!fid_is_file(&old_fid) || !fid_is_file(&new_fid))
+ rc = -EINVAL;
+ if (rc) {
+error: CT_ERROR(rc, "%s:%u: two FIDs expected in '%s'",
+ list, nl, line);
err_major++;
continue;
}
static int ct_rebind(void)
{
- int rc;
+ int rc;
if (opt.o_dst) {
struct lu_fid old_fid;
struct lu_fid new_fid;
- if (sscanf(opt.o_src, SFID, RFID(&old_fid)) != 3 ||
- !fid_is_file(&old_fid)) {
+ rc = llapi_fid_parse(opt.o_src, &old_fid, NULL);
+ if (!rc && !fid_is_file(&old_fid))
rc = -EINVAL;
- CT_ERROR(rc, "'%s' invalid FID format", opt.o_src);
+ if (rc) {
+ CT_ERROR(rc, "invalid source FID '%s'", opt.o_src);
return rc;
}
- if (sscanf(opt.o_dst, SFID, RFID(&new_fid)) != 3 ||
- !fid_is_file(&new_fid)) {
+ rc = llapi_fid_parse(opt.o_dst, &new_fid, NULL);
+ if (!rc && !fid_is_file(&new_fid))
rc = -EINVAL;
- CT_ERROR(rc, "'%s' invalid FID format", opt.o_dst);
+ if (rc) {
+ CT_ERROR(rc, "invalid destination FID '%s'", opt.o_dst);
return rc;
}
}
rc = llapi_hsm_copytool_register(&ctdata, opt.o_mnt,
- opt.o_archive_cnt,
+ opt.o_archive_id_used,
opt.o_archive_id, 0);
if (rc < 0) {
CT_ERROR(rc, "cannot start copytool interface");
}
}
+ if (opt.o_archive_id_cnt > 0) {
+ free(opt.o_archive_id);
+ opt.o_archive_id = NULL;
+ opt.o_archive_id_cnt = 0;
+ }
+
return 0;
}