]>
Commit | Line | Data |
---|---|---|
a01ba4b2 ZJS |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
3 | #include "clean-ipc.h" | |
008798e9 | 4 | #include "core-varlink.h" |
a01ba4b2 ZJS |
5 | #include "dbus.h" |
6 | #include "fd-util.h" | |
7 | #include "fileio.h" | |
8 | #include "format-util.h" | |
baa6a42d | 9 | #include "initrd-util.h" |
a01ba4b2 ZJS |
10 | #include "macro.h" |
11 | #include "manager-serialize.h" | |
12 | #include "manager.h" | |
13 | #include "parse-util.h" | |
14 | #include "serialize.h" | |
15 | #include "syslog-util.h" | |
16 | #include "unit-serialize.h" | |
17 | #include "user-util.h" | |
008798e9 | 18 | #include "varlink-internal.h" |
a01ba4b2 ZJS |
19 | |
20 | int manager_open_serialization(Manager *m, FILE **ret_f) { | |
254d1313 | 21 | _cleanup_close_ int fd = -EBADF; |
a01ba4b2 ZJS |
22 | FILE *f; |
23 | ||
24 | assert(ret_f); | |
25 | ||
26 | fd = open_serialization_fd("systemd-state"); | |
27 | if (fd < 0) | |
28 | return fd; | |
29 | ||
30 | f = take_fdopen(&fd, "w+"); | |
31 | if (!f) | |
32 | return -errno; | |
33 | ||
34 | *ret_f = f; | |
35 | return 0; | |
36 | } | |
37 | ||
38 | static bool manager_timestamp_shall_serialize(ManagerTimestamp t) { | |
39 | if (!in_initrd()) | |
40 | return true; | |
41 | ||
42 | /* The following timestamps only apply to the host system, hence only serialize them there */ | |
43 | return !IN_SET(t, | |
44 | MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH, | |
45 | MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH, | |
46 | MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH, | |
47 | MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH); | |
48 | } | |
49 | ||
50 | static void manager_serialize_uid_refs_internal( | |
51 | FILE *f, | |
52 | Hashmap *uid_refs, | |
53 | const char *field_name) { | |
54 | ||
55 | void *p, *k; | |
56 | ||
57 | assert(f); | |
58 | assert(field_name); | |
59 | ||
60 | /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as | |
61 | * the actual counter of it is better rebuild after a reload/reexec. */ | |
62 | ||
63 | HASHMAP_FOREACH_KEY(p, k, uid_refs) { | |
64 | uint32_t c; | |
65 | uid_t uid; | |
66 | ||
67 | uid = PTR_TO_UID(k); | |
68 | c = PTR_TO_UINT32(p); | |
69 | ||
70 | if (!(c & DESTROY_IPC_FLAG)) | |
71 | continue; | |
72 | ||
73 | (void) serialize_item_format(f, field_name, UID_FMT, uid); | |
74 | } | |
75 | } | |
76 | ||
77 | static void manager_serialize_uid_refs(Manager *m, FILE *f) { | |
78 | manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid"); | |
79 | } | |
80 | ||
81 | static void manager_serialize_gid_refs(Manager *m, FILE *f) { | |
82 | manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid"); | |
83 | } | |
84 | ||
85 | int manager_serialize( | |
86 | Manager *m, | |
87 | FILE *f, | |
88 | FDSet *fds, | |
89 | bool switching_root) { | |
90 | ||
91 | const char *t; | |
92 | Unit *u; | |
93 | int r; | |
94 | ||
95 | assert(m); | |
96 | assert(f); | |
97 | assert(fds); | |
98 | ||
99 | _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m); | |
100 | ||
101 | (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id); | |
102 | (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs); | |
103 | (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs); | |
a01ba4b2 ZJS |
104 | (void) serialize_bool(f, "ready-sent", m->ready_sent); |
105 | (void) serialize_bool(f, "taint-logged", m->taint_logged); | |
106 | (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs); | |
107 | ||
a01ba4b2 ZJS |
108 | if (m->show_status_overridden != _SHOW_STATUS_INVALID) |
109 | (void) serialize_item(f, "show-status-overridden", | |
110 | show_status_to_string(m->show_status_overridden)); | |
111 | ||
112 | if (m->log_level_overridden) | |
113 | (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level()); | |
114 | if (m->log_target_overridden) | |
115 | (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target())); | |
116 | ||
117 | (void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]); | |
118 | (void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]); | |
119 | (void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]); | |
5717062e | 120 | (void) serialize_usec(f, "pretimeout-watchdog-overridden", m->watchdog_overridden[WATCHDOG_PRETIMEOUT]); |
aff3a9e1 | 121 | (void) serialize_item(f, "pretimeout-watchdog-governor-overridden", m->watchdog_pretimeout_governor_overridden); |
a01ba4b2 ZJS |
122 | |
123 | for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { | |
124 | _cleanup_free_ char *joined = NULL; | |
125 | ||
126 | if (!manager_timestamp_shall_serialize(q)) | |
127 | continue; | |
128 | ||
129 | joined = strjoin(manager_timestamp_to_string(q), "-timestamp"); | |
130 | if (!joined) | |
131 | return log_oom(); | |
132 | ||
133 | (void) serialize_dual_timestamp(f, joined, m->timestamps + q); | |
134 | } | |
135 | ||
136 | if (!switching_root) | |
137 | (void) serialize_strv(f, "env", m->client_environment); | |
138 | ||
139 | if (m->notify_fd >= 0) { | |
140 | r = serialize_fd(f, fds, "notify-fd", m->notify_fd); | |
141 | if (r < 0) | |
142 | return r; | |
143 | ||
144 | (void) serialize_item(f, "notify-socket", m->notify_socket); | |
145 | } | |
146 | ||
147 | if (m->cgroups_agent_fd >= 0) { | |
148 | r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd); | |
149 | if (r < 0) | |
150 | return r; | |
151 | } | |
152 | ||
153 | if (m->user_lookup_fds[0] >= 0) { | |
154 | int copy0, copy1; | |
155 | ||
156 | copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]); | |
157 | if (copy0 < 0) | |
158 | return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m"); | |
159 | ||
160 | copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]); | |
161 | if (copy1 < 0) | |
162 | return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m"); | |
163 | ||
164 | (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1); | |
165 | } | |
166 | ||
d9365956 LB |
167 | (void) serialize_item_format(f, |
168 | "dump-ratelimit", | |
169 | USEC_FMT " " USEC_FMT " %u %u", | |
170 | m->dump_ratelimit.begin, | |
171 | m->dump_ratelimit.interval, | |
172 | m->dump_ratelimit.num, | |
173 | m->dump_ratelimit.burst); | |
174 | ||
a01ba4b2 ZJS |
175 | bus_track_serialize(m->subscribed, f, "subscribed"); |
176 | ||
177 | r = dynamic_user_serialize(m, f, fds); | |
178 | if (r < 0) | |
179 | return r; | |
180 | ||
181 | manager_serialize_uid_refs(m, f); | |
182 | manager_serialize_gid_refs(m, f); | |
183 | ||
e76506b7 | 184 | r = exec_shared_runtime_serialize(m, f, fds); |
a01ba4b2 ZJS |
185 | if (r < 0) |
186 | return r; | |
187 | ||
008798e9 AZ |
188 | r = varlink_server_serialize(m->varlink_server, f, fds); |
189 | if (r < 0) | |
190 | return r; | |
191 | ||
a01ba4b2 ZJS |
192 | (void) fputc('\n', f); |
193 | ||
194 | HASHMAP_FOREACH_KEY(u, t, m->units) { | |
195 | if (u->id != t) | |
196 | continue; | |
197 | ||
198 | r = unit_serialize(u, f, fds, switching_root); | |
199 | if (r < 0) | |
200 | return r; | |
201 | } | |
202 | ||
203 | r = fflush_and_check(f); | |
204 | if (r < 0) | |
205 | return log_error_errno(r, "Failed to flush serialization: %m"); | |
206 | ||
207 | r = bus_fdset_add_all(m, fds); | |
208 | if (r < 0) | |
209 | return log_error_errno(r, "Failed to add bus sockets to serialization: %m"); | |
210 | ||
211 | return 0; | |
212 | } | |
213 | ||
214 | static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) { | |
215 | Unit *u; | |
216 | int r; | |
217 | ||
218 | r = manager_load_unit(m, name, NULL, NULL, &u); | |
219 | if (r < 0) { | |
220 | if (r == -ENOMEM) | |
221 | return r; | |
222 | return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name); | |
223 | } | |
224 | ||
225 | r = unit_deserialize(u, f, fds); | |
226 | if (r < 0) { | |
227 | if (r == -ENOMEM) | |
228 | return r; | |
229 | return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name); | |
230 | } | |
231 | ||
232 | return 0; | |
233 | } | |
234 | ||
235 | static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) { | |
236 | const char *unit_name; | |
237 | int r; | |
238 | ||
239 | for (;;) { | |
240 | _cleanup_free_ char *line = NULL; | |
241 | /* Start marker */ | |
242 | r = read_line(f, LONG_LINE_MAX, &line); | |
243 | if (r < 0) | |
244 | return log_error_errno(r, "Failed to read serialization line: %m"); | |
245 | if (r == 0) | |
246 | break; | |
247 | ||
248 | unit_name = strstrip(line); | |
249 | ||
250 | r = manager_deserialize_one_unit(m, unit_name, f, fds); | |
251 | if (r == -ENOMEM) | |
252 | return r; | |
253 | if (r < 0) { | |
254 | r = unit_deserialize_skip(f); | |
255 | if (r < 0) | |
256 | return r; | |
257 | } | |
258 | } | |
259 | ||
260 | return 0; | |
261 | } | |
262 | ||
263 | static void manager_deserialize_uid_refs_one_internal( | |
264 | Hashmap** uid_refs, | |
265 | const char *value) { | |
266 | ||
267 | uid_t uid; | |
268 | uint32_t c; | |
269 | int r; | |
270 | ||
271 | assert(uid_refs); | |
272 | assert(value); | |
273 | ||
274 | r = parse_uid(value, &uid); | |
275 | if (r < 0 || uid == 0) { | |
6cb105b8 | 276 | log_debug("Unable to parse UID/GID reference serialization: %s", value); |
a01ba4b2 ZJS |
277 | return; |
278 | } | |
279 | ||
280 | if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) { | |
281 | log_oom(); | |
282 | return; | |
283 | } | |
284 | ||
285 | c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid))); | |
286 | if (c & DESTROY_IPC_FLAG) | |
287 | return; | |
288 | ||
289 | c |= DESTROY_IPC_FLAG; | |
290 | ||
291 | r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c)); | |
292 | if (r < 0) { | |
293 | log_debug_errno(r, "Failed to add UID/GID reference entry: %m"); | |
294 | return; | |
295 | } | |
296 | } | |
297 | ||
298 | static void manager_deserialize_uid_refs_one(Manager *m, const char *value) { | |
299 | manager_deserialize_uid_refs_one_internal(&m->uid_refs, value); | |
300 | } | |
301 | ||
302 | static void manager_deserialize_gid_refs_one(Manager *m, const char *value) { | |
303 | manager_deserialize_uid_refs_one_internal(&m->gid_refs, value); | |
304 | } | |
305 | ||
306 | int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { | |
008798e9 | 307 | bool deserialize_varlink_sockets = false; |
a01ba4b2 ZJS |
308 | int r = 0; |
309 | ||
310 | assert(m); | |
311 | assert(f); | |
312 | ||
313 | if (DEBUG_LOGGING) { | |
314 | if (fdset_isempty(fds)) | |
315 | log_debug("No file descriptors passed"); | |
316 | else { | |
317 | int fd; | |
318 | ||
319 | FDSET_FOREACH(fd, fds) { | |
320 | _cleanup_free_ char *fn = NULL; | |
321 | ||
322 | r = fd_get_path(fd, &fn); | |
323 | if (r < 0) | |
e2341b6b DT |
324 | log_debug_errno(r, "Received serialized fd %i %s %m", |
325 | fd, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT)); | |
a01ba4b2 | 326 | else |
e2341b6b DT |
327 | log_debug("Received serialized fd %i %s %s", |
328 | fd, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), strna(fn)); | |
a01ba4b2 ZJS |
329 | } |
330 | } | |
331 | } | |
332 | ||
333 | log_debug("Deserializing state..."); | |
334 | ||
335 | /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have | |
336 | * increased it to non-zero, which is why we just increase it by one here and down again at the end of this | |
337 | * call. */ | |
338 | _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m); | |
339 | ||
340 | for (;;) { | |
0df7d525 LP |
341 | _cleanup_free_ char *l = NULL; |
342 | const char *val; | |
a01ba4b2 | 343 | |
0df7d525 | 344 | r = deserialize_read_line(f, &l); |
a01ba4b2 | 345 | if (r < 0) |
0df7d525 LP |
346 | return r; |
347 | if (r == 0) /* eof or end marker */ | |
a01ba4b2 ZJS |
348 | break; |
349 | ||
350 | if ((val = startswith(l, "current-job-id="))) { | |
351 | uint32_t id; | |
352 | ||
353 | if (safe_atou32(val, &id) < 0) | |
354 | log_notice("Failed to parse current job id value '%s', ignoring.", val); | |
355 | else | |
356 | m->current_job_id = MAX(m->current_job_id, id); | |
357 | ||
358 | } else if ((val = startswith(l, "n-installed-jobs="))) { | |
359 | uint32_t n; | |
360 | ||
361 | if (safe_atou32(val, &n) < 0) | |
362 | log_notice("Failed to parse installed jobs counter '%s', ignoring.", val); | |
363 | else | |
364 | m->n_installed_jobs += n; | |
365 | ||
366 | } else if ((val = startswith(l, "n-failed-jobs="))) { | |
367 | uint32_t n; | |
368 | ||
369 | if (safe_atou32(val, &n) < 0) | |
370 | log_notice("Failed to parse failed jobs counter '%s', ignoring.", val); | |
371 | else | |
372 | m->n_failed_jobs += n; | |
373 | ||
a01ba4b2 ZJS |
374 | } else if ((val = startswith(l, "ready-sent="))) { |
375 | int b; | |
376 | ||
377 | b = parse_boolean(val); | |
378 | if (b < 0) | |
379 | log_notice("Failed to parse ready-sent flag '%s', ignoring.", val); | |
380 | else | |
381 | m->ready_sent = m->ready_sent || b; | |
382 | ||
383 | } else if ((val = startswith(l, "taint-logged="))) { | |
384 | int b; | |
385 | ||
386 | b = parse_boolean(val); | |
387 | if (b < 0) | |
388 | log_notice("Failed to parse taint-logged flag '%s', ignoring.", val); | |
389 | else | |
390 | m->taint_logged = m->taint_logged || b; | |
391 | ||
392 | } else if ((val = startswith(l, "service-watchdogs="))) { | |
393 | int b; | |
394 | ||
395 | b = parse_boolean(val); | |
396 | if (b < 0) | |
397 | log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val); | |
398 | else | |
399 | m->service_watchdogs = b; | |
400 | ||
a01ba4b2 ZJS |
401 | } else if ((val = startswith(l, "show-status-overridden="))) { |
402 | ShowStatus s; | |
403 | ||
404 | s = show_status_from_string(val); | |
405 | if (s < 0) | |
406 | log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val); | |
407 | else | |
408 | manager_override_show_status(m, s, "deserialize"); | |
409 | ||
410 | } else if ((val = startswith(l, "log-level-override="))) { | |
411 | int level; | |
412 | ||
413 | level = log_level_from_string(val); | |
414 | if (level < 0) | |
415 | log_notice("Failed to parse log-level-override value '%s', ignoring.", val); | |
416 | else | |
417 | manager_override_log_level(m, level); | |
418 | ||
419 | } else if ((val = startswith(l, "log-target-override="))) { | |
420 | LogTarget target; | |
421 | ||
422 | target = log_target_from_string(val); | |
423 | if (target < 0) | |
424 | log_notice("Failed to parse log-target-override value '%s', ignoring.", val); | |
425 | else | |
426 | manager_override_log_target(m, target); | |
427 | ||
428 | } else if ((val = startswith(l, "runtime-watchdog-overridden="))) { | |
429 | usec_t t; | |
430 | ||
431 | if (deserialize_usec(val, &t) < 0) | |
432 | log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val); | |
433 | else | |
434 | manager_override_watchdog(m, WATCHDOG_RUNTIME, t); | |
435 | ||
436 | } else if ((val = startswith(l, "reboot-watchdog-overridden="))) { | |
437 | usec_t t; | |
438 | ||
439 | if (deserialize_usec(val, &t) < 0) | |
440 | log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val); | |
441 | else | |
442 | manager_override_watchdog(m, WATCHDOG_REBOOT, t); | |
443 | ||
444 | } else if ((val = startswith(l, "kexec-watchdog-overridden="))) { | |
445 | usec_t t; | |
446 | ||
447 | if (deserialize_usec(val, &t) < 0) | |
448 | log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val); | |
449 | else | |
450 | manager_override_watchdog(m, WATCHDOG_KEXEC, t); | |
451 | ||
5717062e CK |
452 | } else if ((val = startswith(l, "pretimeout-watchdog-overridden="))) { |
453 | usec_t t; | |
454 | ||
455 | if (deserialize_usec(val, &t) < 0) | |
456 | log_notice("Failed to parse pretimeout-watchdog-overridden value '%s', ignoring.", val); | |
457 | else | |
458 | manager_override_watchdog(m, WATCHDOG_PRETIMEOUT, t); | |
459 | ||
aff3a9e1 LB |
460 | } else if ((val = startswith(l, "pretimeout-watchdog-governor-overridden="))) { |
461 | r = free_and_strdup(&m->watchdog_pretimeout_governor_overridden, val); | |
462 | if (r < 0) | |
463 | return r; | |
464 | ||
a01ba4b2 ZJS |
465 | } else if (startswith(l, "env=")) { |
466 | r = deserialize_environment(l + 4, &m->client_environment); | |
467 | if (r < 0) | |
468 | log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l); | |
469 | ||
470 | } else if ((val = startswith(l, "notify-fd="))) { | |
471 | int fd; | |
472 | ||
e652663a | 473 | if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd)) |
a01ba4b2 ZJS |
474 | log_notice("Failed to parse notify fd, ignoring: \"%s\"", val); |
475 | else { | |
476 | m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source); | |
477 | safe_close(m->notify_fd); | |
478 | m->notify_fd = fdset_remove(fds, fd); | |
479 | } | |
480 | ||
481 | } else if ((val = startswith(l, "notify-socket="))) { | |
482 | r = free_and_strdup(&m->notify_socket, val); | |
483 | if (r < 0) | |
484 | return r; | |
485 | ||
486 | } else if ((val = startswith(l, "cgroups-agent-fd="))) { | |
487 | int fd; | |
488 | ||
e652663a | 489 | if ((fd = parse_fd(val)) < 0 || !fdset_contains(fds, fd)) |
a01ba4b2 ZJS |
490 | log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val); |
491 | else { | |
492 | m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source); | |
493 | safe_close(m->cgroups_agent_fd); | |
494 | m->cgroups_agent_fd = fdset_remove(fds, fd); | |
495 | } | |
496 | ||
497 | } else if ((val = startswith(l, "user-lookup="))) { | |
498 | int fd0, fd1; | |
499 | ||
500 | if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1)) | |
501 | log_notice("Failed to parse user lookup fd, ignoring: %s", val); | |
502 | else { | |
503 | m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source); | |
504 | safe_close_pair(m->user_lookup_fds); | |
505 | m->user_lookup_fds[0] = fdset_remove(fds, fd0); | |
506 | m->user_lookup_fds[1] = fdset_remove(fds, fd1); | |
507 | } | |
508 | ||
509 | } else if ((val = startswith(l, "dynamic-user="))) | |
510 | dynamic_user_deserialize_one(m, val, fds); | |
511 | else if ((val = startswith(l, "destroy-ipc-uid="))) | |
512 | manager_deserialize_uid_refs_one(m, val); | |
513 | else if ((val = startswith(l, "destroy-ipc-gid="))) | |
514 | manager_deserialize_gid_refs_one(m, val); | |
515 | else if ((val = startswith(l, "exec-runtime="))) | |
e76506b7 | 516 | (void) exec_shared_runtime_deserialize_one(m, val, fds); |
a01ba4b2 ZJS |
517 | else if ((val = startswith(l, "subscribed="))) { |
518 | ||
519 | if (strv_extend(&m->deserialized_subscribed, val) < 0) | |
520 | return -ENOMEM; | |
008798e9 AZ |
521 | } else if ((val = startswith(l, "varlink-server-socket-address="))) { |
522 | if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) { | |
523 | _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL; | |
524 | ||
525 | r = manager_setup_varlink_server(m, &s); | |
526 | if (r < 0) { | |
527 | log_warning_errno(r, "Failed to setup varlink server, ignoring: %m"); | |
528 | continue; | |
529 | } | |
530 | ||
531 | r = varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL); | |
532 | if (r < 0) { | |
533 | log_warning_errno(r, "Failed to attach varlink connection to event loop, ignoring: %m"); | |
534 | continue; | |
535 | } | |
536 | ||
537 | m->varlink_server = TAKE_PTR(s); | |
538 | deserialize_varlink_sockets = true; | |
539 | } | |
a01ba4b2 | 540 | |
8c35a977 | 541 | /* To avoid unnecessary deserialization (i.e. during reload vs. reexec) we only deserialize |
008798e9 AZ |
542 | * the FDs if we had to create a new m->varlink_server. The deserialize_varlink_sockets flag |
543 | * is initialized outside of the loop, is flipped after the VarlinkServer is setup, and | |
544 | * remains set until all serialized contents are handled. */ | |
545 | if (deserialize_varlink_sockets) | |
546 | (void) varlink_server_deserialize_one(m->varlink_server, val, fds); | |
d9365956 LB |
547 | } else if ((val = startswith(l, "dump-ratelimit="))) { |
548 | usec_t begin, interval; | |
549 | unsigned num, burst; | |
550 | ||
551 | if (sscanf(val, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4) | |
552 | log_notice("Failed to parse dump ratelimit, ignoring: %s", val); | |
553 | else { | |
554 | /* If we changed the values across versions, flush the counter */ | |
555 | if (interval != m->dump_ratelimit.interval || burst != m->dump_ratelimit.burst) | |
556 | m->dump_ratelimit.num = 0; | |
557 | else | |
558 | m->dump_ratelimit.num = num; | |
559 | m->dump_ratelimit.begin = begin; | |
560 | } | |
561 | ||
a01ba4b2 ZJS |
562 | } else { |
563 | ManagerTimestamp q; | |
564 | ||
565 | for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { | |
566 | val = startswith(l, manager_timestamp_to_string(q)); | |
567 | if (!val) | |
568 | continue; | |
569 | ||
570 | val = startswith(val, "-timestamp="); | |
571 | if (val) | |
572 | break; | |
573 | } | |
574 | ||
575 | if (q < _MANAGER_TIMESTAMP_MAX) /* found it */ | |
576 | (void) deserialize_dual_timestamp(val, m->timestamps + q); | |
7870de03 | 577 | else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=")) /* ignore deprecated values */ |
a01ba4b2 ZJS |
578 | log_notice("Unknown serialization item '%s', ignoring.", l); |
579 | } | |
580 | } | |
581 | ||
582 | return manager_deserialize_units(m, f, fds); | |
583 | } |