core: do BindMount/MountImage operations in async control process

These operations might require slow I/O, and thus might block PID1's main
loop for an undeterminated amount of time. Instead of performing them
inline, fork a worker process and stash away the D-Bus message, and reply
once we get a SIGCHILD indicating they have completed. That way we don't
break compatibility and callers can continue to rely on the fact that when
they get the method reply the operation either succeeded or failed.

To keep backward compatibility, unlike reload control processes, these
are ran inside init.scope and not the target cgroup. Unlike ExecReload,
this is under our control and is not defined by the unit. This is necessary
because previously the operation also wasn't ran from the target cgroup,
so suddenly forking a copy-on-write copy of pid1 into the target cgroup
will make memory usage spike, and if there is a MemoryMax= or MemoryHigh=
set and the cgroup is already close to the limit, it will cause an OOM
kill, where previously it would have worked fine.
This commit is contained in:
Luca Boccassi
2024-08-29 12:48:55 +01:00
committed by Luca Boccassi
parent 5121f7c45b
commit 5162829ec8
25 changed files with 480 additions and 146 deletions
+1
View File
@@ -57,6 +57,7 @@ int verb_is_active(int argc, char *argv[], void *userdata) {
static const UnitActiveState states[] = {
UNIT_ACTIVE,
UNIT_RELOADING,
UNIT_REFRESHING,
};
/* According to LSB: 3, "program is not running" */
@@ -22,6 +22,7 @@ static int list_dependencies_print(const char *name, UnitActiveState state, int
switch (state) {
case UNIT_ACTIVE:
case UNIT_RELOADING:
case UNIT_REFRESHING:
case UNIT_ACTIVATING:
on = ansi_highlight_green();
break;
+1 -1
View File
@@ -149,7 +149,7 @@ static int output_units_list(const UnitInfo *unit_infos, size_t c) {
/* Here override any load_state highlighting */
on_circle = ansi_highlight_red();
circle = true;
} else if (STR_IN_SET(u->active_state, "reloading", "activating", "maintenance", "deactivating")) {
} else if (STR_IN_SET(u->active_state, "reloading", "activating", "maintenance", "refreshing", "deactivating")) {
on_sub = on_active = ansi_highlight();
if (!circle) { /* Here we let load_state highlighting win */
+6 -6
View File
@@ -301,7 +301,7 @@ static void format_active_state(const char *active_state, const char **active_on
if (streq_ptr(active_state, "failed")) {
*active_on = ansi_highlight_red();
*active_off = ansi_normal();
} else if (STRPTR_IN_SET(active_state, "active", "reloading")) {
} else if (STRPTR_IN_SET(active_state, "active", "reloading", "refreshing")) {
*active_on = ansi_highlight_green();
*active_off = ansi_normal();
} else
@@ -440,10 +440,10 @@ static void print_status_info(
if (!isempty(i->result) && !streq(i->result, "success"))
printf(" (Result: %s)", i->result);
timestamp = STRPTR_IN_SET(i->active_state, "active", "reloading") ? i->active_enter_timestamp :
STRPTR_IN_SET(i->active_state, "inactive", "failed") ? i->inactive_enter_timestamp :
STRPTR_IN_SET(i->active_state, "activating") ? i->inactive_exit_timestamp :
i->active_exit_timestamp;
timestamp = STRPTR_IN_SET(i->active_state, "active", "reloading", "refreshing") ? i->active_enter_timestamp :
STRPTR_IN_SET(i->active_state, "inactive", "failed") ? i->inactive_enter_timestamp :
STRPTR_IN_SET(i->active_state, "activating") ? i->inactive_exit_timestamp :
i->active_exit_timestamp;
if (timestamp_is_set(timestamp)) {
printf(" since %s; %s\n",
@@ -2199,7 +2199,7 @@ static int show_one(
if (show_mode == SYSTEMCTL_SHOW_STATUS) {
print_status_info(bus, &info, ellipsized);
if (info.active_state && !STR_IN_SET(info.active_state, "active", "reloading"))
if (info.active_state && !STR_IN_SET(info.active_state, "active", "reloading", "refreshing"))
return EXIT_PROGRAM_NOT_RUNNING;
return EXIT_PROGRAM_RUNNING_OR_SERVICE_OK;
+1 -1
View File
@@ -361,7 +361,7 @@ int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_maske
if (r < 0)
return r;
if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING))
if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING, UNIT_REFRESHING))
continue;
r = strv_extend(&active, *i);