• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 15263807472

26 May 2025 08:53PM UTC coverage: 72.046% (-0.002%) from 72.048%
15263807472

push

github

yuwata
src/core/manager.c: log preset activity on first boot

This gives us a little more information about what units were enabled
or disabled on that first boot and will be useful for OS developers
tracking down the source of unit state.

An example with this enabled looks like:

```
NET: Registered PF_VSOCK protocol family
systemd[1]: Applying preset policy.
systemd[1]: Unit /etc/systemd/system/dnsmasq.service is masked, ignoring.
systemd[1]: Unit /etc/systemd/system/systemd-repart.service is masked, ignoring.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket'.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir.mount' → '/etc/systemd/system/var-mnt-workdir.mount'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir\x2dtmp.mount' → '/etc/systemd/system/var-mnt-workdir\x2dtmp.mount'.
systemd[1]: Created symlink '/etc/systemd/system/afterburn-sshkeys.target.requires/afterburn-sshkeys@core.service' → '/usr/lib/systemd/system/afterburn-sshkeys@.service'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket' → '/usr/lib/systemd/system/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket' → '/usr/lib/systemd/system/systemd-resolved-monitor.socket'.
systemd[1]: Populated /etc with preset unit settings.
```

Considering it only happens on first boot and not on every boot I think
the extra information is worth the extra verbosity in the logs just for
that boot.

5 of 6 new or added lines in 1 file covered. (83.33%)

5463 existing lines in 165 files now uncovered.

299151 of 415222 relevant lines covered (72.05%)

702386.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.56
/src/basic/cgroup-util.h
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3

4
#include "forward.h"
5

6
#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"
7
#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified"
8
#define SYSTEMD_CGROUP_CONTROLLER "_systemd"
9

10
/* An enum of well known cgroup controllers */
11
typedef enum CGroupController {
12
        /* Original cgroup controllers */
13
        CGROUP_CONTROLLER_CPU,
14
        CGROUP_CONTROLLER_CPUACCT,    /* v1 only */
15
        CGROUP_CONTROLLER_CPUSET,     /* v2 only */
16
        CGROUP_CONTROLLER_IO,         /* v2 only */
17
        CGROUP_CONTROLLER_BLKIO,      /* v1 only */
18
        CGROUP_CONTROLLER_MEMORY,
19
        CGROUP_CONTROLLER_DEVICES,    /* v1 only */
20
        CGROUP_CONTROLLER_PIDS,
21

22
        /* BPF-based pseudo-controllers, v2 only */
23
        CGROUP_CONTROLLER_BPF_FIREWALL,
24
        CGROUP_CONTROLLER_BPF_DEVICES,
25
        CGROUP_CONTROLLER_BPF_FOREIGN,
26
        CGROUP_CONTROLLER_BPF_SOCKET_BIND,
27
        CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES,
28
        /* The BPF hook implementing RestrictFileSystems= is not defined here.
29
         * It's applied as late as possible in exec_invoke() so we don't block
30
         * our own unit setup code. */
31

32
        _CGROUP_CONTROLLER_MAX,
33
        _CGROUP_CONTROLLER_INVALID = -EINVAL,
34
} CGroupController;
35

36
#define CGROUP_CONTROLLER_TO_MASK(c) (1U << (c))
37

38
/* A bit mask of well known cgroup controllers */
39
typedef enum CGroupMask {
40
        CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU),
41
        CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT),
42
        CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET),
43
        CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO),
44
        CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
45
        CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
46
        CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES),
47
        CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS),
48
        CGROUP_MASK_BPF_FIREWALL = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FIREWALL),
49
        CGROUP_MASK_BPF_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_DEVICES),
50
        CGROUP_MASK_BPF_FOREIGN = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FOREIGN),
51
        CGROUP_MASK_BPF_SOCKET_BIND = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_SOCKET_BIND),
52
        CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES),
53

54
        /* All real cgroup v1 controllers */
55
        CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS,
56

57
        /* All real cgroup v2 controllers */
58
        CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS,
59

60
        /* All controllers we want to delegate in case of Delegate=yes. Which are pretty much the v2 controllers only, as delegation on v1 is not safe, and bpf stuff isn't a real controller */
61
        CGROUP_MASK_DELEGATE = CGROUP_MASK_V2,
