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

systemd / systemd / 28689257516

03 Jul 2026 11:32PM UTC coverage: 72.9% (+0.3%) from 72.618%
28689257516

push

github

bluca
hwdb: map mic-mute key on Logitech K950 (Bluetooth)

The mic-mute key on the Logitech K950 keyboard (046D:B388, Bluetooth)
emits BTN_0 (scancode 0x100e1) instead of a usable key, so it does
nothing under GNOME/KDE. Map it to KEY_MICMUTE, its intended function.

Scancode determined with evtest on the device.

343301 of 470919 relevant lines covered (72.9%)

1344559.44 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 <fcntl.h>
4
#include <sys/sysinfo.h>
5
#include <sys/utsname.h>
6

7
#include "sd-device.h"
8
#include "sd-id128.h"
9
#include "sd-json.h"
10
#include "sd-varlink.h"
11

12
#include "alloc-util.h"
13
#include "architecture.h"
14
#include "confidential-virt.h"
15
#include "cpu-set-util.h"
16
#include "env-file.h"
17
#include "errno-util.h"
18
#include "fd-util.h"
19
#include "fileio.h"
20
#include "hostname-setup.h"
21
#include "hostname-util.h"
22
#include "limits-util.h"
23
#include "log.h"
24
#include "metrics.h"
25
#include "os-util.h"
26
#include "report-basic.h"
27
#include "string-util.h"
28
#include "virt.h"
29

30
static int architecture_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
31
        assert(mf && mf->name);
×
32
        assert(link);
×
33

34
        return metric_build_send_string(
×
35
                        mf,
36
                        link,
37
                        /* object= */ NULL,
38
                        architecture_to_string(uname_architecture()),
39
                        /* fields= */ NULL);
40
}
41

42
static int boot_id_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
43
        sd_id128_t id;
×
44
        int r;
×
45

46
        assert(mf && mf->name);
×
47
        assert(link);
×
48

49
        r = sd_id128_get_boot(&id);
×
50
        if (r < 0)
×
51
                return r;
×
52

53
        return metric_build_send_string(
×
54
                        mf,
55
                        link,
56
                        /* object= */ NULL,
57
                        SD_ID128_TO_STRING(id),
×
58
                        /* fields= */ NULL);
59
}
60

61
static int hostname_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
62
        _cleanup_free_ char *hostname = NULL;
×
63
        int r;
×
64

65
        assert(mf && mf->name);
×
66
        assert(link);
×
67

68
        r = gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT, &hostname);
×
69
        if (r < 0)
×
70
                return r;
71

72
        return metric_build_send_string(
×
73
                        mf,
74
                        link,
75
                        /* object= */ NULL,
76
                        hostname,
77
                        /* fields= */ NULL);
78
}
79

80
static int kernel_version_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
81
        struct utsname u;
×
82

83
        assert(mf && mf->name);
×
84
        assert(link);
×
85

86
        assert_se(uname(&u) >= 0);
×
87

88
        return metric_build_send_string(
×
89
                        mf,
90
                        link,
91
                        /* object= */ NULL,
92
                        u.release,
93
                        /* fields= */ NULL);
94
}
95

96
static int machine_id_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
97
        sd_id128_t id;
×
98
        int r;
×
99

100
        assert(mf && mf->name);
×
101
        assert(link);
×
102

103
        r = sd_id128_get_machine(&id);
×
104
        if (r < 0)
×
105
                return r;
×
106

107
        return metric_build_send_string(
×
108
                        mf,
109
                        link,
110
                        /* object= */ NULL,
111
                        SD_ID128_TO_STRING(id),
×
112
                        /* fields= */ NULL);
113
}
114

115
static int physical_memory_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
116
        assert(mf && mf->name);
×
117
        assert(link);
×
118

119
        return metric_build_send_unsigned(
×
120
                        mf,
121
                        link,
122
                        /* object= */ NULL,
123
                        physical_memory(),
124
                        /* fields= */ NULL);
125
}
126

127
static int cpus_online_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
128
        int r;
×
129

130
        assert(mf && mf->name);
×
131
        assert(link);
×
132

133
        unsigned n_cpus;
×
134
        r = cpus_online(&n_cpus);
×
135
        if (r < 0)
×
136
                return r;
×
137

