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

systemd / systemd / 15720680019

17 Jun 2025 07:58PM UTC coverage: 72.087% (-0.02%) from 72.109%
15720680019

push

github

web-flow
sd-lldp: several improvements (#37845)

This makes
- sd-lldp-tx not send machine ID as chassis ID, but use application
specific machine ID,
- sd-lldp-tx emit vlan ID if it is running on a vlan interface,
- Describe() DBus method also reply LLDP configurations,
- io.systemd.Network.GetLLDPNeighbors varlink method provides vlan ID,
if received.

Closes #37613.

59 of 76 new or added lines in 3 files covered. (77.63%)

4663 existing lines in 75 files now uncovered.

300494 of 416851 relevant lines covered (72.09%)

704683.58 hits per line

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

24.05
/src/core/dbus-timer.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "alloc-util.h"
4
#include "bus-get-properties.h"
5
#include "calendarspec.h"
6
#include "dbus-timer.h"
7
#include "dbus-util.h"
8
#include "string-util.h"
9
#include "strv.h"
10
#include "timer.h"
11
#include "unit.h"
12

13
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult);
376✔
14

15
static int property_get_monotonic_timers(
9✔
16
                sd_bus *bus,
17
                const char *path,
18
                const char *interface,
19
                const char *property,
20
                sd_bus_message *reply,
21
                void *userdata,
22
                sd_bus_error *error) {
23

24
        Timer *t = ASSERT_PTR(userdata);
9✔
25
        int r;
9✔
26

27
        assert(bus);
9✔
28
        assert(reply);
9✔
29

30
        r = sd_bus_message_open_container(reply, 'a', "(stt)");
9✔
31
        if (r < 0)
9✔
32
                return r;
33

34
        LIST_FOREACH(value, v, t->values) {
21✔
35
                _cleanup_free_ char *usec = NULL;
6✔
36

37
                if (v->base == TIMER_CALENDAR)
12✔
38
                        continue;
6✔
39

40
                usec = timer_base_to_usec_string(v->base);
6✔
41
                if (!usec)
6✔
42
                        return -ENOMEM;
43

44
                r = sd_bus_message_append(reply, "(stt)", usec, v->value, v->next_elapse);
6✔
45
                if (r < 0)
6✔
46
                        return r;
47
        }
48

49
        return sd_bus_message_close_container(reply);
9✔
50
}
51

52
static int property_get_calendar_timers(
9✔
53
                sd_bus *bus,
54
                const char *path,
55
                const char *interface,
56
                const char *property,
57
                sd_bus_message *reply,
58
                void *userdata,
59
                sd_bus_error *error) {
60

61
        Timer *t = ASSERT_PTR(userdata);
9✔
62
        int r;
9✔
63

64
        assert(bus);
9✔
65
        assert(reply);
9✔
66

67
        r = sd_bus_message_open_container(reply, 'a', "(sst)");
9✔
68
        if (r < 0)
9✔
69
                return r;
70

71
        LIST_FOREACH(value, v, t->values) {
21✔
72
                _cleanup_free_ char *buf = NULL;
6✔
73

74
                if (v->base != TIMER_CALENDAR)
12✔
75
                        continue;
6✔
76

77
                r = calendar_spec_to_string(v->calendar_spec, &buf);
6✔
78
                if (r < 0)
6✔
79
                        return r;
80

81
                r = sd_bus_message_append(reply, "(sst)", timer_base_to_string(v->base), buf, v->next_elapse);
6✔
82
                if (r < 0)
6✔
83
                        return r;
84
        }
85

86
        return sd_bus_message_close_container(reply);
9✔
87
}
88

89
static int property_get_next_elapse_monotonic(
376✔
90
                sd_bus *bus,
91
                const char *path,
92
                const char *interface,
93
                const char *property,
94
                sd_bus_message *reply,
95
                void *userdata,
96
                sd_bus_error *error) {
97

98
        Timer *t = ASSERT_PTR(userdata);
376✔
99

100
        assert(bus);
376✔
101
        assert(reply);
376✔
102

103
        return sd_bus_message_append(reply, "t", timer_next_elapse_monotonic(t));
376✔
104
}
105