62

63
        /* All cgroup v2 BPF pseudo-controllers */
64
        CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES,
65

66
        _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1,
67
} CGroupMask;
68

69
static inline CGroupMask CGROUP_MASK_EXTEND_JOINED(CGroupMask mask) {
1,337,564✔
70
        /* We always mount "cpu" and "cpuacct" in the same hierarchy. Hence, when one bit is set also set the other */
71

72
        if (mask & (CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT))
1,337,564✔
73
                mask |= (CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT);
21,282✔
74

75
        return mask;
1,328,507✔
76
}
77

78
/* Special values for all weight knobs on unified hierarchy */
79
#define CGROUP_WEIGHT_INVALID UINT64_MAX
80
#define CGROUP_WEIGHT_IDLE UINT64_C(0)
81
#define CGROUP_WEIGHT_MIN UINT64_C(1)
82
#define CGROUP_WEIGHT_MAX UINT64_C(10000)
83
#define CGROUP_WEIGHT_DEFAULT UINT64_C(100)
84

85
#define CGROUP_LIMIT_MIN UINT64_C(0)
86
#define CGROUP_LIMIT_MAX UINT64_MAX
87

UNCOV
88
static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) {
×
UNCOV
89
        return
×
UNCOV
90
            x == CGROUP_WEIGHT_INVALID ||
×
UNCOV
91
            (x >= CGROUP_WEIGHT_MIN && x <= CGROUP_WEIGHT_MAX);
×
92
}
93

94
/* IO limits on unified hierarchy */
95
typedef enum CGroupIOLimitType {
96
        CGROUP_IO_RBPS_MAX,
97
        CGROUP_IO_WBPS_MAX,
98
        CGROUP_IO_RIOPS_MAX,
99
        CGROUP_IO_WIOPS_MAX,
100

101
        _CGROUP_IO_LIMIT_TYPE_MAX,
102
        _CGROUP_IO_LIMIT_TYPE_INVALID = -EINVAL,
103
} CGroupIOLimitType;
104

105
extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX];
106

107
const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_;
108
CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_;
109

110
/* Special values for the cpu.shares attribute */
111
#define CGROUP_CPU_SHARES_INVALID UINT64_MAX
112
#define CGROUP_CPU_SHARES_MIN UINT64_C(2)
113
#define CGROUP_CPU_SHARES_MAX UINT64_C(262144)
114
#define CGROUP_CPU_SHARES_DEFAULT UINT64_C(1024)
115

116
static inline bool CGROUP_CPU_SHARES_IS_OK(uint64_t x) {
117
        return
118
            x == CGROUP_CPU_SHARES_INVALID ||
119
            (x >= CGROUP_CPU_SHARES_MIN && x <= CGROUP_CPU_SHARES_MAX);
120
}
121

122
/* Special values for the special {blkio,io}.bfq.weight attribute */
123
#define CGROUP_BFQ_WEIGHT_INVALID UINT64_MAX
124
#define CGROUP_BFQ_WEIGHT_MIN UINT64_C(1)
125
#define CGROUP_BFQ_WEIGHT_MAX UINT64_C(1000)
126
#define CGROUP_BFQ_WEIGHT_DEFAULT UINT64_C(100)
127

128
/* Convert the normal io.weight value to io.bfq.weight */
UNCOV
129
static inline uint64_t BFQ_WEIGHT(uint64_t io_weight) {
×
UNCOV
130
        return
×
131
            io_weight <= CGROUP_WEIGHT_DEFAULT ?
UNCOV
132
            CGROUP_BFQ_WEIGHT_DEFAULT - (CGROUP_WEIGHT_DEFAULT - io_weight) * (CGROUP_BFQ_WEIGHT_DEFAULT - CGROUP_BFQ_WEIGHT_MIN) / (CGROUP_WEIGHT_DEFAULT - CGROUP_WEIGHT_MIN) :
×
UNCOV
133
            CGROUP_BFQ_WEIGHT_DEFAULT + (io_weight - CGROUP_WEIGHT_DEFAULT) * (CGROUP_BFQ_WEIGHT_MAX - CGROUP_BFQ_WEIGHT_DEFAULT) / (CGROUP_WEIGHT_MAX - CGROUP_WEIGHT_DEFAULT);
×
134
}
135

