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;
75 d
->meta
.ignore_on_snapshot
= true;
78 static void device_done(Unit
*u
) {
79 Device
*d
= DEVICE(u
);
83 device_unset_sysfs(d
);
86 static void device_set_state(Device
*d
, DeviceState state
) {
87 DeviceState old_state
;
93 if (state
!= old_state
)
94 log_debug("%s changed %s -> %s",
96 device_state_to_string(old_state
),
97 device_state_to_string(state
));
99 unit_notify(UNIT(d
), state_translation_table
[old_state
], state_translation_table
[state
], true);
102 static int device_coldplug(Unit
*u
) {
103 Device
*d
= DEVICE(u
);
106 assert(d
->state
== DEVICE_DEAD
);
109 device_set_state(d
, DEVICE_PLUGGED
);
114 static void device_dump(Unit
*u
, FILE *f
, const char *prefix
) {
115 Device
*d
= DEVICE(u
);
120 "%sDevice State: %s\n"
121 "%sSysfs Path: %s\n",
122 prefix
, device_state_to_string(d
->state
),
123 prefix
, strna(d
->sysfs
));
126 static UnitActiveState
device_active_state(Unit
*u
) {
129 return state_translation_table
[DEVICE(u
)->state
];
132 static const char *device_sub_state_to_string(Unit
*u
) {
135 return device_state_to_string(DEVICE(u
)->state
);
138 static int device_add_escaped_name(Unit
*u
, const char *dn
) {
144 assert(dn
[0] == '/');
146 if (!(e
= unit_name_from_path(dn
, ".device")))
149 r
= unit_add_name(u
, e
);
152 if (r
< 0 && r
!= -EEXIST
)
158 static int device_find_escape_name(Manager
*m
, const char *dn
, Unit
**_u
) {
164 assert(dn
[0] == '/');
167 if (!(e
= unit_name_from_path(dn
, ".device")))
170 u
= manager_get_unit(m
, e
);
181 static int device_update_unit(Manager
*m
, struct udev_device
*dev
, const char *path
, bool main
) {
182 const char *sysfs
, *model
;
189 if (!(sysfs
= udev_device_get_syspath(dev
)))
192 if ((r
= device_find_escape_name(m
, path
, &u
)) < 0)
195 if (u
&& DEVICE(u
)->sysfs
&& !path_equal(DEVICE(u
)->sysfs
, sysfs
))
201 u
= unit_new(m
, sizeof(Device
));
205 r
= device_add_escaped_name(u
, path
);
209 unit_add_to_load_queue(u
);
213 /* If this was created via some dependency and has not
214 * actually been seen yet ->sysfs will not be
215 * initialized. Hence initialize it if necessary. */
217 if (!DEVICE(u
)->sysfs
) {
220 if (!(DEVICE(u
)->sysfs
= strdup(sysfs
))) {
225 if (!m
->devices_by_sysfs
)
226 if (!(m
->devices_by_sysfs
= hashmap_new(string_hash_func
, string_compare_func
))) {
231 first
= hashmap_get(m
->devices_by_sysfs
, sysfs
);
232 LIST_PREPEND(Device
, same_sysfs
, first
, DEVICE(u
));
234 if ((r
= hashmap_replace(m
->devices_by_sysfs
, DEVICE(u
)->sysfs
, first
)) < 0)
238 if ((model
= udev_device_get_property_value(dev
, "ID_MODEL_FROM_DATABASE")) ||
239 (model
= udev_device_get_property_value(dev
, "ID_MODEL"))) {
240 if ((r
= unit_set_description(u
, model
)) < 0)
243 if ((r
= unit_set_description(u
, path
)) < 0)
247 /* The additional systemd udev properties we only
248 * interpret for the main object */
249 const char *wants
, *alias
;
251 if ((alias
= udev_device_get_property_value(dev
, "SYSTEMD_ALIAS"))) {
253 log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs
, alias
);
255 if ((r
= device_add_escaped_name(u
, alias
)) < 0)
260 if ((wants
= udev_device_get_property_value(dev
, "SYSTEMD_WANTS"))) {
264 FOREACH_WORD_QUOTED(w
, l
, wants
, state
) {
267 if (!(e
= strndup(w
, l
))) {
272 r
= unit_add_dependency_by_name(u
, UNIT_WANTS
, e
, NULL
, true);
281 unit_add_to_dbus_queue(u
);
285 log_warning("Failed to load device unit: %s", strerror(-r
));
293 static int device_process_new_device(Manager
*m
, struct udev_device
*dev
, bool update_state
) {
294 const char *sysfs
, *dn
;
295 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
299 if (!(sysfs
= udev_device_get_syspath(dev
)))
302 /* Add the main unit named after the sysfs path */
303 device_update_unit(m
, dev
, sysfs
, true);
305 /* Add an additional unit for the device node */
306 if ((dn
= udev_device_get_devnode(dev
)))
307 device_update_unit(m
, dev
, dn
, false);
309 /* Add additional units for all symlinks */
310 first
= udev_device_get_devlinks_list_entry(dev
);
311 udev_list_entry_foreach(item
, first
) {
315 /* Don't bother with the /dev/block links */
316 p
= udev_list_entry_get_name(item
);
318 if (path_startswith(p
, "/dev/block/") ||
319 path_startswith(p
, "/dev/char/"))
322 /* Verify that the symlink in the FS actually belongs
323 * to this device. This is useful to deal with
324 * conflicting devices, e.g. when two disks want the
325 * same /dev/disk/by-label/xxx link because they have
326 * the same label. We want to make sure that the same
327 * device that won the symlink wins in systemd, so we
328 * check the device node major/minor*/
329 if (stat(p
, &st
) >= 0)
330 if ((!S_ISBLK(st
.st_mode
) && !S_ISCHR(st
.st_mode
)) ||
331 st
.st_rdev
!= udev_device_get_devnum(dev
))
334 device_update_unit(m
, dev
, p
, false);
340 manager_dispatch_load_queue(m
);
342 l
= hashmap_get(m
->devices_by_sysfs
, sysfs
);
343 LIST_FOREACH(same_sysfs
, d
, l
)
344 device_set_state(d
, DEVICE_PLUGGED
);
350 static int device_process_path(Manager
*m
, const char *path
, bool update_state
) {
352 struct udev_device
*dev
;
357 if (!(dev
= udev_device_new_from_syspath(m
->udev
, path
))) {
358 log_warning("Failed to get udev device object from udev for path %s.", path
);
362 r
= device_process_new_device(m
, dev
, update_state
);
363 udev_device_unref(dev
);
367 static int device_process_removed_device(Manager
*m
, struct udev_device
*dev
) {
374 if (!(sysfs
= udev_device_get_syspath(dev
)))
377 /* Remove all units of this sysfs path */
378 while ((d
= hashmap_get(m
->devices_by_sysfs
, sysfs
))) {
379 device_unset_sysfs(d
);
380 device_set_state(d
, DEVICE_DEAD
);
386 static Unit
*device_following(Unit
*u
) {
387 Device
*d
= DEVICE(u
);
388 Device
*other
, *first
= NULL
;
392 if (startswith(u
->id
, "sys-"))
395 /* Make everybody follow the unit that's named after the sysfs path */
396 for (other
= d
->same_sysfs_next
; other
; other
= other
->same_sysfs_next
)
397 if (startswith(other
->meta
.id
, "sys-"))
400 for (other
= d
->same_sysfs_prev
; other
; other
= other
->same_sysfs_prev
) {
401 if (startswith(other
->meta
.id
, "sys-"))
410 static int device_following_set(Unit
*u
, Set
**_s
) {
411 Device
*d
= DEVICE(u
);
419 if (!d
->same_sysfs_prev
&& !d
->same_sysfs_next
) {
424 if (!(s
= set_new(NULL
, NULL
)))
427 for (other
= d
->same_sysfs_next
; other
; other
= other
->same_sysfs_next
)
428 if ((r
= set_put(s
, other
)) < 0)
431 for (other
= d
->same_sysfs_prev
; other
; other
= other
->same_sysfs_prev
)
432 if ((r
= set_put(s
, other
)) < 0)
443 static void device_shutdown(Manager
*m
) {
446 if (m
->udev_monitor
) {
447 udev_monitor_unref(m
->udev_monitor
);
448 m
->udev_monitor
= NULL
;
456 hashmap_free(m
->devices_by_sysfs
);
457 m
->devices_by_sysfs
= NULL
;
460 static int device_enumerate(Manager
*m
) {
461 struct epoll_event ev
;
463 struct udev_enumerate
*e
= NULL
;
464 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
469 if (!(m
->udev
= udev_new()))
472 if (!(m
->udev_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev"))) {
477 /* This will fail if we are unprivileged, but that
478 * should not matter much, as user instances won't run
480 udev_monitor_set_receive_buffer_size(m
->udev_monitor
, 128*1024*1024);
482 if (udev_monitor_filter_add_match_tag(m
->udev_monitor
, "systemd") < 0) {
487 if (udev_monitor_enable_receiving(m
->udev_monitor
) < 0) {
492 m
->udev_watch
.type
= WATCH_UDEV
;
493 m
->udev_watch
.fd
= udev_monitor_get_fd(m
->udev_monitor
);
497 ev
.data
.ptr
= &m
->udev_watch
;
499 if (epoll_ctl(m
->epoll_fd
, EPOLL_CTL_ADD
, m
->udev_watch
.fd
, &ev
) < 0)
503 if (!(e
= udev_enumerate_new(m
->udev
))) {
507 if (udev_enumerate_add_match_tag(e
, "systemd") < 0) {
512 if (udev_enumerate_scan_devices(e
) < 0) {
517 first
= udev_enumerate_get_list_entry(e
);
518 udev_list_entry_foreach(item
, first
)
519 device_process_path(m
, udev_list_entry_get_name(item
), false);
521 udev_enumerate_unref(e
);
526 udev_enumerate_unref(e
);
532 void device_fd_event(Manager
*m
, int events
) {
533 struct udev_device
*dev
;
535 const char *action
, *ready
;
539 if (events
!= EPOLLIN
) {
540 static RATELIMIT_DEFINE(limit
, 10*USEC_PER_SEC
, 5);
542 if (!ratelimit_test(&limit
))
543 log_error("Failed to get udev event: %m");
544 if (!(events
& EPOLLIN
))
548 if (!(dev
= udev_monitor_receive_device(m
->udev_monitor
))) {
550 * libudev might filter-out devices which pass the bloom filter,
551 * so getting NULL here is not necessarily an error
556 if (!(action
= udev_device_get_action(dev
))) {
557 log_error("Failed to get udev action string.");
561 ready
= udev_device_get_property_value(dev
, "SYSTEMD_READY");
563 if (streq(action
, "remove") || (ready
&& parse_boolean(ready
) == 0)) {
564 if ((r
= device_process_removed_device(m
, dev
)) < 0) {
565 log_error("Failed to process udev device event: %s", strerror(-r
));
569 if ((r
= device_process_new_device(m
, dev
, true)) < 0) {
570 log_error("Failed to process udev device event: %s", strerror(-r
));
576 udev_device_unref(dev
);
579 static const char* const device_state_table
[_DEVICE_STATE_MAX
] = {
580 [DEVICE_DEAD
] = "dead",
581 [DEVICE_PLUGGED
] = "plugged"
584 DEFINE_STRING_TABLE_LOOKUP(device_state
, DeviceState
);
586 const UnitVTable device_vtable
= {
588 .object_size
= sizeof(Device
),
594 .no_instances
= true,
598 .load
= unit_load_fragment_and_dropin_optional
,
600 .coldplug
= device_coldplug
,
604 .active_state
= device_active_state
,
605 .sub_state_to_string
= device_sub_state_to_string
,
607 .bus_interface
= "org.freedesktop.systemd1.Device",
608 .bus_message_handler
= bus_device_message_handler
,
609 .bus_invalidating_properties
= bus_device_invalidating_properties
,
611 .following
= device_following
,
612 .following_set
= device_following_set
,
614 .enumerate
= device_enumerate
,
615 .shutdown
= device_shutdown