138
        return metric_build_send_unsigned(
×
139
                        mf,
140
                        link,
141
                        /* object= */ NULL,
142
                        n_cpus,
143
                        /* fields= */ NULL);
144
}
145

146
static int load_average_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
147
        enum {
×
148
                LOAD_AVERAGE_FIELD_1MIN,
149
                LOAD_AVERAGE_FIELD_5MIN,
150
                LOAD_AVERAGE_FIELD_15MIN,
151
                _LOAD_AVERAGE_FIELD_MAX,
152
        };
153

154
        int r;
×
155

156
        assert(mf && mf->name);
×
157
        assert(link);
×
158

159
        /* The classic Linux load average, i.e. the exponentially damped moving average of the number of
160
         * runnable plus uninterruptible tasks over the last 1, 5 and 15 minutes. The kernel exposes these as
161
         * fixed-point numbers shifted left by SI_LOAD_SHIFT bits. */
162

163
        struct sysinfo info;
×
164
        if (sysinfo(&info) < 0)
×
165
                return log_debug_errno(errno, "Failed to call sysinfo(): %m");
×
166

167
        assert_cc(_LOAD_AVERAGE_FIELD_MAX == ELEMENTSOF(info.loads));
168

169
        for (size_t i = 0; i < _LOAD_AVERAGE_FIELD_MAX; i++) {
×
170

171
                r = metric_build_send_double(
×
172
                                mf + i,
×
173
                                link,
174
                                /* object= */ NULL,
175
                                (double) info.loads[i] / (UINT64_C(1) << SI_LOAD_SHIFT),
×
176
                                /* fields= */ NULL);
177
                if (r < 0)
×
178
                        return r;
179
        }
180

181
        return 0;
182
}
183

184
static int swap_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
185
        assert(mf && mf->name);
×
186
        assert(link);
×
187

188
        /* The total amount of configured swap space, in bytes. */
189

190
        struct sysinfo info;
×
191
        if (sysinfo(&info) < 0)
×
192
                return log_debug_errno(errno, "Failed to call sysinfo(): %m");
×
193

194
        /* Overflow is unrealistic (would need >16 EiB of swap), but use MUL_SAFE to make this obvious to
195
         * static analyzers. */
196
        uint64_t swap;
×
197
        assert_se(MUL_SAFE(&swap, (uint64_t) info.totalswap, (uint64_t) info.mem_unit));
×
198

199
        return metric_build_send_unsigned(
×
200
                        mf,
201
                        link,
202
                        /* object= */ NULL,
203
                        swap,
204
                        /* fields= */ NULL);
205
}
206

207
enum {
208
        FIELD_PRETTY_NAME,
209
        FIELD_NAME,
210
        FIELD_ID,
211
        FIELD_CPE_NAME,
212
        FIELD_VARIANT_ID,
213
        FIELD_VERSION_ID,
214
        FIELD_BUILD_ID,
215
        FIELD_IMAGE_VERSION,
216
        FIELD_IMAGE_ID,
217
        FIELD_SUPPORT_END,
218
        FIELD_EXPERIMENT,
219
        FIELD_SYSEXT_LEVEL,
220
        FIELD_CONFEXT_LEVEL,
221
        _FIELD_MAX,
222
};
223

224
static int os_release_generate(const MetricFamily mf[static _FIELD_MAX - 1], sd_varlink *link, void *userdata) {
×
225
        char* values[_FIELD_MAX] = {};
×
226
        CLEANUP_ELEMENTS(values, free_many_charp);
×
227
        int r;
×
228

229
        assert(mf && mf->name);
×
230
        assert(link);
×
231

232
        r = parse_os_release(NULL,
×
233
                             "PRETTY_NAME",   &values[FIELD_PRETTY_NAME],
234
                             "NAME",          &values[FIELD_NAME],
235
                             "ID",            &values[FIELD_ID],
236
                             "CPE_NAME",      &values[FIELD_CPE_NAME],
237
                             "VARIANT_ID",    &values[FIELD_VARIANT_ID],
238
                             "VERSION_ID",    &values[FIELD_VERSION_ID],
239
                             "BUILD_ID",      &values[FIELD_BUILD_ID],
240
                             "IMAGE_VERSION", &values[FIELD_IMAGE_VERSION],
241
                             "IMAGE_ID",      &values[FIELD_IMAGE_ID],
242
                             "SUPPORT_END",   &values[FIELD_SUPPORT_END],
243
                             "EXPERIMENT",    &values[FIELD_EXPERIMENT],
244
                             "SYSEXT_LEVEL",  &values[FIELD_SYSEXT_LEVEL],
245
                             "CONFEXT_LEVEL", &values[FIELD_CONFEXT_LEVEL]);
246
        if (r < 0) {
×
247
                log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
×
248
                               "Failed to read os-release file, ignoring: %m");
249
                return 0;
250
        }
