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

systemd / systemd / 25834419893

13 May 2026 10:51PM UTC coverage: 72.584% (+0.07%) from 72.513%
25834419893

push

github

bluca
nsresourced: re-link GID delegation file after atomic UID file write

userns_registry_remove() restores a sub-delegated UID range by writing
the previous owner's data to u<UID>.delegate with WRITE_STRING_FILE_ATOMIC.
Atomic writes go via a temp file and rename, which replaces the directory
entry with a fresh inode and severs the hardlink to g<GID>.delegate. The
stale GID side then keeps pointing at the prior inode with outdated owner
and ancestor data, so subsequent lookups via GID return wrong results.

Re-create the hardlink after the atomic write so the two views stay in
sync, matching what userns_registry_store() already does after writing
a new delegation.

5 of 8 new or added lines in 1 file covered. (62.5%)

4652 existing lines in 93 files now uncovered.

328958 of 453210 relevant lines covered (72.58%)

1305869.89 hits per line

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

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

3
#include <sys/utsname.h>
4

5
#include "sd-id128.h"
6
#include "sd-json.h"
7
#include "sd-varlink.h"
8

9
#include "alloc-util.h"
10
#include "architecture.h"
11
#include "hostname-setup.h"
12
#include "log.h"
13
#include "metrics.h"
14
#include "os-util.h"
15
#include "report-basic.h"
16
#include "virt.h"
17

UNCOV
18
static int architecture_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
19
        assert(mf && mf->name);
×
UNCOV
20
        assert(link);
×
21

UNCOV
22
        return metric_build_send_string(
×
23
                        mf,
24
                        link,
25
                        /* object= */ NULL,
26
                        architecture_to_string(uname_architecture()),
27
                        /* fields= */ NULL);
28
}
29

30
static int boot_id_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
UNCOV
31
        sd_id128_t id;
×
32
        int r;
×
33

34
        assert(mf && mf->name);
×
UNCOV
35
        assert(link);
×
36

UNCOV
37
        r = sd_id128_get_boot(&id);
×
UNCOV
38
        if (r < 0)
×
39
                return r;
×
40

UNCOV
41
        return metric_build_send_string(
×
42
                        mf,
43
                        link,
44
                        /* object= */ NULL,
45
                        SD_ID128_TO_STRING(id),
×
46
                        /* fields= */ NULL);
47
}
48

49
static int hostname_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
50
        _cleanup_free_ char *hostname = NULL;
×
UNCOV
51
        int r;
×
52

53
        assert(mf && mf->name);
×
UNCOV
54
        assert(link);
×
55

UNCOV
56
        r = gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT, &hostname);
×
UNCOV
57
        if (r < 0)
×
58
                return r;
59

60
        return metric_build_send_string(
×
61
                        mf,
62
                        link,
63
                        /* object= */ NULL,
64
                        hostname,
65
                        /* fields= */ NULL);
66
}
67

UNCOV
68
static int kernel_version_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
UNCOV
69
        struct utsname u;
×
70

UNCOV
71
        assert(mf && mf->name);
×
UNCOV
72
        assert(link);
×
73

74
        assert_se(uname(&u) >= 0);
×
75

76
        return metric_build_send_string(
×
77
                        mf,
78
                        link,
79
                        /* object= */ NULL,
80
                        u.release,
81
                        /* fields= */ NULL);
82
}
83

84
static int machine_id_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
UNCOV
85
        sd_id128_t id;
×
UNCOV
86
        int r;
×
87

UNCOV
88
        assert(mf && mf->name);
×
UNCOV
89
        assert(link);
×
90

91
        r = sd_id128_get_machine(&id);
×
92
        if (r < 0)
×
UNCOV
93
                return r;
×
94

UNCOV
95
        return metric_build_send_string(
×
96
                        mf,
97
                        link,
98
                        /* object= */ NULL,
UNCOV
99
                        SD_ID128_TO_STRING(id),
×
100
                        /* fields= */ NULL);
101
}
102

103
enum {
104
        FIELD_PRETTY_NAME,
105
        FIELD_NAME,
106
        FIELD_ID,
107
        FIELD_CPE_NAME,
108
        FIELD_VARIANT_ID,
109
        FIELD_VERSION_ID,
110
        FIELD_BUILD_ID,
111
        FIELD_IMAGE_VERSION,
112
        FIELD_IMAGE_ID,
113
        FIELD_SUPPORT_END,
114
        FIELD_EXPERIMENT,
115
        FIELD_SYSEXT_LEVEL,
116
        FIELD_CONFEXT_LEVEL,
117
        _FIELD_MAX,
118
};
119

UNCOV
120
static int os_release_generate(const MetricFamily mf[static _FIELD_MAX - 1], sd_varlink *link, void *userdata) {
×
UNCOV
121
        char* values[_FIELD_MAX] = {};
×
UNCOV
122
        CLEANUP_ELEMENTS(values, free_many_charp);
×
UNCOV
123
        int r;
×
124

UNCOV
125
        assert(mf && mf->name);
×
UNCOV
126
        assert(link);
×
127

UNCOV
128
        r = parse_os_release(NULL,
×
129
                             "PRETTY_NAME",   &values[FIELD_PRETTY_NAME],
130
                             "NAME",          &values[FIELD_NAME],
131
                             "ID",            &values[FIELD_ID],
132
                             "CPE_NAME",      &values[FIELD_CPE_NAME],
133
                             "VARIANT_ID",    &values[FIELD_VARIANT_ID],
134
                             "VERSION_ID",    &values[FIELD_VERSION_ID],
135
                             "BUILD_ID",      &values[FIELD_BUILD_ID],
136
                             "IMAGE_VERSION", &values[FIELD_IMAGE_VERSION],
137
                             "IMAGE_ID",      &values[FIELD_IMAGE_ID],
138
                             "SUPPORT_END",   &values[FIELD_SUPPORT_END],
139
                             "EXPERIMENT",    &values[FIELD_EXPERIMENT],
140
                             "SYSEXT_LEVEL",  &values[FIELD_SYSEXT_LEVEL],
141
                             "CONFEXT_LEVEL", &values[FIELD_CONFEXT_LEVEL]);
UNCOV
142
        if (r < 0) {
×
UNCOV
143
                log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
×
144
                               "Failed to read os-release file, ignoring: %m");
145
                return 0;
146
        }
