X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flhsmtool_posix.c;h=dda85512601562997a49198ddd518ba8af9fa205;hb=62a9ad817017d677b1914f0838d4a66ce64d2270;hp=6df6af593e024d7cf1022e22088193a860f170fd;hpb=d5ad6ff819e635c6ba337586cf70698b7728ff7f;p=fs%2Flustre-release.git diff --git a/lustre/utils/lhsmtool_posix.c b/lustre/utils/lhsmtool_posix.c index 6df6af5..dda8551 100644 --- a/lustre/utils/lhsmtool_posix.c +++ b/lustre/utils/lhsmtool_posix.c @@ -41,7 +41,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -57,6 +60,10 @@ #define ONE_MB 0x100000 +#ifndef NSEC_PER_SEC +# define NSEC_PER_SEC 1000000000UL +#endif + /* copytool uses a 32b bitmask field to register with kuc * archive num = 0 => all * archive num from 1 to 32 @@ -85,6 +92,7 @@ struct options { enum ct_action o_action; char *o_event_fifo; char *o_mnt; + int o_mnt_fd; char *o_hsm_root; char *o_src; /* for import, or rebind */ char *o_dst; /* for import, or rebind */ @@ -115,27 +123,34 @@ static char fs_name[MAX_OBD_NAME + 1]; static struct hsm_copytool_private *ctdata; +static inline double ct_now(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); -#define CT_ERROR(_rc, _format, ...) \ + return tv.tv_sec + 0.000001 * tv.tv_usec; +} + +#define CT_ERROR(_rc, _format, ...) \ llapi_error(LLAPI_MSG_ERROR, _rc, \ - "%s[%ld]: "_format, \ - cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) -#define CT_DEBUG(_format, ...) \ + "%f %s[%ld]: "_format, \ + ct_now(), cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) + +#define CT_DEBUG(_format, ...) \ llapi_error(LLAPI_MSG_DEBUG | LLAPI_MSG_NO_ERRNO, 0, \ - "%s[%ld]: "_format, \ - cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) + "%f %s[%ld]: "_format, \ + ct_now(), cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) + #define CT_WARN(_format, ...) \ llapi_error(LLAPI_MSG_WARN | LLAPI_MSG_NO_ERRNO, 0, \ - "%s[%ld]: "_format, \ - cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) -#define CT_TRACE(_format, ...) \ + "%f %s[%ld]: "_format, \ + ct_now(), cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) + +#define CT_TRACE(_format, ...) \ llapi_error(LLAPI_MSG_INFO | LLAPI_MSG_NO_ERRNO, 0, \ - "%s[%ld]: "_format, \ - cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) -#define CT_PRINTF(_format, ...) \ - llapi_printf(LLAPI_MSG_NORMAL, \ - "%s[%ld]: "_format, \ - cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) + "%f %s[%ld]: "_format, \ + ct_now(), cmd_name, syscall(SYS_gettid), ## __VA_ARGS__) static void usage(const char *name, int rc) { @@ -331,6 +346,7 @@ static int ct_parseopts(int argc, char * const *argv) } opt.o_mnt = argv[optind]; + opt.o_mnt_fd = -1; CT_TRACE("action=%d src=%s dst=%s mount_point=%s", opt.o_action, opt.o_src, opt.o_dst, opt.o_mnt); @@ -366,6 +382,9 @@ static int ct_mkdir_p(const char *path) int rc; ptr = strdup(path); + if (ptr == NULL) + return -errno; + saved = ptr; while (*ptr == '/') ptr++; @@ -485,45 +504,13 @@ static int ct_restore_stripe(const char *src, const char *dst, int dst_fd, rc = fsetxattr(dst_fd, XATTR_LUSTRE_LOV, lovea, lovea_size, XATTR_CREATE); if (rc < 0) { - CT_ERROR(errno, "cannot set lov EA on '%s'", dst); rc = -errno; + CT_ERROR(rc, "cannot set lov EA on '%s'", dst); } return rc; } -static void bandwidth_ctl_delay(int wsize) -{ - static unsigned long long tot_bytes; - static time_t start_time; - static time_t last_time; - time_t now = time(0); - double tot_time; - double excess; - unsigned int sleep_time; - - if (now > last_time + 5) { - tot_bytes = 0; - start_time = last_time = now; - } - - tot_bytes += wsize; - tot_time = now - start_time; - if (tot_time < 1) - tot_time = 1; - - excess = tot_bytes - tot_time * opt.o_bandwidth; - sleep_time = excess * 1000000 / opt.o_bandwidth; - if ((now - start_time) % 10 == 1) - CT_TRACE("bandwith control: excess=%E sleep for %dus", excess, - sleep_time); - - if (excess > 0) - usleep(sleep_time); - - last_time = now; -} - static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src, const char *dst, int src_fd, int dst_fd, const struct hsm_action_item *hai, long hal_flags) @@ -535,10 +522,13 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src, char *buf = NULL; __u64 write_total = 0; __u64 length; - time_t last_print_time = time(NULL); + time_t last_report_time; int rc = 0; - - CT_TRACE("going to copy data from '%s' to '%s'", src, dst); + double start_ct_now = ct_now(); + /* Bandwidth Control */ + time_t start_time; + time_t now; + time_t last_bw_print; if (fstat(src_fd, &src_st) < 0) { rc = -errno; @@ -576,6 +566,8 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src, /* Don't read beyond a given extent */ length = min(hai->hai_extent.length, src_st.st_size); + start_time = last_bw_print = last_report_time = time(NULL); + he.offset = offset; he.length = 0; rc = llapi_hsm_action_progress(hcp, &he, length, 0); @@ -595,7 +587,8 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src, goto out; } - CT_DEBUG("Going to copy "LPU64" bytes %s -> %s\n", length, src, dst); + CT_TRACE("start copy of "LPU64" bytes from '%s' to '%s'", + length, src, dst); while (write_total < length) { ssize_t rsize; @@ -624,12 +617,50 @@ static int ct_copy_data(struct hsm_copyaction_private *hcp, const char *src, write_total += wsize; offset += wsize; - if (opt.o_bandwidth != 0) - /* sleep if needed, to honor bandwidth limits */ - bandwidth_ctl_delay(wsize); + now = time(NULL); + /* sleep if needed, to honor bandwidth limits */ + if (opt.o_bandwidth != 0) { + unsigned long long write_theory; - if (time(0) >= last_print_time + opt.o_report_int) { - last_print_time = time(0); + write_theory = (now - start_time) * opt.o_bandwidth; + + if (write_theory < write_total) { + unsigned long long excess; + struct timespec delay; + + excess = write_total - write_theory; + + delay.tv_sec = excess / opt.o_bandwidth; + delay.tv_nsec = (excess % opt.o_bandwidth) * + NSEC_PER_SEC / opt.o_bandwidth; + + if (now >= last_bw_print + opt.o_report_int) { + CT_TRACE("bandwith control: %lluB/s " + "excess=%llu sleep for " + "%lld.%09lds", + opt.o_bandwidth, excess, + (long long)delay.tv_sec, + delay.tv_nsec); + last_bw_print = now; + } + + do { + rc = nanosleep(&delay, &delay); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { + CT_ERROR(errno, "delay for bandwidth " + "control failed to sleep: " + "residual=%lld.%09lds", + (long long)delay.tv_sec, + delay.tv_nsec); + rc = 0; + } + } + } + + now = time(NULL); + if (now >= last_report_time + opt.o_report_int) { + last_report_time = now; CT_TRACE("%%"LPU64" ", 100 * write_total / length); he.length = write_total; rc = llapi_hsm_action_progress(hcp, &he, length, 0); @@ -668,6 +699,9 @@ out: if (buf != NULL) free(buf); + CT_TRACE("copied "LPU64" bytes in %f seconds", + length, ct_now() - start_ct_now); + return rc; } @@ -856,7 +890,7 @@ static int ct_archive(const struct hsm_action_item *hai, const long hal_flags) if (hai->hai_extent.length == -1) { /* whole file, write it to tmp location and atomically * replace old archived file */ - strncat(dst, "_tmp", sizeof(dst) - strlen(dst) - 1); + strlcat(dst, "_tmp", sizeof(dst)); /* we cannot rely on the same test because ct_copy_data() * updates hai_extent.length */ rename_needed = true; @@ -877,7 +911,7 @@ static int ct_archive(const struct hsm_action_item *hai, const long hal_flags) src_fd = llapi_hsm_action_get_fd(hcp); if (src_fd < 0) { - rc = -errno; + rc = src_fd; CT_ERROR(rc, "cannot open '%s' for read", src); goto fini_major; } @@ -1081,7 +1115,7 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags) int hp_flags = 0; int src_fd = -1; int dst_fd = -1; - int mdt_index = -1; /* Not implemented */ + int mdt_index = -1; int open_flags = 0; bool set_lovea; struct lu_fid dfid; @@ -1093,6 +1127,13 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags) /* build backend file name from released file FID */ ct_path_archive(src, sizeof(src), opt.o_hsm_root, &hai->hai_fid); + rc = llapi_get_mdt_index_by_fid(opt.o_mnt_fd, &hai->hai_fid, + &mdt_index); + if (rc < 0) { + CT_ERROR(rc, "cannot get mdt index "DFID"", + PFID(&hai->hai_fid)); + return rc; + } /* restore loads and sets the LOVEA w/o interpreting it to avoid * dependency on the structure format. */ rc = ct_load_stripe(src, lov_buf, &lov_size); @@ -1136,6 +1177,11 @@ static int ct_restore(const struct hsm_action_item *hai, const long hal_flags) } dst_fd = llapi_hsm_action_get_fd(hcp); + if (dst_fd < 0) { + rc = dst_fd; + CT_ERROR(rc, "cannot open '%s' for write", dst); + goto fini; + } if (set_lovea) { /* the layout cannot be allocated through .fid so we have to @@ -1202,7 +1248,7 @@ static int ct_remove(const struct hsm_action_item *hai, const long hal_flags) goto fini; } - strncat(dst, ".lov", sizeof(dst) - strlen(dst) - 1); + strlcat(dst, ".lov", sizeof(dst)); rc = unlink(dst); if (rc < 0) { rc = -errno; @@ -1392,10 +1438,20 @@ static char *path_concat(const char *dirname, const char *basename) static int ct_import_fid(const lustre_fid *import_fid) { - char fid_path[PATH_MAX]; + char fid_path[PATH_MAX]; + int rc; + + ct_path_lustre(fid_path, sizeof(fid_path), opt.o_mnt, import_fid); + rc = access(fid_path, F_OK); + if (rc == 0 || errno != ENOENT) { + rc = (errno == 0) ? -EEXIST : -errno; + CT_ERROR(rc, "cannot import '"DFID"'", PFID(import_fid)); + return rc; + } ct_path_archive(fid_path, sizeof(fid_path), opt.o_hsm_root, import_fid); + CT_TRACE("Resolving "DFID" to %s", PFID(import_fid), fid_path); return ct_import_one(fid_path, opt.o_dst); @@ -1519,8 +1575,8 @@ static int ct_rebind_one(const lustre_fid *old_fid, const lustre_fid *new_fid) return -errno; } /* rename lov file */ - strncat(src, ".lov", sizeof(src) - strlen(src) - 1); - strncat(dst, ".lov", sizeof(dst) - strlen(dst) - 1); + strlcat(src, ".lov", sizeof(src)); + strlcat(dst, ".lov", sizeof(dst)); if (rename(src, dst)) CT_ERROR(errno, "cannot rename '%s' to '%s'", src, dst); @@ -1680,21 +1736,28 @@ out: static int ct_max_sequence(void) { - int rc, i; - char path[PATH_MAX]; - __u64 seq = 0; - __u16 subseq; + int rc, i; + char path[PATH_MAX]; + __u64 seq = 0; + __u16 subseq; - strncpy(path, opt.o_hsm_root, sizeof(path)); + strlcpy(path, opt.o_hsm_root, sizeof(path)); /* FID sequence is stored in top-level directory names: * hsm_root/16bits (high weight)/16 bits/16 bits/16 bits (low weight). */ for (i = 0; i < 4; i++) { + size_t path_len; + rc = ct_dir_level_max(path, &subseq); if (rc != 0) return rc; seq |= ((__u64)subseq << ((3 - i) * 16)); - sprintf(path + strlen(path), "/%04x", subseq); + path_len = strlen(path); + rc = snprintf(path + path_len, sizeof(path) - path_len, + "/%04x", subseq); + if (rc >= (sizeof(path) - path_len)) + return -E2BIG; + path[sizeof(path) - 1] = '\0'; } printf("max_sequence: "LPX64"\n", seq); @@ -1738,8 +1801,9 @@ static int ct_run(void) llapi_error_callback_set(llapi_hsm_log_error); } - rc = llapi_hsm_copytool_register(&ctdata, opt.o_mnt, 0, - opt.o_archive_cnt, opt.o_archive_id); + rc = llapi_hsm_copytool_register(&ctdata, opt.o_mnt, + opt.o_archive_cnt, + opt.o_archive_id, 0); if (rc < 0) { CT_ERROR(rc, "cannot start copytool interface"); return rc; @@ -1760,8 +1824,6 @@ static int ct_run(void) if (rc == -ESHUTDOWN) { CT_TRACE("shutting down"); break; - } else if (rc == -EAGAIN) { - continue; /* msg not for us */ } else if (rc < 0) { CT_WARN("cannot receive action list: %s", strerror(-rc)); @@ -1805,8 +1867,6 @@ static int ct_run(void) hai = hai_next(hai); } - llapi_hsm_action_list_free(&hal); - if (opt.o_abort_on_error && err_major) break; } @@ -1836,7 +1896,15 @@ static int ct_setup(void) if (rc < 0) { CT_ERROR(rc, "cannot find a Lustre filesystem mounted at '%s'", opt.o_mnt); - return -rc; + return rc; + } + + opt.o_mnt_fd = open(opt.o_mnt, O_RDONLY); + if (opt.o_mnt_fd < 0) { + rc = -errno; + CT_ERROR(rc, "cannot open mount point at '%s'", + opt.o_mnt); + return rc; } return rc; @@ -1846,13 +1914,22 @@ static int ct_cleanup(void) { int rc; - if (arc_fd < 0) - return 0; + if (opt.o_mnt_fd >= 0) { + rc = close(opt.o_mnt_fd); + if (rc < 0) { + rc = -errno; + CT_ERROR(rc, "cannot close mount point"); + return rc; + } + } - if (close(arc_fd) < 0) { - rc = -errno; - CT_ERROR(rc, "cannot close archive root directory"); - return rc; + if (arc_fd >= 0) { + rc = close(arc_fd); + if (rc < 0) { + rc = -errno; + CT_ERROR(rc, "cannot close archive root directory"); + return rc; + } } return 0; @@ -1862,14 +1939,16 @@ int main(int argc, char **argv) { int rc; - strncpy(cmd_name, basename(argv[0]), sizeof(cmd_name)); + strlcpy(cmd_name, basename(argv[0]), sizeof(cmd_name)); rc = ct_parseopts(argc, argv); if (rc < 0) { CT_WARN("try '%s --help' for more information", cmd_name); return -rc; } - ct_setup(); + rc = ct_setup(); + if (rc < 0) + goto error_cleanup; switch (opt.o_action) { case CA_IMPORT: @@ -1891,6 +1970,7 @@ int main(int argc, char **argv) " rc=%d (%s)", err_major, err_minor, rc, strerror(-rc)); +error_cleanup: ct_cleanup(); return -rc;