• 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

40.46
/src/core/bpf-socket-bind.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#if BPF_FRAMEWORK
4
#include <bpf/bpf.h>
5
#endif
6

7
#include "fd-util.h"
8
#include "bpf-socket-bind.h"
9
#include "unit.h"
10

11
#if BPF_FRAMEWORK
12
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
13
#include "bpf-dlopen.h"
14
#include "bpf-link.h"
15
#include "bpf-util.h"
16
#include "bpf/socket_bind/socket-bind-api.bpf.h"
17
#include "bpf/socket_bind/socket-bind-skel.h"
18

19
static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) {
43✔
20
        /* socket_bind_bpf__destroy handles object == NULL case */
21
        (void) socket_bind_bpf__destroy(obj);
43✔
22

23
        return NULL;
43✔
24
}
25

26
DEFINE_TRIVIAL_CLEANUP_FUNC(struct socket_bind_bpf *, socket_bind_bpf_free);
289✔
27

28
static int update_rules_map(
86✔
29
                int map_fd,
30
                CGroupSocketBindItem *head) {
31

32
        uint32_t i = 0;
86✔
33

34
        assert(map_fd >= 0);
86✔
35

36
        if (!head) {
86✔
37
                static const struct socket_bind_rule val = {
86✔
38
                        .address_family = SOCKET_BIND_RULE_AF_MATCH_NOTHING,
39
                };
40

41
                if (sym_bpf_map_update_elem(map_fd, &i, &val, BPF_ANY) != 0)
86✔
42
                        return -errno;
×
43
        }
44

45
        LIST_FOREACH(socket_bind_items, item, head) {
86✔
46
                struct socket_bind_rule val = {
×
47
                        .address_family = (uint32_t) item->address_family,
×
48
                        .protocol = item->ip_protocol,
×
49
                        .nr_ports = item->nr_ports,
×
50
                        .port_min = item->port_min,
×
51
                };
52

53
                uint32_t key = i++;
×
54

55
                if (sym_bpf_map_update_elem(map_fd, &key, &val, BPF_ANY) != 0)
×
56
                        return -errno;
×
57
        }
58

59
        return 0;
60
}
61

62
static int prepare_socket_bind_bpf(
43✔
63
                Unit *u,
64
                CGroupSocketBindItem *allow,
65
                CGroupSocketBindItem *deny,
66
                struct socket_bind_bpf **ret_obj) {
67

68
        _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
43✔
69
        size_t allow_count = 0, deny_count = 0;
43✔
70
        int allow_map_fd, deny_map_fd, r;
43✔
71

72
        assert(ret_obj);
43✔
73

74
        LIST_FOREACH(socket_bind_items, item, allow)
43✔
75
                allow_count++;
×
76

77
        LIST_FOREACH(socket_bind_items, item, deny)
43✔
78
                deny_count++;
×
79

80
        if (allow_count > SOCKET_BIND_MAX_RULES)
43✔
81
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL),
×
82
                                           "bpf-socket-bind: Maximum number of socket bind rules=%i is exceeded", SOCKET_BIND_MAX_RULES);
83

84
        if (deny_count > SOCKET_BIND_MAX_RULES)
43✔
85
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL),
×
86
                                           "bpf-socket-bind: Maximum number of socket bind rules=%i is exceeded", SOCKET_BIND_MAX_RULES);
87

88
        obj = socket_bind_bpf__open();
43✔
89
        if (!obj)
43✔
90
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "bpf-socket-bind: Failed to open BPF object: %m");
×
91

92
        if (sym_bpf_map__set_max_entries(obj->maps.sd_bind_allow, MAX(allow_count, 1u)) != 0)
43✔
93
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno,
×
94
                                           "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow));
95

96
        if (sym_bpf_map__set_max_entries(obj->maps.sd_bind_deny, MAX(deny_count, 1u)) != 0)
43✔
97
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno,
×
98
                                           "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny));
99

100
        if (socket_bind_bpf__load(obj) != 0)
43✔
101
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno,
×
102
                                           "bpf-socket-bind: Failed to load BPF object: %m");
103

104
        allow_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_allow);
43✔
105
        assert(allow_map_fd >= 0);
43✔
106

107
        r = update_rules_map(allow_map_fd, allow);
43✔
108
        if (r < 0)
43✔
109
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r,
×
110
                                           "bpf-socket-bind: Failed to put socket bind allow rules into BPF map '%s'",
111
                                           sym_bpf_map__name(obj->maps.sd_bind_allow));
112

113
        deny_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_deny);
43✔
114
        assert(deny_map_fd >= 0);
43✔
115

116
        r = update_rules_map(deny_map_fd, deny);
43✔
117
        if (r < 0)
43✔
118
                return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r,
×
119
                                           "bpf-socket-bind: Failed to put socket bind deny rules into BPF map '%s'",
120
                                           sym_bpf_map__name(obj->maps.sd_bind_deny));
121

122
        *ret_obj = TAKE_PTR(obj);
43✔
123
        return 0;
43✔
124
}
125

126
int bpf_socket_bind_supported(void) {
246✔
127
        _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
246✔
128
        int r;
246✔
129

130
        if (!cgroup_bpf_supported())
246✔
131
                return false;
132

133
        if (!compat_libbpf_probe_bpf_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*opts=*/NULL)) {
237✔
134
                log_debug("bpf-socket-bind: BPF program type cgroup_sock_addr is not supported");
194✔
135
                return false;
194✔
136
        }