106
const sd_bus_vtable bus_timer_vtable[] = {
107
        SD_BUS_VTABLE_START(0),
108
        SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
109
        SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
110
        SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
111
        SD_BUS_PROPERTY("OnClockChange", "b", bus_property_get_bool, offsetof(Timer, on_clock_change), SD_BUS_VTABLE_PROPERTY_CONST),
112
        SD_BUS_PROPERTY("OnTimezoneChange", "b", bus_property_get_bool, offsetof(Timer, on_timezone_change), SD_BUS_VTABLE_PROPERTY_CONST),
113
        SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
114
        SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", property_get_next_elapse_monotonic, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
115
        BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
116
        SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
117
        SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
118
        SD_BUS_PROPERTY("RandomizedDelayUSec", "t", bus_property_get_usec, offsetof(Timer, random_delay_usec), SD_BUS_VTABLE_PROPERTY_CONST),
119
        SD_BUS_PROPERTY("RandomizedOffsetUSec", "t", bus_property_get_usec, offsetof(Timer, random_offset_usec), SD_BUS_VTABLE_PROPERTY_CONST),
120
        SD_BUS_PROPERTY("FixedRandomDelay", "b", bus_property_get_bool, offsetof(Timer, fixed_random_delay), SD_BUS_VTABLE_PROPERTY_CONST),
121
        SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
122
        SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
123
        SD_BUS_PROPERTY("RemainAfterElapse", "b", bus_property_get_bool, offsetof(Timer, remain_after_elapse), SD_BUS_VTABLE_PROPERTY_CONST),
124
        SD_BUS_PROPERTY("DeferReactivation", "b", bus_property_get_bool, offsetof(Timer, defer_reactivation), SD_BUS_VTABLE_PROPERTY_CONST),
125
        SD_BUS_VTABLE_END
126
};
127

UNCOV
128
static int timer_add_one_monotonic_spec(
×
129
                Timer *t,
130
                const char *name,
131
                TimerBase base,
132
                UnitWriteFlags flags,
133
                usec_t usec,
134
                sd_bus_error *error) {
135

136
        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
UNCOV
137
                TimerValue *v;
×
138

UNCOV
139
                unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name,
×
140
                                    "%s=%s",
141
                                    timer_base_to_string(base),
UNCOV
142
                                    FORMAT_TIMESPAN(usec, USEC_PER_MSEC));
×
143

144
                v = new(TimerValue, 1);
×
145
                if (!v)
×
UNCOV
146
                        return -ENOMEM;
×
147

UNCOV
148
                *v = (TimerValue) {
×
149
                        .base = base,
150
                        .value = usec,
151
                };
152

UNCOV
153
                LIST_PREPEND(value, t->values, v);
×
154
        }
155

156
        return 1;
157
}
158

UNCOV
159
static int timer_add_one_calendar_spec(
×
160
                Timer *t,
161
                const char *name,
162
                TimerBase base,
163
                UnitWriteFlags flags,
164
                const char *str,
165
                sd_bus_error *error) {
166

167
        _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
×
UNCOV
168
        int r;
×
169

170
        r = calendar_spec_from_string(str, &c);
×
171
        if (r == -EINVAL)
×
172
                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid calendar spec");
×
UNCOV
173
        if (r < 0)
×
174
                return r;
175

176
        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
×
UNCOV
177
                unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name,
×
178
                                    "%s=%s", timer_base_to_string(base), str);
179

180
                TimerValue *v = new(TimerValue, 1);
×
UNCOV
181
                if (!v)
×
182
                        return -ENOMEM;
183

UNCOV
184
                *v = (TimerValue) {
×
185
                        .base = base,
UNCOV
186
                        .calendar_spec = TAKE_PTR(c),
×
187
                };
188

UNCOV
189
                LIST_PREPEND(value, t->values, v);
×
190
        }
191

192
        return 1;
193
};
194

UNCOV
195
static int bus_timer_set_transient_property(
×
196
                Timer *t,
197
                const char *name,
198
                sd_bus_message *message,
199
                UnitWriteFlags flags,
200
                sd_bus_error *error) {
201

202
        Unit *u = UNIT(t);
×
UNCOV
203
        int r;
×
204

205
        assert(t);
×
206
        assert(name);
×
UNCOV
207
        assert(message);
×
208

UNCOV
209
        flags |= UNIT_PRIVATE;
×
210

211
        if (streq(name, "AccuracyUSec"))
×
UNCOV
212
                return bus_set_transient_usec(u, name, &t->accuracy_usec, message, flags, error);
×
213

214
        if (streq(name, "AccuracySec")) {
×
215
                log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead.");
×
UNCOV
216
                return bus_set_transient_usec(u, "AccuracyUSec", &t->accuracy_usec, message, flags, error);
×
217
        }
218

219
        if (streq(name, "RandomizedDelayUSec"))
×
UNCOV
220
                return bus_set_transient_usec(u, name, &t->random_delay_usec, message, flags, error);
×
221

222
        if (streq(name, "RandomizedOffsetUSec"))
×
UNCOV
223
                return bus_set_transient_usec(u, name, &t->random_offset_usec, message, flags, error);
×
224

225
        if (streq(name, "FixedRandomDelay"))
×
UNCOV
226
                return bus_set_transient_bool(u, name, &t->fixed_random_delay, message, flags, error);
×
227

228
        if (streq(name, "WakeSystem"))
×
UNCOV
229
                return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
×
230

231
        if (streq(name, "Persistent"))
×
UNCOV
232
                return bus_set_transient_bool(u, name, &t->persistent, message, flags, error);
×
233

234
        if (streq(name, "RemainAfterElapse"))
×
UNCOV
235
                return bus_set_transient_bool(u, name, &t->remain_after_elapse, message, flags, error);
×
236

237
        if (streq(name, "OnTimezoneChange"))
×
UNCOV
238
                return bus_set_transient_bool(u, name, &t->on_timezone_change, message, flags, error);
×
239

240
        if (streq(name, "OnClockChange"))
×
UNCOV
241
                return bus_set_transient_bool(u, name, &t->on_clock_change, message, flags, error);
×
242

243
        if (streq(name, "DeferReactivation"))
×
244
                return bus_set_transient_bool(u, name, &t->defer_reactivation, message, flags, error);
×
245

UNCOV
246
        if (streq(name, "TimersMonotonic")) {
×
247
                const char *base_name;
×
248
                usec_t usec;
×
249
                bool empty = true;
×
250

251
                r = sd_bus_message_enter_container(message, 'a', "(st)");
×
252
                if (r < 0)
×
UNCOV
253
                        return r;
×
254

255
                while ((r = sd_bus_message_read(message, "(st)", &base_name, &usec)) > 0) {
×
256
                        TimerBase b;
×
257

UNCOV
258
                        b = timer_base_from_string(base_name);
×
259
                        if (b < 0 || b == TIMER_CALENDAR)
×
260
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
261
                                                         "Invalid timer base: %s", base_name);
262

UNCOV
263
                        r = timer_add_one_monotonic_spec(t, name, b, flags, usec, error);
×
UNCOV
264
                        if (r < 0)
×
265
                                return r;
266

267
                        empty = false;
268
                }
269
                if (r < 0)
×
270
                        return r;
271

272
                r = sd_bus_message_exit_container(message);
×
273
                if (r < 0)
×
274
                        return r;
275

UNCOV
276
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
×
277
                        timer_free_values(t);
×
UNCOV
278
                        unit_write_setting(u, flags, name, "OnActiveSec=");
×
279
                }
