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;
{
struct hsm_copyaction_private *hcp = NULL;
char src[PATH_MAX];
- char dst[PATH_MAX] = "";
+ char dst[PATH_MAX + 4] = "";
+ char root[PATH_MAX] = "";
int rc;
int rcf = 0;
bool rename_needed = false;
* destination = lustre FID
*/
ct_path_lustre(src, sizeof(src), opt.o_mnt, &hai->hai_dfid);
- ct_path_archive(dst, sizeof(dst), opt.o_hsm_root, &hai->hai_fid);
+ ct_path_archive(root, sizeof(root), opt.o_hsm_root, &hai->hai_fid);
if (hai->hai_extent.length == -1) {
/* whole file, write it to tmp location and atomically
* replace old archived file */
- strlcat(dst, "_tmp", sizeof(dst));
+ snprintf(dst, sizeof(dst), "%s_tmp", root);
/* we cannot rely on the same test because ct_copy_data()
* updates hai_extent.length */
rename_needed = true;
+ } else {
+ snprintf(dst, sizeof(dst), "%s", root);
}
CT_TRACE("archiving '%s' to '%s'", src, dst);
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"
static int ct_remove(const struct hsm_action_item *hai, const long hal_flags)
{
struct hsm_copyaction_private *hcp = NULL;
- char dst[PATH_MAX];
+ char dst[PATH_MAX], attr[PATH_MAX + 4];
int rc;
rc = ct_begin(&hcp, hai);
goto fini;
}
- strlcat(dst, ".lov", sizeof(dst));
- rc = unlink(dst);
+ snprintf(attr, sizeof(attr), "%s.lov", dst);
+ rc = unlink(attr);
if (rc < 0) {
rc = -errno;
- CT_ERROR(rc, "cannot unlink '%s'", dst);
+ CT_ERROR(rc, "cannot unlink '%s'", attr);
err_minor++;
goto 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);
ct_path_archive(dst, sizeof(dst), opt.o_hsm_root, new_fid);
if (!opt.o_dry_run) {
+ char src_attr[PATH_MAX + 4];
+ char dst_attr[PATH_MAX + 4];
+
ct_mkdir_p(dst);
if (rename(src, dst)) {
rc = -errno;
return -errno;
}
/* rename lov file */
- strlcat(src, ".lov", sizeof(src));
- strlcat(dst, ".lov", sizeof(dst));
- if (rename(src, dst))
- CT_ERROR(errno, "cannot rename '%s' to '%s'", src, dst);
+ snprintf(src_attr, sizeof(src_attr), "%s.lov", src);
+ snprintf(dst_attr, sizeof(dst_attr), "%s.lov", dst);
+ if (rename(src_attr, dst_attr))
+ CT_ERROR(errno, "cannot rename '%s' to '%s'",
+ src_attr, dst_attr);
}
return 0;
__u64 seq = 0;
__u16 subseq;
- strlcpy(path, opt.o_hsm_root, sizeof(path));
+ snprintf(path, sizeof(path), "%s", opt.o_hsm_root);
/* FID sequence is stored in top-level directory names:
* hsm_root/16bits (high weight)/16 bits/16 bits/16 bits (low weight).
*/
}
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;
}
{
int rc;
- strlcpy(cmd_name, basename(argv[0]), sizeof(cmd_name));
+ snprintf(cmd_name, sizeof(cmd_name), "%s", basename(argv[0]));
rc = ct_parseopts(argc, argv);
if (rc < 0) {
CT_WARN("try '%s --help' for more information", cmd_name);
return -rc;
}
-