147

148
        for (size_t i = 1; i < _FIELD_MAX; i++) {
×
149
                const char *v = values[i];
×
UNCOV
150
                if (i == FIELD_NAME && values[FIELD_PRETTY_NAME])
×
UNCOV
151
                        v = values[FIELD_PRETTY_NAME];  /* Prefer PRETTY_NAME to NAME */
×
152

153
                if (v) {
×
UNCOV
154
                        r = metric_build_send_string(
×
UNCOV
155
                                        mf + i - 1,
×
156
                                        link,
157
                                        /* object= */ NULL,
158
                                        v,
159
                                        /* fields= */ NULL);
UNCOV
160
                        if (r < 0)
×
161
                                return r;
162
                }
163
        }
164

165
        return 0;
166
}
167

UNCOV
168
static int virtualization_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
UNCOV
169
        assert(mf && mf->name);
×
UNCOV
170
        assert(link);
×
171

UNCOV
172
        Virtualization v = detect_virtualization();
×
UNCOV
173
        if (v < 0)
×
174
                return v;
175

UNCOV
176
        return metric_build_send_string(
×
177
                        mf,
178
                        link,
179
                        /* object= */ NULL,
180
                        virtualization_to_string(v),
181
                        /* fields= */ NULL);
182
}
183

184
#define OS_RELEASE_STANDARD_FIELD(name)                                 \
185
        {                                                               \
186
                METRIC_IO_SYSTEMD_BASIC_PREFIX "OSRelease." name,       \
187
                "Operating system identification (" name "= field from os-release)", \
188
                METRIC_FAMILY_TYPE_STRING,                              \
189
                .generate = NULL,                                       \
190
        }
191

192
static const MetricFamily metric_family_table[] = {
193
        /* Keep entries ordered alphabetically */
194
        {
195
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Architecture",
196
                "CPU architecture",
197
                METRIC_FAMILY_TYPE_STRING,
198
                .generate = architecture_generate,
199
        },
200
        {
201
                METRIC_IO_SYSTEMD_BASIC_PREFIX "BootID",
202
                "Current boot ID",
203
                METRIC_FAMILY_TYPE_STRING,
204
                .generate = boot_id_generate,
205
        },
206
        {
207
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Hostname",
208
                "System hostname",
209
                METRIC_FAMILY_TYPE_STRING,
210
                .generate = hostname_generate,
211
        },
212
        {
213
                METRIC_IO_SYSTEMD_BASIC_PREFIX "KernelVersion",
214
                "Kernel version",
215
                METRIC_FAMILY_TYPE_STRING,
216
                .generate = kernel_version_generate,
217
        },
218
        {
219
                METRIC_IO_SYSTEMD_BASIC_PREFIX "MachineID",
220
                "Machine ID",
221
                METRIC_FAMILY_TYPE_STRING,
222
                .generate = machine_id_generate,
223
        },
224
        {
225
                METRIC_IO_SYSTEMD_BASIC_PREFIX "OSRelease.NAME",
226
                "Operating system human-readable name (PRETTY_NAME= or NAME= field from os-release)",
227
                METRIC_FAMILY_TYPE_STRING,
228
                .generate = os_release_generate,
229
        },
230
        OS_RELEASE_STANDARD_FIELD("ID"),
231
        OS_RELEASE_STANDARD_FIELD("CPE_NAME"),
232
        OS_RELEASE_STANDARD_FIELD("VARIANT_ID"),
233
        OS_RELEASE_STANDARD_FIELD("VERSION_ID"),
234
        OS_RELEASE_STANDARD_FIELD("BUILD_ID"),
235
        OS_RELEASE_STANDARD_FIELD("IMAGE_VERSION"),
236
        OS_RELEASE_STANDARD_FIELD("IMAGE_ID"),
237
        OS_RELEASE_STANDARD_FIELD("SUPPORT_END"),
238
        OS_RELEASE_STANDARD_FIELD("EXPERIMENT"),
239
        OS_RELEASE_STANDARD_FIELD("SYSEXT_LEVEL"),
240
        OS_RELEASE_STANDARD_FIELD("CONFEXT_LEVEL"),
241
        /* Keep those ↑ in sync with os_release_generate(). */
242
        {
243
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Virtualization",
244
                "Virtualization type",
245
                METRIC_FAMILY_TYPE_STRING,
246
                .generate = virtualization_generate,
247
        },
248
        {}
249
};
250

UNCOV
251
int vl_method_describe_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
×
UNCOV
252
        return metrics_method_describe(metric_family_table, link, parameters, flags, userdata);
×
253
}
254

UNCOV
255
int vl_method_list_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
×
UNCOV
256
        return metrics_method_list(metric_family_table, link, parameters, flags, userdata);
×
257
}
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