• 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

74.27
/src/machine/image-dbus.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <sys/file.h>
4
#include <sys/mount.h>
5

6
#include "alloc-util.h"
7
#include "bus-get-properties.h"
8
#include "bus-label.h"
9
#include "bus-polkit.h"
10
#include "bus-util.h"
11
#include "copy.h"
12
#include "discover-image.h"
13
#include "dissect-image.h"
14
#include "fd-util.h"
15
#include "fileio.h"
16
#include "fs-util.h"
17
#include "image-dbus.h"
18
#include "io-util.h"
19
#include "loop-util.h"
20
#include "machined.h"
21
#include "mount-util.h"
22
#include "operation.h"
23
#include "os-util.h"
24
#include "process-util.h"
25
#include "raw-clone.h"
26
#include "strv.h"
27
#include "user-util.h"
28

29
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType);
36✔
30

31
int bus_image_method_remove(
12✔
32
                sd_bus_message *message,
33
                void *userdata,
34
                sd_bus_error *error) {
35

36
        _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
12✔
37
        Image *image = ASSERT_PTR(userdata);
12✔
38
        Manager *m = image->userdata;
12✔
39
        pid_t child;
12✔
40
        int r;
12✔
41

42
        assert(message);
12✔
43

44
        if (m->n_operations >= OPERATIONS_MAX)
12✔
45
                return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
×
46

47
        const char *details[] = {
12✔
48
                "image", image->name,
12✔
49
                "verb", "remove",
50
                NULL
51
        };
52

53
        r = bus_verify_polkit_async(
12✔
54
                        message,
55
                        "org.freedesktop.machine1.manage-images",
56
                        details,
57
                        &m->polkit_registry,
58
                        error);
59
        if (r < 0)
12✔
60
                return r;
61
        if (r == 0)
12✔
62
                return 1; /* Will call us back */
63

64
        if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
12✔
65
                return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
×
66

67
        r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child);
12✔
68
        if (r < 0)
24✔
69
                return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
×
70
        if (r == 0) {
24✔
71
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
12✔
72
                r = image_remove(image);
12✔
73
                report_errno_and_exit(errno_pipe_fd[1], r);
12✔
74
        }
75

76
        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
12✔
77

78
        r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
12✔
79
        if (r < 0) {
12✔
80
                (void) sigkill_wait(child);
×
81
                return r;
82
        }
83

84
        errno_pipe_fd[0] = -EBADF;
12✔
85

86
        return 1;
12✔
87
}
88

89
int bus_image_method_rename(
3✔
90
                sd_bus_message *message,
91
                void *userdata,
92
                sd_bus_error *error) {
93

94
        Image *image = ASSERT_PTR(userdata);
3✔
95
        Manager *m = image->userdata;
3✔
96
        const char *new_name;
3✔
97
        int r;
3✔
98

99
        assert(message);
3✔
100

101
        r = sd_bus_message_read(message, "s", &new_name);
3✔
102
        if (r < 0)
3✔
103
                return r;
3✔
104

105
        if (!image_name_is_valid(new_name))
3✔
106
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
×
107

108
        const char *details[] = {
3✔
109
                "image", image->name,
3✔
110
                "verb", "rename",
111
                "new_name", new_name,
112
                NULL
113
        };
114

115
        r = bus_verify_polkit_async(
3✔
116
                        message,
117
                        "org.freedesktop.machine1.manage-images",
118
                        details,
119
                        &m->polkit_registry,
120
                        error);
121
        if (r < 0)
3✔
122
                return r;
123
        if (r == 0)
3✔
124
                return 1; /* Will call us back */
125

126
        r = rename_image_and_update_cache(m, image, new_name);
3✔
127
        if (r < 0)
3✔
128
                return sd_bus_error_set_errnof(error, r, "Failed to rename image: %m");
×
129

130
        return sd_bus_reply_method_return(message, NULL);
3✔
131
}
132