136
/* Special values for the blkio.weight attribute */
137
#define CGROUP_BLKIO_WEIGHT_INVALID UINT64_MAX
138
#define CGROUP_BLKIO_WEIGHT_MIN UINT64_C(10)
139
#define CGROUP_BLKIO_WEIGHT_MAX UINT64_C(1000)
140
#define CGROUP_BLKIO_WEIGHT_DEFAULT UINT64_C(500)
141

142
static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
143
        return
144
            x == CGROUP_BLKIO_WEIGHT_INVALID ||
145
            (x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX);
146
}
147

148
typedef enum CGroupUnified {
149
        CGROUP_UNIFIED_UNKNOWN = -1,
150
        CGROUP_UNIFIED_NONE = 0,        /* Both systemd and controllers on legacy */
151
        CGROUP_UNIFIED_SYSTEMD = 1,     /* Only systemd on unified */
152
        CGROUP_UNIFIED_ALL = 2,         /* Both systemd and controllers on unified */
153
} CGroupUnified;
154

155
/*
156
 * General rules:
157
 *
158
 * We accept named hierarchies in the syntax "foo" and "name=foo".
159
 *
160
 * We expect that named hierarchies do not conflict in name with a
161
 * kernel hierarchy, modulo the "name=" prefix.
162
 *
163
 * We always generate "normalized" controller names, i.e. without the
164
 * "name=" prefix.
165
 *
166
 * We require absolute cgroup paths. When returning, we will always
167
 * generate paths with multiple adjacent / removed.
168
 */
169

170
int cg_path_open(const char *controller, const char *path);
171
int cg_cgroupid_open(int fsfd, uint64_t id);
172

173
int cg_path_from_cgroupid(int cgroupfs_fd, uint64_t id, char **ret);
174
int cg_get_cgroupid_at(int dfd, const char *path, uint64_t *ret);
175
static inline int cg_path_get_cgroupid(const char *path, uint64_t *ret) {
4,011✔
176
        return cg_get_cgroupid_at(AT_FDCWD, path, ret);
4,011✔
177
}
178
static inline int cg_fd_get_cgroupid(int fd, uint64_t *ret) {
33✔
179
        return cg_get_cgroupid_at(fd, NULL, ret);
33✔
180
}
181

182
typedef enum CGroupFlags {
183
        CGROUP_SIGCONT            = 1 << 0,
184
        CGROUP_IGNORE_SELF        = 1 << 1,
185
        CGROUP_DONT_SKIP_UNMAPPED = 1 << 2,
186
} CGroupFlags;
187

188
int cg_enumerate_processes(const char *controller, const char *path, FILE **ret);
189
int cg_read_pid(FILE *f, pid_t *ret, CGroupFlags flags);
190
int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags);
191
int cg_read_event(const char *controller, const char *path, const char *event, char **ret);
192

193
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **ret);
194
int cg_read_subgroup(DIR *d, char **ret);
195

196
typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata);
197

198
int cg_kill(const char *path, int sig, CGroupFlags flags, Set *killed_pids, cg_kill_log_func_t log_kill, void *userdata);
199
int cg_kill_kernel_sigkill(const char *path);
200
int cg_kill_recursive(const char *path, int sig, CGroupFlags flags, Set *killed_pids, cg_kill_log_func_t log_kill, void *userdata);
201

202
int cg_split_spec(const char *spec, char **ret_controller, char **ret_path);
203
int cg_mangle_path(const char *path, char **ret);
204

205
int cg_get_path(const char *controller, const char *path, const char *suffix, char **ret);
206
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **ret);
207

208
int cg_pid_get_path(const char *controller, pid_t pid, char **ret);
209
int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret);
210

211
int cg_is_threaded(const char *path);
212

213
int cg_is_delegated(const char *path);
214
int cg_is_delegated_fd(int fd);
215

216
int cg_has_coredump_receive(const char *path);
217

218
int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value);
219
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
220
int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char * const *keys, char **values);
221

222
int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
223

224
/* Does a parse_boolean() on the attribute contents and sets ret accordingly */
225
int cg_get_attribute_as_bool(const char *controller, const char *path, const char *attribute, bool *ret);
226

227
int cg_get_owner(const char *path, uid_t *ret_uid);
228

