• 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

84.48
/src/basic/sigbus.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <signal.h>
4
#include <sys/mman.h>
5

6
#include "memory-util.h"
7
#include "sigbus.h"
8
#include "signal-util.h"
9

10
#define SIGBUS_QUEUE_MAX 64
11

12
static struct sigaction old_sigaction;
13
static unsigned n_installed = 0;
14

15
/* We maintain a fixed size list of page addresses that triggered a
16
   SIGBUS. We access with list with atomic operations, so that we
17
   don't have to deal with locks between signal handler and main
18
   programs in possibly multiple threads. */
19

20
static void* volatile sigbus_queue[SIGBUS_QUEUE_MAX];
21
static volatile sig_atomic_t n_sigbus_queue = 0;
22

23
static void sigbus_push(void *addr) {
2✔
24
        assert(addr);
2✔
25

26
        /* Find a free place, increase the number of entries and leave, if we can */
27
        FOREACH_ELEMENT(u, sigbus_queue) {
3✔
28
                /* OK to initialize this here since we haven't started the atomic ops yet */
29
                void *tmp = NULL;
3✔
30
                if (__atomic_compare_exchange_n(u, &tmp, addr, false,
3✔
31
                                                __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
32
                        __atomic_fetch_add(&n_sigbus_queue, 1, __ATOMIC_SEQ_CST);
2✔
33
                        return;
2✔
34
                }
35
        }
36

37
        /* If we can't, make sure the queue size is out of bounds, to
38
         * mark it as overflowed */
UNCOV
39
        for (;;) {
×
UNCOV
40
                sig_atomic_t c;
×
41

UNCOV
42
                __atomic_thread_fence(__ATOMIC_SEQ_CST);
×
UNCOV
43
                c = n_sigbus_queue;
×
44

45
                if (c > SIGBUS_QUEUE_MAX) /* already overflowed */
×
46
                        return;
2✔
47

48
                /* OK if we clobber c here, since we either immediately return
49
                 * or it will be immediately reinitialized on next loop */
UNCOV
50
                if (__atomic_compare_exchange_n(&n_sigbus_queue, &c, c + SIGBUS_QUEUE_MAX, false,
×
51
                                                __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
52
                        return;
53
        }
54
}
55

56
int sigbus_pop(void **ret) {
22,020,306✔
57
        assert(ret);
22,020,306✔
58

59
        for (;;) {
22,020,306✔
60
                unsigned u, c;
22,020,306✔
61

62
                __atomic_thread_fence(__ATOMIC_SEQ_CST);
22,020,306✔
63
                c = n_sigbus_queue;
22,020,306✔
64

65
                if (_likely_(c == 0))
22,020,306✔
66
                        return 0;
67

68
                if (_unlikely_(c > SIGBUS_QUEUE_MAX))
2✔
69
                        return -EOVERFLOW;
70

71
                for (u = 0; u < SIGBUS_QUEUE_MAX; u++) {
3✔
72
                        void *addr;
3✔
73

74
                        addr = sigbus_queue[u];
3✔
75
                        if (!addr)
3✔
76
                                continue;
1✔
77

78
                        /* OK if we clobber addr here, since we either immediately return
79
                         * or it will be immediately reinitialized on next loop */
80
                        if (__atomic_compare_exchange_n(&sigbus_queue[u], &addr, NULL, false,
2✔
81
                                                        __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
82
                                __atomic_fetch_sub(&n_sigbus_queue, 1, __ATOMIC_SEQ_CST);
2✔
83
                                /* If we successfully entered this if condition, addr won't
84
                                 * have been modified since its assignment, so safe to use it */
85
                                *ret = addr;
2✔
86
                                return 1;
2✔
87
                        }
88
                }
89
        }
90
}
91

92
static void sigbus_handler(int sn, siginfo_t *si, void *data) {
2✔
93
        unsigned long ul;
2✔
94
        void *aligned;
2✔
95

96
        assert(sn == SIGBUS);
2✔
97
        assert(si);
2✔
98

99
        if (si->si_code != BUS_ADRERR || !si->si_addr) {
2✔
UNCOV
100
                assert_se(sigaction(SIGBUS, &old_sigaction, NULL) >= 0);
×
UNCOV
101
                propagate_signal(sn, si);
×
UNCOV
102
                return;
×
103
        }
104

105
        ul = (unsigned long) si->si_addr;
2✔
106
        ul = ul / page_size();
2✔
107
        ul = ul * page_size();
2✔
108
        aligned = (void*) ul;
2✔
109

110
        /* Let's remember which address failed */
111
        sigbus_push(aligned);
2✔
112

113
        /* Replace mapping with an anonymous page, so that the
114
         * execution can continue, however with a zeroed out page */
115
        assert_se(mmap(aligned, page_size(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) == aligned);
2✔
116
}
117

118
void sigbus_install(void) {
20,041✔
119
        static const struct sigaction sa = {
20,041✔
120
                .sa_sigaction = sigbus_handler,
121
                .sa_flags = SA_SIGINFO,
122
        };
123

124
        /* make sure that sysconf() is not called from a signal handler because
125
        * it is not guaranteed to be async-signal-safe since POSIX.1-2008 */
126
        (void) page_size();
20,041✔
127

128
        n_installed++;
20,041✔
129

130
        if (n_installed == 1)
20,041✔
131
                assert_se(sigaction(SIGBUS, &sa, &old_sigaction) >= 0);
20,041✔
132

133
        return;
20,041✔
134
}
135

136
void sigbus_reset(void) {
1✔
137

138
        if (n_installed <= 0)
1✔
139
                return;
140

141
        n_installed--;
1✔
142

143
        if (n_installed == 0)
1✔
144
                assert_se(sigaction(SIGBUS, &old_sigaction, NULL) >= 0);
1✔
145

146
        return;
147
}
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