int o_shadow_tree;
int o_verbose;
int o_copy_xattrs;
- int o_archive_cnt;
- int o_archive_id[LL_HSM_MAX_ARCHIVE];
+ 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) {
- case 'A':
- if ((opt.o_archive_cnt >= LL_HSM_MAX_ARCHIVE) ||
- (atoi(optarg) >= LL_HSM_MAX_ARCHIVE)) {
- rc = -E2BIG;
- CT_ERROR(rc, "archive number must be less"
- "than %zu", LL_HSM_MAX_ARCHIVE);
+ case 'A': {
+ char *end = NULL;
+ int val = strtol(optarg, &end, 10);
+
+ if (*end != '\0') {
+ rc = -EINVAL;
+ CT_ERROR(rc, "invalid archive-id: '%s'",
+ optarg);
return rc;
}
- opt.o_archive_id[opt.o_archive_cnt] = atoi(optarg);
- opt.o_archive_cnt++;
+ /* 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;
+ }
+
+ /* skip the duplicated id */
+ for (i = 0; i < opt.o_archive_id_used; i++) {
+ if (opt.o_archive_id[i] == val)
+ goto repeat;
+ }
+ /* 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 */
case 'c':
unit = ONE_MB;
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);
}
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;
}
return -rc;
}
-