• 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

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

3
#include <poll.h>
4
#include <stdio.h>
5
#include <string.h>
6
#include <time.h>
7
#include <unistd.h>
8

9
#include "errno-util.h"
10
#include "io-util.h"
11
#include "time-util.h"
12

13
int flush_fd(int fd) {
3,658✔
14
        int count = 0;
3,658✔
15

16
        /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
17
         * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
18
         * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
19
         * was set to non-blocking too. */
20

21
        for (;;) {
6,635✔
22
                char buf[LINE_MAX];
6,635✔
23
                ssize_t l;
6,635✔
24
                int r;
6,635✔
25

26
                r = fd_wait_for_event(fd, POLLIN, 0);
6,635✔
27
                if (r < 0) {
6,635✔
UNCOV
28
                        if (r == -EINTR)
×
29
                                continue;
×
30

31
                        return r;
3,658✔
32
                }
33
                if (r == 0)
6,635✔
34
                        return count;
35

36
                l = read(fd, buf, sizeof(buf));
2,977✔
37
                if (l < 0) {
2,977✔
UNCOV
38
                        if (errno == EINTR)
×
39
                                continue;
×
40

UNCOV
41
                        if (errno == EAGAIN)
×
42
                                return count;
43

UNCOV
44
                        return -errno;
×
45
                } else if (l == 0)
2,977✔
46
                        return count;
47

48
                count += (int) l;
2,977✔
49
        }
50
}
51

52
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
13,035✔
53
        uint8_t *p = ASSERT_PTR(buf);
13,035✔
54
        ssize_t n = 0;
13,035✔
55

56
        assert(fd >= 0);
13,035✔
57

58
        /* If called with nbytes == 0, let's call read() at least once, to validate the operation */
59

60
        if (nbytes > (size_t) SSIZE_MAX)
13,035✔
61
                return -EINVAL;
62

63
        do {
24,302✔
64
                ssize_t k;
24,302✔
65

66
                k = read(fd, p, nbytes);
24,302✔
67
                if (k < 0) {
24,302✔
UNCOV
68
                        if (errno == EINTR)
×
69
                                continue;
×
70

UNCOV
71
                        if (errno == EAGAIN && do_poll) {
×
72

73
                                /* We knowingly ignore any return value here,
74
                                 * and expect that any error/EOF is reported
75
                                 * via read() */
76

UNCOV
77
                                (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
×
78
                                continue;
×
79
                        }
80

UNCOV
81
                        return n > 0 ? n : -errno;
×
82
                }
83

84
                if (k == 0)
24,302✔
85
                        return n;
86

87
                assert((size_t) k <= nbytes);
12,939✔
88
                assert(k <= SSIZE_MAX - n);
12,939✔
89

90
                p += k;
12,939✔
91
                nbytes -= k;
12,939✔
92
                n += k;
12,939✔
93
        } while (nbytes > 0);
12,939✔
94

95
        return n;
96
}
97

98
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
1,447✔
99
        ssize_t n;
1,447✔
100

101
        n = loop_read(fd, buf, nbytes, do_poll);
1,447✔
102
        if (n < 0)
1,447✔
UNCOV
103
                return (int) n;
×
104
        if ((size_t) n != nbytes)
1,447✔
UNCOV
105
                return -EIO;
×
106

107
        return 0;
108
}
109

110
int loop_write_full(int fd, const void *buf, size_t nbytes, usec_t timeout) {
40,657✔
111
        const uint8_t *p;
40,657✔
112
        usec_t end;
40,657✔
113
        int r;
40,657✔
114

115
        assert(fd >= 0);
40,657✔
116
        assert(buf || nbytes == 0);
40,657✔
117

118
        if (nbytes == 0) {
40,657✔
119
                static const dummy_t dummy[0];
120
                assert_cc(sizeof(dummy) == 0);
121
                p = (const void*) dummy; /* Some valid pointer, in case NULL was specified */
122
        } else {
123
                if (nbytes == SIZE_MAX)
40,631✔
124
                        nbytes = strlen(buf);
404✔
125
                else if (_unlikely_(nbytes > (size_t) SSIZE_MAX))
40,227✔
126
                        return -EINVAL;
127

128
                p = buf;
129
        }
130

131
        /* When timeout is 0 or USEC_INFINITY this is not used. But we initialize it to a sensible value. */
132
        end = timestamp_is_set(timeout) ? usec_add(now(CLOCK_MONOTONIC), timeout) : USEC_INFINITY;
40,744✔
133

134
        do {
40,657✔
135
                ssize_t k;
40,657✔
136

137
                k = write(fd, p, nbytes);
40,657✔
138
                if (k < 0) {
40,657✔
139
                        if (errno == EINTR)
1✔
UNCOV
140
                                continue;
×
141

142
                        if (errno != EAGAIN || timeout == 0)
1✔
143
                                return -errno;
1✔
144

UNCOV
145
                        usec_t wait_for;
×
146

UNCOV
147
                        if (timeout == USEC_INFINITY)
×
148
                                wait_for = USEC_INFINITY;
149
                        else {
UNCOV
150
                                usec_t t = now(CLOCK_MONOTONIC);
×
151
                                if (t >= end)
×
152
                                        return -ETIME;
153

UNCOV
154
                                wait_for = usec_sub_unsigned(end, t);
×
155
                        }
156

UNCOV
157
                        r = fd_wait_for_event(fd, POLLOUT, wait_for);
×
158
                        if (timeout == USEC_INFINITY || ERRNO_IS_NEG_TRANSIENT(r))
×
159
                                /* If timeout == USEC_INFINITY we knowingly ignore any return value
160
                                 * here, and expect that any error/EOF is reported via write() */
UNCOV
161
                                continue;
×
162
                        if (r < 0)
×
163
                                return r;
UNCOV
164
                        if (r == 0)
×
165
                                return -ETIME;
UNCOV
166
                        continue;
×
167
                }
168

169
                if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
40,656✔
170
                        return -EIO;
171

172
                assert((size_t) k <= nbytes);
40,656✔
173

174
                p += k;
40,656✔
175
                nbytes -= k;
40,656✔
176
        } while (nbytes > 0);
40,656✔
177

178
        return 0;
179
}
180

