mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-15 21:00:05 +01:00
Improve progress routine for cryptsetup utilities.
The progress routine is now fully translated and prints out progress in following manner (examples): Progress: 25,5%, ETA 00m31s, 7 GiB written, speed 838,6 MiB/s Progress: 25,5%, ETA 20h11m31s, 7 GiB written, speed 24 KiB/s Progress: 25,5%, ETA 06 days, 12 MiB written, speed 4 KiB/s Also got rid of -lm dependency due to floor(). Fixes: #671.
This commit is contained in:
@@ -20,7 +20,17 @@
|
||||
*/
|
||||
|
||||
#include "cryptsetup.h"
|
||||
#include <math.h>
|
||||
|
||||
#define MINUTES_90 UINT64_C(5400000000) /* 90 minutes in microseconds */
|
||||
#define HOURS_36 UINT64_C(129600000000) /* 36 hours in microseconds */
|
||||
|
||||
#define MINUTES(A) (A) / UINT64_C(60000000) /* microseconds to minutes */
|
||||
#define SECONDS(A) (A) / UINT64_C(1000000) /* microseconds to seconds */
|
||||
#define HOURS(A) (A) / UINT64_C(3600000000) /* microseconds to hours */
|
||||
#define DAYS(A) (A) / UINT64_C(86400000000) /* microseconds to days */
|
||||
|
||||
#define REMAIN_SECONDS(A) (SECONDS((A))) % 60
|
||||
#define REMAIN_MINUTES(A) (MINUTES((A))) % 60
|
||||
|
||||
/* The difference in microseconds between two times in "timeval" format. */
|
||||
static uint64_t time_diff(struct timeval *start, struct timeval *end)
|
||||
@@ -35,13 +45,117 @@ static void tools_clear_line(void)
|
||||
log_std("\33[2K\r");
|
||||
}
|
||||
|
||||
static void bytes_to_units(uint64_t *bytes, const char **units)
|
||||
{
|
||||
if (*bytes < (UINT64_C(1) << 32)) { /* less than 4 GiBs */
|
||||
*units = "MiB";
|
||||
*bytes >>= 20;
|
||||
} else if (*bytes < (UINT64_C(1) << 42)) { /* less than 4 TiBs */
|
||||
*units = "GiB";
|
||||
*bytes >>= 30;
|
||||
} else if (*bytes < (UINT64_C(1) << 52)) { /* less than 4 PiBs */
|
||||
*units = "TiB";
|
||||
*bytes >>= 40;
|
||||
} else if (*bytes < (UINT64_C(1) << 62)) { /* less than 4 EiBs */
|
||||
*units = "PiB";
|
||||
*bytes >>= 50;
|
||||
} else {
|
||||
*units = "EiB";
|
||||
*bytes >>= 60;
|
||||
}
|
||||
}
|
||||
|
||||
static bool time_to_human_string(uint64_t usecs, char *buf, size_t buf_len)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
if (usecs < MINUTES_90)
|
||||
r = snprintf(buf, buf_len, _("%02" PRIu64 "m%02" PRIu64 "s"), MINUTES(usecs), REMAIN_SECONDS(usecs));
|
||||
else if (usecs < HOURS_36)
|
||||
r = snprintf(buf, buf_len, _("%02" PRIu64 "h%02" PRIu64 "m%02" PRIu64 "s"), HOURS(usecs), REMAIN_MINUTES(usecs), REMAIN_SECONDS(usecs));
|
||||
else
|
||||
r = snprintf(buf, buf_len, _("%02" PRIu64 " days"), DAYS(usecs));
|
||||
|
||||
if (r < 0 || (size_t)r >= buf_len)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void log_progress(uint64_t bytes, uint64_t device_size, uint64_t eta, double uib, const char *ustr, const char *eol)
|
||||
{
|
||||
double progress;
|
||||
int r;
|
||||
const char *units;
|
||||
char time[128], written[128], speed[128];
|
||||
|
||||
/*
|
||||
* TRANSLATORS: 'time' string with examples:
|
||||
* "12m44s" : meaning 12 minutes 44 seconds
|
||||
* "26h12m44s" : meaning 26 hours 12 minutes 44 seconds
|
||||
* "3 days"
|
||||
*/
|
||||
if (!time_to_human_string(eta, time, sizeof(time)))
|
||||
return;
|
||||
|
||||
progress = (double)bytes / device_size * 100.0;
|
||||
|
||||
bytes_to_units(&bytes, &units);
|
||||
r = snprintf(written, sizeof(written), _("%4" PRIu64 " %s written"), bytes, units);
|
||||
if (r < 0 || (size_t)r >= sizeof(written))
|
||||
return;
|
||||
|
||||
r = snprintf(speed, sizeof(speed), _("speed %5.1f %s/s"), uib, ustr);
|
||||
if (r < 0 || (size_t)r >= sizeof(speed))
|
||||
return;
|
||||
|
||||
/*
|
||||
* TRANSLATORS: 'time', 'written' and 'speed' string are supposed
|
||||
* to get translated as well. 'eol' is always new-line or empty.
|
||||
* See above.
|
||||
*/
|
||||
log_std(_("Progress: %5.1f%%, ETA %s, %s, %s%s"),
|
||||
progress, time, written, speed, eol);
|
||||
}
|
||||
|
||||
static void log_progress_final(uint64_t time_spent, uint64_t bytes, double uib, const char *ustr)
|
||||
{
|
||||
int r;
|
||||
const char *units;
|
||||
char time[128], written[128], speed[128];
|
||||
|
||||
/*
|
||||
* TRANSLATORS: 'time' string with examples:
|
||||
* "12m44s" : meaning 12 minutes 44 seconds
|
||||
* "26h12m44s" : meaning 26 hours 12 minutes 44 seconds
|
||||
* "3 days"
|
||||
*/
|
||||
if (!time_to_human_string(time_spent, time, sizeof(time)))
|
||||
return;
|
||||
|
||||
bytes_to_units(&bytes, &units);
|
||||
r = snprintf(written, sizeof(written) - 1, _("%4" PRIu64 " %s written"), bytes, units);
|
||||
if (r < 0 || (size_t)r >= sizeof(written))
|
||||
return;
|
||||
|
||||
r = snprintf(speed, sizeof(speed) - 1, _("speed %5.1f %s/s"), uib, ustr);
|
||||
if (r < 0 || (size_t)r >= sizeof(speed))
|
||||
return;
|
||||
|
||||
/*
|
||||
* TRANSLATORS: 'time', 'written' and 'speed' string are supposed
|
||||
* to get translated as well. See above
|
||||
*/
|
||||
log_std(_("Finished, time %s, %s, %s\n"), time, written, speed);
|
||||
}
|
||||
|
||||
static void tools_time_progress(uint64_t device_size, uint64_t bytes, struct tools_progress_params *parms)
|
||||
{
|
||||
struct timeval now_time;
|
||||
uint64_t mbytes, eta, frequency;
|
||||
uint64_t eta, frequency;
|
||||
double tdiff, uib;
|
||||
int final = (bytes == device_size);
|
||||
const char *eol, *ustr = "";
|
||||
const char *eol, *ustr;
|
||||
bool final = (bytes == device_size);
|
||||
|
||||
gettimeofday(&now_time, NULL);
|
||||
if (parms->start_time.tv_sec == 0 && parms->start_time.tv_usec == 0) {
|
||||
@@ -68,36 +182,30 @@ static void tools_time_progress(uint64_t device_size, uint64_t bytes, struct too
|
||||
if (!tdiff)
|
||||
return;
|
||||
|
||||
mbytes = bytes / 1024 / 1024;
|
||||
uib = (double)(bytes - parms->start_offset) / tdiff;
|
||||
|
||||
eta = (uint64_t)(device_size / uib - tdiff);
|
||||
eta = (uint64_t)((device_size / uib - tdiff) * 1E6);
|
||||
|
||||
if (uib > 1073741824.0f) {
|
||||
uib /= 1073741824.0f;
|
||||
ustr = "Gi";
|
||||
ustr = "GiB";
|
||||
} else if (uib > 1048576.0f) {
|
||||
uib /= 1048576.0f;
|
||||
ustr = "Mi";
|
||||
ustr = "MiB";
|
||||
} else if (uib > 1024.0f) {
|
||||
uib /= 1024.0f;
|
||||
ustr = "Ki";
|
||||
}
|
||||
ustr = "KiB";
|
||||
} else
|
||||
ustr = "B";
|
||||
|
||||
if (!parms->frequency)
|
||||
tools_clear_line();
|
||||
|
||||
if (final)
|
||||
log_std("Finished, time %02" PRIu64 ":%02" PRIu64 ".%03" PRIu64 ", "
|
||||
"%4" PRIu64 " MiB written, speed %5.1f %sB/s\n",
|
||||
(uint64_t)tdiff / 60,
|
||||
(uint64_t)tdiff % 60,
|
||||
(uint64_t)((tdiff - floor(tdiff)) * 1000.0),
|
||||
mbytes, uib, ustr);
|
||||
log_progress_final((uint64_t)(tdiff * 1E6), bytes, uib, ustr);
|
||||
else
|
||||
log_std("Progress: %5.1f%%, ETA %02llu:%02llu, "
|
||||
"%4llu MiB written, speed %5.1f %sB/s%s",
|
||||
(double)bytes / device_size * 100,
|
||||
eta / 60, eta % 60, mbytes, uib, ustr, eol);
|
||||
log_progress(bytes, device_size, eta, uib, ustr, eol);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user