133
int bus_image_method_clone(
13✔
134
                sd_bus_message *message,
135
                void *userdata,
136
                sd_bus_error *error) {
137

138
        _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
13✔
139
        Image *image = ASSERT_PTR(userdata);
13✔
140
        Manager *m = ASSERT_PTR(image->userdata);
13✔
141
        const char *new_name;
13✔
142
        int r, read_only;
13✔
143
        pid_t child;
13✔
144

145
        assert(message);
13✔
146

147
        if (m->n_operations >= OPERATIONS_MAX)
13✔
148
                return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
×
149

150
        r = sd_bus_message_read(message, "sb", &new_name, &read_only);
13✔
151
        if (r < 0)
13✔
152
                return r;
153

154
        if (!image_name_is_valid(new_name))
13✔
155
                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
×
156

157
        const char *details[] = {
13✔
158
                "image", image->name,
13✔
159
                "verb", "clone",
160
                "new_name", new_name,
161
                NULL
162
        };
163

164
        r = bus_verify_polkit_async(
13✔
165
                        message,
166
                        "org.freedesktop.machine1.manage-images",
167
                        details,
168
                        &m->polkit_registry,
169
                        error);
170
        if (r < 0)
13✔
171
                return r;
172
        if (r == 0)
13✔
173
                return 1; /* Will call us back */
174

175
        if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
13✔
176
                return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
×
177

178
        r = safe_fork("(sd-imgclone)", FORK_RESET_SIGNALS, &child);
13✔
179
        if (r < 0)
26✔
180
                return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
×
181
        if (r == 0) {
26✔
182
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
13✔
183
                r = image_clone(image, new_name, read_only, m->runtime_scope);
13✔
184
                report_errno_and_exit(errno_pipe_fd[1], r);
13✔
185
        }
186

187
        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
13✔
188

189
        r = operation_new_with_bus_reply(m, /* machine= */ NULL, child, message, errno_pipe_fd[0], /* ret= */ NULL);
13✔
190
        if (r < 0) {
13✔
191
                (void) sigkill_wait(child);
×
192
                return r;
193
        }
194

195
        errno_pipe_fd[0] = -EBADF;
13✔
196

197
        return 1;
13✔
198
}
199

200
int bus_image_method_mark_read_only(
2✔
201
                sd_bus_message *message,
202
                void *userdata,
203
                sd_bus_error *error) {
204

205
        Image *image = userdata;
2✔
206
        Manager *m = image->userdata;
2✔
207
        int read_only, r;
2✔
208

209
        assert(message);
2✔
210

211
        r = sd_bus_message_read(message, "b", &read_only);
2✔
212
        if (r < 0)
2✔
213
                return r;
2✔
214

215
        const char *details[] = {
4✔
216
                "image", image->name,
2✔
217
                "verb", "mark_read_only",
218
                "read_only", one_zero(read_only),
2✔
219
                NULL
220
        };
221

222
        r = bus_verify_polkit_async(
2✔
223
                        message,
224
                        "org.freedesktop.machine1.manage-images",
225
                        details,
226
                        &m->polkit_registry,
227
                        error);
228
        if (r < 0)
2✔
229
                return r;
230
        if (r == 0)
2✔
231
                return 1; /* Will call us back */
232

233
        r = image_read_only(image, read_only);
2✔
234
        if (r < 0)
2✔
235
                return r;
236

237
        return sd_bus_reply_method_return(message, NULL);
2✔
238
}
239

240
int bus_image_method_set_limit(
×
241
                sd_bus_message *message,
242
                void *userdata,
243
                sd_bus_error *error) {
244

245
        Image *image = userdata;
×
246
        Manager *m = image->userdata;
×
247
        uint64_t limit;
×
248
        int r;
×
249

250
        assert(message);
×
251

252
        r = sd_bus_message_read(message, "t", &limit);
×
253
        if (r < 0)
×
254
                return r;
×
255
        if (!FILE_SIZE_VALID_OR_INFINITY(limit))
×
256
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
×
257

258
        const char *details[] = {
×
259
                "machine", image->name,
×
260
                "verb", "set_limit",
261
                NULL
262
        };
263

264
        r = bus_verify_polkit_async(
×
265
                        message,
266
                        "org.freedesktop.machine1.manage-images",
267
                        details,
268
                        &m->polkit_registry,
269
                        error);
270
        if (r < 0)
×
271
                return r;
272
        if (r == 0)
×
273
                return 1; /* Will call us back */
274

275
        r = image_set_limit(image, limit);
×
276
        if (r < 0)
×
277
                return r;
278

279
        return sd_bus_reply_method_return(message, NULL);
×
280
}
281

282
int bus_image_method_get_hostname(
18✔
283
                sd_bus_message *message,
284
                void *userdata,
285
                sd_bus_error *error) {
286

287
        Image *image = userdata;
18✔
288
        int r;
18✔
289

290
        if (!image->metadata_valid) {
18✔
291
                r = image_read_metadata(image, &image_policy_container);
18✔
292
                if (r < 0)
18✔
293
                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
4✔
294
        }
295

296
        return sd_bus_reply_method_return(message, "s", image->hostname);
14✔
297
}
298