UNCOV
181
int pipe_eof(int fd) {
×
182
        int r;
×
183

UNCOV
184
        r = fd_wait_for_event(fd, POLLIN, 0);
×
185
        if (r <= 0)
×
186
                return r;
187

UNCOV
188
        return !!(r & POLLHUP);
×
189
}
190

191
int ppoll_usec_full(struct pollfd *fds, size_t nfds, usec_t timeout, const sigset_t *ss) {
365,586✔
192
        int r;
365,586✔
193

194
        assert(fds || nfds == 0);
365,586✔
195

196
        /* This is a wrapper around ppoll() that does primarily two things:
197
         *
198
         *  ✅ Takes a usec_t instead of a struct timespec
199
         *
200
         *  ✅ Guarantees that if an invalid fd is specified we return EBADF (i.e. converts POLLNVAL to
201
         *     EBADF). This is done because EBADF is a programming error usually, and hence should bubble up
202
         *     as error, and not be eaten up as non-error POLLNVAL event.
203
         *
204
         *  ⚠️ ⚠️ ⚠️ Note that this function does not add any special handling for EINTR. Don't forget
205
         *  poll()/ppoll() will return with EINTR on any received signal always, there is no automatic
206
         *  restarting via SA_RESTART available. Thus, typically you want to handle EINTR not as an error,
207
         *  but just as reason to restart things, under the assumption you use a more appropriate mechanism
208
         *  to handle signals, such as signalfd() or signal handlers. ⚠️ ⚠️ ⚠️
209
         */
210

211
        if (nfds == 0 && timeout == 0)
365,586✔
212
                return 0;
365,586✔
213

214
        r = ppoll(fds, nfds, timeout == USEC_INFINITY ? NULL : TIMESPEC_STORE(timeout), ss);
365,586✔
215
        if (r < 0)
365,586✔
UNCOV
216
                return -errno;
×
217
        if (r == 0)
365,586✔
218
                return 0;
219

220
        for (size_t i = 0, n = r; i < nfds && n > 0; i++) {
633,028✔
221
                if (fds[i].revents == 0)
317,175✔
222
                        continue;
1,248✔
223
                if (fds[i].revents & POLLNVAL)
315,927✔
224
                        return -EBADF;
225
                n--;
315,927✔
226
        }
227

228
        return r;
229
}
230

231
int fd_wait_for_event(int fd, int event, usec_t timeout) {
65,966✔
232
        struct pollfd pollfd = {
65,966✔
233
                .fd = fd,
234
                .events = event,
235
        };
236
        int r;
65,966✔
237

238
        /* ⚠️ ⚠️ ⚠️ Keep in mind you almost certainly want to handle -EINTR gracefully in the caller, see
239
         * ppoll_usec() above! ⚠️ ⚠️ ⚠️ */
240

241
        r = ppoll_usec(&pollfd, 1, timeout);
65,966✔
242
        if (r <= 0)
65,966✔
243
                return r;
65,966✔
244

245
        return pollfd.revents;
16,236✔
246
}
247

248
static size_t nul_length(const uint8_t *p, size_t sz) {
316,108,352✔
249
        size_t n = 0;
316,108,352✔
250

251
        while (sz > 0) {
570,189,932✔
252
                if (*p != 0)
570,172,884✔
253
                        break;
254

255
                n++;
254,081,580✔
256
                p++;
254,081,580✔
257
                sz--;
254,081,580✔
258
        }
259

260
        return n;
316,108,352✔
261
}
262

263
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
33,135✔
264
        const uint8_t *q, *w, *e;
33,135✔
265
        ssize_t l;
33,135✔
266

267
        q = w = p;
33,135✔
268
        e = q + sz;
33,135✔
269
        while (q < e) {
316,141,487✔
270
                size_t n;
316,108,352✔
271

272
                n = nul_length(q, e - q);
316,108,352✔
273

274
                /* If there are more than the specified run length of
275
                 * NUL bytes, or if this is the beginning or the end
276
                 * of the buffer, then seek instead of write */
277
                if ((n > run_length) ||
316,108,352✔
278
                    (n > 0 && q == p) ||
315,941,486✔
279
                    (n > 0 && q + n >= e)) {
27,782,348✔
280
                        if (q > w) {
176,918✔
281
                                l = write(fd, w, q - w);
163,711✔
282
                                if (l < 0)
163,711✔
UNCOV
283
                                        return -errno;
×
284
                                if (l != q -w)
163,711✔
285
                                        return -EIO;
286
                        }
287

288
                        if (lseek(fd, n, SEEK_CUR) < 0)
176,918✔
UNCOV
289
                                return -errno;
×
290

291
                        q += n;
176,918✔
292
                        w = q;
176,918✔
293
                } else if (n > 0)
27,776,033✔
294
                        q += n;
295
                else
296
                        q++;
288,155,401✔
297
        }
298

299
        if (q > w) {
33,135✔
300
                l = write(fd, w, q - w);
16,087✔
301
                if (l < 0)
16,087✔
UNCOV
302
                        return -errno;
×
303
                if (l != q - w)
16,087✔
304
                        return -EIO;
305
        }
306

307
        return q - (const uint8_t*) p;
33,135✔
308
}
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