summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/terminal-util.c6
-rw-r--r--src/boot/efi/boot.c2
-rw-r--r--src/core/cgroup.c212
-rw-r--r--src/core/cgroup.h16
-rw-r--r--src/core/core-varlink.c50
-rw-r--r--src/core/core-varlink.h2
-rw-r--r--src/core/import-creds.c4
-rw-r--r--src/core/manager-serialize.c2
-rw-r--r--src/core/meson.build32
-rw-r--r--src/core/path.c2
-rw-r--r--src/core/unit.c27
-rw-r--r--src/id128/id128.c37
-rwxr-xr-xsrc/kernel-install/90-loaderentry.install.in5
-rwxr-xr-xsrc/kernel-install/90-uki-copy.install6
-rw-r--r--src/libsystemd/meson.build2
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c34
-rw-r--r--src/login/logind-dbus.c5
-rw-r--r--src/login/logind-user.c26
-rw-r--r--src/partition/meson.build2
-rw-r--r--src/partition/repart.c32
-rw-r--r--src/shared/bootspec.c27
-rw-r--r--src/shared/exec-util.c1
-rw-r--r--src/shared/gpt.c21
-rw-r--r--src/shared/gpt.h1
-rw-r--r--src/shared/install.c14
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/spawn-polkit-agent.c11
-rw-r--r--src/shared/varlink-internal.h40
-rw-r--r--src/shared/varlink.c40
-rw-r--r--src/shutdown/meson.build2
-rw-r--r--src/systemctl/systemctl-util.c17
-rw-r--r--src/sysusers/meson.build2
-rw-r--r--src/test/meson.build8
-rw-r--r--src/test/test-install-root.c32
-rw-r--r--src/tmpfiles/meson.build2
-rwxr-xr-xsrc/ukify/test/test_ukify.py49
-rw-r--r--src/vmspawn/vmspawn-util.h2
38 files changed, 443 insertions, 334 deletions
diff --git a/src/basic/meson.build b/src/basic/meson.build
index 9a21457..b538775 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -274,7 +274,7 @@ filesystem_switch_case_h = custom_target(
basic_sources += [filesystem_list_h, filesystem_switch_case_h, filesystems_gperf_h]
-libbasic = static_library(
+libbasic_static = static_library(
'basic',
basic_sources,
fundamental_sources,
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index dda5920..3a1b7b2 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -584,8 +584,9 @@ int vt_disallocate(const char *name) {
(void) loop_write(fd2,
"\033[r" /* clear scrolling region */
"\033[H" /* move home */
- "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
- 10);
+ "\033[3J" /* clear screen including scrollback, requires Linux 2.6.40 */
+ "\033c", /* reset to initial state */
+ SIZE_MAX);
return 0;
}
@@ -1558,7 +1559,6 @@ int terminal_reset_ansi_seq(int fd) {
return log_debug_errno(r, "Failed to set terminal to non-blocking mode: %m");
k = loop_write_full(fd,
- "\033c" /* reset to initial state */
"\033[!p" /* soft terminal reset */
"\033]104\007" /* reset colors */
"\033[?7h", /* enable line-wrapping */
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 8287c21..e1f0817 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -1337,7 +1337,7 @@ static void boot_entry_parse_tries(
return;
/* Boot counter in the middle of the name? */
- if (!streq16(counter, suffix))
+ if (!strcaseeq16(counter, suffix))
return;
entry->tries_left = tries_left;
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 34fd2a2..76d7629 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -102,8 +102,9 @@ bool unit_has_startup_cgroup_constraints(Unit *u) {
c->startup_memory_low_set;
}
-bool unit_has_host_root_cgroup(Unit *u) {
+bool unit_has_host_root_cgroup(const Unit *u) {
assert(u);
+ assert(u->manager);
/* Returns whether this unit manages the root cgroup. This will return true if this unit is the root slice and
* the manager manages the root cgroup. */
@@ -2685,7 +2686,7 @@ int unit_set_cgroup_path(Unit *u, const char *path) {
if (crt && streq_ptr(crt->cgroup_path, path))
return 0;
- unit_release_cgroup(u);
+ unit_release_cgroup(u, /* drop_cgroup_runtime = */ true);
crt = unit_setup_cgroup_runtime(u);
if (!crt)
@@ -3483,7 +3484,7 @@ int unit_realize_cgroup(Unit *u) {
return unit_realize_cgroup_now(u, manager_state(u->manager));
}
-void unit_release_cgroup(Unit *u) {
+void unit_release_cgroup(Unit *u, bool drop_cgroup_runtime) {
assert(u);
/* Forgets all cgroup details for this cgroup — but does *not* destroy the cgroup. This is hence OK to call
@@ -3514,7 +3515,8 @@ void unit_release_cgroup(Unit *u) {
crt->cgroup_memory_inotify_wd = -1;
}
- *(CGroupRuntime**) ((uint8_t*) u + UNIT_VTABLE(u)->cgroup_runtime_offset) = cgroup_runtime_free(crt);
+ if (drop_cgroup_runtime)
+ *(CGroupRuntime**) ((uint8_t*) u + UNIT_VTABLE(u)->cgroup_runtime_offset) = cgroup_runtime_free(crt);
}
int unit_cgroup_is_empty(Unit *u) {
@@ -3535,22 +3537,24 @@ int unit_cgroup_is_empty(Unit *u) {
return r;
}
-bool unit_maybe_release_cgroup(Unit *u) {
+static bool unit_maybe_release_cgroup(Unit *u) {
int r;
- assert(u);
+ /* Releases the cgroup only if it is recursively empty.
+ * Returns true if the cgroup was released, false otherwise. */
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return true;
+ assert(u);
/* Don't release the cgroup if there are still processes under it. If we get notified later when all
* the processes exit (e.g. the processes were in D-state and exited after the unit was marked as
* failed) we need the cgroup paths to continue to be tracked by the manager so they can be looked up
* and cleaned up later. */
r = unit_cgroup_is_empty(u);
- if (r == 1) {
- unit_release_cgroup(u);
+ if (r > 0) {
+ /* Do not free CGroupRuntime when called from unit_prune_cgroup. Various accounting data
+ * we should keep, especially CPU usage and *_peak ones which would be shown even after
+ * the unit stops. */
+ unit_release_cgroup(u, /* drop_cgroup_runtime = */ false);
return true;
}
@@ -3558,8 +3562,8 @@ bool unit_maybe_release_cgroup(Unit *u) {
}
void unit_prune_cgroup(Unit *u) {
- int r;
bool is_root_slice;
+ int r;
assert(u);
@@ -3597,9 +3601,8 @@ void unit_prune_cgroup(Unit *u) {
if (!unit_maybe_release_cgroup(u)) /* Returns true if the cgroup was released */
return;
- crt = unit_get_cgroup_runtime(u); /* The above might have destroyed the runtime object, let's see if it's still there */
- if (!crt)
- return;
+ assert(crt == unit_get_cgroup_runtime(u));
+ assert(!crt->cgroup_path);
crt->cgroup_realized = false;
crt->cgroup_realized_mask = 0;
@@ -4526,6 +4529,10 @@ int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, uin
if (!UNIT_CGROUP_BOOL(u, memory_accounting))
return -ENODATA;
+ /* The root cgroup doesn't expose this information. */
+ if (unit_has_host_root_cgroup(u))
+ return -ENODATA;
+
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
if (!crt)
return -ENODATA;
@@ -4533,10 +4540,6 @@ int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, uin
/* If the cgroup is already gone, we try to find the last cached value. */
goto finish;
- /* The root cgroup doesn't expose this information. */
- if (unit_has_host_root_cgroup(u))
- return -ENODATA;
-
if (!FLAGS_SET(crt->cgroup_realized_mask, CGROUP_MASK_MEMORY))
return -ENODATA;
@@ -4592,15 +4595,14 @@ int unit_get_tasks_current(Unit *u, uint64_t *ret) {
return cg_get_attribute_as_uint64("pids", crt->cgroup_path, "pids.current", ret);
}
-static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
- uint64_t ns;
+static int unit_get_cpu_usage_raw(const Unit *u, const CGroupRuntime *crt, nsec_t *ret) {
int r;
assert(u);
+ assert(crt);
assert(ret);
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt->cgroup_path)
return -ENODATA;
/* The root cgroup doesn't expose this information, let's get it from /proc instead */
@@ -4614,25 +4616,24 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
r = cg_all_unified();
if (r < 0)
return r;
- if (r > 0) {
- _cleanup_free_ char *val = NULL;
- uint64_t us;
+ if (r == 0)
+ return cg_get_attribute_as_uint64("cpuacct", crt->cgroup_path, "cpuacct.usage", ret);
- r = cg_get_keyed_attribute("cpu", crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
- if (IN_SET(r, -ENOENT, -ENXIO))
- return -ENODATA;
- if (r < 0)
- return r;
+ _cleanup_free_ char *val = NULL;
+ uint64_t us;
- r = safe_atou64(val, &us);
- if (r < 0)
- return r;
+ r = cg_get_keyed_attribute("cpu", crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
+ if (IN_SET(r, -ENOENT, -ENXIO))
+ return -ENODATA;
+ if (r < 0)
+ return r;
- ns = us * NSEC_PER_USEC;
- } else
- return cg_get_attribute_as_uint64("cpuacct", crt->cgroup_path, "cpuacct.usage", ret);
+ r = safe_atou64(val, &us);
+ if (r < 0)
+ return r;
+
+ *ret = us * NSEC_PER_USEC;
- *ret = ns;
return 0;
}
@@ -4646,14 +4647,14 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
* started. If the cgroup has been removed already, returns the last cached value. To cache the value, simply
* call this function with a NULL return value. */
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!UNIT_CGROUP_BOOL(u, cpu_accounting))
return -ENODATA;
- if (!UNIT_CGROUP_BOOL(u, cpu_accounting))
+ CGroupRuntime *crt = unit_get_cgroup_runtime(u);
+ if (!crt)
return -ENODATA;
- r = unit_get_cpu_usage_raw(u, &ns);
+ r = unit_get_cpu_usage_raw(u, crt, &ns);
if (r == -ENODATA && crt->cpu_usage_last != NSEC_INFINITY) {
/* If we can't get the CPU usage anymore (because the cgroup was already removed, for example), use our
* cached value. */
@@ -4694,7 +4695,7 @@ int unit_get_ip_accounting(
return -ENODATA;
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt)
return -ENODATA;
fd = IN_SET(metric, CGROUP_IP_INGRESS_BYTES, CGROUP_IP_INGRESS_PACKETS) ?
@@ -4770,22 +4771,27 @@ int unit_get_effective_limit(Unit *u, CGroupLimitType type, uint64_t *ret) {
return 0;
}
-static int unit_get_io_accounting_raw(Unit *u, uint64_t ret[static _CGROUP_IO_ACCOUNTING_METRIC_MAX]) {
- static const char *const field_names[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
+static int unit_get_io_accounting_raw(
+ const Unit *u,
+ const CGroupRuntime *crt,
+ uint64_t ret[static _CGROUP_IO_ACCOUNTING_METRIC_MAX]) {
+
+ static const char* const field_names[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
[CGROUP_IO_READ_BYTES] = "rbytes=",
[CGROUP_IO_WRITE_BYTES] = "wbytes=",
[CGROUP_IO_READ_OPERATIONS] = "rios=",
[CGROUP_IO_WRITE_OPERATIONS] = "wios=",
};
+
uint64_t acc[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {};
_cleanup_free_ char *path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(u);
+ assert(crt);
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt->cgroup_path)
return -ENODATA;
if (unit_has_host_root_cgroup(u))
@@ -4869,13 +4875,13 @@ int unit_get_io_accounting(
return -ENODATA;
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt)
return -ENODATA;
if (allow_cache && crt->io_accounting_last[metric] != UINT64_MAX)
goto done;
- r = unit_get_io_accounting_raw(u, raw);
+ r = unit_get_io_accounting_raw(u, crt, raw);
if (r == -ENODATA && crt->io_accounting_last[metric] != UINT64_MAX)
goto done;
if (r < 0)
@@ -4896,45 +4902,52 @@ done:
return 0;
}
-int unit_reset_cpu_accounting(Unit *u) {
+static int unit_reset_cpu_accounting(Unit *unit, CGroupRuntime *crt) {
int r;
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return 0;
+ assert(crt);
+ crt->cpu_usage_base = 0;
crt->cpu_usage_last = NSEC_INFINITY;
- r = unit_get_cpu_usage_raw(u, &crt->cpu_usage_base);
- if (r < 0) {
- crt->cpu_usage_base = 0;
- return r;
+ if (unit) {
+ r = unit_get_cpu_usage_raw(unit, crt, &crt->cpu_usage_base);
+ if (r < 0 && r != -ENODATA)
+ return r;
}
return 0;
}
-void unit_reset_memory_accounting_last(Unit *u) {
- assert(u);
+static int unit_reset_io_accounting(Unit *unit, CGroupRuntime *crt) {
+ int r;
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return;
+ assert(crt);
+
+ zero(crt->io_accounting_base);
+ FOREACH_ELEMENT(i, crt->io_accounting_last)
+ *i = UINT64_MAX;
+
+ if (unit) {
+ r = unit_get_io_accounting_raw(unit, crt, crt->io_accounting_base);
+ if (r < 0 && r != -ENODATA)
+ return r;
+ }
+
+ return 0;
+}
+
+static void cgroup_runtime_reset_memory_accounting_last(CGroupRuntime *crt) {
+ assert(crt);
FOREACH_ELEMENT(i, crt->memory_accounting_last)
*i = UINT64_MAX;
}
-int unit_reset_ip_accounting(Unit *u) {
+static int cgroup_runtime_reset_ip_accounting(CGroupRuntime *crt) {
int r = 0;
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return 0;
+ assert(crt);
if (crt->ip_accounting_ingress_map_fd >= 0)
RET_GATHER(r, bpf_firewall_reset_accounting(crt->ip_accounting_ingress_map_fd));
@@ -4947,46 +4960,19 @@ int unit_reset_ip_accounting(Unit *u) {
return r;
}
-void unit_reset_io_accounting_last(Unit *u) {
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return;
-
- FOREACH_ARRAY(i, crt->io_accounting_last, _CGROUP_IO_ACCOUNTING_METRIC_MAX)
- *i = UINT64_MAX;
-}
-
-int unit_reset_io_accounting(Unit *u) {
- int r;
+int unit_reset_accounting(Unit *u) {
+ int r = 0;
assert(u);
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt)
return 0;
- unit_reset_io_accounting_last(u);
-
- r = unit_get_io_accounting_raw(u, crt->io_accounting_base);
- if (r < 0) {
- zero(crt->io_accounting_base);
- return r;
- }
-
- return 0;
-}
-
-int unit_reset_accounting(Unit *u) {
- int r = 0;
-
- assert(u);
-
- RET_GATHER(r, unit_reset_cpu_accounting(u));
- RET_GATHER(r, unit_reset_io_accounting(u));
- RET_GATHER(r, unit_reset_ip_accounting(u));
- unit_reset_memory_accounting_last(u);
+ cgroup_runtime_reset_memory_accounting_last(crt);
+ RET_GATHER(r, unit_reset_cpu_accounting(u, crt));
+ RET_GATHER(r, unit_reset_io_accounting(u, crt));
+ RET_GATHER(r, cgroup_runtime_reset_ip_accounting(crt));
return r;
}
@@ -5210,7 +5196,7 @@ int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {
return parse_cpu_set_full(v, cpus, false, NULL, NULL, 0, NULL);
}
-CGroupRuntime *cgroup_runtime_new(void) {
+CGroupRuntime* cgroup_runtime_new(void) {
_cleanup_(cgroup_runtime_freep) CGroupRuntime *crt = NULL;
crt = new(CGroupRuntime, 1);
@@ -5218,8 +5204,6 @@ CGroupRuntime *cgroup_runtime_new(void) {
return NULL;
*crt = (CGroupRuntime) {
- .cpu_usage_last = NSEC_INFINITY,
-
.cgroup_control_inotify_wd = -1,
.cgroup_memory_inotify_wd = -1,
@@ -5234,19 +5218,15 @@ CGroupRuntime *cgroup_runtime_new(void) {
.cgroup_invalidated_mask = _CGROUP_MASK_ALL,
};
- FOREACH_ELEMENT(i, crt->memory_accounting_last)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->io_accounting_base)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->io_accounting_last)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->ip_accounting_extra)
- *i = UINT64_MAX;
+ unit_reset_cpu_accounting(/* unit = */ NULL, crt);
+ unit_reset_io_accounting(/* unit = */ NULL, crt);
+ cgroup_runtime_reset_memory_accounting_last(crt);
+ assert_se(cgroup_runtime_reset_ip_accounting(crt) >= 0);
return TAKE_PTR(crt);
}
-CGroupRuntime *cgroup_runtime_free(CGroupRuntime *crt) {
+CGroupRuntime* cgroup_runtime_free(CGroupRuntime *crt) {
if (!crt)
return NULL;
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 72fe275..5170c7b 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -449,10 +449,7 @@ int unit_watch_cgroup_memory(Unit *u);
void unit_add_to_cgroup_realize_queue(Unit *u);
int unit_cgroup_is_empty(Unit *u);
-void unit_release_cgroup(Unit *u);
-/* Releases the cgroup only if it is recursively empty.
- * Returns true if the cgroup was released, false otherwise. */
-bool unit_maybe_release_cgroup(Unit *u);
+void unit_release_cgroup(Unit *u, bool drop_cgroup_runtime);
void unit_add_to_cgroup_empty_queue(Unit *u);
int unit_check_oomd_kill(Unit *u);
@@ -489,11 +486,6 @@ int unit_get_io_accounting(Unit *u, CGroupIOAccountingMetric metric, bool allow_
int unit_get_ip_accounting(Unit *u, CGroupIPAccountingMetric metric, uint64_t *ret);
int unit_get_effective_limit(Unit *u, CGroupLimitType type, uint64_t *ret);
-int unit_reset_cpu_accounting(Unit *u);
-void unit_reset_memory_accounting_last(Unit *u);
-int unit_reset_ip_accounting(Unit *u);
-void unit_reset_io_accounting_last(Unit *u);
-int unit_reset_io_accounting(Unit *u);
int unit_reset_accounting(Unit *u);
#define UNIT_CGROUP_BOOL(u, name) \
@@ -503,7 +495,7 @@ int unit_reset_accounting(Unit *u);
})
bool manager_owns_host_root_cgroup(Manager *m);
-bool unit_has_host_root_cgroup(Unit *u);
+bool unit_has_host_root_cgroup(const Unit *u);
bool unit_has_startup_cgroup_constraints(Unit *u);
@@ -527,8 +519,8 @@ int unit_cgroup_freezer_action(Unit *u, FreezerAction action);
const char* freezer_action_to_string(FreezerAction a) _const_;
FreezerAction freezer_action_from_string(const char *s) _pure_;
-CGroupRuntime *cgroup_runtime_new(void);
-CGroupRuntime *cgroup_runtime_free(CGroupRuntime *crt);
+CGroupRuntime* cgroup_runtime_new(void);
+CGroupRuntime* cgroup_runtime_free(CGroupRuntime *crt);
DEFINE_TRIVIAL_CLEANUP_FUNC(CGroupRuntime*, cgroup_runtime_free);
int cgroup_runtime_serialize(Unit *u, FILE *f, FDSet *fds);
diff --git a/src/core/core-varlink.c b/src/core/core-varlink.c
index 3e6168d..8005f6d 100644
--- a/src/core/core-varlink.c
+++ b/src/core/core-varlink.c
@@ -5,6 +5,7 @@
#include "strv.h"
#include "user-util.h"
#include "varlink.h"
+#include "varlink-internal.h"
#include "varlink-io.systemd.UserDatabase.h"
#include "varlink-io.systemd.ManagedOOM.h"
@@ -500,12 +501,17 @@ static void vl_disconnect(VarlinkServer *s, Varlink *link, void *userdata) {
m->managed_oom_varlink = varlink_unref(link);
}
-static int manager_setup_varlink_server(Manager *m, VarlinkServer **ret) {
+int manager_setup_varlink_server(Manager *m) {
_cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
int r;
assert(m);
- assert(ret);
+
+ if (m->varlink_server)
+ return 0;
+
+ if (!MANAGER_IS_SYSTEM(m))
+ return -EINVAL;
r = varlink_server_new(&s, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
if (r < 0)
@@ -533,51 +539,51 @@ static int manager_setup_varlink_server(Manager *m, VarlinkServer **ret) {
if (r < 0)
return log_debug_errno(r, "Failed to register varlink disconnect handler: %m");
- *ret = TAKE_PTR(s);
- return 0;
+ r = varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to attach varlink connection to event loop: %m");
+
+ m->varlink_server = TAKE_PTR(s);
+ return 1;
}
static int manager_varlink_init_system(Manager *m) {
- _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
int r;
assert(m);
- if (m->varlink_server)
- return 1;
-
if (!MANAGER_IS_SYSTEM(m))
return 0;
- r = manager_setup_varlink_server(m, &s);
+ r = manager_setup_varlink_server(m);
if (r < 0)
return log_error_errno(r, "Failed to set up varlink server: %m");
+ bool fresh = r > 0;
if (!MANAGER_IS_TEST_RUN(m)) {
(void) mkdir_p_label("/run/systemd/userdb", 0755);
FOREACH_STRING(address, "/run/systemd/userdb/io.systemd.DynamicUser", VARLINK_ADDR_PATH_MANAGED_OOM_SYSTEM) {
- if (MANAGER_IS_RELOADING(m)) {
- /* If manager is reloading, we skip listening on existing addresses, since
- * the fd should be acquired later through deserialization. */
- if (access(address, F_OK) >= 0)
+ if (!fresh) {
+ /* We might have got sockets through deserialization. Do not bind to them twice. */
+
+ bool found = false;
+ LIST_FOREACH(sockets, ss, m->varlink_server->sockets)
+ if (path_equal(ss->address, address)) {
+ found = true;
+ break;
+ }
+
+ if (found)
continue;
- if (errno != ENOENT)
- return log_error_errno(errno,
- "Failed to check if varlink socket '%s' exists: %m", address);
}
- r = varlink_server_listen_address(s, address, 0666);
+ r = varlink_server_listen_address(m->varlink_server, address, 0666);
if (r < 0)
return log_error_errno(r, "Failed to bind to varlink socket '%s': %m", address);
}
}
- r = varlink_server_attach_event(s, m->event, EVENT_PRIORITY_IPC);
- if (r < 0)
- return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
-
- m->varlink_server = TAKE_PTR(s);
return 1;
}
diff --git a/src/core/core-varlink.h b/src/core/core-varlink.h
index 20507a4..4b77620 100644
--- a/src/core/core-varlink.h
+++ b/src/core/core-varlink.h
@@ -3,6 +3,8 @@
#include "manager.h"
+int manager_setup_varlink_server(Manager *m);
+
int manager_varlink_init(Manager *m);
void manager_varlink_done(Manager *m);
diff --git a/src/core/import-creds.c b/src/core/import-creds.c
index f27ffed..e6cf40d 100644
--- a/src/core/import-creds.c
+++ b/src/core/import-creds.c
@@ -595,9 +595,11 @@ static int import_credentials_smbios(ImportCredentialContext *c) {
return log_oom();
r = read_virtual_file(p, sizeof(dmi_field_header) + CREDENTIALS_TOTAL_SIZE_MAX, (char**) &data, &size);
+ if (r == -ENOENT) /* Once we reach ENOENT there are no more DMI Type 11 fields around. */
+ break;
if (r < 0) {
/* Once we reach ENOENT there are no more DMI Type 11 fields around. */
- log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r, "Failed to open '%s', ignoring: %m", p);
+ log_warning_errno(r, "Failed to open '%s', ignoring: %m", p);
break;
}
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
index b4af82b..1d2959a 100644
--- a/src/core/manager-serialize.c
+++ b/src/core/manager-serialize.c
@@ -506,7 +506,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
return r;
} else if ((val = startswith(l, "varlink-server-socket-address="))) {
if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) {
- r = manager_varlink_init(m);
+ r = manager_setup_varlink_server(m);
if (r < 0) {
log_warning_errno(r, "Failed to setup varlink server, ignoring: %m");
continue;
diff --git a/src/core/meson.build b/src/core/meson.build
index 7a2012a..dbeb752 100644
--- a/src/core/meson.build
+++ b/src/core/meson.build
@@ -110,17 +110,13 @@ load_fragment_gperf_nulstr_c = custom_target(
libcore_name = 'systemd-core-@0@'.format(shared_lib_tag)
-libcore = shared_library(
+libcore_static = static_library(
libcore_name,
libcore_sources,
load_fragment_gperf_c,
load_fragment_gperf_nulstr_c,
include_directories : includes,
c_args : ['-fvisibility=default'],
- link_args : ['-shared',
- '-Wl,--version-script=' + libshared_sym_path],
- link_depends : libshared_sym_path,
- link_with : libshared,
dependencies : [libacl,
libapparmor,
libaudit,
@@ -135,6 +131,16 @@ libcore = shared_library(
libselinux,
threads,
userspace],
+ build_by_default : false)
+
+libcore = shared_library(
+ libcore_name,
+ c_args : ['-fvisibility=default'],
+ link_args : ['-shared',
+ '-Wl,--version-script=' + libshared_sym_path],
+ link_depends : libshared_sym_path,
+ link_whole: libcore_static,
+ link_with : libshared,
install : true,
install_dir : pkglibdir)
@@ -150,6 +156,17 @@ systemd_executor_sources = files(
'exec-invoke.c',
)
+executor_libs = get_option('link-executor-shared') ? \
+ [
+ libcore,
+ libshared,
+ ] : [
+ libcore_static,
+ libshared_static,
+ libbasic_static,
+ libsystemd_static,
+ ]
+
executables += [
libexec_template + {
'name' : 'systemd',
@@ -167,10 +184,7 @@ executables += [
'public' : true,
'sources' : systemd_executor_sources,
'include_directories' : core_includes,
- 'link_with' : [
- libcore,
- libshared,
- ],
+ 'link_with' : executor_libs,
'dependencies' : [
libapparmor,
libpam,
diff --git a/src/core/path.c b/src/core/path.c
index fdb6ca4..50f6db1 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -81,7 +81,7 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
tmp = *cut;
*cut = '\0';
- flags = IN_MOVE_SELF | IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
+ flags = IN_MOVE_SELF | IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO;
} else {
cut = NULL;
flags = flags_table[s->type];
diff --git a/src/core/unit.c b/src/core/unit.c
index 852926b..01c9983 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -129,9 +129,6 @@ Unit* unit_new(Manager *m, size_t size) {
.burst = 16
};
- unit_reset_memory_accounting_last(u);
- unit_reset_io_accounting_last(u);
-
return u;
}
@@ -484,8 +481,8 @@ bool unit_may_gc(Unit *u) {
/* If the unit has a cgroup, then check whether there's anything in it. If so, we should stay
* around. Units with active processes should never be collected. */
r = unit_cgroup_is_empty(u);
- if (r <= 0 && r != -ENXIO)
- return false; /* ENXIO means: currently not realized */
+ if (r <= 0 && !IN_SET(r, -ENXIO, -EOWNERDEAD))
+ return false; /* ENXIO/EOWNERDEAD means: currently not realized */
if (!UNIT_VTABLE(u)->may_gc)
return true;
@@ -790,7 +787,7 @@ Unit* unit_free(Unit *u) {
if (u->on_console)
manager_unref_console(u->manager);
- unit_release_cgroup(u);
+ unit_release_cgroup(u, /* drop_cgroup_runtime = */ true);
if (!MANAGER_IS_RELOADING(u->manager))
unit_unlink_state_files(u);
@@ -3816,8 +3813,6 @@ static bool fragment_mtime_newer(const char *path, usec_t mtime, bool path_maske
}
bool unit_need_daemon_reload(Unit *u) {
- _cleanup_strv_free_ char **dropins = NULL;
-
assert(u);
assert(u->manager);
@@ -3833,16 +3828,20 @@ bool unit_need_daemon_reload(Unit *u) {
if (fragment_mtime_newer(u->source_path, u->source_mtime, false))
return true;
- if (u->load_state == UNIT_LOADED)
+ if (u->load_state == UNIT_LOADED) {
+ _cleanup_strv_free_ char **dropins = NULL;
+
(void) unit_find_dropin_paths(u, &dropins);
- if (!strv_equal(u->dropin_paths, dropins))
- return true;
- /* … any drop-ins that are masked are simply omitted from the list. */
- STRV_FOREACH(path, u->dropin_paths)
- if (fragment_mtime_newer(*path, u->dropin_mtime, false))
+ if (!strv_equal(u->dropin_paths, dropins))
return true;
+ /* … any drop-ins that are masked are simply omitted from the list. */
+ STRV_FOREACH(path, u->dropin_paths)
+ if (fragment_mtime_newer(*path, u->dropin_mtime, false))
+ return true;
+ }
+
return false;
}
diff --git a/src/id128/id128.c b/src/id128/id128.c
index fa86cf6..875d22d 100644
--- a/src/id128/id128.c
+++ b/src/id128/id128.c
@@ -16,7 +16,7 @@
#include "verbs.h"
static Id128PrettyPrintMode arg_mode = ID128_PRINT_ID128;
-static sd_id128_t arg_app = {};
+static sd_id128_t arg_app = SD_ID128_NULL;
static bool arg_value = false;
static PagerFlags arg_pager_flags = 0;
static bool arg_legend = true;
@@ -72,15 +72,12 @@ static int verb_invocation_id(int argc, char **argv, void *userdata) {
}
static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) {
- sd_id128_t u;
int r;
assert(table);
- if (sd_id128_is_null(arg_app))
- u = uuid;
- else
- assert_se(sd_id128_get_app_specific(uuid, arg_app, &u) == 0);
+ if (!name)
+ name = "XYZ";
if (arg_mode == ID128_PRINT_PRETTY) {
_cleanup_free_ char *id = NULL;
@@ -91,7 +88,7 @@ static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first
ascii_strupper(id);
- r = id128_pretty_print_sample(id, u);
+ r = id128_pretty_print_sample(id, uuid);
if (r < 0)
return r;
if (!first)
@@ -100,19 +97,19 @@ static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first
}
if (arg_value)
- return id128_pretty_print(u, arg_mode);
+ return id128_pretty_print(uuid, arg_mode);
if (!*table) {
*table = table_new("name", "id");
if (!*table)
return log_oom();
+
table_set_width(*table, 0);
}
return table_add_many(*table,
TABLE_STRING, name,
- arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID,
- u);
+ arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID, uuid);
}
static int verb_show(int argc, char **argv, void *userdata) {
@@ -120,23 +117,26 @@ static int verb_show(int argc, char **argv, void *userdata) {
int r;
argv = strv_skip(argv, 1);
- if (strv_isempty(argv))
+ if (strv_isempty(argv)) {
+ if (!sd_id128_is_null(arg_app))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "'show --app-specific=' can only be used with explicit UUID input.");
+
for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
if (r < 0)
return r;
}
- else
+ } else
STRV_FOREACH(p, argv) {
sd_id128_t uuid;
- bool have_uuid;
- const char *id;
+ const char *id = NULL;
/* Check if the argument is an actual UUID first */
- have_uuid = sd_id128_from_string(*p, &uuid) >= 0;
+ bool is_uuid = sd_id128_from_string(*p, &uuid) >= 0;
- if (have_uuid)
- id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ";
+ if (is_uuid)
+ id = gpt_partition_type_uuid_to_string(uuid);
else {
GptPartitionType type;
@@ -148,6 +148,9 @@ static int verb_show(int argc, char **argv, void *userdata) {
id = *p;
}
+ if (!sd_id128_is_null(arg_app))
+ assert_se(sd_id128_get_app_specific(uuid, arg_app, &uuid) >= 0);
+
r = show_one(&table, id, uuid, p == argv);
if (r < 0)
return r;
diff --git a/src/kernel-install/90-loaderentry.install.in b/src/kernel-install/90-loaderentry.install.in
index 766d321..4ef6aca 100755
--- a/src/kernel-install/90-loaderentry.install.in
+++ b/src/kernel-install/90-loaderentry.install.in
@@ -101,6 +101,11 @@ if [ -f "$TRIES_FILE" ]; then
echo "$TRIES_FILE does not contain an integer." >&2
exit 1
fi
+ if [ -f "$LOADER_ENTRY" ]; then
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+ echo "Removing previous loader entry '$LOADER_ENTRY' without boot counting." >&2
+ rm -f "$LOADER_ENTRY" "${LOADER_ENTRY%.conf}+"*.conf
+ fi
LOADER_ENTRY="${LOADER_ENTRY%.conf}+$TRIES.conf"
fi
diff --git a/src/kernel-install/90-uki-copy.install b/src/kernel-install/90-uki-copy.install
index d443c4b..d6f7134 100755
--- a/src/kernel-install/90-uki-copy.install
+++ b/src/kernel-install/90-uki-copy.install
@@ -61,6 +61,12 @@ if [ -f "$TRIES_FILE" ]; then
echo "$TRIES_FILE does not contain an integer." >&2
exit 1
fi
+ if [ -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" ]; then
+ [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+ echo "Removing previous UKI '$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi' without boot counting." >&2
+ rm -f "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi" "$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+"*.efi
+ fi
+
UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION+$TRIES.efi"
else
UKI_FILE="$UKI_DIR/$ENTRY_TOKEN-$KERNEL_VERSION.efi"
diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build
index 6d4337d..2435492 100644
--- a/src/libsystemd/meson.build
+++ b/src/libsystemd/meson.build
@@ -118,7 +118,7 @@ libsystemd_static = static_library(
libsystemd_sources,
include_directories : libsystemd_includes,
c_args : libsystemd_c_args,
- link_with : [libbasic],
+ link_with : [libbasic_static],
dependencies : [threads,
librt,
userspace],
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index 71ab3d8..00d3328 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -701,13 +701,11 @@ static int enumerator_scan_dir_and_add_devices(
dir = opendir(path);
if (!dir) {
- bool ignore = errno == ENOENT;
+ /* This is necessarily racey, so ignore missing directories */
+ if (errno == ENOENT)
+ return 0;
- /* this is necessarily racey, so ignore missing directories */
- log_debug_errno(errno,
- "sd-device-enumerator: Failed to open directory %s%s: %m",
- path, ignore ? ", ignoring" : "");
- return ignore ? 0 : -errno;
+ return log_debug_errno(errno, "sd-device-enumerator: Failed to open directory '%s': %m", path);
}
FOREACH_DIRENT_ALL(de, dir, return -errno) {
@@ -767,12 +765,10 @@ static int enumerator_scan_dir(
dir = opendir(path);
if (!dir) {
- bool ignore = errno == ENOENT;
+ if (errno == ENOENT)
+ return 0;
- log_debug_errno(errno,
- "sd-device-enumerator: Failed to open directory %s%s: %m",
- path, ignore ? ", ignoring" : "");
- return ignore ? 0 : -errno;
+ return log_debug_errno(errno, "sd-device-enumerator: Failed to open directory '%s': %m", path);
}
FOREACH_DIRENT_ALL(de, dir, return -errno) {
@@ -804,12 +800,10 @@ static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const c
dir = opendir(path);
if (!dir) {
- bool ignore = errno == ENOENT;
+ if (errno == ENOENT)
+ return 0;
- log_debug_errno(errno,
- "sd-device-enumerator: Failed to open directory %s%s: %m",
- path, ignore ? ", ignoring" : "");
- return ignore ? 0 : -errno;
+ return log_debug_errno(errno, "sd-device-enumerator: Failed to open directory '%s': %m", path);
}
/* TODO: filter away subsystems? */
@@ -892,12 +886,10 @@ static int parent_crawl_children(sd_device_enumerator *enumerator, const char *p
dir = opendir(path);
if (!dir) {
- bool ignore = errno == ENOENT;
+ if (errno == ENOENT)
+ return 0;
- log_debug_errno(errno,
- "sd-device-enumerator: Failed to open directory %s%s: %m",
- path, ignore ? ", ignoring" : "");
- return ignore ? 0 : -errno;
+ return log_debug_errno(errno, "sd-device-enumerator: Failed to open directory '%s': %m", path);
}
FOREACH_DIRENT_ALL(de, dir, return -errno) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index a657b6e..0521863 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1484,8 +1484,11 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu
return -errno;
u = hashmap_get(m->users, UID_TO_PTR(uid));
- if (u)
+ if (u) {
+ /* Make sure that disabling lingering will terminate the user tracking if no sessions pin it. */
+ u->gc_mode = USER_GC_BY_PIN;
user_add_to_gc_queue(u);
+ }
}
return sd_bus_reply_method_return(message, NULL);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 8066b3e..276d5b8 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -821,30 +821,30 @@ UserState user_get_state(User *u) {
if (!u->started || u->runtime_dir_job)
return USER_OPENING;
- bool any = false, all_closing = true;
+ /* USER_GC_BY_PIN: Only pinning sessions count. None -> closing
+ * USER_GC_BY_ANY: 'manager' sessions also count. However, if lingering is enabled, 'lingering' state
+ * shall be preferred. 'online' if the manager is manually started by user. */
+
+ bool has_pinning = false, all_closing = true;
LIST_FOREACH(sessions_by_user, i, u->sessions) {
- SessionState state;
+ bool pinned = SESSION_CLASS_PIN_USER(i->class);
- /* Ignore sessions that don't pin the user, i.e. are not supposed to have an effect on user state */
- if (!SESSION_CLASS_PIN_USER(i->class))
+ if (u->gc_mode == USER_GC_BY_PIN && !pinned)
continue;
- state = session_get_state(i);
- if (state == SESSION_ACTIVE)
+ has_pinning = has_pinning || pinned;
+
+ SessionState state = session_get_state(i);
+ if (state == SESSION_ACTIVE && pinned)
return USER_ACTIVE;
if (state != SESSION_CLOSING)
all_closing = false;
-
- any = true;
}
- if (any)
- return all_closing ? USER_CLOSING : USER_ONLINE;
-
- if (user_check_linger_file(u) > 0 && user_unit_active(u))
+ if (!has_pinning && user_check_linger_file(u) > 0 && user_unit_active(u))
return USER_LINGERING;
- return USER_CLOSING;
+ return all_closing ? USER_CLOSING : USER_ONLINE;
}
int user_kill(User *u, int signo) {
diff --git a/src/partition/meson.build b/src/partition/meson.build
index 52e1368..2cfe43e 100644
--- a/src/partition/meson.build
+++ b/src/partition/meson.build
@@ -32,7 +32,7 @@ executables += [
'sources' : files('repart.c'),
'c_args' : '-DSTANDALONE',
'link_with' : [
- libbasic,
+ libbasic_static,
libshared_fdisk,
libshared_static,
libsystemd_static,
diff --git a/src/partition/repart.c b/src/partition/repart.c
index f87a87e..8a5ce7e 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -1895,6 +1895,34 @@ static int config_parse_encrypted_volume(
static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_verity, verity_mode, VerityMode, VERITY_OFF, "Invalid verity mode");
static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_minimize, minimize_mode, MinimizeMode, MINIMIZE_OFF, "Invalid minimize mode");
+static int partition_finalize_fstype(Partition *p, const char *path) {
+ _cleanup_free_ char *e = NULL, *upper = NULL;
+
+ assert(p);
+ assert(path);
+
+ if (!gpt_partition_type_has_filesystem(p->type))
+ return 0;
+
+ upper = strdup(partition_designator_to_string(p->type.designator));
+ if (!upper)
+ return log_oom();
+
+ e = strjoin("SYSTEMD_REPART_OVERRIDE_FSTYPE_", string_replace_char(ascii_strupper(upper), '-', '_'));
+ if (!e)
+ return log_oom();
+
+ const char *v = secure_getenv(e);
+ if (!v || streq(p->format, v))
+ return 0;
+
+ log_syntax(NULL, LOG_NOTICE, path, 1, 0,
+ "Overriding defined file system type '%s' for '%s' partition with '%s'.",
+ p->format, partition_designator_to_string(p->type.designator), v);
+
+ return free_and_strdup_warn(&p->format, v);
+}
+
static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
ConfigTableItem table[] = {
@@ -2084,6 +2112,10 @@ static int partition_read_definition(Partition *p, const char *path, const char
} else if (streq(p->split_name_format, "-"))
p->split_name_format = mfree(p->split_name_format);
+ r = partition_finalize_fstype(p, path);
+ if (r < 0)
+ return r;
+
return 1;
}
diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
index 4bc3ae7..9466866 100644
--- a/src/shared/bootspec.c
+++ b/src/shared/bootspec.c
@@ -505,6 +505,12 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
assert(a);
assert(b);
+ /* This mimics a function of the same name in src/boot/efi/sd-boot.c */
+
+ r = CMP(a->tries_left == 0, b->tries_left == 0);
+ if (r != 0)
+ return r;
+
r = CMP(!a->sort_key, !b->sort_key);
if (r != 0)
return r;
@@ -523,7 +529,18 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
return r;
}
- return -strverscmp_improved(a->id, b->id);
+ r = -strverscmp_improved(a->id, b->id);
+ if (r != 0)
+ return r;
+
+ if (a->tries_left != UINT_MAX || b->tries_left != UINT_MAX)
+ return 0;
+
+ r = -CMP(a->tries_left, b->tries_left);
+ if (r != 0)
+ return r;
+
+ return CMP(a->tries_done, b->tries_done);
}
static int config_check_inode_relevant_and_unseen(BootConfig *config, int fd, const char *fname) {
@@ -743,11 +760,11 @@ static int find_sections(
r = pe_load_headers(fd, &dos_header, &pe_header);
if (r < 0)
- return log_warning_errno(r, "Failed to parse PE file '%s': %m", path);
+ return log_error_errno(r, "Failed to parse PE file '%s': %m", path);
r = pe_load_sections(fd, dos_header, pe_header, &sections);
if (r < 0)
- return log_warning_errno(r, "Failed to parse PE sections of '%s': %m", path);
+ return log_error_errno(r, "Failed to parse PE sections of '%s': %m", path);
if (ret_pe_header)
*ret_pe_header = TAKE_PTR(pe_header);
@@ -809,7 +826,7 @@ static int find_osrel_section(
r = pe_read_section_data(fd, pe_header, sections, ".osrel", PE_SECTION_SIZE_MAX, (void**) ret_osrelease, NULL);
if (r < 0)
- return log_warning_errno(r, "Failed to read .osrel section of '%s': %m", path);
+ return log_error_errno(r, "Failed to read .osrel section of '%s': %m", path);
return 0;
}
@@ -829,7 +846,7 @@ static int find_uki_sections(
return r;
if (!pe_is_uki(pe_header, sections))
- return log_warning_errno(SYNTHETIC_ERRNO(EBADMSG), "Parsed PE file '%s' is not a UKI.", path);
+ return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Parsed PE file '%s' is not a UKI.", path);
r = find_osrel_section(fd, path, sections, pe_header, ret_osrelease);
if (r < 0)
diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c
index 996edbf..6f61eb2 100644
--- a/src/shared/exec-util.c
+++ b/src/shared/exec-util.c
@@ -609,5 +609,6 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
va_end(ap);
execv(path, l);
+ log_error_errno(errno, "Failed to execute %s: %m", path);
_exit(EXIT_FAILURE);
}
diff --git a/src/shared/gpt.c b/src/shared/gpt.c
index d639463..f3e5247 100644
--- a/src/shared/gpt.c
+++ b/src/shared/gpt.c
@@ -143,21 +143,30 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ARM64, "aarch64"), /* Alias: must be listed after arm64 */
_GPT_ARCH_SEXTET(IA64, "ia64"),
_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64"),
+ _GPT_ARCH_SEXTET(LOONGARCH64, "loong64"), /* Alias: must be listed after loongarch64 */
_GPT_ARCH_SEXTET(MIPS, "mips"),
_GPT_ARCH_SEXTET(MIPS64, "mips64"),
_GPT_ARCH_SEXTET(MIPS_LE, "mips-le"),
+ _GPT_ARCH_SEXTET(MIPS_LE, "mipsel"), /* Alias: must be listed after mips-le */
_GPT_ARCH_SEXTET(MIPS64_LE, "mips64-le"),
+ _GPT_ARCH_SEXTET(MIPS64_LE, "mips64el"), /* Alias: must be listed after mips64-le */
_GPT_ARCH_SEXTET(PARISC, "parisc"),
+ _GPT_ARCH_SEXTET(PARISC, "hppa"), /* Alias: must be listed after parisc */
_GPT_ARCH_SEXTET(PPC, "ppc"),
_GPT_ARCH_SEXTET(PPC64, "ppc64"),
_GPT_ARCH_SEXTET(PPC64_LE, "ppc64-le"),
_GPT_ARCH_SEXTET(PPC64_LE, "ppc64le"), /* Alias: must be listed after ppc64-le */
+ _GPT_ARCH_SEXTET(PPC64_LE, "ppc64el"), /* Alias: must be listed after ppc64-le */
_GPT_ARCH_SEXTET(RISCV32, "riscv32"),
_GPT_ARCH_SEXTET(RISCV64, "riscv64"),
_GPT_ARCH_SEXTET(S390, "s390"),
_GPT_ARCH_SEXTET(S390X, "s390x"),
_GPT_ARCH_SEXTET(TILEGX, "tilegx"),
_GPT_ARCH_SEXTET(X86, "x86"),
+ _GPT_ARCH_SEXTET(X86, "i386"), /* Alias: must be listed after x86 */
+ _GPT_ARCH_SEXTET(X86, "i486"), /* Alias: must be listed after x86 */
+ _GPT_ARCH_SEXTET(X86, "i586"), /* Alias: must be listed after x86 */
+ _GPT_ARCH_SEXTET(X86, "i686"), /* Alias: must be listed after x86 */
_GPT_ARCH_SEXTET(X86_64, "x86-64"),
_GPT_ARCH_SEXTET(X86_64, "x86_64"), /* Alias: must be listed after x86-64 */
_GPT_ARCH_SEXTET(X86_64, "amd64"), /* Alias: must be listed after x86-64 */
@@ -339,6 +348,18 @@ bool gpt_partition_type_knows_no_auto(GptPartitionType type) {
PARTITION_SWAP);
}
+bool gpt_partition_type_has_filesystem(GptPartitionType type) {
+ return IN_SET(type.designator,
+ PARTITION_ROOT,
+ PARTITION_USR,
+ PARTITION_HOME,
+ PARTITION_SRV,
+ PARTITION_ESP,
+ PARTITION_XBOOTLDR,
+ PARTITION_TMP,
+ PARTITION_VAR);
+}
+
bool gpt_header_has_signature(const GptHeader *p) {
assert(p);
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index 21976e5..3d04c19 100644
--- a/src/shared/gpt.h
+++ b/src/shared/gpt.h
@@ -72,6 +72,7 @@ const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type);
bool gpt_partition_type_knows_read_only(GptPartitionType type);
bool gpt_partition_type_knows_growfs(GptPartitionType type);
bool gpt_partition_type_knows_no_auto(GptPartitionType type);
+bool gpt_partition_type_has_filesystem(GptPartitionType type);
typedef struct {
uint8_t partition_type_guid[16];
diff --git a/src/shared/install.c b/src/shared/install.c
index c94b456..53566b7 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1989,7 +1989,9 @@ static int install_info_symlink_alias(
}
broken = r == 0; /* symlink target does not exist? */
- RET_GATHER(ret, create_symlink(lp, alias_target ?: info->path, alias_path, force || broken, changes, n_changes));
+ r = create_symlink(lp, alias_target ?: info->path, alias_path, force || broken, changes, n_changes);
+ if (r != 0 && ret >= 0)
+ ret = r;
}
return ret;
@@ -2012,7 +2014,7 @@ static int install_info_symlink_wants(
UnitNameFlags valid_dst_type = UNIT_NAME_ANY;
const char *n;
- int r = 0, q;
+ int r, q;
assert(info);
assert(lp);
@@ -2083,7 +2085,7 @@ static int install_info_symlink_wants(
return -ENOMEM;
q = create_symlink(lp, info->path, path, /* force = */ true, changes, n_changes);
- if ((q < 0 && r >= 0) || r == 0)
+ if (q != 0 && r >= 0)
r = q;
if (unit_file_exists(scope, lp, dst) == 0) {
@@ -2155,15 +2157,15 @@ static int install_info_apply(
r = install_info_symlink_alias(scope, info, lp, config_path, force, changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->wanted_by, ".wants/", changes, n_changes);
- if (r == 0)
+ if (q != 0 && r >= 0)
r = q;
q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->required_by, ".requires/", changes, n_changes);
- if (r == 0)
+ if (q != 0 && r >= 0)
r = q;
q = install_info_symlink_wants(scope, file_flags, info, lp, config_path, info->upheld_by, ".upholds/", changes, n_changes);
- if (r == 0)
+ if (q != 0 && r >= 0)
r = q;
return r;
diff --git a/src/shared/meson.build b/src/shared/meson.build
index c5106d8..e513c0e 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -358,7 +358,7 @@ libshared = shared_library(
'-Wl,--version-script=' + libshared_sym_path],
link_depends : libshared_sym_path,
link_whole : [libshared_static,
- libbasic,
+ libbasic_static,
libsystemd_static],
dependencies : [libshared_deps,
userspace],
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
index ce3c5fb..fd91bd6 100644
--- a/src/shared/spawn-polkit-agent.c
+++ b/src/shared/spawn-polkit-agent.c
@@ -43,16 +43,21 @@ int polkit_agent_open(void) {
xsprintf(notify_fd, "%i", pipe_fd[1]);
r = fork_agent("(polkit-agent)",
- &pipe_fd[1], 1,
+ &pipe_fd[1],
+ 1,
&agent_pid,
POLKIT_AGENT_BINARY_PATH,
- POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
+ POLKIT_AGENT_BINARY_PATH,
+ "--notify-fd",
+ notify_fd,
+ "--fallback",
+ NULL);
/* Close the writing side, because that's the one for the agent */
safe_close(pipe_fd[1]);
if (r < 0)
- log_error_errno(r, "Failed to fork TTY ask password agent: %m");
+ log_error_errno(r, "Failed to fork polkit agent: %m");
else
/* Wait until the agent closes the fd */
(void) fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
diff --git a/src/shared/varlink-internal.h b/src/shared/varlink-internal.h
index 715202a..bc30108 100644
--- a/src/shared/varlink-internal.h
+++ b/src/shared/varlink-internal.h
@@ -6,5 +6,45 @@
#include "fdset.h"
#include "varlink.h"
+typedef struct VarlinkServerSocket VarlinkServerSocket;
+
+struct VarlinkServerSocket {
+ VarlinkServer *server;
+
+ int fd;
+ char *address;
+
+ sd_event_source *event_source;
+
+ LIST_FIELDS(VarlinkServerSocket, sockets);
+};
+
+struct VarlinkServer {
+ unsigned n_ref;
+ VarlinkServerFlags flags;
+
+ LIST_HEAD(VarlinkServerSocket, sockets);
+
+ Hashmap *methods; /* Fully qualified symbol name of a method → VarlinkMethod */
+ Hashmap *interfaces; /* Fully qualified interface name → VarlinkInterface* */
+ Hashmap *symbols; /* Fully qualified symbol name of method/error → VarlinkSymbol* */
+ VarlinkConnect connect_callback;
+ VarlinkDisconnect disconnect_callback;
+
+ sd_event *event;
+ int64_t event_priority;
+
+ unsigned n_connections;
+ Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */
+
+ void *userdata;
+ char *description;
+
+ unsigned connections_max;
+ unsigned connections_per_uid_max;
+
+ bool exit_on_idle;
+};
+
int varlink_server_serialize(VarlinkServer *s, FILE *f, FDSet *fds);
int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *fds);
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index 034e72b..0a6d2c8 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -210,46 +210,6 @@ struct Varlink {
pid_t exec_pid;
};
-typedef struct VarlinkServerSocket VarlinkServerSocket;
-
-struct VarlinkServerSocket {
- VarlinkServer *server;
-
- int fd;
- char *address;
-
- sd_event_source *event_source;
-
- LIST_FIELDS(VarlinkServerSocket, sockets);
-};
-
-struct VarlinkServer {
- unsigned n_ref;
- VarlinkServerFlags flags;
-
- LIST_HEAD(VarlinkServerSocket, sockets);
-
- Hashmap *methods; /* Fully qualified symbol name of a method → VarlinkMethod */
- Hashmap *interfaces; /* Fully qualified interface name → VarlinkInterface* */
- Hashmap *symbols; /* Fully qualified symbol name of method/error → VarlinkSymbol* */
- VarlinkConnect connect_callback;
- VarlinkDisconnect disconnect_callback;
-
- sd_event *event;
- int64_t event_priority;
-
- unsigned n_connections;
- Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */
-
- void *userdata;
- char *description;
-
- unsigned connections_max;
- unsigned connections_per_uid_max;
-
- bool exit_on_idle;
-};
-
static const char* const varlink_state_table[_VARLINK_STATE_MAX] = {
[VARLINK_IDLE_CLIENT] = "idle-client",
[VARLINK_AWAITING_REPLY] = "awaiting-reply",
diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build
index 219f9fd..9bc60f8 100644
--- a/src/shutdown/meson.build
+++ b/src/shutdown/meson.build
@@ -20,7 +20,7 @@ executables += [
'sources' : systemd_shutdown_sources,
'c_args' : '-DSTANDALONE',
'link_with' : [
- libbasic,
+ libbasic_static,
libshared_static,
libsystemd_static,
],
diff --git a/src/systemctl/systemctl-util.c b/src/systemctl/systemctl-util.c
index 2482b7c..38e1f23 100644
--- a/src/systemctl/systemctl-util.c
+++ b/src/systemctl/systemctl-util.c
@@ -327,14 +327,15 @@ int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_maske
if (r < 0)
return r;
+ if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
+ goto skip;
+
if (ignore_masked) {
r = unit_is_masked(bus, name);
if (r < 0)
return r;
- if (r > 0) {
- *ret = NULL;
- return 0;
- }
+ if (r > 0)
+ goto skip;
}
dbus_path = unit_dbus_path_from_name(name);
@@ -370,6 +371,10 @@ int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_maske
*ret = TAKE_PTR(active);
return 0;
+
+skip:
+ *ret = NULL;
+ return 0;
}
void warn_triggering_units(sd_bus *bus, const char *unit, const char *operation, bool ignore_masked) {
@@ -383,8 +388,8 @@ void warn_triggering_units(sd_bus *bus, const char *unit, const char *operation,
r = get_active_triggering_units(bus, unit, ignore_masked, &triggered_by);
if (r < 0) {
- log_warning_errno(r,
- "Failed to get triggering units for '%s', ignoring: %m", unit);
+ if (r != -ENOENT) /* A linked unit might have disappeared after disabling */
+ log_warning_errno(r, "Failed to get triggering units for '%s', ignoring: %m", unit);
return;
}
diff --git a/src/sysusers/meson.build b/src/sysusers/meson.build
index 0f9c067..403d82a 100644
--- a/src/sysusers/meson.build
+++ b/src/sysusers/meson.build
@@ -14,7 +14,7 @@ executables += [
'sources' : files('sysusers.c'),
'c_args' : '-DSTANDALONE',
'link_with' : [
- libbasic,
+ libbasic_static,
libshared_static,
libsystemd_static,
],
diff --git a/src/test/meson.build b/src/test/meson.build
index 3abbb94..9d3c7d6 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -274,7 +274,7 @@ executables += [
# only static linking apart from libdl, to make sure that the
# module is linked to all libraries that it uses.
'sources' : files('test-dlopen.c'),
- 'link_with' : libbasic,
+ 'link_with' : libbasic_static,
'dependencies' : libdl,
'install' : false,
'type' : 'manual',
@@ -410,7 +410,7 @@ executables += [
},
test_template + {
'sources' : files('test-sizeof.c'),
- 'link_with' : libbasic,
+ 'link_with' : libbasic_static,
},
test_template + {
'sources' : files('test-time-util.c'),
@@ -590,7 +590,7 @@ executables += [
test_template + {
'sources' : files('../libsystemd/sd-device/test-sd-device-thread.c'),
'link_with' : [
- libbasic,
+ libbasic_static,
libsystemd,
],
'dependencies' : threads,
@@ -598,7 +598,7 @@ executables += [
test_template + {
'sources' : files('../libudev/test-udev-device-thread.c'),
'link_with' : [
- libbasic,
+ libbasic_static,
libudev,
],
'dependencies' : threads,
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index 1e7ed27..433cf22 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -23,12 +23,14 @@ TEST(basic_mask_and_enable) {
InstallChange *changes = NULL;
size_t n_changes = 0;
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "a.service", NULL) == -ENOENT);
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "b.service", NULL) == -ENOENT);
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "c.service", NULL) == -ENOENT);
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "d.service", NULL) == -ENOENT);
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "e.service", NULL) == -ENOENT);
- assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "f.service", NULL) == -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "a.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "b.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "c.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "d.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "e.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "f.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "g.service", NULL), -ENOENT);
+ ASSERT_EQ(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "h.service", NULL), -ENOENT);
p = strjoina(root, "/usr/lib/systemd/system/a.service");
assert_se(write_string_file(p,
@@ -197,6 +199,24 @@ TEST(basic_mask_and_enable) {
changes = NULL; n_changes = 0;
assert_se(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "f.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+
+ /* Test enabling units with only Alias= (unit_file_enable should return > 0 to indicate we did
+ * something, #33411) */
+
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR "/g.service");
+ ASSERT_OK(write_string_file(p,
+ "[Install]\n"
+ "Alias=h.service\n", WRITE_STRING_FILE_CREATE));
+
+ ASSERT_GT(unit_file_enable(RUNTIME_SCOPE_SYSTEM, 0, root, STRV_MAKE("g.service"), &changes, &n_changes), 0);
+ install_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+
+ ASSERT_OK(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "g.service", &state));
+ ASSERT_EQ(state, UNIT_FILE_ENABLED);
+
+ ASSERT_OK(unit_file_get_state(RUNTIME_SCOPE_SYSTEM, root, "h.service", &state));
+ ASSERT_EQ(state, UNIT_FILE_ALIAS);
}
TEST(linked_units) {
diff --git a/src/tmpfiles/meson.build b/src/tmpfiles/meson.build
index 2e91850..09ad839 100644
--- a/src/tmpfiles/meson.build
+++ b/src/tmpfiles/meson.build
@@ -20,7 +20,7 @@ executables += [
'sources' : systemd_tmpfiles_sources,
'c_args' : '-DSTANDALONE',
'link_with' : [
- libbasic,
+ libbasic_static,
libshared_static,
libsystemd_static,
],
diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py
index 0e3f932..e3d49d4 100755
--- a/src/ukify/test/test_ukify.py
+++ b/src/ukify/test/test_ukify.py
@@ -1,11 +1,21 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
+# The tests can be called via pytest:
+# PATH=build/:$PATH pytest -v src/ukify/test/test_ukify.py
+# or directly:
+# PATH=build/:$PATH src/ukify/test/test_ukify.py
+# or via the meson test machinery output:
+# meson test -C build test-ukify -v
+# or without verbose output:
+# meson test -C build test-ukify
+
# pylint: disable=unused-import,import-outside-toplevel,useless-else-on-loop
# pylint: disable=consider-using-with,wrong-import-position,unspecified-encoding
# pylint: disable=protected-access,redefined-outer-name
import base64
+import glob
import json
import os
import pathlib
@@ -389,28 +399,17 @@ def test_help_error(capsys):
@pytest.fixture(scope='session')
def kernel_initrd():
- opts = ukify.create_parser().parse_args(arg_tools)
- bootctl = ukify.find_tool('bootctl', opts=opts)
- if bootctl is None:
- return None
-
- try:
- text = subprocess.check_output([bootctl, 'list', '--json=short'],
- text=True)
- except subprocess.CalledProcessError:
+ items = sorted(glob.glob('/lib/modules/*/vmlinuz'))
+ if not items:
return None
- items = json.loads(text)
+ # This doesn't necessarilly give us the latest version, since we're just
+ # using alphanumeric ordering. But this is fine, a predictable result is
+ # enough.
+ linux = items[-1]
- for item in items:
- try:
- linux = f"{item['root']}{item['linux']}"
- initrd = f"{item['root']}{item['initrd'][0].split(' ')[0]}"
- except (KeyError, IndexError):
- continue
- return ['--linux', linux, '--initrd', initrd]
- else:
- return None
+ # We don't look _into_ the initrd. Any file is OK.
+ return ['--linux', linux, '--initrd', ukify.__file__]
def test_check_splash():
try:
@@ -699,7 +698,7 @@ def test_pcr_signing(kernel_initrd, tmp_path):
'--uname=1.2.3',
'--cmdline=ARG1 ARG2 ARG3',
'--os-release=ID=foobar\n',
- '--pcr-banks=sha1', # use sha1 because it doesn't really matter
+ '--pcr-banks=sha384', # sha1 might not be allowed, use something else
f'--pcr-private-key={priv.name}',
] + arg_tools
@@ -742,8 +741,8 @@ def test_pcr_signing(kernel_initrd, tmp_path):
assert open(tmp_path / 'out.cmdline').read() == 'ARG1 ARG2 ARG3'
sig = open(tmp_path / 'out.pcrsig').read()
sig = json.loads(sig)
- assert list(sig.keys()) == ['sha1']
- assert len(sig['sha1']) == 4 # four items for four phases
+ assert list(sig.keys()) == ['sha384']
+ assert len(sig['sha384']) == 4 # four items for four phases
shutil.rmtree(tmp_path)
@@ -775,7 +774,7 @@ def test_pcr_signing2(kernel_initrd, tmp_path):
'--uname=1.2.3',
'--cmdline=ARG1 ARG2 ARG3',
'--os-release=ID=foobar\n',
- '--pcr-banks=sha1',
+ '--pcr-banks=sha384',
f'--pcrpkey={pub2.name}',
f'--pcr-public-key={pub.name}',
f'--pcr-private-key={priv.name}',
@@ -815,8 +814,8 @@ def test_pcr_signing2(kernel_initrd, tmp_path):
sig = open(tmp_path / 'out.pcrsig').read()
sig = json.loads(sig)
- assert list(sig.keys()) == ['sha1']
- assert len(sig['sha1']) == 6 # six items for six phases paths
+ assert list(sig.keys()) == ['sha384']
+ assert len(sig['sha384']) == 6 # six items for six phases paths
shutil.rmtree(tmp_path)
diff --git a/src/vmspawn/vmspawn-util.h b/src/vmspawn/vmspawn-util.h
index ee02752..959cb47 100644
--- a/src/vmspawn/vmspawn-util.h
+++ b/src/vmspawn/vmspawn-util.h
@@ -40,6 +40,8 @@
# define QEMU_MACHINE_TYPE "s390-ccw-virtio"
#elif defined(__powerpc__) || defined(__powerpc64__)
# define QEMU_MACHINE_TYPE "pseries"
+#elif defined(__mips__)
+# define QEMU_MACHINE_TYPE "malta"
#else
# error "No qemu machine defined for this architecture"
#endif