Also, show it in import-fs/repart.
/* shared/ forward declarations */
-typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
+typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, uint64_t bytes_per_second, void *userdata);
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
struct local_address;
uint64_t size;
bool started;
bool logged_incomplete;
+ uint64_t bps;
} ProgressInfo;
static void progress_info_free(ProgressInfo *p) {
if (p->size == 0)
log_info("Copying tree, currently at '%s'...", p->path);
- else
+ else if (p->bps == UINT64_MAX)
log_info("Copying tree, currently at '%s' (@%s)...", p->path, FORMAT_BYTES(p->size));
+ else
+ log_info("Copying tree, currently at '%s' (@%s, %s/s)...", p->path, FORMAT_BYTES(p->size), FORMAT_BYTES(p->bps));
}
static int progress_path(const char *path, const struct stat *st, void *userdata) {
return 0;
}
-static int progress_bytes(uint64_t nbytes, void *userdata) {
+static int progress_bytes(uint64_t nbytes, uint64_t bps, void *userdata) {
ProgressInfo *p = ASSERT_PTR(userdata);
assert(p->size != UINT64_MAX);
p->size += nbytes;
+ p->bps = bps;
progress_show(p);
return 0;
static int import_fs(int argc, char *argv[], void *userdata) {
_cleanup_(rm_rf_subvolume_and_freep) char *temp_path = NULL;
- _cleanup_(progress_info_free) ProgressInfo progress = {};
+ _cleanup_(progress_info_free) ProgressInfo progress = { .bps = UINT64_MAX };
_cleanup_free_ char *l = NULL, *final_path = NULL;
const char *path = NULL, *local = NULL, *dest = NULL;
_cleanup_close_ int open_fd = -EBADF;
return 0;
}
-static int progress_bytes(uint64_t n_bytes, void *userdata) {
+static int progress_bytes(uint64_t n_bytes, uint64_t bps, void *userdata) {
Partition *p = ASSERT_PTR(userdata);
unsigned percent;
if (!ratelimit_below(&p->progress_ratelimit))
return 0;
- (void) draw_progress_barf(
- percent,
- "%s %s %s %s/%s",
- strna(p->copy_blocks_path),
- glyph(GLYPH_ARROW_RIGHT),
- strna(p->definition_path),
- FORMAT_BYTES(p->copy_blocks_done),
- FORMAT_BYTES(p->copy_blocks_size));
+ if (bps != UINT64_MAX)
+ (void) draw_progress_barf(
+ percent,
+ "%s %s %s %s/%s %s/s",
+ strna(p->copy_blocks_path),
+ glyph(GLYPH_ARROW_RIGHT),
+ strna(p->definition_path),
+ FORMAT_BYTES(p->copy_blocks_done),
+ FORMAT_BYTES(p->copy_blocks_size),
+ FORMAT_BYTES(bps));
+ else
+ (void) draw_progress_barf(
+ percent,
+ "%s %s %s %s/%s",
+ strna(p->copy_blocks_path),
+ glyph(GLYPH_ARROW_RIGHT),
+ strna(p->definition_path),
+ FORMAT_BYTES(p->copy_blocks_done),
+ FORMAT_BYTES(p->copy_blocks_size));
p->last_percent = percent;
#include "path-util.h"
#include "rm-rf.h"
#include "selinux-util.h"
+#include "set.h"
#include "signal-util.h"
#include "stat-util.h"
-#include "set.h"
#include "stdio-util.h"
#include "string-util.h"
#include "sync-util.h"
+#include "time-util.h"
#include "tmpfile-util.h"
#include "umask-util.h"
#include "user-util.h"
}
}
+ usec_t start_timestamp = USEC_INFINITY;
+ if (progress)
+ start_timestamp = now(CLOCK_MONOTONIC);
+
for (;;) {
ssize_t n;
size_t m;
try_sendfile = false;
if (progress) {
- r = progress(n, userdata);
+ usec_t t = now(CLOCK_MONOTONIC);
+ usec_t d = usec_sub_unsigned(t, start_timestamp);
+ uint64_t bps = UINT64_MAX;
+ if (d > USEC_PER_SEC * 3U)
+ bps = (uint64_t) (copied_total / ((double) d / USEC_PER_SEC));
+
+ r = progress(n, bps, userdata);
if (r < 0)
return r;
}
_DENY_TYPE_INVALID = -EINVAL,
} DenyType;
-typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
+typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, uint64_t bytes_per_second, void *userdata);
typedef int (*copy_progress_path_t)(const char *path, const struct stat *st, void *userdata);
int copy_file_fd_at_full(int dir_fdf, const char *from, int to, CopyFlags copy_flags, copy_progress_bytes_t progress, void *userdata);