]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/device.c
strv: make iterator in STRV_FOREACH() declaread in the loop
[thirdparty/systemd.git] / src / core / device.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
a7334b09 2
25ac040b 3#include <errno.h>
f94ea366 4#include <sys/epoll.h>
25ac040b 5
ad172d19
LP
6#include "sd-messages.h"
7
b5efdb8a 8#include "alloc-util.h"
88116909 9#include "bus-error.h"
4139c1b2 10#include "dbus-device.h"
6fcbec6f 11#include "dbus-unit.h"
4366e598 12#include "device-util.h"
6bedfcbb 13#include "device.h"
07630cea 14#include "log.h"
6bedfcbb 15#include "parse-util.h"
9eb977db 16#include "path-util.h"
ad172d19 17#include "ratelimit.h"
d68c645b 18#include "serialize.h"
8fcde012 19#include "stat-util.h"
07630cea
LP
20#include "string-util.h"
21#include "swap.h"
2efa43dc 22#include "udev-util.h"
07630cea 23#include "unit-name.h"
9670d583 24#include "unit.h"
5cb5a6ff 25
f50e0a01
LP
26static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
27 [DEVICE_DEAD] = UNIT_INACTIVE,
628c89cc
LP
28 [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
29 [DEVICE_PLUGGED] = UNIT_ACTIVE,
f50e0a01
LP
30};
31
d0955f00 32static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata);
66f3fdbb 33static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask);
718db961 34
8fe914ec 35static void device_unset_sysfs(Device *d) {
f1421cc6 36 Hashmap *devices;
8fe914ec
LP
37 Device *first;
38
39 assert(d);
40
a7f241db
LP
41 if (!d->sysfs)
42 return;
43
44 /* Remove this unit from the chain of devices which share the
45 * same sysfs path. */
f1421cc6
LP
46 devices = UNIT(d)->manager->devices_by_sysfs;
47 first = hashmap_get(devices, d->sysfs);
71fda00f 48 LIST_REMOVE(same_sysfs, first, d);
8fe914ec 49
a7f241db 50 if (first)
f1421cc6 51 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
a7f241db 52 else
f1421cc6 53 hashmap_remove(devices, d->sysfs);
a7f241db 54
a1e58e8e 55 d->sysfs = mfree(d->sysfs);
8fe914ec
LP
56}
57
628c89cc 58static int device_set_sysfs(Device *d, const char *sysfs) {
ccd419f0 59 _cleanup_free_ char *copy = NULL;
628c89cc 60 Device *first;
628c89cc
LP
61 int r;
62
63 assert(d);
64
65 if (streq_ptr(d->sysfs, sysfs))
66 return 0;
67
548f6937 68 r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &path_hash_ops);
628c89cc
LP
69 if (r < 0)
70 return r;
71
72 copy = strdup(sysfs);
73 if (!copy)
74 return -ENOMEM;
75
76 device_unset_sysfs(d);
77
78 first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
79 LIST_PREPEND(same_sysfs, first, d);
80
81 r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
82 if (r < 0) {
83 LIST_REMOVE(same_sysfs, first, d);
628c89cc
LP
84 return r;
85 }
86
ccd419f0 87 d->sysfs = TAKE_PTR(copy);
7c4d1394
MS
88 unit_add_to_dbus_queue(UNIT(d));
89
628c89cc
LP
90 return 0;
91}
92
faf919f1
LP
93static void device_init(Unit *u) {
94 Device *d = DEVICE(u);
95
96 assert(d);
1124fe6f 97 assert(UNIT(d)->load_state == UNIT_STUB);
faf919f1 98
8fe914ec
LP
99 /* In contrast to all other unit types we timeout jobs waiting
100 * for devices by default. This is because they otherwise wait
35b8ca3a 101 * indefinitely for plugged in devices, something which cannot
8fe914ec
LP
102 * happen for the other units since their operations time out
103 * anyway. */
d9732d78 104 u->job_running_timeout = u->manager->default_timeout_start_usec;
c8f4d764 105
f1421cc6 106 u->ignore_on_isolate = true;
66f3fdbb
LP
107
108 d->deserialized_state = _DEVICE_STATE_INVALID;
faf919f1
LP
109}
110
87f0e418
LP
111static void device_done(Unit *u) {
112 Device *d = DEVICE(u);
034c6ed7
LP
113
114 assert(d);
e537352b 115
8fe914ec 116 device_unset_sysfs(d);
88116909 117 d->wants_property = strv_free(d->wants_property);
e537352b
LP
118}
119
1d4c6f5b
ZJS
120static int device_load(Unit *u) {
121 int r;
122
c3620770 123 r = unit_load_fragment_and_dropin(u, false);
1d4c6f5b
ZJS
124 if (r < 0)
125 return r;
126
127 if (!u->description) {
e41db484
LP
128 /* Generate a description based on the path, to be used until the device is initialized
129 properly */
1d4c6f5b
ZJS
130 r = unit_name_to_path(u->id, &u->description);
131 if (r < 0)
132 log_unit_debug_errno(u, r, "Failed to unescape name: %m");
133 }
134
135 return 0;
136}
137
f50e0a01
LP
138static void device_set_state(Device *d, DeviceState state) {
139 DeviceState old_state;
140 assert(d);
5cb5a6ff 141
6fcbec6f
LP
142 if (d->state != state)
143 bus_unit_send_pending_change_signal(UNIT(d), false);
144
f50e0a01
LP
145 old_state = d->state;
146 d->state = state;
5cb5a6ff 147
244f8055
LP
148 if (state == DEVICE_DEAD)
149 device_unset_sysfs(d);
150
e537352b 151 if (state != old_state)
f2341e0a 152 log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
f50e0a01 153
2ad2e41a 154 unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], 0);
f50e0a01
LP
155}
156
be847e82 157static int device_coldplug(Unit *u) {
f50e0a01
LP
158 Device *d = DEVICE(u);
159
160 assert(d);
161 assert(d->state == DEVICE_DEAD);
162
66f3fdbb 163 /* First, let's put the deserialized state and found mask into effect, if we have it. */
918e6f1c 164
66f3fdbb
LP
165 if (d->deserialized_state < 0 ||
166 (d->deserialized_state == d->state &&
167 d->deserialized_found == d->found))
168 return 0;
f50e0a01 169
66f3fdbb
LP
170 d->found = d->deserialized_found;
171 device_set_state(d, d->deserialized_state);
f50e0a01
LP
172 return 0;
173}
174
66f3fdbb
LP
175static void device_catchup(Unit *u) {
176 Device *d = DEVICE(u);
177
178 assert(d);
179
180 /* Second, let's update the state with the enumerated state if it's different */
181 if (d->enumerated_found == d->found)
182 return;
183
184 device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK);
185}
186
75d0aba4
YW
187static const struct {
188 DeviceFound flag;
189 const char *name;
190} device_found_map[] = {
66f3fdbb
LP
191 { DEVICE_FOUND_UDEV, "found-udev" },
192 { DEVICE_FOUND_MOUNT, "found-mount" },
193 { DEVICE_FOUND_SWAP, "found-swap" },
75d0aba4
YW
194};
195
196static int device_found_to_string_many(DeviceFound flags, char **ret) {
197 _cleanup_free_ char *s = NULL;
75d0aba4
YW
198
199 assert(ret);
200
fe96c0f8 201 for (size_t i = 0; i < ELEMENTSOF(device_found_map); i++) {
6e0f878e 202 if (!FLAGS_SET(flags, device_found_map[i].flag))
75d0aba4
YW
203 continue;
204
c2bc710b 205 if (!strextend_with_separator(&s, ",", device_found_map[i].name))
75d0aba4
YW
206 return -ENOMEM;
207 }
208
209 *ret = TAKE_PTR(s);
210
211 return 0;
212}
213
214static int device_found_from_string_many(const char *name, DeviceFound *ret) {
215 DeviceFound flags = 0;
216 int r;
217
218 assert(ret);
219
220 for (;;) {
221 _cleanup_free_ char *word = NULL;
222 DeviceFound f = 0;
223 unsigned i;
224
225 r = extract_first_word(&name, &word, ",", 0);
226 if (r < 0)
227 return r;
228 if (r == 0)
229 break;
230
69ce73d1 231 for (i = 0; i < ELEMENTSOF(device_found_map); i++)
75d0aba4
YW
232 if (streq(word, device_found_map[i].name)) {
233 f = device_found_map[i].flag;
234 break;
235 }
236
237 if (f == 0)
238 return -EINVAL;
239
240 flags |= f;
241 }
242
243 *ret = flags;
244 return 0;
245}
246
f6200941 247static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
75d0aba4 248 _cleanup_free_ char *s = NULL;
f6200941
LP
249 Device *d = DEVICE(u);
250
c73f413d 251 assert(d);
f6200941
LP
252 assert(u);
253 assert(f);
254 assert(fds);
255
d68c645b 256 (void) serialize_item(f, "state", device_state_to_string(d->state));
75d0aba4 257
43ba7d71 258 if (device_found_to_string_many(d->found, &s) >= 0)
d68c645b 259 (void) serialize_item(f, "found", s);
0108f6ec
DM
260
261 return 0;
f6200941
LP
262}
263
264static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
265 Device *d = DEVICE(u);
75d0aba4 266 int r;
f6200941 267
c73f413d 268 assert(d);
f6200941
LP
269 assert(u);
270 assert(key);
271 assert(value);
272 assert(fds);
273
274 if (streq(key, "state")) {
275 DeviceState state;
276
277 state = device_state_from_string(value);
278 if (state < 0)
8bb2c8c9 279 log_unit_debug(u, "Failed to parse state value, ignoring: %s", value);
f6200941
LP
280 else
281 d->deserialized_state = state;
918e6f1c
FB
282
283 } else if (streq(key, "found")) {
66f3fdbb 284 r = device_found_from_string_many(value, &d->deserialized_found);
75d0aba4 285 if (r < 0)
5e1ee764 286 log_unit_debug_errno(u, r, "Failed to parse found value '%s', ignoring: %m", value);
918e6f1c 287
f6200941 288 } else
f2341e0a 289 log_unit_debug(u, "Unknown serialization key: %s", key);
f6200941
LP
290
291 return 0;
292}
293
f50e0a01 294static void device_dump(Unit *u, FILE *f, const char *prefix) {
25ac040b 295 Device *d = DEVICE(u);
4d86c235 296 _cleanup_free_ char *s = NULL;
5cb5a6ff 297
25ac040b 298 assert(d);
5cb5a6ff 299
4d86c235
ZJS
300 (void) device_found_to_string_many(d->found, &s);
301
5cb5a6ff 302 fprintf(f,
25ac040b 303 "%sDevice State: %s\n"
4d86c235
ZJS
304 "%sSysfs Path: %s\n"
305 "%sFound: %s\n",
a16e1123 306 prefix, device_state_to_string(d->state),
4d86c235
ZJS
307 prefix, strna(d->sysfs),
308 prefix, strna(s));
88116909 309
de010b0b
YW
310 STRV_FOREACH(i, d->wants_property)
311 fprintf(f, "%sudev SYSTEMD_WANTS: %s\n",
312 prefix, *i);
f50e0a01
LP
313}
314
44a6b1b6 315_pure_ static UnitActiveState device_active_state(Unit *u) {
f50e0a01
LP
316 assert(u);
317
318 return state_translation_table[DEVICE(u)->state];
25ac040b
LP
319}
320
44a6b1b6 321_pure_ static const char *device_sub_state_to_string(Unit *u) {
10a94420
LP
322 assert(u);
323
a16e1123 324 return device_state_to_string(DEVICE(u)->state);
10a94420
LP
325}
326
4366e598 327static int device_update_description(Unit *u, sd_device *dev, const char *path) {
1d4c6f5b
ZJS
328 _cleanup_free_ char *j = NULL;
329 const char *model, *label, *desc;
628c89cc 330 int r;
965e5c5d
LP
331
332 assert(u);
965e5c5d
LP
333 assert(path);
334
1d4c6f5b
ZJS
335 desc = path;
336
337 if (dev &&
338 (sd_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE", &model) >= 0 ||
339 sd_device_get_property_value(dev, "ID_MODEL", &model) >= 0)) {
340 desc = model;
965e5c5d
LP
341
342 /* Try to concatenate the device model string with a label, if there is one */
4366e598
YW
343 if (sd_device_get_property_value(dev, "ID_FS_LABEL", &label) >= 0 ||
344 sd_device_get_property_value(dev, "ID_PART_ENTRY_NAME", &label) >= 0 ||
345 sd_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER", &label) >= 0) {
965e5c5d 346
1d4c6f5b 347 desc = j = strjoin(model, " ", label);
ea8ec43b
LP
348 if (!j)
349 return log_oom();
1d4c6f5b
ZJS
350 }
351 }
ea8ec43b 352
1d4c6f5b 353 r = unit_set_description(u, desc);
628c89cc 354 if (r < 0)
ea8ec43b 355 return log_unit_error_errno(u, r, "Failed to set device description: %m");
965e5c5d 356
ea8ec43b 357 return 0;
965e5c5d
LP
358}
359
4366e598 360static int device_add_udev_wants(Unit *u, sd_device *dev) {
88116909 361 _cleanup_strv_free_ char **added = NULL;
de040543 362 const char *wants, *property;
88116909 363 Device *d = DEVICE(u);
965e5c5d
LP
364 int r;
365
88116909 366 assert(d);
965e5c5d
LP
367 assert(dev);
368
463d0d15 369 property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
de040543 370
4366e598
YW
371 r = sd_device_get_property_value(dev, property, &wants);
372 if (r < 0)
de040543
LP
373 return 0;
374
375 for (;;) {
ceed8f0c 376 _cleanup_free_ char *word = NULL, *k = NULL;
965e5c5d 377
4ec85141 378 r = extract_first_word(&wants, &word, NULL, EXTRACT_UNQUOTE);
ceed8f0c 379 if (r == 0)
88116909 380 break;
ceed8f0c
ZJS
381 if (r == -ENOMEM)
382 return log_oom();
383 if (r < 0)
dcebc9ba 384 return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
965e5c5d 385
88116909 386 if (unit_name_is_valid(word, UNIT_NAME_TEMPLATE) && d->sysfs) {
dcebc9ba
LP
387 _cleanup_free_ char *escaped = NULL;
388
389 /* If the unit name is specified as template, then automatically fill in the sysfs path of the
390 * device as instance name, properly escaped. */
391
88116909 392 r = unit_name_path_escape(d->sysfs, &escaped);
dcebc9ba 393 if (r < 0)
88116909 394 return log_unit_error_errno(u, r, "Failed to escape %s: %m", d->sysfs);
dcebc9ba
LP
395
396 r = unit_name_replace_instance(word, escaped, &k);
397 if (r < 0)
398 return log_unit_error_errno(u, r, "Failed to build %s instance of template %s: %m", escaped, word);
399 } else {
400 /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */
401
37cbc1d5 402 r = unit_name_mangle(word, UNIT_NAME_MANGLE_WARN, &k);
dcebc9ba
LP
403 if (r < 0)
404 return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
405 }
965e5c5d 406
35d8c19a 407 r = unit_add_dependency_by_name(u, UNIT_WANTS, k, true, UNIT_DEPENDENCY_UDEV);
965e5c5d 408 if (r < 0)
de040543 409 return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
88116909
LP
410
411 r = strv_push(&added, k);
412 if (r < 0)
413 return log_oom();
414
415 k = NULL;
965e5c5d 416 }
88116909 417
de010b0b 418 if (d->state != DEVICE_DEAD)
88116909
LP
419 /* So here's a special hack, to compensate for the fact that the udev database's reload cycles are not
420 * synchronized with our own reload cycles: when we detect that the SYSTEMD_WANTS property of a device
421 * changes while the device unit is already up, let's manually trigger any new units listed in it not
5238e957 422 * seen before. This typically happens during the boot-time switch root transition, as udev devices
88116909
LP
423 * will generally already be up in the initrd, but SYSTEMD_WANTS properties get then added through udev
424 * rules only available on the host system, and thus only when the initial udev coldplug trigger runs.
425 *
426 * We do this only if the device has been up already when we parse this, as otherwise the usual
427 * dependency logic that is run from the dead → plugged transition will trigger these deps. */
88116909
LP
428 STRV_FOREACH(i, added) {
429 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
430
431 if (strv_contains(d->wants_property, *i)) /* Was this unit already listed before? */
432 continue;
433
50cbaba4 434 r = manager_add_job_by_name(u->manager, JOB_START, *i, JOB_FAIL, NULL, &error, NULL);
88116909
LP
435 if (r < 0)
436 log_unit_warning_errno(u, r, "Failed to enqueue SYSTEMD_WANTS= job, ignoring: %s", bus_error_message(&error, r));
437 }
88116909 438
8cc53fae 439 return strv_free_and_replace(d->wants_property, added);
965e5c5d
LP
440}
441
4366e598 442static bool device_is_bound_by_mounts(Device *d, sd_device *dev) {
ebc8968b 443 const char *bound_by;
40b1a32c 444 int r;
ebc8968b
FB
445
446 assert(d);
447 assert(dev);
448
4366e598 449 if (sd_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND", &bound_by) >= 0) {
40b1a32c
LP
450 r = parse_boolean(bound_by);
451 if (r < 0)
71f79b56 452 log_device_warning_errno(dev, r, "Failed to parse SYSTEMD_MOUNT_DEVICE_BOUND='%s' udev property, ignoring: %m", bound_by);
ebc8968b 453
40b1a32c
LP
454 d->bind_mounts = r > 0;
455 } else
456 d->bind_mounts = false;
457
458 return d->bind_mounts;
ebc8968b
FB
459}
460
86cdffd1 461static void device_upgrade_mount_deps(Unit *u) {
ebc8968b 462 Unit *other;
eef85c4a 463 void *v;
ebc8968b
FB
464 int r;
465
eef85c4a
LP
466 /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
467
15ed3c3a 468 HASHMAP_FOREACH_KEY(v, other, unit_get_dependencies(u, UNIT_REQUIRED_BY)) {
ebc8968b
FB
469 if (other->type != UNIT_MOUNT)
470 continue;
471
eef85c4a 472 r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
ebc8968b 473 if (r < 0)
86cdffd1 474 log_unit_warning_errno(u, r, "Failed to add BindsTo= dependency between device and mount unit, ignoring: %m");
ebc8968b 475 }
ebc8968b
FB
476}
477
4366e598 478static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool main) {
628c89cc 479 _cleanup_free_ char *e = NULL;
2005219f 480 const char *sysfs = NULL;
25ac040b 481 Unit *u = NULL;
25ac040b 482 bool delete;
965e5c5d 483 int r;
25ac040b
LP
484
485 assert(m);
965e5c5d 486 assert(path);
25ac040b 487
2005219f 488 if (dev) {
4366e598 489 r = sd_device_get_syspath(dev, &sysfs);
9951c8df
LP
490 if (r < 0)
491 return log_device_debug_errno(dev, r, "Couldn't get syspath from device, ignoring: %m");
2005219f 492 }
7f275a9f 493
7410616c 494 r = unit_name_from_path(path, ".device", &e);
ad172d19
LP
495 if (r < 0) {
496 /* Let's complain about overly long device names only at most once every 5s or so. This is
497 * something we should mention, since relevant devices are not manageable by systemd, but not
498 * flood the log about. */
499 static RateLimit rate_limit = {
500 .interval = 5 * USEC_PER_SEC,
501 .burst = 1,
502 };
503
504 /* If we cannot convert a device name to a unit name then let's ignore the device. So far,
505 * devices with such long names weren't really the kind you want to manage with systemd
506 * anyway, hence this shouldn't be a problem. */
507
508 if (r == -ENAMETOOLONG)
509 return log_struct_errno(
510 ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r,
511 "MESSAGE_ID=" SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE_STR,
512 "DEVICE=%s", path,
513 LOG_MESSAGE("Device path '%s' too long to fit into unit name, ignoring device.", path));
514
515 return log_struct_errno(
516 ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r,
517 "MESSAGE_ID=" SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE_STR,
518 "DEVICE=%s", path,
519 LOG_MESSAGE("Failed to generate valid unit name from device path '%s', ignoring device: %m", path));
520 }
628c89cc
LP
521
522 u = manager_get_unit(m, e);
38b9b72e 523 if (u) {
66f3fdbb
LP
524 /* The device unit can still be present even if the device was unplugged: a mount unit can reference it
525 * hence preventing the GC to have garbaged it. That's desired since the device unit may have a
526 * dependency on the mount unit which was added during the loading of the later. When the device is
527 * plugged the sysfs might not be initialized yet, as we serialize the device's state but do not
528 * serialize the sysfs path across reloads/reexecs. Hence, when coming back from a reload/restart we
529 * might have the state valid, but not the sysfs path. Hence, let's filter out conflicting devices, but
530 * let's accept devices in any state with no sysfs path set. */
531
532 if (DEVICE(u)->state == DEVICE_PLUGGED &&
533 DEVICE(u)->sysfs &&
534 sysfs &&
d85ff944
YW
535 !path_equal(DEVICE(u)->sysfs, sysfs))
536 return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EEXIST),
537 "Device %s appeared twice with different sysfs paths %s and %s, ignoring the latter.",
538 e, DEVICE(u)->sysfs, sysfs);
25ac040b 539
38b9b72e
LP
540 delete = false;
541
5238e957 542 /* Let's remove all dependencies generated due to udev properties. We'll re-add whatever is configured
38b9b72e
LP
543 * now below. */
544 unit_remove_dependencies(u, UNIT_DEPENDENCY_UDEV);
545 } else {
aab14b13
LP
546 delete = true;
547
a581e45a 548 r = unit_new_for_name(m, sizeof(Device), e, &u);
66f3fdbb 549 if (r < 0) {
71f79b56 550 log_device_error_errno(dev, r, "Failed to allocate device unit %s: %m", e);
25ac040b 551 goto fail;
66f3fdbb 552 }
25ac040b 553
ee6cb288 554 unit_add_to_load_queue(u);
38b9b72e 555 }
ee6cb288 556
66f3fdbb 557 /* If this was created via some dependency and has not actually been seen yet ->sysfs will not be
ee6cb288 558 * initialized. Hence initialize it if necessary. */
2005219f
MP
559 if (sysfs) {
560 r = device_set_sysfs(DEVICE(u), sysfs);
66f3fdbb 561 if (r < 0) {
71f79b56 562 log_unit_error_errno(u, r, "Failed to set sysfs path %s: %m", sysfs);
2005219f 563 goto fail;
66f3fdbb 564 }
ee6cb288 565
66f3fdbb 566 /* The additional systemd udev properties we only interpret for the main object */
2005219f
MP
567 if (main)
568 (void) device_add_udev_wants(u, dev);
569 }
25ac040b 570
1d4c6f5b
ZJS
571 (void) device_update_description(u, dev, path);
572
75a50eb0
LP
573 /* So the user wants the mount units to be bound to the device but a mount unit might has been seen
574 * by systemd before the device appears on its radar. In this case the device unit is partially
575 * initialized and includes the deps on the mount unit but at that time the "bind mounts" flag wasn't
576 * present. Fix this up now. */
40b1a32c 577 if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
ebc8968b 578 device_upgrade_mount_deps(u);
f94ea366 579
25ac040b
LP
580 return 0;
581
582fail:
c9d5c9c0 583 if (delete)
25ac040b 584 unit_free(u);
ee5f3479 585
25ac040b
LP
586 return r;
587}
588
75a50eb0 589static void device_process_new(Manager *m, sd_device *dev) {
f1421cc6 590 const char *sysfs, *dn, *alias;
4366e598 591 dev_t devnum;
003ac9d0 592 int r;
8fe914ec
LP
593
594 assert(m);
595
4366e598 596 if (sd_device_get_syspath(dev, &sysfs) < 0)
75a50eb0 597 return;
8fe914ec 598
75a50eb0
LP
599 /* Add the main unit named after the sysfs path. If this one fails, don't bother with the rest, as
600 * this one shall be the main device unit the others just follow. (Compare with how
601 * device_following() is implemented, see below, which looks for the sysfs device.) */
602 if (device_setup_unit(m, dev, sysfs, true) < 0)
603 return;
8fe914ec
LP
604
605 /* Add an additional unit for the device node */
4366e598 606 if (sd_device_get_devname(dev, &dn) >= 0)
628c89cc 607 (void) device_setup_unit(m, dev, dn, false);
8fe914ec
LP
608
609 /* Add additional units for all symlinks */
4366e598 610 if (sd_device_get_devnum(dev, &devnum) >= 0) {
8fe914ec
LP
611 const char *p;
612
4366e598
YW
613 FOREACH_DEVICE_DEVLINK(dev, p) {
614 struct stat st;
8fe914ec 615
4366e598
YW
616 if (PATH_STARTSWITH_SET(p, "/dev/block/", "/dev/char/"))
617 continue;
8fe914ec 618
75a50eb0
LP
619 /* Verify that the symlink in the FS actually belongs to this device. This is useful
620 * to deal with conflicting devices, e.g. when two disks want the same
621 * /dev/disk/by-label/xxx link because they have the same label. We want to make sure
622 * that the same device that won the symlink wins in systemd, so we check the device
623 * node major/minor */
4366e598
YW
624 if (stat(p, &st) >= 0 &&
625 ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
626 st.st_rdev != devnum))
5845b46b
LP
627 continue;
628
4366e598
YW
629 (void) device_setup_unit(m, dev, p, false);
630 }
8fe914ec
LP
631 }
632
4366e598
YW
633 /* Add additional units for all explicitly configured aliases */
634 if (sd_device_get_property_value(dev, "SYSTEMD_ALIAS", &alias) < 0)
75a50eb0 635 return;
4366e598 636
ceed8f0c 637 for (;;) {
8fb242ab 638 _cleanup_free_ char *word = NULL;
8fe914ec 639
4ec85141 640 r = extract_first_word(&alias, &word, NULL, EXTRACT_UNQUOTE);
ceed8f0c 641 if (r == 0)
8bb2c8c9 642 break;
ceed8f0c 643 if (r == -ENOMEM)
75a50eb0 644 return (void) log_oom();
ceed8f0c 645 if (r < 0)
75a50eb0 646 return (void) log_device_warning_errno(dev, r, "Failed to parse SYSTEMD_ALIAS property, ignoring: %m");
f1421cc6 647
a7f8be01 648 if (!path_is_absolute(word))
71f79b56 649 log_device_warning(dev, "SYSTEMD_ALIAS is not an absolute path, ignoring: %s", word);
a7f8be01 650 else if (!path_is_normalized(word))
71f79b56 651 log_device_warning(dev, "SYSTEMD_ALIAS is not a normalized path, ignoring: %s", word);
a7f8be01
LP
652 else
653 (void) device_setup_unit(m, dev, word, false);
8fe914ec 654 }
8fe914ec
LP
655}
656
66f3fdbb 657static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
628c89cc
LP
658 assert(d);
659
4b58153d 660 /* Didn't exist before, but does now? if so, generate a new invocation ID for it */
66f3fdbb 661 if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
4b58153d
LP
662 (void) unit_acquire_invocation_id(UNIT(d));
663
66f3fdbb
LP
664 if (FLAGS_SET(now, DEVICE_FOUND_UDEV))
665 /* When the device is known to udev we consider it plugged. */
f6200941 666 device_set_state(d, DEVICE_PLUGGED);
66f3fdbb
LP
667 else if (now != DEVICE_NOT_FOUND && !FLAGS_SET(previous, DEVICE_FOUND_UDEV))
668 /* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the
f6200941
LP
669 * kernel knows it now, and udev might soon too. */
670 device_set_state(d, DEVICE_TENTATIVE);
244f8055 671 else
66f3fdbb
LP
672 /* If nobody sees the device, or if the device was previously seen by udev and now is only referenced
673 * from the kernel, then we consider the device is gone, the kernel just hasn't noticed it yet. */
f6200941 674 device_set_state(d, DEVICE_DEAD);
628c89cc
LP
675}
676
66f3fdbb 677static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
c6e892bc
YW
678 Manager *m;
679
66f3fdbb
LP
680 assert(d);
681
c6e892bc
YW
682 m = UNIT(d)->manager;
683
684 if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) {
66f3fdbb
LP
685 DeviceFound n, previous;
686
687 /* When we are already running, then apply the new mask right-away, and trigger state changes
688 * right-away */
689
690 n = (d->found & ~mask) | (found & mask);
691 if (n == d->found)
692 return;
693
694 previous = d->found;
695 d->found = n;
696
697 device_found_changed(d, previous, n);
698 } else
699 /* We aren't running yet, let's apply the new mask to the shadow variable instead, which we'll apply as
700 * soon as we catch-up with the state. */
701 d->enumerated_found = (d->enumerated_found & ~mask) | (found & mask);
702}
703
485ae697 704static void device_update_found_by_sysfs(Manager *m, const char *sysfs, DeviceFound found, DeviceFound mask) {
03677889 705 Device *l;
25ac040b
LP
706
707 assert(m);
628c89cc 708 assert(sysfs);
25ac040b 709
485ae697
LP
710 if (mask == 0)
711 return;
25ac040b 712
f1421cc6 713 l = hashmap_get(m->devices_by_sysfs, sysfs);
80a226b2 714 LIST_FOREACH(same_sysfs, d, l)
485ae697 715 device_update_found_one(d, found, mask);
25ac040b
LP
716}
717
68695ce4 718static void device_update_found_by_name(Manager *m, const char *path, DeviceFound found, DeviceFound mask) {
628c89cc
LP
719 _cleanup_free_ char *e = NULL;
720 Unit *u;
7410616c 721 int r;
f94ea366
LP
722
723 assert(m);
628c89cc 724 assert(path);
f94ea366 725
485ae697 726 if (mask == 0)
68695ce4 727 return;
f94ea366 728
7410616c
LP
729 r = unit_name_from_path(path, ".device", &e);
730 if (r < 0)
68695ce4 731 return (void) log_debug_errno(r, "Failed to generate unit name from device path, ignoring: %m");
f94ea366 732
628c89cc
LP
733 u = manager_get_unit(m, e);
734 if (!u)
68695ce4 735 return;
628c89cc 736
485ae697 737 device_update_found_one(DEVICE(u), found, mask);
f94ea366
LP
738}
739
4366e598 740static bool device_is_ready(sd_device *dev) {
f1421cc6
LP
741 const char *ready;
742
743 assert(dev);
744
2efa43dc
YW
745 if (device_is_renaming(dev) > 0)
746 return false;
747
242c1c07
LP
748 /* Is it really tagged as 'systemd' right now? */
749 if (sd_device_has_current_tag(dev, "systemd") <= 0)
750 return false;
751
4366e598 752 if (sd_device_get_property_value(dev, "SYSTEMD_READY", &ready) < 0)
f1421cc6
LP
753 return true;
754
755 return parse_boolean(ready) != 0;
756}
757
a7f241db
LP
758static Unit *device_following(Unit *u) {
759 Device *d = DEVICE(u);
03677889 760 Device *first = NULL;
a7f241db
LP
761
762 assert(d);
763
ac155bb8 764 if (startswith(u->id, "sys-"))
a7f241db
LP
765 return NULL;
766
767 /* Make everybody follow the unit that's named after the sysfs path */
bd335c96 768 LIST_FOREACH(same_sysfs, other, d->same_sysfs_next)
1124fe6f 769 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
770 return UNIT(other);
771
bd335c96 772 LIST_FOREACH_BACKWARDS(same_sysfs, other, d->same_sysfs_prev) {
1124fe6f 773 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
774 return UNIT(other);
775
776 first = other;
777 }
778
779 return UNIT(first);
780}
781
f1421cc6 782static int device_following_set(Unit *u, Set **_set) {
03677889 783 Device *d = DEVICE(u);
af4fa99d 784 _cleanup_set_free_ Set *set = NULL;
6210e7fc
LP
785 int r;
786
787 assert(d);
f1421cc6 788 assert(_set);
6210e7fc 789
f1421cc6
LP
790 if (LIST_JUST_US(same_sysfs, d)) {
791 *_set = NULL;
6210e7fc
LP
792 return 0;
793 }
794
d5099efc 795 set = set_new(NULL);
f1421cc6 796 if (!set)
6210e7fc
LP
797 return -ENOMEM;
798
bd335c96 799 LIST_FOREACH(same_sysfs, other, d->same_sysfs_next) {
f1421cc6
LP
800 r = set_put(set, other);
801 if (r < 0)
95f14a3e 802 return r;
f1421cc6 803 }
6210e7fc 804
bd335c96 805 LIST_FOREACH_BACKWARDS(same_sysfs, other, d->same_sysfs_prev) {
f1421cc6
LP
806 r = set_put(set, other);
807 if (r < 0)
95f14a3e 808 return r;
f1421cc6 809 }
6210e7fc 810
95f14a3e 811 *_set = TAKE_PTR(set);
6210e7fc 812 return 1;
6210e7fc
LP
813}
814
25ac040b
LP
815static void device_shutdown(Manager *m) {
816 assert(m);
817
d0955f00 818 m->device_monitor = sd_device_monitor_unref(m->device_monitor);
525d3cc7 819 m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
25ac040b
LP
820}
821
ba64af90 822static void device_enumerate(Manager *m) {
4366e598
YW
823 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
824 sd_device *dev;
718db961 825 int r;
25ac040b
LP
826
827 assert(m);
828
d0955f00
YW
829 if (!m->device_monitor) {
830 r = sd_device_monitor_new(&m->device_monitor);
831 if (r < 0) {
832 log_error_errno(r, "Failed to allocate device monitor: %m");
a16e1123
LP
833 goto fail;
834 }
f94ea366 835
47ae6e67
LP
836 /* This will fail if we are unprivileged, but that
837 * should not matter much, as user instances won't run
838 * during boot. */
d0955f00 839 (void) sd_device_monitor_set_receive_buffer_size(m->device_monitor, 128*1024*1024);
99448c1f 840
d0955f00 841 r = sd_device_monitor_filter_add_match_tag(m->device_monitor, "systemd");
ba64af90
LP
842 if (r < 0) {
843 log_error_errno(r, "Failed to add udev tag match: %m");
e1ce2c27 844 goto fail;
ba64af90 845 }
e1ce2c27 846
deb2b734 847 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
ba64af90 848 if (r < 0) {
d0955f00 849 log_error_errno(r, "Failed to attach event to device monitor: %m");
a16e1123 850 goto fail;
ba64af90 851 }
f94ea366 852
deb2b734 853 r = sd_device_monitor_start(m->device_monitor, device_dispatch_io, m);
ba64af90 854 if (r < 0) {
d0955f00 855 log_error_errno(r, "Failed to start device monitor: %m");
718db961 856 goto fail;
ba64af90 857 }
a16e1123 858 }
f94ea366 859
4366e598 860 r = sd_device_enumerator_new(&e);
ba64af90 861 if (r < 0) {
9b674e25 862 log_error_errno(r, "Failed to allocate device enumerator: %m");
e1ce2c27 863 goto fail;
ba64af90 864 }
25ac040b 865
4366e598 866 r = sd_device_enumerator_add_match_tag(e, "systemd");
ba64af90 867 if (r < 0) {
4366e598 868 log_error_errno(r, "Failed to set tag for device enumeration: %m");
e1202047 869 goto fail;
ba64af90 870 }
e1202047 871
8437c059 872 FOREACH_DEVICE(e, dev) {
628c89cc
LP
873 const char *sysfs;
874
628c89cc
LP
875 if (!device_is_ready(dev))
876 continue;
877
75a50eb0 878 device_process_new(m, dev);
4366e598
YW
879
880 if (sd_device_get_syspath(dev, &sysfs) < 0)
881 continue;
882
66f3fdbb 883 device_update_found_by_sysfs(m, sysfs, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV);
628c89cc 884 }
25ac040b 885
ba64af90 886 return;
25ac040b
LP
887
888fail:
25ac040b 889 device_shutdown(m);
5cb5a6ff
LP
890}
891
87934b36 892static void device_propagate_reload_by_sysfs(Manager *m, const char *sysfs) {
03677889 893 Device *l;
87934b36
LP
894 int r;
895
896 assert(m);
897 assert(sysfs);
898
899 l = hashmap_get(m->devices_by_sysfs, sysfs);
80a226b2 900 LIST_FOREACH(same_sysfs, d, l) {
87934b36
LP
901 if (d->state == DEVICE_DEAD)
902 continue;
903
904 r = manager_propagate_reload(m, UNIT(d), JOB_REPLACE, NULL);
905 if (r < 0)
906 log_warning_errno(r, "Failed to propagate reload, ignoring: %m");
907 }
908}
909
c8ad151a 910static void device_remove_old_on_move(Manager *m, sd_device *dev) {
87bc687a
YW
911 _cleanup_free_ char *syspath_old = NULL, *e = NULL;
912 const char *devpath_old;
913 int r;
914
915 r = sd_device_get_property_value(dev, "DEVPATH_OLD", &devpath_old);
c8ad151a
LP
916 if (r < 0)
917 return (void) log_device_debug_errno(dev, r, "Failed to get DEVPATH_OLD= property on 'move' uevent, ignoring: %m");
87bc687a
YW
918
919 syspath_old = path_join("/sys", devpath_old);
920 if (!syspath_old)
c8ad151a 921 return (void) log_oom();
87bc687a
YW
922
923 r = unit_name_from_path(syspath_old, ".device", &e);
924 if (r < 0)
4d94c74f 925 return (void) log_device_debug_errno(dev, r, "Failed to generate unit name from old device path, ignoring: %m");
87bc687a
YW
926
927 device_update_found_by_sysfs(m, syspath_old, 0, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP);
87bc687a
YW
928}
929
d0955f00 930static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
a1130022 931 sd_device_action_t action;
718db961 932 Manager *m = userdata;
a7395c86 933 const char *sysfs;
718db961 934 int r;
f94ea366
LP
935
936 assert(m);
d0955f00 937 assert(dev);
f94ea366 938
4366e598
YW
939 r = sd_device_get_syspath(dev, &sysfs);
940 if (r < 0) {
71f79b56 941 log_device_error_errno(dev, r, "Failed to get device sys path: %m");
628c89cc
LP
942 return 0;
943 }
944
a1130022 945 r = sd_device_get_action(dev, &action);
4366e598 946 if (r < 0) {
a7395c86 947 log_device_error_errno(dev, r, "Failed to get udev action: %m");
718db961 948 return 0;
f94ea366
LP
949 }
950
a1130022 951 if (!IN_SET(action, SD_DEVICE_ADD, SD_DEVICE_REMOVE, SD_DEVICE_MOVE))
87934b36 952 device_propagate_reload_by_sysfs(m, sysfs);
f332611a 953
a1130022 954 if (action == SD_DEVICE_MOVE)
c8ad151a 955 device_remove_old_on_move(m, dev);
87bc687a 956
ae6ad21e
LP
957 /* A change event can signal that a device is becoming ready, in particular if the device is using
958 * the SYSTEMD_READY logic in udev so we need to reach the else block of the following if, even for
959 * change events */
a1130022 960 if (action == SD_DEVICE_REMOVE) {
628c89cc 961 r = swap_process_device_remove(m, dev);
9670d583 962 if (r < 0)
71f79b56 963 log_device_warning_errno(dev, r, "Failed to process swap device remove event, ignoring: %m");
9670d583 964
ae6ad21e
LP
965 /* If we get notified that a device was removed by udev, then it's completely gone, hence
966 * unset all found bits */
485ae697 967 device_update_found_by_sysfs(m, sysfs, 0, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP);
f1421cc6 968
628c89cc
LP
969 } else if (device_is_ready(dev)) {
970
75a50eb0 971 device_process_new(m, dev);
628c89cc
LP
972
973 r = swap_process_device_new(m, dev);
9670d583 974 if (r < 0)
71f79b56 975 log_device_warning_errno(dev, r, "Failed to process swap device new event, ignoring: %m");
9670d583 976
f1421cc6
LP
977 manager_dispatch_load_queue(m);
978
628c89cc 979 /* The device is found now, set the udev found bit */
485ae697 980 device_update_found_by_sysfs(m, sysfs, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV);
ae6ad21e
LP
981 } else
982 /* The device is nominally around, but not ready for us. Hence unset the udev bit, but leave
983 * the rest around. */
485ae697 984 device_update_found_by_sysfs(m, sysfs, 0, DEVICE_FOUND_UDEV);
f94ea366 985
718db961 986 return 0;
f94ea366
LP
987}
988
1c2e9646 989static bool device_supported(void) {
0faacd47 990 static int read_only = -1;
0faacd47
LP
991
992 /* If /sys is read-only we don't support device units, and any
993 * attempts to start one should fail immediately. */
994
995 if (read_only < 0)
996 read_only = path_is_read_only_fs("/sys");
997
998 return read_only <= 0;
999}
1000
4366e598 1001static int validate_node(Manager *m, const char *node, sd_device **ret) {
628c89cc 1002 struct stat st;
e5ca27b7 1003 int r;
628c89cc 1004
34c20ee0
LP
1005 assert(m);
1006 assert(node);
1007 assert(ret);
1008
1009 /* Validates a device node that showed up in /proc/swaps or /proc/self/mountinfo if it makes sense for us to
1010 * track. Note that this validator is fine within missing device nodes, but not with badly set up ones! */
1011
1012 if (!path_startswith(node, "/dev")) {
1013 *ret = NULL;
1014 return 0; /* bad! */
1015 }
1016
1017 if (stat(node, &st) < 0) {
1018 if (errno != ENOENT)
1019 return log_error_errno(errno, "Failed to stat() device node file %s: %m", node);
1020
1021 *ret = NULL;
1022 return 1; /* good! (though missing) */
1023
1024 } else {
4366e598 1025 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
34c20ee0 1026
a1130022 1027 r = sd_device_new_from_stat_rdev(&dev, &st);
e5ca27b7 1028 if (r == -ENOENT) {
34c20ee0
LP
1029 *ret = NULL;
1030 return 1; /* good! (though missing) */
e5ca27b7
LP
1031 } else if (r == -ENOTTY) {
1032 *ret = NULL;
1033 return 0; /* bad! (not a device node but some other kind of file system node) */
1034 } else if (r < 0)
1035 return log_error_errno(r, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
34c20ee0
LP
1036
1037 *ret = TAKE_PTR(dev);
1038 return 1; /* good! */
1039 }
1040}
1041
1042void device_found_node(Manager *m, const char *node, DeviceFound found, DeviceFound mask) {
628c89cc
LP
1043 assert(m);
1044 assert(node);
1045
4c6d20de 1046 if (!device_supported())
485ae697 1047 return;
4c6d20de 1048
34c20ee0
LP
1049 if (mask == 0)
1050 return;
1051
1052 /* This is called whenever we find a device referenced in /proc/swaps or /proc/self/mounts. Such a device might
1053 * be mounted/enabled at a time where udev has not finished probing it yet, and we thus haven't learned about
66f3fdbb
LP
1054 * it yet. In this case we will set the device unit to "tentative" state.
1055 *
1056 * This takes a pair of DeviceFound flags parameters. The 'mask' parameter is a bit mask that indicates which
1057 * bits of 'found' to copy into the per-device DeviceFound flags field. Thus, this function may be used to set
1058 * and unset individual bits in a single call, while merging partially with previous state. */
628c89cc 1059
485ae697 1060 if ((found & mask) != 0) {
4366e598 1061 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
628c89cc 1062
34c20ee0
LP
1063 /* If the device is known in the kernel and newly appeared, then we'll create a device unit for it,
1064 * under the name referenced in /proc/swaps or /proc/self/mountinfo. But first, let's validate if
1065 * everything is alright with the device node. */
628c89cc 1066
e41db484 1067 if (validate_node(m, node, &dev) <= 0)
34c20ee0 1068 return; /* Don't create a device unit for this if the device node is borked. */
628c89cc
LP
1069
1070 (void) device_setup_unit(m, dev, node, false);
1071 }
1072
1073 /* Update the device unit's state, should it exist */
485ae697 1074 (void) device_update_found_by_name(m, node, found, mask);
628c89cc
LP
1075}
1076
ebc8968b 1077bool device_shall_be_bound_by(Unit *device, Unit *u) {
8bb2c8c9
LP
1078 assert(device);
1079 assert(u);
ebc8968b
FB
1080
1081 if (u->type != UNIT_MOUNT)
1082 return false;
1083
1084 return DEVICE(device)->bind_mounts;
1085}
1086
87f0e418 1087const UnitVTable device_vtable = {
7d17cfbc 1088 .object_size = sizeof(Device),
f975e971
LP
1089 .sections =
1090 "Unit\0"
1091 "Device\0"
1092 "Install\0",
5cb5a6ff 1093
c5a97ed1
LP
1094 .gc_jobs = true,
1095
faf919f1 1096 .init = device_init,
034c6ed7 1097 .done = device_done,
1d4c6f5b 1098 .load = device_load,
718db961 1099
f50e0a01 1100 .coldplug = device_coldplug,
66f3fdbb 1101 .catchup = device_catchup,
f50e0a01 1102
f6200941
LP
1103 .serialize = device_serialize,
1104 .deserialize_item = device_deserialize_item,
1105
5cb5a6ff
LP
1106 .dump = device_dump,
1107
f50e0a01 1108 .active_state = device_active_state,
10a94420 1109 .sub_state_to_string = device_sub_state_to_string,
25ac040b 1110
a7f241db 1111 .following = device_following,
6210e7fc 1112 .following_set = device_following_set,
a7f241db 1113
f50e0a01 1114 .enumerate = device_enumerate,
c6918296 1115 .shutdown = device_shutdown,
0faacd47 1116 .supported = device_supported,
c6918296
MS
1117
1118 .status_message_formats = {
1119 .starting_stopping = {
1120 [0] = "Expecting device %s...",
1121 },
1122 .finished_start_job = {
1123 [JOB_DONE] = "Found device %s.",
1124 [JOB_TIMEOUT] = "Timed out waiting for device %s.",
1125 },
1126 },
5cb5a6ff 1127};