sysupdate: Report download progress via sd_notify

We set up a NOTIFY_SOCKET to get download progress notifications from
each individual import helper. Along with the number of import jobs we
have to run, this gives an overall progress value which we report using
sd_notify
This commit is contained in:
Adrian Vovk
2024-07-12 14:38:09 +01:00
committed by Tom Coldrick
parent e37164cafc
commit 8db5e9b657
4 changed files with 283 additions and 22 deletions
+40 -6
View File
@@ -25,6 +25,7 @@
#include "path-util.h"
#include "pretty-print.h"
#include "set.h"
#include "signal-util.h"
#include "sort-util.h"
#include "string-util.h"
#include "strv.h"
@@ -135,7 +136,7 @@ static int context_read_definitions(
if (!GREEDY_REALLOC(c->transfers, c->n_transfers + 1))
return log_oom();
t = transfer_new();
t = transfer_new(c);
if (!t)
return log_oom();
@@ -744,6 +745,30 @@ static int context_make_online(Context **ret, const char *node) {
return 0;
}
static int context_on_acquire_progress(const Transfer *t, const Instance *inst, unsigned percentage) {
const Context *c = ASSERT_PTR(t->context);
size_t i, n = c->n_transfers;
uint64_t base, scaled;
unsigned overall;
for (i = 0; i < n; i++)
if (c->transfers[i] == t)
break;
assert(i < n); /* We should have found the index */
base = (100 * 100 * i) / n;
scaled = (100 * percentage) / n;
overall = (unsigned) ((base + scaled) / 100);
assert(overall <= 100);
log_debug("Transfer %" PRIu64 "/%zu is %u%% complete (%u%% overall).", i+1, n, percentage, overall);
return sd_notifyf(/* unset= */ false, "X_SYSUPDATE_PROGRESS=%u\n"
"X_SYSUPDATE_TRANSFERS_LEFT=%zu\n"
"X_SYSUPDATE_TRANSFERS_DONE=%zu\n"
"STATUS=Updating to '%s' (%u%% complete).",
overall, n - i, i, inst->metadata.version, overall);
}
static int context_apply(
Context *c,
const char *version,
@@ -793,8 +818,10 @@ static int context_apply(
log_info("Selected update '%s' for install.", us->version);
(void) sd_notifyf(false,
"STATUS=Making room for '%s'.", us->version);
(void) sd_notifyf(/* unset= */ false,
"READY=1\n"
"X_SYSUPDATE_VERSION=%s\n"
"STATUS=Making room for '%s'.", us->version, us->version);
/* Let's make some room. We make sure for each transfer we have one free space to fill. While
* removing stuff we'll protect the version we are trying to acquire. Why that? Maybe an earlier
@@ -809,14 +836,15 @@ static int context_apply(
if (arg_sync)
sync();
(void) sd_notifyf(false,
"STATUS=Updating to '%s'.\n", us->version);
(void) sd_notifyf(/* unset= */ false,
"STATUS=Updating to '%s'.", us->version);
/* There should now be one instance picked for each transfer, and the order is the same */
assert(us->n_instances == c->n_transfers);
for (size_t i = 0; i < c->n_transfers; i++) {
r = transfer_acquire_instance(c->transfers[i], us->instances[i]);
r = transfer_acquire_instance(c->transfers[i], us->instances[i],
context_on_acquire_progress, c);
if (r < 0)
return r;
}
@@ -824,6 +852,9 @@ static int context_apply(
if (arg_sync)
sync();
(void) sd_notifyf(/* unset= */ false,
"STATUS=Installing '%s'.", us->version);
for (size_t i = 0; i < c->n_transfers; i++) {
r = transfer_install_instance(c->transfers[i], us->instances[i], arg_root);
if (r < 0)
@@ -1412,6 +1443,9 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
/* SIGCHLD signal must be blocked for sd_event_add_child to work */
BLOCK_SIGNALS(SIGCHLD);
return sysupdate_main(argc, argv);
}