mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 16:37:19 +09:00
copy: calculate bytes per second while copying, and pass to progress info
Also, show it in import-fs/repart.
This commit is contained in:
committed by
Luca Boccassi
parent
e566236fc1
commit
acd4943528
@@ -236,7 +236,7 @@ typedef struct sd_hwdb sd_hwdb;
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef struct ProgressInfo {
|
||||
uint64_t size;
|
||||
bool started;
|
||||
bool logged_incomplete;
|
||||
uint64_t bps;
|
||||
} ProgressInfo;
|
||||
|
||||
static void progress_info_free(ProgressInfo *p) {
|
||||
@@ -72,8 +73,10 @@ static void progress_show(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) {
|
||||
@@ -90,12 +93,13 @@ 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;
|
||||
@@ -103,7 +107,7 @@ static int progress_bytes(uint64_t nbytes, void *userdata) {
|
||||
|
||||
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;
|
||||
|
||||
@@ -5377,7 +5377,7 @@ static int partition_format_verity_sig(Context *context, Partition *p) {
|
||||
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;
|
||||
|
||||
@@ -5395,14 +5395,25 @@ static int progress_bytes(uint64_t n_bytes, void *userdata) {
|
||||
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;
|
||||
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
#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"
|
||||
@@ -263,6 +264,10 @@ int copy_bytes_full(
|
||||
}
|
||||
}
|
||||
|
||||
usec_t start_timestamp = USEC_INFINITY;
|
||||
if (progress)
|
||||
start_timestamp = now(CLOCK_MONOTONIC);
|
||||
|
||||
for (;;) {
|
||||
ssize_t n;
|
||||
size_t m;
|
||||
@@ -511,7 +516,13 @@ int copy_bytes_full(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef enum DenyType {
|
||||
_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);
|
||||
|
||||
Reference in New Issue
Block a user