299
int bus_image_method_get_machine_id(
18✔
300
                sd_bus_message *message,
301
                void *userdata,
302
                sd_bus_error *error) {
303

304
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
18✔
305
        Image *image = userdata;
18✔
306
        int r;
18✔
307

308
        if (!image->metadata_valid) {
18✔
309
                r = image_read_metadata(image, &image_policy_container);
16✔
310
                if (r < 0)
16✔
311
                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
4✔
312
        }
313

314
        r = sd_bus_message_new_method_return(message, &reply);
14✔
315
        if (r < 0)
14✔
316
                return r;
317

318
        if (sd_id128_is_null(image->machine_id)) /* Add an empty array if the ID is zero */
14✔
319
                r = sd_bus_message_append(reply, "ay", 0);
14✔
320
        else
321
                r = sd_bus_message_append_array(reply, 'y', image->machine_id.bytes, 16);
×
322
        if (r < 0)
14✔
323
                return r;
324

325
        return sd_bus_send(NULL, reply, NULL);
14✔
326
}
327

328
int bus_image_method_get_machine_info(
18✔
329
                sd_bus_message *message,
330
                void *userdata,
331
                sd_bus_error *error) {
332

333
        Image *image = userdata;
18✔
334
        int r;
18✔
335

336
        if (!image->metadata_valid) {
18✔
337
                r = image_read_metadata(image, &image_policy_container);
14✔
338
                if (r < 0)
14✔
339
                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
4✔
340
        }
341

342
        return bus_reply_pair_array(message, image->machine_info);
14✔
343
}
344

345
int bus_image_method_get_os_release(
18✔
346
                sd_bus_message *message,
347
                void *userdata,
348
                sd_bus_error *error) {
349

350
        Image *image = userdata;
18✔
351
        int r;
18✔
352

353
        if (!image->metadata_valid) {
18✔
354
                r = image_read_metadata(image, &image_policy_container);
13✔
355
                if (r < 0)
13✔
356
                        return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
4✔
357
        }
358

359
        return bus_reply_pair_array(message, image->os_release);
14✔
360
}
361

362
static int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
36✔
363
        _cleanup_free_ char *e = NULL;
36✔
364
        Manager *m = userdata;
36✔
365
        Image *image;
36✔
366
        const char *p;
36✔
367
        int r;
36✔
368

369
        assert(bus);
36✔
370
        assert(path);
36✔
371
        assert(interface);
36✔
372
        assert(found);
36✔
373

374
        p = startswith(path, "/org/freedesktop/machine1/image/");
36✔
375
        if (!p)
36✔
376
                return 0;
377

378
        e = bus_label_unescape(p);
36✔
379
        if (!e)
36✔
380
                return -ENOMEM;
381

382
        r = manager_acquire_image(m, e, &image);
36✔
383
        if (r == -ENOENT)
36✔
384
                return 0;
385
        if (r < 0)
36✔
386
                return r;
387

388
        *found = image;
36✔
389
        return 1;
36✔
390
}
391

392
char* image_bus_path(const char *name) {
89✔
393
        _cleanup_free_ char *e = NULL;
89✔
394

395
        assert(name);
89✔
396

397
        e = bus_label_escape(name);
89✔
398
        if (!e)
89✔
399
                return NULL;
400

401
        return strjoin("/org/freedesktop/machine1/image/", e);
89✔
402
}
403

404
static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
×
405
        _cleanup_hashmap_free_ Hashmap *images = NULL;
×
406
        _cleanup_strv_free_ char **l = NULL;
×
407
        Manager *m = ASSERT_PTR(userdata);
×
408
        Image *image;
×
409
        int r;
×
410

411
        assert(bus);
×
412
        assert(path);
×
413
        assert(nodes);
×
414

415
        images = hashmap_new(&image_hash_ops);
×
416
        if (!images)
×
417
                return -ENOMEM;
418

419
        r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images);
×
420
        if (r < 0)
×
421
                return r;
422

423
        HASHMAP_FOREACH(image, images) {
×
424
                char *p;
×
425

426
                p = image_bus_path(image->name);
×
427
                if (!p)
×
428
                        return -ENOMEM;
×
429

430
                r = strv_consume(&l, p);
×
431
                if (r < 0)
×
432
                        return r;
433
        }
434

435
        *nodes = TAKE_PTR(l);
×
436

437
        return 1;
×
438
}
439

440
const sd_bus_vtable image_vtable[] = {
441
        SD_BUS_VTABLE_START(0),
442
        SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
443
        SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
444
        SD_BUS_PROPERTY("Type", "s", property_get_type,  offsetof(Image, type), 0),
445
        SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
446
        SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
447
        SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
448
        SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
449
        SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
450
        SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
451
        SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
452
        SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
453
        SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
454
        SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
455
        SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
456
        SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
457
        SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
458
        SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
459
        SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
460
        SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
461
        SD_BUS_VTABLE_END
462
};
463

464
const BusObjectImplementation image_object = {
465
        "/org/freedesktop/machine1/image",
466
        "org.freedesktop.machine1.Image",
467
        .fallback_vtables = BUS_FALLBACK_VTABLES({image_vtable, image_object_find}),
468
        .node_enumerator = image_node_enumerator,
469
};
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