1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/epoll.h>
30 #include "unit-name.h"
31 #include "dbus-device.h"
34 static const UnitActiveState state_translation_table
[_DEVICE_STATE_MAX
] = {
35 [DEVICE_DEAD
] = UNIT_INACTIVE
,
36 [DEVICE_PLUGGED
] = UNIT_ACTIVE
39 static void device_unset_sysfs(Device
*d
) {
47 /* Remove this unit from the chain of devices which share the
49 first
= hashmap_get(d
->meta
.manager
->devices_by_sysfs
, d
->sysfs
);
50 LIST_REMOVE(Device
, same_sysfs
, first
, d
);
53 hashmap_remove_and_replace(d
->meta
.manager
->devices_by_sysfs
, d
->sysfs
, first
->sysfs
, first
);
55 hashmap_remove(d
->meta
.manager
->devices_by_sysfs
, d
->sysfs
);
61 static void device_init(Unit
*u
) {
62 Device
*d
= DEVICE(u
);
65 assert(d
->meta
.load_state
== UNIT_STUB
);
67 /* In contrast to all other unit types we timeout jobs waiting
68 * for devices by default. This is because they otherwise wait
69 * indefinitely for plugged in devices, something which cannot
70 * happen for the other units since their operations time out
72 d
->meta
.job_timeout
= DEFAULT_TIMEOUT_USEC
;
74 d
->meta
.ignore_on_isolate
= true;
77 static void device_done(Unit
*u
) {
78 Device
*d
= DEVICE(u
);
82 device_unset_sysfs(d
);
85 static void device_set_state(Device
*d
, DeviceState state
) {
86 DeviceState old_state
;
92 if (state
!= old_state
)
93 log_debug("%s changed %s -> %s",
95 device_state_to_string(old_state
),
96 device_state_to_string(state
));
98 unit_notify(UNIT(d
), state_translation_table
[old_state
], state_translation_table
[state
], true);
101 static int device_coldplug(Unit
*u
) {
102 Device
*d
= DEVICE(u
);
105 assert(d
->state
== DEVICE_DEAD
);
108 device_set_state(d
, DEVICE_PLUGGED
);
113 static void device_dump(Unit
*u
, FILE *f
, const char *prefix
) {
114 Device
*d
= DEVICE(u
);
119 "%sDevice State: %s\n"
120 "%sSysfs Path: %s\n",
121 prefix
, device_state_to_string(d
->state
),
122 prefix
, strna(d
->sysfs
));
125 static UnitActiveState
device_active_state(Unit
*u
) {
128 return state_translation_table
[DEVICE(u
)->state
];
131 static const char *device_sub_state_to_string(Unit
*u
) {
134 return device_state_to_string(DEVICE(u
)->state
);
137 static int device_add_escaped_name(Unit
*u
, const char *dn
) {
143 assert(dn
[0] == '/');
145 if (!(e
= unit_name_from_path(dn
, ".device")))
148 r
= unit_add_name(u
, e
);
151 if (r
< 0 && r
!= -EEXIST
)
157 static int device_find_escape_name(Manager
*m
, const char *dn
, Unit
**_u
) {
163 assert(dn
[0] == '/');
166 if (!(e
= unit_name_from_path(dn
, ".device")))
169 u
= manager_get_unit(m
, e
);
180 static int device_update_unit(Manager
*m
, struct udev_device
*dev
, const char *path
, bool main
) {
181 const char *sysfs
, *model
;
188 if (!(sysfs
= udev_device_get_syspath(dev
)))
191 if ((r
= device_find_escape_name(m
, path
, &u
)) < 0)
194 if (u
&& DEVICE(u
)->sysfs
&& !path_equal(DEVICE(u
)->sysfs
, sysfs
))
200 if (!(u
= unit_new(m
)))
203 if ((r
= device_add_escaped_name(u
, path
)) < 0)
206 unit_add_to_load_queue(u
);
210 /* If this was created via some dependency and has not
211 * actually been seen yet ->sysfs will not be
212 * initialized. Hence initialize it if necessary. */
214 if (!DEVICE(u
)->sysfs
) {
217 if (!(DEVICE(u
)->sysfs
= strdup(sysfs
))) {
222 if (!m
->devices_by_sysfs
)
223 if (!(m
->devices_by_sysfs
= hashmap_new(string_hash_func
, string_compare_func
))) {
228 first
= hashmap_get(m
->devices_by_sysfs
, sysfs
);
229 LIST_PREPEND(Device
, same_sysfs
, first
, DEVICE(u
));
231 if ((r
= hashmap_replace(m
->devices_by_sysfs
, DEVICE(u
)->sysfs
, first
)) < 0)
235 if ((model
= udev_device_get_property_value(dev
, "ID_MODEL_FROM_DATABASE")) ||
236 (model
= udev_device_get_property_value(dev
, "ID_MODEL"))) {
237 if ((r
= unit_set_description(u
, model
)) < 0)
240 if ((r
= unit_set_description(u
, path
)) < 0)
244 /* The additional systemd udev properties we only
245 * interpret for the main object */
246 const char *wants
, *alias
;
248 if ((alias
= udev_device_get_property_value(dev
, "SYSTEMD_ALIAS"))) {
250 log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs
, alias
);
252 if ((r
= device_add_escaped_name(u
, alias
)) < 0)
257 if ((wants
= udev_device_get_property_value(dev
, "SYSTEMD_WANTS"))) {
261 FOREACH_WORD_QUOTED(w
, l
, wants
, state
) {
264 if (!(e
= strndup(w
, l
))) {
269 r
= unit_add_dependency_by_name(u
, UNIT_WANTS
, e
, NULL
, true);
278 unit_add_to_dbus_queue(u
);
282 log_warning("Failed to load device unit: %s", strerror(-r
));
290 static int device_process_new_device(Manager
*m
, struct udev_device
*dev
, bool update_state
) {
291 const char *sysfs
, *dn
;
292 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
296 if (!(sysfs
= udev_device_get_syspath(dev
)))
299 /* Add the main unit named after the sysfs path */
300 device_update_unit(m
, dev
, sysfs
, true);
302 /* Add an additional unit for the device node */
303 if ((dn
= udev_device_get_devnode(dev
)))
304 device_update_unit(m
, dev
, dn
, false);
306 /* Add additional units for all symlinks */
307 first
= udev_device_get_devlinks_list_entry(dev
);
308 udev_list_entry_foreach(item
, first
) {
312 /* Don't bother with the /dev/block links */
313 p
= udev_list_entry_get_name(item
);
315 if (path_startswith(p
, "/dev/block/") ||
316 path_startswith(p
, "/dev/char/"))
319 /* Verify that the symlink in the FS actually belongs
320 * to this device. This is useful to deal with
321 * conflicting devices, e.g. when two disks want the
322 * same /dev/disk/by-label/xxx link because they have
323 * the same label. We want to make sure that the same
324 * device that won the symlink wins in systemd, so we
325 * check the device node major/minor*/
326 if (stat(p
, &st
) >= 0)
327 if ((!S_ISBLK(st
.st_mode
) && !S_ISCHR(st
.st_mode
)) ||
328 st
.st_rdev
!= udev_device_get_devnum(dev
))
331 device_update_unit(m
, dev
, p
, false);
337 manager_dispatch_load_queue(m
);
339 l
= hashmap_get(m
->devices_by_sysfs
, sysfs
);
340 LIST_FOREACH(same_sysfs
, d
, l
)
341 device_set_state(d
, DEVICE_PLUGGED
);
347 static int device_process_path(Manager
*m
, const char *path
, bool update_state
) {
349 struct udev_device
*dev
;
354 if (!(dev
= udev_device_new_from_syspath(m
->udev
, path
))) {
355 log_warning("Failed to get udev device object from udev for path %s.", path
);
359 r
= device_process_new_device(m
, dev
, update_state
);
360 udev_device_unref(dev
);
364 static int device_process_removed_device(Manager
*m
, struct udev_device
*dev
) {
371 if (!(sysfs
= udev_device_get_syspath(dev
)))
374 /* Remove all units of this sysfs path */
375 while ((d
= hashmap_get(m
->devices_by_sysfs
, sysfs
))) {
376 device_unset_sysfs(d
);
377 device_set_state(d
, DEVICE_DEAD
);
383 static Unit
*device_following(Unit
*u
) {
384 Device
*d
= DEVICE(u
);
385 Device
*other
, *first
= NULL
;
389 if (startswith(u
->meta
.id
, "sys-"))
392 /* Make everybody follow the unit that's named after the sysfs path */
393 for (other
= d
->same_sysfs_next
; other
; other
= other
->same_sysfs_next
)
394 if (startswith(other
->meta
.id
, "sys-"))
397 for (other
= d
->same_sysfs_prev
; other
; other
= other
->same_sysfs_prev
) {
398 if (startswith(other
->meta
.id
, "sys-"))
407 static int device_following_set(Unit
*u
, Set
**_s
) {
408 Device
*d
= DEVICE(u
);
416 if (!d
->same_sysfs_prev
&& !d
->same_sysfs_next
) {
421 if (!(s
= set_new(NULL
, NULL
)))
424 for (other
= d
->same_sysfs_next
; other
; other
= other
->same_sysfs_next
)
425 if ((r
= set_put(s
, other
)) < 0)
428 for (other
= d
->same_sysfs_prev
; other
; other
= other
->same_sysfs_prev
)
429 if ((r
= set_put(s
, other
)) < 0)
440 static void device_shutdown(Manager
*m
) {
443 if (m
->udev_monitor
) {
444 udev_monitor_unref(m
->udev_monitor
);
445 m
->udev_monitor
= NULL
;
453 hashmap_free(m
->devices_by_sysfs
);
454 m
->devices_by_sysfs
= NULL
;
457 static int device_enumerate(Manager
*m
) {
458 struct epoll_event ev
;
460 struct udev_enumerate
*e
= NULL
;
461 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
466 if (!(m
->udev
= udev_new()))
469 if (!(m
->udev_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev"))) {
474 /* This will fail if we are unprivileged, but that
475 * should not matter much, as user instances won't run
477 udev_monitor_set_receive_buffer_size(m
->udev_monitor
, 128*1024*1024);
479 if (udev_monitor_filter_add_match_tag(m
->udev_monitor
, "systemd") < 0) {
484 if (udev_monitor_enable_receiving(m
->udev_monitor
) < 0) {
489 m
->udev_watch
.type
= WATCH_UDEV
;
490 m
->udev_watch
.fd
= udev_monitor_get_fd(m
->udev_monitor
);
494 ev
.data
.ptr
= &m
->udev_watch
;
496 if (epoll_ctl(m
->epoll_fd
, EPOLL_CTL_ADD
, m
->udev_watch
.fd
, &ev
) < 0)
500 if (!(e
= udev_enumerate_new(m
->udev
))) {
504 if (udev_enumerate_add_match_tag(e
, "systemd") < 0) {
509 if (udev_enumerate_scan_devices(e
) < 0) {
514 first
= udev_enumerate_get_list_entry(e
);
515 udev_list_entry_foreach(item
, first
)
516 device_process_path(m
, udev_list_entry_get_name(item
), false);
518 udev_enumerate_unref(e
);
523 udev_enumerate_unref(e
);
529 void device_fd_event(Manager
*m
, int events
) {
530 struct udev_device
*dev
;
532 const char *action
, *ready
;
536 if (events
!= EPOLLIN
) {
537 static RATELIMIT_DEFINE(limit
, 10*USEC_PER_SEC
, 5);
539 if (!ratelimit_test(&limit
))
540 log_error("Failed to get udev event: %m");
541 if (!(events
& EPOLLIN
))
545 if (!(dev
= udev_monitor_receive_device(m
->udev_monitor
))) {
547 * libudev might filter-out devices which pass the bloom filter,
548 * so getting NULL here is not necessarily an error
553 if (!(action
= udev_device_get_action(dev
))) {
554 log_error("Failed to get udev action string.");
558 ready
= udev_device_get_property_value(dev
, "SYSTEMD_READY");
560 if (streq(action
, "remove") || (ready
&& parse_boolean(ready
) == 0)) {
561 if ((r
= device_process_removed_device(m
, dev
)) < 0) {
562 log_error("Failed to process udev device event: %s", strerror(-r
));
566 if ((r
= device_process_new_device(m
, dev
, true)) < 0) {
567 log_error("Failed to process udev device event: %s", strerror(-r
));
573 udev_device_unref(dev
);
576 static const char* const device_state_table
[_DEVICE_STATE_MAX
] = {
577 [DEVICE_DEAD
] = "dead",
578 [DEVICE_PLUGGED
] = "plugged"
581 DEFINE_STRING_TABLE_LOOKUP(device_state
, DeviceState
);
583 const UnitVTable device_vtable
= {
586 .no_instances
= true,
587 .no_snapshots
= true,
591 .load
= unit_load_fragment_and_dropin_optional
,
593 .coldplug
= device_coldplug
,
597 .active_state
= device_active_state
,
598 .sub_state_to_string
= device_sub_state_to_string
,
600 .bus_interface
= "org.freedesktop.systemd1.Device",
601 .bus_message_handler
= bus_device_message_handler
,
602 .bus_invalidating_properties
= bus_device_invalidating_properties
,
604 .following
= device_following
,
605 .following_set
= device_following_set
,
607 .enumerate
= device_enumerate
,
608 .shutdown
= device_shutdown