#include <sys/types.h>
#include <libcfs/util/string.h>
-#include <linux/lustre_fid.h>
+#include <linux/lustre/lustre_fid.h>
#include <lustre/lustreapi.h>
/* Progress reporting period */
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;
}
static int ct_path_lustre(char *buf, int sz, const char *mnt,
- const lustre_fid *fid)
+ const struct lu_fid *fid)
{
return snprintf(buf, sz, "%s/%s/fid/"DFID_NOBRACE, mnt,
dot_lustre_name, PFID(fid));
}
static int ct_path_archive(char *buf, int sz, const char *archive_dir,
- const lustre_fid *fid)
+ const struct lu_fid *fid)
{
return snprintf(buf, sz, "%s/%04x/%04x/%04x/%04x/%04x/%04x/"
DFID_NOBRACE, archive_dir,
{
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);
}
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"
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;
+
+ /* ignore the error when lov file does not exist. */
+ if (rc == -ENOENT)
+ rc = 0;
+ else
+ goto fini;
}
fini:
static int ct_import_one(const char *src, const char *dst)
{
char newarc[PATH_MAX];
- lustre_fid fid;
+ struct lu_fid fid;
struct stat st;
int rc;
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);
return result;
}
-static int ct_import_fid(const lustre_fid *import_fid)
+static int ct_import_fid(const struct lu_fid *import_fid)
{
char fid_path[PATH_MAX];
int rc;
DIR *dir;
struct dirent *ent;
char *srcpath, *newpath;
- lustre_fid import_fid;
+ struct lu_fid import_fid;
int rc;
if (relpath == NULL)
return rc;
}
-static int ct_rebind_one(const lustre_fid *old_fid, const lustre_fid *new_fid)
+static int ct_rebind_one(const struct lu_fid *old_fid,
+ const struct lu_fid *new_fid)
{
char src[PATH_MAX];
char dst[PATH_MAX];
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;
}
-static bool fid_is_file(lustre_fid *fid)
+static bool fid_is_file(struct lu_fid *fid)
{
return fid_is_norm(fid) || fid_is_igif(fid);
}
/* each line consists of 2 FID */
while ((r = getline(&line, &line_size, filp)) != -1) {
- lustre_fid old_fid;
- lustre_fid new_fid;
+ struct lu_fid old_fid;
+ struct lu_fid new_fid;
/* Ignore empty and commented out ('#...') lines. */
if (should_ignore_line(line))
int rc;
if (opt.o_dst) {
- lustre_fid old_fid;
- lustre_fid new_fid;
+ 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)) {
__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;
}
-