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

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

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

87.88
/src/resolve/resolved-socket-graveyard.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "resolved-manager.h"
4
#include "resolved-socket-graveyard.h"
5

6
#define SOCKET_GRAVEYARD_USEC (5 * USEC_PER_SEC)
7
#define SOCKET_GRAVEYARD_MAX 100
8

9
/* This implements a socket "graveyard" for UDP sockets. If a socket fd is added to the graveyard it is kept
10
 * open for a couple of more seconds, expecting one reply. Once the reply is received the fd is closed
11
 * immediately, or if none is received it is closed after the timeout. Why all this? So that if we contact a
12
 * DNS server, and it doesn't reply instantly, and we lose interest in the response and thus close the fd, we
13
 * don't end up sending back an ICMP error once the server responds but we aren't listening anymore. (See
14
 * https://github.com/systemd/systemd/issues/17421 for further information.)
15
 *
16
 * Note that we don't allocate any timer event source to clear up the graveyard once the socket's timeout is
17
 * reached. Instead we operate lazily: we close old entries when adding a new fd to the graveyard, or
18
 * whenever any code runs manager_socket_graveyard_process() — which the DNS transaction code does right
19
 * before allocating a new UDP socket. */
20

21
static SocketGraveyard* socket_graveyard_free(SocketGraveyard *g) {
188✔
22
        if (!g)
188✔
23
                return NULL;
24

25
        if (g->manager) {
188✔
26
                assert(g->manager->n_socket_graveyard > 0);
188✔
27
                g->manager->n_socket_graveyard--;
188✔
28

29
                if (g->manager->socket_graveyard_oldest == g)
188✔
30
                        g->manager->socket_graveyard_oldest = g->graveyard_prev;
175✔
31

32
                LIST_REMOVE(graveyard, g->manager->socket_graveyard, g);
188✔
33

34
                assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard);
188✔
35
                assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard_oldest);
188✔
36
        }
37

38
        if (g->io_event_source) {
188✔
39
                log_debug("Closing graveyard socket fd %i", sd_event_source_get_io_fd(g->io_event_source));
188✔
40
                sd_event_source_disable_unref(g->io_event_source);
188✔
41
        }
42

43
        return mfree(g);
188✔
44
}
45

46
DEFINE_TRIVIAL_CLEANUP_FUNC(SocketGraveyard*, socket_graveyard_free);
189✔
47

48
void manager_socket_graveyard_process(Manager *m) {
9,798✔
49
        usec_t n = USEC_INFINITY;
9,798✔
50

51
        assert(m);
9,798✔
52

53
        while (m->socket_graveyard_oldest) {
9,966✔
54
                SocketGraveyard *g = m->socket_graveyard_oldest;
1,648✔
55

56
                if (n == USEC_INFINITY)
1,648✔
57
                        assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &n) >= 0);
1,540✔
58

59
                if (g->deadline > n)
1,648✔
60
                        break;
61

62
                socket_graveyard_free(g);
168✔
63
        }
64
}
9,798✔
65

66
void manager_socket_graveyard_clear(Manager *m) {
162✔
67
        assert(m);
162✔
68

69
        while (m->socket_graveyard)
182✔
70
                socket_graveyard_free(m->socket_graveyard);
20✔
71
}
162✔
72

73
static int on_io_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
×
74
        SocketGraveyard *g = ASSERT_PTR(userdata);
×
75

76
        /* An IO event happened on the graveyard fd. We don't actually care which event that is, and we don't
77
         * read any incoming packet off the socket. We just close the fd, that's enough to not trigger the
78
         * ICMP unreachable port event */
79

80
        socket_graveyard_free(g);
×
81
        return 0;
×
82
}
83

84
static void manager_socket_graveyard_make_room(Manager *m) {
189✔
85
        assert(m);
189✔
86

87
        while (m->n_socket_graveyard >= SOCKET_GRAVEYARD_MAX)
189✔
88
                socket_graveyard_free(m->socket_graveyard_oldest);
×
89
}
189✔
90

91
int manager_add_socket_to_graveyard(Manager *m, int fd) {
189✔
92
        _cleanup_(socket_graveyard_freep) SocketGraveyard *g = NULL;
189✔
93
        int r;
189✔
94

95
        assert(m);
189✔
96
        assert(fd >= 0);
189✔
97

98
        manager_socket_graveyard_process(m);
189✔
99
        manager_socket_graveyard_make_room(m);
189✔
100

101
        g = new(SocketGraveyard, 1);
189✔
102
        if (!g)
189✔
103
                return log_oom();
×
104

105
        *g = (SocketGraveyard) {
189✔
106
                .manager = m,
107
        };
108

109
        LIST_PREPEND(graveyard, m->socket_graveyard, g);
189✔
110
        if (!m->socket_graveyard_oldest)
189✔
111
                m->socket_graveyard_oldest = g;
68✔
112

113
        m->n_socket_graveyard++;
189✔
114

115
        assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &g->deadline) >= 0);
189✔
116
        g->deadline += SOCKET_GRAVEYARD_USEC;
189✔
117

118
        r = sd_event_add_io(m->event, &g->io_event_source, fd, EPOLLIN, on_io_event, g);
189✔
119
        if (r < 0)
189✔
120
                return log_error_errno(r, "Failed to create graveyard IO source: %m");
×
121

122
        r = sd_event_source_set_io_fd_own(g->io_event_source, true);
189✔
123
        if (r < 0)
189✔
124
                return log_error_errno(r, "Failed to enable graveyard IO source fd ownership: %m");
×
125

126
        (void) sd_event_source_set_description(g->io_event_source, "graveyard");
189✔
127

128
        log_debug("Added socket %i to graveyard", fd);
189✔
129

130
        TAKE_PTR(g);
189✔
131
        return 0;
189✔
132
}
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