1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
11 static void device_done(Unit
*u
) {
12 Device
*d
= DEVICE(u
);
18 static void device_dump(Unit
*u
, FILE *f
, const char *prefix
) {
20 static const char* const state_table
[_DEVICE_STATE_MAX
] = {
21 [DEVICE_DEAD
] = "dead",
22 [DEVICE_AVAILABLE
] = "available"
25 Device
*d
= DEVICE(u
);
30 "%sDevice State: %s\n"
32 prefix
, state_table
[d
->state
],
36 static int device_add_escaped_name(Unit
*u
, const char *prefix
, const char *dn
, bool make_id
) {
44 if (!(e
= unit_name_escape_path(prefix
, dn
+1, ".device")))
47 r
= unit_add_name(u
, e
);
49 if (r
>= 0 && make_id
)
54 if (r
< 0 && r
!= -EEXIST
)
60 static int device_process_device(Manager
*m
, struct udev_device
*dev
) {
61 const char *dn
, *names
, *wants
, *sysfs
;
67 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
71 /* Check whether this entry is even relevant for us. */
72 dn
= udev_device_get_devnode(dev
);
73 names
= udev_device_get_property_value(dev
, "SYSTEMD_NAMES");
74 wants
= udev_device_get_property_value(dev
, "SYSTEMD_WANTS");
76 if (!dn
&& !names
&& !wants
)
79 /* Ok, seems kinda interesting. Now, let's see if this one
82 if (!(sysfs
= udev_device_get_syspath(dev
)))
85 assert(sysfs
[0] == '/');
86 if (!(e
= unit_name_escape_path("sysfs-", sysfs
+1, ".device")))
89 if (!(u
= manager_get_unit(m
, e
))) {
94 if (!(u
= unit_new(m
))) {
99 r
= unit_add_name(u
, e
);
105 if (!(DEVICE(u
)->sysfs
= strdup(sysfs
))) {
110 if ((model
= udev_device_get_property_value(dev
, "ID_MODEL_FROM_DATABASE")) ||
111 (model
= udev_device_get_property_value(dev
, "ID_MODEL")))
112 if (!(u
->meta
.description
= strdup(model
))) {
123 if ((r
= device_add_escaped_name(u
, "node-", dn
, true)) < 0)
126 first
= udev_device_get_devlinks_list_entry(dev
);
127 udev_list_entry_foreach(item
, first
)
128 if ((r
= device_add_escaped_name(u
, "node-", udev_list_entry_get_name(item
), false)) < 0)
132 FOREACH_WORD(w
, l
, names
, state
) {
133 if (!(e
= strndup(w
, l
)))
136 r
= unit_add_name(u
, e
);
139 if (r
< 0 && r
!= -EEXIST
)
145 if (set_isempty(u
->meta
.names
)) {
151 FOREACH_WORD(w
, l
, wants
, state
) {
152 if (!(e
= strndup(w
, l
)))
155 r
= unit_add_dependency_by_name(u
, UNIT_WANTS
, e
);
163 unit_add_to_load_queue(u
);
172 static int device_process_path(Manager
*m
, const char *path
) {
174 struct udev_device
*dev
;
179 if (!(dev
= udev_device_new_from_syspath(m
->udev
, path
))) {
180 log_warning("Failed to get udev device object from udev for path %s.", path
);
184 r
= device_process_device(m
, dev
);
185 udev_device_unref(dev
);
189 static void device_shutdown(Manager
*m
) {
196 static int device_enumerate(Manager
*m
) {
198 struct udev_enumerate
*e
= NULL
;
199 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
203 if (!(m
->udev
= udev_new()))
206 if (!(e
= udev_enumerate_new(m
->udev
))) {
211 if (udev_enumerate_scan_devices(e
) < 0) {
216 first
= udev_enumerate_get_list_entry(e
);
217 udev_list_entry_foreach(item
, first
)
218 device_process_path(m
, udev_list_entry_get_name(item
));
220 udev_enumerate_unref(e
);
226 udev_enumerate_unref(e
);
232 static UnitActiveState
device_active_state(Unit
*u
) {
233 return DEVICE(u
)->state
== DEVICE_DEAD
? UNIT_INACTIVE
: UNIT_ACTIVE
;
236 const UnitVTable device_vtable
= {
239 .init
= unit_load_fragment_and_dropin
,
243 .enumerate
= device_enumerate
,
244 .shutdown
= device_shutdown
,
246 .active_state
= device_active_state