• 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

73.17
/src/basic/limits-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "alloc-util.h"
6
#include "cgroup-util.h"
7
#include "limits-util.h"
8
#include "log.h"
9
#include "memory-util.h"
10
#include "parse-util.h"
11
#include "process-util.h"
12
#include "procfs-util.h"
13

14
uint64_t physical_memory(void) {
4,457✔
15
        _cleanup_free_ char *root = NULL, *value = NULL;
4,457✔
16
        uint64_t mem, lim;
4,457✔
17
        size_t ps;
4,457✔
18
        long sc;
4,457✔
19
        int r;
4,457✔
20

21
        /* We return this as uint64_t in case we are running as 32-bit process on a 64-bit kernel with huge amounts of
22
         * memory.
23
         *
24
         * In order to support containers nicely that have a configured memory limit we'll take the minimum of the
25
         * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */
26

27
        sc = sysconf(_SC_PHYS_PAGES);
4,457✔
28
        assert(sc > 0);
4,457✔
29

30
        ps = page_size();
4,457✔
31
        mem = (uint64_t) sc * (uint64_t) ps;
4,457✔
32

33
        r = cg_get_root_path(&root);
4,457✔
34
        if (r < 0) {
4,457✔
UNCOV
35
                log_debug_errno(r, "Failed to determine root cgroup, ignoring cgroup memory limit: %m");
×
36
                return mem;
×
37
        }
38

39
        r = cg_all_unified();
4,457✔
40
        if (r < 0) {
4,457✔
UNCOV
41
                log_debug_errno(r, "Failed to determine root unified mode, ignoring cgroup memory limit: %m");
×
42
                return mem;
×
43
        }
44
        if (r > 0) {
4,457✔
45
                r = cg_get_attribute("memory", root, "memory.max", &value);
4,457✔
46
                if (r == -ENOENT) /* Field does not exist on the system's top-level cgroup, hence don't
4,457✔
47
                                   * complain. (Note that it might exist on our own root though, if we live
48
                                   * in a cgroup namespace, hence check anyway instead of not even
49
                                   * trying.) */
50
                        return mem;
51
                if (r < 0) {
3,767✔
UNCOV
52
                        log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m");
×
53
                        return mem;
×
54
                }
55

56
                if (streq(value, "max"))
3,767✔
57
                        return mem;
58
        } else {
UNCOV
59
                r = cg_get_attribute("memory", root, "memory.limit_in_bytes", &value);
×
60
                if (r < 0) {
×
61
                        log_debug_errno(r, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m");
×
62
                        return mem;
×
63
                }
64
        }
65

UNCOV
66
        r = safe_atou64(value, &lim);
×
67
        if (r < 0) {
×
68
                log_debug_errno(r, "Failed to parse cgroup memory limit '%s', ignoring: %m", value);
×
69
                return mem;
×
70
        }
UNCOV
71
        if (lim == UINT64_MAX)
×
72
                return mem;
73

74
        /* Make sure the limit is a multiple of our own page size */
UNCOV
75
        lim /= ps;
×
76
        lim *= ps;
×
77

UNCOV
78
        return MIN(mem, lim);
×
79
}
80

81
uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
357✔
82
        uint64_t p, m, ps;
357✔
83

84
        /* Shortcut two special cases */
85
        if (v == 0)
357✔
86
                return 0;
87
        if (v == max)
353✔
88
                return physical_memory();
4✔
89

90
        assert(max > 0);
349✔
91

92
        /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
93
         * the result is a multiple of the page size (rounds down). */
94

95
        ps = page_size();
349✔
96
        assert(ps > 0);
349✔
97

98
        p = physical_memory() / ps;
349✔
99
        assert(p > 0);
349✔
100

101
        if (v > UINT64_MAX / p)
349✔
102
                return UINT64_MAX;
103

104
        m = p * v;
348✔
105
        m /= max;
348✔
106

107
        if (m > UINT64_MAX / ps)
348✔
108
                return UINT64_MAX;
109

110
        return m * ps;
348✔
111
}
112

113
uint64_t system_tasks_max(void) {
6,910✔
114
        uint64_t a = TASKS_MAX, b = TASKS_MAX, c = TASKS_MAX;
6,910✔
115
        _cleanup_free_ char *root = NULL;
6,910✔
116
        int r;
6,910✔
117

118
        /* Determine the maximum number of tasks that may run on this system. We check three sources to
119
         * determine this limit:
120
         *
121
         * a) kernel.threads-max sysctl: the maximum number of tasks (threads) the kernel allows.
122
         *
123
         *    This puts a direct limit on the number of concurrent tasks.
124
         *
125
         * b) kernel.pid_max sysctl: the maximum PID value.
126
         *
127
         *    This limits the numeric range PIDs can take, and thus indirectly also limits the number of
128
         *    concurrent threads. It's primarily a compatibility concept: some crappy old code used a signed
129
         *    16-bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond
130
         *    INT16_MAX by default.
131
         *
132
         *    Also note the weird definition: PIDs assigned will be kept below this value, which means
133
         *    the number of tasks that can be created is one lower, as PID 0 is not a valid process ID.
134
         *
135
         * c) pids.max on the root cgroup: the kernel's configured maximum number of tasks.
136
         *
137
         * and then pick the smallest of the three.
138
         *
139
         * By default pid_max is set to much lower values than threads-max, hence the limit people come into
140
         * contact with first, as it's the lowest boundary they need to bump when they want higher number of
141
         * processes.
142
         */
143

144
        r = procfs_get_threads_max(&a);
6,910✔
145
        if (r < 0)
6,910✔
UNCOV
146
                log_debug_errno(r, "Failed to read kernel.threads-max, ignoring: %m");
×
147

148
        r = procfs_get_pid_max(&b);
6,910✔
149
        if (r < 0)
6,910✔
UNCOV
150
                log_debug_errno(r, "Failed to read kernel.pid_max, ignoring: %m");
×
151
        else if (b > 0)
6,910✔
152
                /* Subtract one from pid_max, since PID 0 is not a valid PID */
153
                b--;
6,910✔
154

155
        r = cg_get_root_path(&root);
6,910✔
156
        if (r < 0)
6,910✔
UNCOV
157
                log_debug_errno(r, "Failed to determine cgroup root path, ignoring: %m");
×
158
        else {
159
                /* We'll have the "pids.max" attribute on the our root cgroup only if we are in a
160
                 * CLONE_NEWCGROUP namespace. On the top-level namespace this attribute is missing, hence
161
                 * suppress any message about that */
162
                r = cg_get_attribute_as_uint64("pids", root, "pids.max", &c);
6,910✔
163
                if (r < 0 && r != -ENODATA)
6,910✔
UNCOV
164
                        log_debug_errno(r, "Failed to read pids.max attribute of root cgroup, ignoring: %m");
×
165
        }
166

167
        return MIN3(a, b, c);
6,910✔
168
}
169

170
uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
5,576✔
171
        uint64_t t, m;
5,576✔
172

173
        /* Shortcut two special cases */
174
        if (v == 0)
5,576✔
175
                return 0;
176
        if (v == max)
5,572✔
177
                return system_tasks_max();
4✔
178

179
        assert(max > 0);
5,568✔
180

181
        /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
182
         * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
183

184
        t = system_tasks_max();
5,568✔
185
        assert(t > 0);
5,568✔
186

187
        if (v > UINT64_MAX / t) /* overflow? */
5,568✔
188
                return UINT64_MAX;
189

190
        m = t * v;
5,567✔
191
        return m / max;
5,567✔
192
}
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