251

252
        for (size_t i = 1; i < _FIELD_MAX; i++) {
×
253
                const char *v = values[i];
×
254
                if (i == FIELD_NAME && values[FIELD_PRETTY_NAME])
×
255
                        v = values[FIELD_PRETTY_NAME];  /* Prefer PRETTY_NAME to NAME */
×
256

257
                if (v) {
×
258
                        r = metric_build_send_string(
×
259
                                        mf + i - 1,
×
260
                                        link,
261
                                        /* object= */ NULL,
262
                                        v,
263
                                        /* fields= */ NULL);
264
                        if (r < 0)
×
265
                                return r;
266
                }
267
        }
268

269
        return 0;
270
}
271

272
static int machine_info_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
273
        enum {
×
274
                MACHINE_INFO_FIELD_PRETTY_HOSTNAME,
275
                MACHINE_INFO_FIELD_DEPLOYMENT,
276
                MACHINE_INFO_FIELD_LOCATION,
277
                MACHINE_INFO_FIELD_TAGS,
278
                _MACHINE_INFO_FIELD_MAX,
279
        };
280

281
        char* values[_MACHINE_INFO_FIELD_MAX] = {};
×
282
        CLEANUP_ELEMENTS(values, free_many_charp);
×
283
        int r;
×
284

285
        assert(mf && mf->name);
×
286
        assert(link);
×
287

288
        r = parse_env_file(/* f= */ NULL, etc_machine_info(),
×
289
                           "PRETTY_HOSTNAME", &values[MACHINE_INFO_FIELD_PRETTY_HOSTNAME],
290
                           "DEPLOYMENT",      &values[MACHINE_INFO_FIELD_DEPLOYMENT],
291
                           "LOCATION",        &values[MACHINE_INFO_FIELD_LOCATION],
292
                           "TAGS",            &values[MACHINE_INFO_FIELD_TAGS]);
293
        if (r < 0) {
×
294
                log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
×
295
                               "Failed to read machine-info file, ignoring: %m");
296
                return 0;
297
        }
298

299
        for (size_t i = 0; i < _MACHINE_INFO_FIELD_MAX; i++) {
×
300
                const char *v = values[i];
×
301
                if (!v)
×
302
                        continue;
×
303

304
                r = metric_build_send_string(
×
305
                                mf + i,
×
306
                                link,
307
                                /* object= */ NULL,
308
                                v,
309
                                /* fields= */ NULL);
310
                if (r < 0)
×
311
                        return r;
312
        }
313

314
        return 0;
315
}
316

317
static int smbios_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
318
        enum {
×
319
                SMBIOS_FIELD_SYS_VENDOR,
320
                SMBIOS_FIELD_PRODUCT_NAME,
321
                SMBIOS_FIELD_PRODUCT_VERSION,
322
                SMBIOS_FIELD_PRODUCT_SKU,
323
                SMBIOS_FIELD_PRODUCT_FAMILY,
324
                SMBIOS_FIELD_PRODUCT_SERIAL,
325
                SMBIOS_FIELD_PRODUCT_UUID,
326
                SMBIOS_FIELD_BOARD_VENDOR,
327
                SMBIOS_FIELD_BOARD_NAME,
328
                SMBIOS_FIELD_BOARD_VERSION,
329
                SMBIOS_FIELD_BOARD_SERIAL,
330
                SMBIOS_FIELD_BOARD_ASSET_TAG,
331
                SMBIOS_FIELD_BIOS_VENDOR,
332
                SMBIOS_FIELD_BIOS_VERSION,
333
                SMBIOS_FIELD_BIOS_DATE,
334
                SMBIOS_FIELD_CHASSIS_TYPE,
335
                SMBIOS_FIELD_CHASSIS_VENDOR,
336
                SMBIOS_FIELD_CHASSIS_SERIAL,
337
                SMBIOS_FIELD_CHASSIS_ASSET_TAG,
338
                _SMBIOS_FIELD_MAX,
339
        };
