summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-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
9 files changed, 171 insertions, 176 deletions
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;
}