229
int cg_set_xattr(const char *path, const char *name, const void *value, size_t size, int flags);
230
int cg_get_xattr_malloc(const char *path, const char *name, char **ret, size_t *ret_size);
231
/* Returns negative on error, and 0 or 1 on success for the bool value */
232
int cg_get_xattr_bool(const char *path, const char *name);
233
int cg_remove_xattr(const char *path, const char *name);
234

235
int cg_is_empty(const char *controller, const char *path);
236
int cg_is_empty_recursive(const char *controller, const char *path);
237

238
int cg_get_root_path(char **path);
239

240
int cg_path_get_session(const char *path, char **ret_session);
241
int cg_path_get_owner_uid(const char *path, uid_t *ret_uid);
242
int cg_path_get_unit(const char *path, char **ret_unit);
243
int cg_path_get_unit_path(const char *path, char **ret_unit);
244
int cg_path_get_user_unit(const char *path, char **ret_unit);
245
int cg_path_get_machine_name(const char *path, char **ret_machine);
246
int cg_path_get_slice(const char *path, char **ret_slice);
247
int cg_path_get_user_slice(const char *path, char **ret_slice);
248

249
int cg_shift_path(const char *cgroup, const char *cached_root, const char **ret_shifted);
250
int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **ret_cgroup);
251

252
int cg_pid_get_session(pid_t pid, char **ret_session);
253
int cg_pidref_get_session(const PidRef *pidref, char **ret);
254
int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid);
255
int cg_pidref_get_owner_uid(const PidRef *pidref, uid_t *ret);
256
int cg_pid_get_unit(pid_t pid, char **ret_unit);
257
int cg_pidref_get_unit(const PidRef *pidref, char **ret);
258
int cg_pid_get_user_unit(pid_t pid, char **ret_unit);
259
int cg_pid_get_machine_name(pid_t pid, char **ret_machine);
260
int cg_pid_get_slice(pid_t pid, char **ret_slice);
261
int cg_pid_get_user_slice(pid_t pid, char **ret_slice);
262

263
int cg_path_decode_unit(const char *cgroup, char **ret_unit);
264

265
bool cg_needs_escape(const char *p);
266
int cg_escape(const char *p, char **ret);
267
char* cg_unescape(const char *p) _pure_;
268

269
bool cg_controller_is_valid(const char *p);
270

271
int cg_slice_to_path(const char *unit, char **ret);
272

273
int cg_mask_supported(CGroupMask *ret);
274
int cg_mask_supported_subtree(const char *root, CGroupMask *ret);
275
int cg_mask_from_string(const char *s, CGroupMask *ret);
276
int cg_mask_to_string(CGroupMask mask, char **ret);
277

278
bool cg_kill_supported(void);
279

280
int cg_all_unified(void);
281
int cg_hybrid_unified(void);
282
int cg_unified_controller(const char *controller);
283
int cg_unified_cached(bool flush);
284
static inline int cg_unified(void) {
4✔
285
        return cg_unified_cached(true);
4✔
286
}
287

288
const char* cgroup_controller_to_string(CGroupController c) _const_;
289
CGroupController cgroup_controller_from_string(const char *s) _pure_;
290

291
typedef enum ManagedOOMMode {
292
        MANAGED_OOM_AUTO,
293
        MANAGED_OOM_KILL,
294
        _MANAGED_OOM_MODE_MAX,
295
        _MANAGED_OOM_MODE_INVALID = -EINVAL,
296
} ManagedOOMMode;
297

298
const char* managed_oom_mode_to_string(ManagedOOMMode m) _const_;
299
ManagedOOMMode managed_oom_mode_from_string(const char *s) _pure_;
300

301
typedef enum ManagedOOMPreference {
302
        MANAGED_OOM_PREFERENCE_NONE = 0,
303
        MANAGED_OOM_PREFERENCE_AVOID = 1,
304
        MANAGED_OOM_PREFERENCE_OMIT = 2,
305
        _MANAGED_OOM_PREFERENCE_MAX,
306
        _MANAGED_OOM_PREFERENCE_INVALID = -EINVAL,
307
} ManagedOOMPreference;
308

309
const char* managed_oom_preference_to_string(ManagedOOMPreference a) _const_;
310
ManagedOOMPreference managed_oom_preference_from_string(const char *s) _pure_;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc