• 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

83.33
/src/machine/operation.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <sys/wait.h>
4
#include <unistd.h>
5

6
#include "alloc-util.h"
7
#include "fd-util.h"
8
#include "log.h"
9
#include "machine.h"
10
#include "machined.h"
11
#include "operation.h"
12
#include "process-util.h"
13

14
static int read_operation_errno(const siginfo_t *si, Operation *o) {
39✔
15
        int r;
39✔
16

17
        assert(si);
39✔
18
        assert(o);
39✔
19

20
        if (si->si_code != CLD_EXITED)
39✔
21
                return log_debug_errno(SYNTHETIC_ERRNO(ESHUTDOWN), "Child died abnormally");
×
22

23
        if (si->si_status == EXIT_SUCCESS)
39✔
24
                r = 0;
38✔
25
        else {
26
                ssize_t n = read(o->errno_fd, &r, sizeof(r));
1✔
27
                if (n < 0)
1✔
28
                        return log_debug_errno(errno, "Failed to read operation's errno: %m");
×
29
                if (n != sizeof(r))
1✔
30
                        return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpectedly short message when reading operation's errno");
×
31
        }
32

33
        return r;
39✔
34
}
35

36
static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
39✔
37
        Operation *o = ASSERT_PTR(userdata);
39✔
38
        int r;
39✔
39

40
        assert(si);
39✔
41

42
        log_debug("Operation " PID_FMT " is now complete with code=%s status=%i",
39✔
43
                  o->pid,
44
                  sigchld_code_to_string(si->si_code), si->si_status);
45

46
        o->pid = 0;
39✔
47

48
        r = read_operation_errno(si, o);
39✔
49
        if (r < 0)
39✔
50
                log_debug_errno(r, "Operation failed: %m");
1✔
51

52
        if (o->message) {
39✔
53
                /* If o->done set, call it. It sends a response, but can return
54
                 * an error in which case it expect this code to reply.
55
                 * If o->done is not set, the default action is to simply return
56
                 * an error on failure or an empty success message on success. */
57

58
                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
59
                if (o->done)
30✔
60
                        r = o->done(o, r, &error);
2✔
61

62
                if (r < 0) {
30✔
63
                        if (!sd_bus_error_is_set(&error))
×
64
                                sd_bus_error_set_errno(&error, r);
×
65

66
                        r = sd_bus_reply_method_error(o->message, &error);
×
67
                        if (r < 0)
×
68
                                log_error_errno(r, "Failed to reply to dbus message: %m");
×
69
                } else if (!o->done) {
30✔
70
                        /* when o->done set it's responsible for sending reply in a happy-path case */
71
                        r = sd_bus_reply_method_return(o->message, NULL);
28✔
72
                        if (r < 0)
28✔
73
                                log_error_errno(r, "Failed to reply to dbus message: %m");
30✔
74
                }
75
        } else if (o->link) {
9✔
76
                /* If o->done set, call it. Unlike o->message case above, this
77
                 * code expect o->done to reply in all cases.
78
                 * If o->done is not set, the default action is to simply return
79
                 * an error on failure or an empty success message on success. */
80

81
                if (o->done)
9✔
82
                        (void) o->done(o, r, /* error = */ NULL);
6✔
83
                else if (r < 0)
3✔
84
                        (void) sd_varlink_error_errno(o->link, r);
×
85
                else
86
                        (void) sd_varlink_reply(o->link, NULL);
3✔
87
        } else
88
                assert_not_reached();
×
89

90
        operation_free(o);
39✔
91
        return 0;
39✔
92
}
93

94
int operation_new(Manager *manager, Machine *machine, pid_t child, int errno_fd, Operation **ret) {
39✔
95
        Operation *o;
39✔
96
        int r;
39✔
97

98
        assert(manager);
39✔
99
        assert(child > 1);
39✔
100
        assert(errno_fd >= 0);
39✔
101
        assert(ret);
39✔
102

103
        o = new(Operation, 1);
39✔
104
        if (!o)
39✔
105
                return -ENOMEM;
106

107
        *o = (Operation) {
39✔
108
                .pid = child,
109
                .errno_fd = errno_fd,
110
                .extra_fd = -EBADF
111
        };
112

113
        r = sd_event_add_child(manager->event, &o->event_source, child, WEXITED, operation_done, o);
39✔
114
        if (r < 0) {
39✔
115
                free(o);
×
116
                return r;
×
117
        }
118

119
        LIST_PREPEND(operations, manager->operations, o);
39✔
120
        manager->n_operations++;
39✔
121
        o->manager = manager;
39✔
122

123
        if (machine) {
39✔
124
                LIST_PREPEND(operations_by_machine, machine->operations, o);
8✔
125
                o->machine = machine;
8✔
126
        }
127

128
        log_debug("Started new operation " PID_FMT ".", child);
39✔
129

130
        /* At this point we took ownership of both the child and the errno file descriptor! */
131

132
        *ret = o;
39✔
133
        return 0;
39✔
134
}
135

136
Operation *operation_free(Operation *o) {
39✔
137
        if (!o)
39✔
138
                return NULL;
139

140
        sd_event_source_unref(o->event_source);
39✔
141

142
        safe_close(o->errno_fd);
39✔
143
        safe_close(o->extra_fd);
39✔
144

145
        if (o->pid > 1)
39✔
146
                (void) sigkill_wait(o->pid);
×
147

148
        sd_bus_message_unref(o->message);
39✔
149
        sd_varlink_unref(o->link);
39✔
150

151
        if (o->manager) {
39✔
152
                LIST_REMOVE(operations, o->manager->operations, o);
39✔
153
                o->manager->n_operations--;
39✔
154
        }
155

156
        if (o->machine)
39✔
157
                LIST_REMOVE(operations_by_machine, o->machine->operations, o);
8✔
158

159
        return mfree(o);
39✔
160
}
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