340

341
        /* The sysfs attribute names exposed by the kernel below /sys/class/dmi/id/. The order must match the
342
         * SMBIOS_STANDARD_FIELD() entries in the metric family table below. */
343
        static const char* const smbios_files[_SMBIOS_FIELD_MAX] = {
×
344
                /* SMBIOS Type 1 */
345
                [SMBIOS_FIELD_SYS_VENDOR]        = "sys_vendor",
346
                [SMBIOS_FIELD_PRODUCT_NAME]      = "product_name",
347
                [SMBIOS_FIELD_PRODUCT_VERSION]   = "product_version",
348
                [SMBIOS_FIELD_PRODUCT_SKU]       = "product_sku",
349
                [SMBIOS_FIELD_PRODUCT_FAMILY]    = "product_family",
350
                [SMBIOS_FIELD_PRODUCT_SERIAL]    = "product_serial",
351
                [SMBIOS_FIELD_PRODUCT_UUID]      = "product_uuid",
352
                /* SMBIOS Type 2 */
353
                [SMBIOS_FIELD_BOARD_VENDOR]      = "board_vendor",
354
                [SMBIOS_FIELD_BOARD_NAME]        = "board_name",
355
                [SMBIOS_FIELD_BOARD_VERSION]     = "board_version",
356
                [SMBIOS_FIELD_BOARD_SERIAL]      = "board_serial",
357
                [SMBIOS_FIELD_BOARD_ASSET_TAG]   = "board_asset_tag",
358
                /* SMBIOS Type 0 */
359
                [SMBIOS_FIELD_BIOS_VENDOR]       = "bios_vendor",
360
                [SMBIOS_FIELD_BIOS_VERSION]      = "bios_version",
361
                [SMBIOS_FIELD_BIOS_DATE]         = "bios_date",
362
                /* SMBIOS Type 3 */
363
                [SMBIOS_FIELD_CHASSIS_TYPE]      = "chassis_type",
364
                [SMBIOS_FIELD_CHASSIS_VENDOR]    = "chassis_vendor",
365
                [SMBIOS_FIELD_CHASSIS_SERIAL]    = "chassis_serial",
366
                [SMBIOS_FIELD_CHASSIS_ASSET_TAG] = "chassis_asset_tag",
367
        };
368

369
        int r;
×
370

371
        assert(mf && mf->name);
×
372
        assert(link);
×
373

374
        /* Reports the fundamental SMBIOS/DMI identification fields. Some of these (serial numbers, asset
375
         * tags, the system UUID) are privacy sensitive and only readable by root — if we lack the
376
         * privileges to read them we simply skip them. */
377

378
        _cleanup_close_ int dir_fd = open("/sys/class/dmi/id", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
×
379
        if (dir_fd < 0) {
×
380
                log_full_errno(ERRNO_IS_DEVICE_ABSENT(errno) ? LOG_DEBUG : LOG_WARNING, errno,
×
381
                               "Failed to open /sys/class/dmi/id/, ignoring: %m");
382
                return 0;
383
        }
384

385
        for (size_t i = 0; i < _SMBIOS_FIELD_MAX; i++) {
×
386
                _cleanup_free_ char *buf = NULL;
×
387

388
                r = read_virtual_file_at(dir_fd, smbios_files[i], /* max_size= */ SIZE_MAX, &buf, /* ret_size= */ NULL);
×
389
                if (r < 0) {
×
390
                        log_full_errno(r == -ENOENT || ERRNO_IS_NEG_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
×
391
                                       "Failed to read SMBIOS field '%s', ignoring: %m", smbios_files[i]);
392
                        continue;
×
393
                }
394

395
                delete_trailing_chars(buf, NEWLINE);
×
396

397
                if (isempty(buf))
×
398
                        continue;
×
399

400
                if (!string_is_safe(buf, STRING_ALLOW_BACKSLASHES|STRING_ALLOW_QUOTES|STRING_ALLOW_GLOBS)) {
×
401
                        log_debug("SMBIOS field '%s' contains unsafe characters, ignoring.", smbios_files[i]);
×
402
                        continue;
×
403
                }
404

405
                r = metric_build_send_string(
×
406
                                mf + i,
×
407
                                link,
408
                                /* object= */ NULL,
409
                                buf,
410
                                /* fields= */ NULL);
411
                if (r < 0)
×
412
                        return r;
×
413
        }
414

415
        return 0;
416
}
417