280

281
                return 1;
×
282

283
        } else if (streq(name, "TimersCalendar")) {
×
284
                const char *base_name, *str;
×
285
                bool empty = true;
×
286

287
                r = sd_bus_message_enter_container(message, 'a', "(ss)");
×
288
                if (r < 0)
×
UNCOV
289
                        return r;
×
290

291
                while ((r = sd_bus_message_read(message, "(ss)", &base_name, &str)) > 0) {
×
292
                        TimerBase b;
×
293

UNCOV
294
                        b = timer_base_from_string(base_name);
×
295
                        if (b != TIMER_CALENDAR)
×
296
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
×
297
                                                         "Invalid timer base: %s", base_name);
298

UNCOV
299
                        r = timer_add_one_calendar_spec(t, name, b, flags, str, error);
×
UNCOV
300
                        if (r < 0)
×
301
                                return r;
302

303
                        empty = false;
304
                }
305
                if (r < 0)
×
306
                        return r;
307

308
                r = sd_bus_message_exit_container(message);
×
309
                if (r < 0)
×
310
                        return r;
311

UNCOV
312
                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
×
313
                        timer_free_values(t);
×
UNCOV
314
                        unit_write_setting(u, flags, name, "OnCalendar=");
×
315
                }
316

UNCOV
317
                return 1;
×
318

UNCOV
319
        } else if (STR_IN_SET(name,
×
320
                       "OnActiveSec",
321
                       "OnBootSec",
322
                       "OnStartupSec",
323
                       "OnUnitActiveSec",
324
                       "OnUnitInactiveSec")) {
325

UNCOV
326
                TimerBase b;
×
327
                usec_t usec;
×
328

329
                log_notice("Client is using obsolete %s= transient property, please use TimersMonotonic= instead.", name);
×
330

331
                b = timer_base_from_string(name);
×
332
                if (b < 0)
×
UNCOV
333
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown timer base %s", name);
×
334

335
                r = sd_bus_message_read(message, "t", &usec);
×
UNCOV
336
                if (r < 0)
×
337
                        return r;
338

339
                return timer_add_one_monotonic_spec(t, name, b, flags, usec, error);
×
340

341
        } else if (streq(name, "OnCalendar")) {
×
342

343
                const char *str;
×
344

345
                log_notice("Client is using obsolete %s= transient property, please use TimersCalendar= instead.", name);
×
346

347
                r = sd_bus_message_read(message, "s", &str);
×
UNCOV
348
                if (r < 0)
×
UNCOV
349
                        return r;
×
350

UNCOV
351
                return timer_add_one_calendar_spec(t, name, TIMER_CALENDAR, flags, str, error);
×
352
        }
353

UNCOV
354
        return 0;
×
355
}
356

UNCOV
357
int bus_timer_set_property(
×
358
                Unit *u,
359
                const char *name,
360
                sd_bus_message *message,
361
                UnitWriteFlags mode,
362
                sd_bus_error *error) {
363

364
        Timer *t = TIMER(u);
×
365

366
        assert(t);
×
367
        assert(name);
×
UNCOV
368
        assert(message);
×
369

UNCOV
370
        if (u->transient && u->load_state == UNIT_STUB)
×
UNCOV
371
                return bus_timer_set_transient_property(t, name, message, mode, error);
×
372

373
        return 0;
374
}
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