137

138
        r = prepare_socket_bind_bpf(/*unit=*/NULL, /*allow_rules=*/NULL, /*deny_rules=*/NULL, &obj);
43✔
139
        if (r < 0) {
43✔
140
                log_debug_errno(r, "bpf-socket-bind: socket bind filtering is not supported: %m");
×
141
                return false;
×
142
        }
143

144
        return bpf_can_link_program(obj->progs.sd_bind4);
43✔
145
}
146

147
int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) {
×
148
        int r;
×
149

150
        assert(u);
×
151

152
        CGroupRuntime *crt = unit_get_cgroup_runtime(u);
×
153
        if (!crt)
×
154
                return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
×
155
                                            "Failed to get control group runtime object.");
156

157
        if (!crt->initial_socket_bind_link_fds) {
×
158
                crt->initial_socket_bind_link_fds = fdset_new();
×
159
                if (!crt->initial_socket_bind_link_fds)
×
160
                        return log_oom();
×
161
        }
162

163
        r = fdset_put(crt->initial_socket_bind_link_fds, fd);
×
164
        if (r < 0)
×
165
                return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to put BPF fd %d to initial fdset", fd);
×
166

167
        return 0;
168
}
169

170
static int socket_bind_install_impl(Unit *u) {
×
171
        _cleanup_(bpf_link_freep) struct bpf_link *ipv4 = NULL, *ipv6 = NULL;
×
172
        _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
×
173
        _cleanup_free_ char *cgroup_path = NULL;
×
174
        _cleanup_close_ int cgroup_fd = -EBADF;
×
175
        CGroupContext *cc;
×
176
        CGroupRuntime *crt;
×
177
        int r;
×
178

179
        assert(u);
×
180

181
        cc = unit_get_cgroup_context(u);
×
182
        if (!cc)
×
183
                return 0;
184

185
        crt = unit_get_cgroup_runtime(u);
×
186
        if (!crt)
×
187
                return 0;
188

189
        r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_path);
×
190
        if (r < 0)
×
191
                return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to get cgroup path: %m");
×
192

193
        if (!cc->socket_bind_allow && !cc->socket_bind_deny)
×
194
                return 0;
195

196
        r = prepare_socket_bind_bpf(u, cc->socket_bind_allow, cc->socket_bind_deny, &obj);
×
197
        if (r < 0)
×
198
                return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to load BPF object: %m");
×
199

200
        cgroup_fd = open(cgroup_path, O_RDONLY | O_CLOEXEC, 0);
×
201
        if (cgroup_fd < 0)
×
202
                return log_unit_error_errno(u, errno, "bpf-socket-bind: Failed to open cgroup %s for reading: %m", cgroup_path);
×
203

204
        ipv4 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind4, cgroup_fd);
×
205
        r = bpf_get_error_translated(ipv4);
×
206
        if (r != 0)
×
207
                return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m",
×
208
                                            sym_bpf_program__name(obj->progs.sd_bind4));
209

210
        ipv6 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind6, cgroup_fd);
×
211
        r = bpf_get_error_translated(ipv6);
×
212
        if (r != 0)
×
213
                return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m",
×
214
                                            sym_bpf_program__name(obj->progs.sd_bind6));
215

216
        crt->ipv4_socket_bind_link = TAKE_PTR(ipv4);
×
217
        crt->ipv6_socket_bind_link = TAKE_PTR(ipv6);
×
218

219
        return 0;
×
220
}
221

222
int bpf_socket_bind_install(Unit *u) {
×
223
        CGroupRuntime *crt;
×
224
        int r;
×
225

226
        assert(u);
×
227

228
        crt = unit_get_cgroup_runtime(u);
×
229
        if (!crt)
×
230
                return 0;
231

232
        r = socket_bind_install_impl(u);
×
233
        fdset_close(crt->initial_socket_bind_link_fds, /* async= */ false);
×
234
        return r;
×
235
}
236

237
int bpf_socket_bind_serialize(Unit *u, FILE *f, FDSet *fds) {
5,105✔
238
        CGroupRuntime *crt;
5,105✔
239
        int r;
5,105✔
240

241
        assert(u);
5,105✔
242

243
        crt = unit_get_cgroup_runtime(u);
5,105✔
244
        if (!crt)
5,105✔
245
                return 0;
246

247
        r = bpf_serialize_link(f, fds, "ipv4-socket-bind-bpf-link", crt->ipv4_socket_bind_link);
5,105✔
248
        if (r < 0)
5,105✔
249
                return r;
250

251
        return bpf_serialize_link(f, fds, "ipv6-socket-bind-bpf-link", crt->ipv6_socket_bind_link);
×
252
}
253

254
#else /* ! BPF_FRAMEWORK */
255
int bpf_socket_bind_supported(void) {
256
        return false;
257
}
258

259
int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) {
260
        return 0;
261
}
262

263
int bpf_socket_bind_install(Unit *u) {
264
        return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
265
                                    "bpf-socket-bind: Failed to install; BPF framework is not supported");
266
}
267

268
int bpf_socket_bind_serialize(Unit *u, FILE *f, FDSet *fds) {
269
        return 0;
270
}
271
#endif
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