418
static int tpm2_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
419
        enum {
×
420
                TPM2_FIELD_MANUFACTURER,
421
                TPM2_FIELD_VENDOR_STRING,
422
                _TPM2_FIELD_MAX,
423
        };
424

425
        /* The udev properties set by the 'tpm2_id' builtin on the tpmrm device. The order must match the
426
         * metric family table entries below. */
427
        static const char* const tpm2_properties[_TPM2_FIELD_MAX] = {
×
428
                [TPM2_FIELD_MANUFACTURER]  = "ID_TPM2_MANUFACTURER",
429
                [TPM2_FIELD_VENDOR_STRING] = "ID_TPM2_VENDOR_STRING",
430
        };
431

432
        int r;
×
433

434
        assert(mf && mf->name);
×
435
        assert(link);
×
436

437
        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
×
438
        r = sd_device_new_from_subsystem_sysname(&dev, "tpmrm", "tpmrm0");
×
439
        if (r < 0) {
×
440
                log_full_errno(ERRNO_IS_NEG_DEVICE_ABSENT(r) ? LOG_DEBUG : LOG_WARNING, r,
×
441
                               "Failed to open tpmrm0 device, ignoring: %m");
442
                return 0;
443
        }
444

445
        for (size_t i = 0; i < _TPM2_FIELD_MAX; i++) {
×
446
                const char *v;
×
447

448
                r = sd_device_get_property_value(dev, tpm2_properties[i], &v);
×
449
                if (r < 0) {
×
450
                        log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
×
451
                                       "Failed to read TPM2 property '%s', ignoring: %m", tpm2_properties[i]);
452
                        continue;
×
453
                }
454

455
                if (isempty(v))
×
456
                        continue;
×
457

458
                r = metric_build_send_string(
×
459
                                mf + i,
×
460
                                link,
461
                                /* object= */ NULL,
462
                                v,
463
                                /* fields= */ NULL);
464
                if (r < 0)
×
465
                        return r;
×
466
        }
467

468
        return 0;
469
}
470

471
static int confidential_virtualization_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
472
        assert(mf && mf->name);
×
473
        assert(link);
×
474

475
        ConfidentialVirtualization cv = detect_confidential_virtualization();
×
476
        if (cv < 0)
×
477
                return cv;
478

479
        return metric_build_send_string(
×
480
                        mf,
481
                        link,
482
                        /* object= */ NULL,
483
                        confidential_virtualization_to_string(cv),
484
                        /* fields= */ NULL);
485
}
486

487
static int virtualization_generate(const MetricFamily *mf, sd_varlink *link, void *userdata) {
×
488
        assert(mf && mf->name);
×
489
        assert(link);
×
490

491
        Virtualization v = detect_virtualization();
×
492
        if (v < 0)
×
493
                return v;
494

495
        return metric_build_send_string(
×
496
                        mf,
497
                        link,
498
                        /* object= */ NULL,
499
                        virtualization_to_string(v),
500
                        /* fields= */ NULL);
501
}
502

503
#define OS_RELEASE_STANDARD_FIELD(name)                                 \
504
        {                                                               \
505
                METRIC_IO_SYSTEMD_BASIC_PREFIX "OSRelease." name,       \
506
                "Operating system identification (" name "= field from os-release)", \
507
                METRIC_FAMILY_TYPE_STRING,                              \
508
        }
509

510
#define MACHINE_INFO_STANDARD_FIELD(name)                               \
511
        {                                                               \
512
                METRIC_IO_SYSTEMD_BASIC_PREFIX "MachineInfo." name,     \
513
                "Machine identification (" name "= field from machine-info)", \
514
                METRIC_FAMILY_TYPE_STRING,                              \
515
        }
516

517
#define SMBIOS_STANDARD_FIELD(name)                                     \
518
        {                                                               \
519
                METRIC_IO_SYSTEMD_BASIC_PREFIX "SMBIOS." name,          \
520
                "Firmware/hardware identification (" name " field from SMBIOS/DMI)", \
521
                METRIC_FAMILY_TYPE_STRING,                              \
522
        }
523

524
static const MetricFamily metric_family_table[] = {
525
        /* Keep entries ordered alphabetically */
526
        {
527
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Architecture",
528
                "CPU architecture",
529
                METRIC_FAMILY_TYPE_STRING,
530
                .generate = architecture_generate,
531
        },
532
        {
533
                METRIC_IO_SYSTEMD_BASIC_PREFIX "BootID",
534
                "Current boot ID",
535
                METRIC_FAMILY_TYPE_STRING,
536
                .generate = boot_id_generate,
537
        },
538
        {
539
                METRIC_IO_SYSTEMD_BASIC_PREFIX "ConfidentialVirtualization",
540
                "Confidential computing technology",
541
                METRIC_FAMILY_TYPE_STRING,
542
                .generate = confidential_virtualization_generate,
543
        },
544
        {
545
                METRIC_IO_SYSTEMD_BASIC_PREFIX "CPUsOnline",
546
                "Number of CPUs currently online",
547
                METRIC_FAMILY_TYPE_GAUGE,
548
                .generate = cpus_online_generate,
549
        },
550
        {
551
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Hostname",
552
                "System hostname",
553
                METRIC_FAMILY_TYPE_STRING,
554
                .generate = hostname_generate,
555
        },
556
        {
557
                METRIC_IO_SYSTEMD_BASIC_PREFIX "KernelVersion",
558
                "Kernel version",
559
                METRIC_FAMILY_TYPE_STRING,
560
                .generate = kernel_version_generate,
561
        },
562
        {
563
                METRIC_IO_SYSTEMD_BASIC_PREFIX "LoadAverage1Min",
564
                "System load average over the last 1 minute",
565
                METRIC_FAMILY_TYPE_GAUGE,
566
                .generate = load_average_generate,
567
        },
568
        {
569
                METRIC_IO_SYSTEMD_BASIC_PREFIX "LoadAverage5Min",
570
                "System load average over the last 5 minutes",
571
                METRIC_FAMILY_TYPE_GAUGE,
572
        },
573
        {
574
                METRIC_IO_SYSTEMD_BASIC_PREFIX "LoadAverage15Min",
575
                "System load average over the last 15 minutes",
576
                METRIC_FAMILY_TYPE_GAUGE,
577
        },
578
        /* Keep those ↑ in sync with load_average_generate(). */
579
        {
580
                METRIC_IO_SYSTEMD_BASIC_PREFIX "MachineID",
581
                "Machine ID",
582
                METRIC_FAMILY_TYPE_STRING,
583
                .generate = machine_id_generate,
584
        },
585
        {
586
                METRIC_IO_SYSTEMD_BASIC_PREFIX "MachineInfo.PRETTY_HOSTNAME",
587
                "Pretty hostname (PRETTY_HOSTNAME= field from machine-info)",
588
                METRIC_FAMILY_TYPE_STRING,
589
                .generate = machine_info_generate,
590
        },
591
        MACHINE_INFO_STANDARD_FIELD("DEPLOYMENT"),
592
        MACHINE_INFO_STANDARD_FIELD("LOCATION"),
593
        MACHINE_INFO_STANDARD_FIELD("TAGS"),
594
        /* Keep those ↑ in sync with machine_info_generate(). */
595
        {
596
                METRIC_IO_SYSTEMD_BASIC_PREFIX "OSRelease.NAME",
597
                "Operating system human-readable name (PRETTY_NAME= or NAME= field from os-release)",
598
                METRIC_FAMILY_TYPE_STRING,
599
                .generate = os_release_generate,
600
        },
601
        OS_RELEASE_STANDARD_FIELD("ID"),
602
        OS_RELEASE_STANDARD_FIELD("CPE_NAME"),
603
        OS_RELEASE_STANDARD_FIELD("VARIANT_ID"),
604
        OS_RELEASE_STANDARD_FIELD("VERSION_ID"),
605
        OS_RELEASE_STANDARD_FIELD("BUILD_ID"),
606
        OS_RELEASE_STANDARD_FIELD("IMAGE_VERSION"),
607
        OS_RELEASE_STANDARD_FIELD("IMAGE_ID"),
608
        OS_RELEASE_STANDARD_FIELD("SUPPORT_END"),
609
        OS_RELEASE_STANDARD_FIELD("EXPERIMENT"),
610
        OS_RELEASE_STANDARD_FIELD("SYSEXT_LEVEL"),
611
        OS_RELEASE_STANDARD_FIELD("CONFEXT_LEVEL"),
612
        /* Keep those ↑ in sync with os_release_generate(). */
613
        {
614
                METRIC_IO_SYSTEMD_BASIC_PREFIX "PhysicalMemoryBytes",
615
                "Installed physical memory in bytes",
616
                METRIC_FAMILY_TYPE_GAUGE,
617
                .generate = physical_memory_generate,
618
        },
619
        {
620
                /* NB: Here we use the naming of the field as per SMBIOS specification, i.e. undo the weird
621
                 * renaming that Linux did on the fields. When new fields are added here, please make sure to
622
                 * check the specification again for naming them. */
623
                METRIC_IO_SYSTEMD_BASIC_PREFIX "SMBIOS.SystemManufacturer",
624
                "Firmware/hardware identification (SystemManufacturer field from SMBIOS/DMI)",
625
                METRIC_FAMILY_TYPE_STRING,
626
                .generate = smbios_generate,
627
        },
628
        SMBIOS_STANDARD_FIELD("SystemProductName"),
629
        SMBIOS_STANDARD_FIELD("SystemVersion"),
630
        SMBIOS_STANDARD_FIELD("SystemSKUNumber"),
631
        SMBIOS_STANDARD_FIELD("SystemFamily"),
632
        SMBIOS_STANDARD_FIELD("SystemSerialNumber"),
633
        SMBIOS_STANDARD_FIELD("SystemUUID"),
634
        SMBIOS_STANDARD_FIELD("BaseBoardManufacturer"),
635
        SMBIOS_STANDARD_FIELD("BaseBoardProduct"),
636
        SMBIOS_STANDARD_FIELD("BaseBoardVersion"),
637
        SMBIOS_STANDARD_FIELD("BaseBoardSerial"),
638
        SMBIOS_STANDARD_FIELD("BaseBoardAssetTag"),
639
        SMBIOS_STANDARD_FIELD("FirmwareVendor"),
640
        SMBIOS_STANDARD_FIELD("FirmwareVersion"),
641
        SMBIOS_STANDARD_FIELD("FirmwareReleaseDate"),
642
        SMBIOS_STANDARD_FIELD("ChassisType"),
643
        SMBIOS_STANDARD_FIELD("ChassisManufacturer"),
644
        SMBIOS_STANDARD_FIELD("ChassisSerialNumber"),
645
        SMBIOS_STANDARD_FIELD("ChassisAssetTagNumber"),
646
        /* Keep those ↑ in sync with smbios_generate(). */
647
        {
648
                METRIC_IO_SYSTEMD_BASIC_PREFIX "SwapBytes",
649
                "Total configured swap space in bytes",
650
                METRIC_FAMILY_TYPE_GAUGE,
651
                .generate = swap_generate,
652
        },
653
        {
654
                METRIC_IO_SYSTEMD_BASIC_PREFIX "TPM2.Manufacturer",
655
                "TPM2 device manufacturer (ID_TPM2_MANUFACTURER property of the tpmrm0 device)",
656
                METRIC_FAMILY_TYPE_STRING,
657
                .generate = tpm2_generate,
658
        },
659
        {
660
                METRIC_IO_SYSTEMD_BASIC_PREFIX "TPM2.VendorString",
661
                "TPM2 device vendor string (ID_TPM2_VENDOR_STRING property of the tpmrm0 device)",
662
                METRIC_FAMILY_TYPE_STRING,
663
        },
664
        /* Keep those ↑ in sync with tpm2_generate(). */
665
        {
666
                METRIC_IO_SYSTEMD_BASIC_PREFIX "Virtualization",
667
                "Virtualization type",
668
                METRIC_FAMILY_TYPE_STRING,
669
                .generate = virtualization_generate,
670
        },
671
        {}
672
};
673

674
int vl_method_describe_metrics(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
×
675
        return metrics_method_describe(metric_family_table, link, parameters, flags, userdata);
×
676
}
677

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