chiark / gitweb /
core: no need to list properties for PropertiesChanged messages anymore
[elogind.git] / src / core / device.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
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   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <sys/epoll.h>
24 #include <libudev.h>
25
26 #include "strv.h"
27 #include "log.h"
28 #include "unit-name.h"
29 #include "dbus-device.h"
30 #include "def.h"
31 #include "path-util.h"
32 #include "udev-util.h"
33 #include "unit.h"
34 #include "swap.h"
35 #include "device.h"
36
37 static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
38         [DEVICE_DEAD] = UNIT_INACTIVE,
39         [DEVICE_PLUGGED] = UNIT_ACTIVE
40 };
41
42 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
43
44 static void device_unset_sysfs(Device *d) {
45         Hashmap *devices;
46         Device *first;
47
48         assert(d);
49
50         if (!d->sysfs)
51                 return;
52
53         /* Remove this unit from the chain of devices which share the
54          * same sysfs path. */
55         devices = UNIT(d)->manager->devices_by_sysfs;
56         first = hashmap_get(devices, d->sysfs);
57         LIST_REMOVE(same_sysfs, first, d);
58
59         if (first)
60                 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
61         else
62                 hashmap_remove(devices, d->sysfs);
63
64         free(d->sysfs);
65         d->sysfs = NULL;
66 }
67
68 static void device_init(Unit *u) {
69         Device *d = DEVICE(u);
70
71         assert(d);
72         assert(UNIT(d)->load_state == UNIT_STUB);
73
74         /* In contrast to all other unit types we timeout jobs waiting
75          * for devices by default. This is because they otherwise wait
76          * indefinitely for plugged in devices, something which cannot
77          * happen for the other units since their operations time out
78          * anyway. */
79         u->job_timeout = u->manager->default_timeout_start_usec;
80
81         u->ignore_on_isolate = true;
82         u->ignore_on_snapshot = true;
83 }
84
85 static void device_done(Unit *u) {
86         Device *d = DEVICE(u);
87
88         assert(d);
89
90         device_unset_sysfs(d);
91 }
92
93 static void device_set_state(Device *d, DeviceState state) {
94         DeviceState old_state;
95         assert(d);
96
97         old_state = d->state;
98         d->state = state;
99
100         if (state != old_state)
101                 log_debug_unit(UNIT(d)->id,
102                                "%s changed %s -> %s", UNIT(d)->id,
103                                device_state_to_string(old_state),
104                                device_state_to_string(state));
105
106         unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
107 }
108
109 static int device_coldplug(Unit *u) {
110         Device *d = DEVICE(u);
111
112         assert(d);
113         assert(d->state == DEVICE_DEAD);
114
115         if (d->sysfs)
116                 device_set_state(d, DEVICE_PLUGGED);
117
118         return 0;
119 }
120
121 static void device_dump(Unit *u, FILE *f, const char *prefix) {
122         Device *d = DEVICE(u);
123
124         assert(d);
125
126         fprintf(f,
127                 "%sDevice State: %s\n"
128                 "%sSysfs Path: %s\n",
129                 prefix, device_state_to_string(d->state),
130                 prefix, strna(d->sysfs));
131 }
132
133 _pure_ static UnitActiveState device_active_state(Unit *u) {
134         assert(u);
135
136         return state_translation_table[DEVICE(u)->state];
137 }
138
139 _pure_ static const char *device_sub_state_to_string(Unit *u) {
140         assert(u);
141
142         return device_state_to_string(DEVICE(u)->state);
143 }
144
145 static int device_add_escaped_name(Unit *u, const char *dn) {
146         _cleanup_free_ char *e = NULL;
147         int r;
148
149         assert(u);
150         assert(dn);
151         assert(dn[0] == '/');
152
153         e = unit_name_from_path(dn, ".device");
154         if (!e)
155                 return -ENOMEM;
156
157         r = unit_add_name(u, e);
158         if (r < 0 && r != -EEXIST)
159                 return r;
160
161         return 0;
162 }
163
164 static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
165         _cleanup_free_ char *e = NULL;
166         Unit *u;
167
168         assert(m);
169         assert(dn);
170         assert(dn[0] == '/');
171         assert(_u);
172
173         e = unit_name_from_path(dn, ".device");
174         if (!e)
175                 return -ENOMEM;
176
177         u = manager_get_unit(m, e);
178         if (u) {
179                 *_u = u;
180                 return 1;
181         }
182
183         return 0;
184 }
185
186 static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
187         const char *sysfs, *model;
188         Unit *u = NULL;
189         int r;
190         bool delete;
191
192         assert(m);
193
194         sysfs = udev_device_get_syspath(dev);
195         if (!sysfs)
196                 return 0;
197
198         r = device_find_escape_name(m, path, &u);
199         if (r < 0)
200                 return r;
201
202         if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
203                 return -EEXIST;
204
205         if (!u) {
206                 delete = true;
207
208                 u = unit_new(m, sizeof(Device));
209                 if (!u)
210                         return log_oom();
211
212                 r = device_add_escaped_name(u, path);
213                 if (r < 0)
214                         goto fail;
215
216                 unit_add_to_load_queue(u);
217         } else
218                 delete = false;
219
220         /* If this was created via some dependency and has not
221          * actually been seen yet ->sysfs will not be
222          * initialized. Hence initialize it if necessary. */
223
224         if (!DEVICE(u)->sysfs) {
225                 Device *first;
226
227                 DEVICE(u)->sysfs = strdup(sysfs);
228                 if (!DEVICE(u)->sysfs) {
229                         r = -ENOMEM;
230                         goto fail;
231                 }
232
233                 r = hashmap_ensure_allocated(&m->devices_by_sysfs, string_hash_func, string_compare_func);
234                 if (r < 0)
235                         goto fail;
236
237                 first = hashmap_get(m->devices_by_sysfs, sysfs);
238                 LIST_PREPEND(same_sysfs, first, DEVICE(u));
239
240                 r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first);
241                 if (r < 0)
242                         goto fail;
243         }
244
245         if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
246             (model = udev_device_get_property_value(dev, "ID_MODEL")))
247                 r = unit_set_description(u, model);
248         else
249                 r = unit_set_description(u, path);
250         if (r < 0)
251                 goto fail;
252
253         if (main) {
254                 const char *wants;
255
256                 /* The additional systemd udev properties we only
257                  * interpret for the main object */
258
259                 wants = udev_device_get_property_value(dev, m->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS");
260                 if (wants) {
261                         char *state, *w;
262                         size_t l;
263
264                         FOREACH_WORD_QUOTED(w, l, wants, state) {
265                                 _cleanup_free_ char *n = NULL;
266                                 char e[l+1];
267
268                                 memcpy(e, w, l);
269                                 e[l] = 0;
270
271                                 n = unit_name_mangle(e);
272                                 if (!n) {
273                                         r = -ENOMEM;
274                                         goto fail;
275                                 }
276
277                                 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
278                                 if (r < 0)
279                                         goto fail;
280                         }
281                 }
282         }
283
284         /* Note that this won't dispatch the load queue, the caller
285          * has to do that if needed and appropriate */
286
287         unit_add_to_dbus_queue(u);
288         return 0;
289
290 fail:
291         log_warning("Failed to load device unit: %s", strerror(-r));
292
293         if (delete && u)
294                 unit_free(u);
295
296         return r;
297 }
298
299 static int device_process_new_device(Manager *m, struct udev_device *dev) {
300         const char *sysfs, *dn, *alias;
301         struct udev_list_entry *item = NULL, *first = NULL;
302         int r;
303
304         assert(m);
305
306         sysfs = udev_device_get_syspath(dev);
307         if (!sysfs)
308                 return 0;
309
310         /* Add the main unit named after the sysfs path */
311         r = device_update_unit(m, dev, sysfs, true);
312         if (r < 0)
313                 return r;
314
315         /* Add an additional unit for the device node */
316         dn = udev_device_get_devnode(dev);
317         if (dn)
318                 device_update_unit(m, dev, dn, false);
319
320         /* Add additional units for all symlinks */
321         first = udev_device_get_devlinks_list_entry(dev);
322         udev_list_entry_foreach(item, first) {
323                 const char *p;
324                 struct stat st;
325
326                 /* Don't bother with the /dev/block links */
327                 p = udev_list_entry_get_name(item);
328
329                 if (path_startswith(p, "/dev/block/") ||
330                     path_startswith(p, "/dev/char/"))
331                         continue;
332
333                 /* Verify that the symlink in the FS actually belongs
334                  * to this device. This is useful to deal with
335                  * conflicting devices, e.g. when two disks want the
336                  * same /dev/disk/by-label/xxx link because they have
337                  * the same label. We want to make sure that the same
338                  * device that won the symlink wins in systemd, so we
339                  * check the device node major/minor*/
340                 if (stat(p, &st) >= 0)
341                         if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
342                             st.st_rdev != udev_device_get_devnum(dev))
343                                 continue;
344
345                 device_update_unit(m, dev, p, false);
346         }
347
348         /* Add additional units for all explicitly configured
349          * aliases */
350         alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
351         if (alias) {
352                 char *state, *w;
353                 size_t l;
354
355                 FOREACH_WORD_QUOTED(w, l, alias, state) {
356                         char e[l+1];
357
358                         memcpy(e, w, l);
359                         e[l] = 0;
360
361                         if (path_is_absolute(e))
362                                 device_update_unit(m, dev, e, false);
363                         else
364                                 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
365                 }
366         }
367
368         return 0;
369 }
370
371 static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
372         const char *sysfs;
373         Device *d, *l;
374
375         assert(m);
376         assert(dev);
377
378         sysfs = udev_device_get_syspath(dev);
379         if (!sysfs)
380                 return;
381
382         l = hashmap_get(m->devices_by_sysfs, sysfs);
383         LIST_FOREACH(same_sysfs, d, l)
384                 device_set_state(d, DEVICE_PLUGGED);
385 }
386
387 static int device_process_removed_device(Manager *m, struct udev_device *dev) {
388         const char *sysfs;
389         Device *d;
390
391         assert(m);
392         assert(dev);
393
394         sysfs = udev_device_get_syspath(dev);
395         if (!sysfs)
396                 return -ENOMEM;
397
398         /* Remove all units of this sysfs path */
399         while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
400                 device_unset_sysfs(d);
401                 device_set_state(d, DEVICE_DEAD);
402         }
403
404         return 0;
405 }
406
407 static bool device_is_ready(struct udev_device *dev) {
408         const char *ready;
409
410         assert(dev);
411
412         ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
413         if (!ready)
414                 return true;
415
416         return parse_boolean(ready) != 0;
417 }
418
419 static int device_process_new_path(Manager *m, const char *path) {
420         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
421
422         assert(m);
423         assert(path);
424
425         dev = udev_device_new_from_syspath(m->udev, path);
426         if (!dev)
427                 return log_oom();
428
429         if (!device_is_ready(dev))
430                 return 0;
431
432         return device_process_new_device(m, dev);
433 }
434
435 static Unit *device_following(Unit *u) {
436         Device *d = DEVICE(u);
437         Device *other, *first = NULL;
438
439         assert(d);
440
441         if (startswith(u->id, "sys-"))
442                 return NULL;
443
444         /* Make everybody follow the unit that's named after the sysfs path */
445         for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
446                 if (startswith(UNIT(other)->id, "sys-"))
447                         return UNIT(other);
448
449         for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
450                 if (startswith(UNIT(other)->id, "sys-"))
451                         return UNIT(other);
452
453                 first = other;
454         }
455
456         return UNIT(first);
457 }
458
459 static int device_following_set(Unit *u, Set **_set) {
460         Device *d = DEVICE(u), *other;
461         Set *set;
462         int r;
463
464         assert(d);
465         assert(_set);
466
467         if (LIST_JUST_US(same_sysfs, d)) {
468                 *_set = NULL;
469                 return 0;
470         }
471
472         set = set_new(NULL, NULL);
473         if (!set)
474                 return -ENOMEM;
475
476         LIST_FOREACH_AFTER(same_sysfs, other, d) {
477                 r = set_put(set, other);
478                 if (r < 0)
479                         goto fail;
480         }
481
482         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
483                 r = set_put(set, other);
484                 if (r < 0)
485                         goto fail;
486         }
487
488         *_set = set;
489         return 1;
490
491 fail:
492         set_free(set);
493         return r;
494 }
495
496 static void device_shutdown(Manager *m) {
497         assert(m);
498
499         m->udev_event_source = sd_event_source_unref(m->udev_event_source);
500
501         if (m->udev_monitor) {
502                 udev_monitor_unref(m->udev_monitor);
503                 m->udev_monitor = NULL;
504         }
505
506         hashmap_free(m->devices_by_sysfs);
507         m->devices_by_sysfs = NULL;
508 }
509
510 static int device_enumerate(Manager *m) {
511         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
512         struct udev_list_entry *item = NULL, *first = NULL;
513         int r;
514
515         assert(m);
516
517         if (!m->udev_monitor) {
518                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
519                 if (!m->udev_monitor) {
520                         r = -ENOMEM;
521                         goto fail;
522                 }
523
524                 /* This will fail if we are unprivileged, but that
525                  * should not matter much, as user instances won't run
526                  * during boot. */
527                 udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
528
529                 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
530                 if (r < 0)
531                         goto fail;
532
533                 r = udev_monitor_enable_receiving(m->udev_monitor);
534                 if (r < 0)
535                         goto fail;
536
537                 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m, &m->udev_event_source);
538                 if (r < 0)
539                         goto fail;
540         }
541
542         e = udev_enumerate_new(m->udev);
543         if (!e) {
544                 r = -ENOMEM;
545                 goto fail;
546         }
547
548         r = udev_enumerate_add_match_tag(e, "systemd");
549         if (r < 0)
550                 goto fail;
551
552         r = udev_enumerate_add_match_is_initialized(e);
553         if (r < 0)
554                 goto fail;
555
556         r = udev_enumerate_scan_devices(e);
557         if (r < 0)
558                 goto fail;
559
560         first = udev_enumerate_get_list_entry(e);
561         udev_list_entry_foreach(item, first)
562                 device_process_new_path(m, udev_list_entry_get_name(item));
563
564         return 0;
565
566 fail:
567         device_shutdown(m);
568         return r;
569 }
570
571 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
572         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
573         Manager *m = userdata;
574         const char *action;
575         int r;
576
577         assert(m);
578
579         if (revents != EPOLLIN) {
580                 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
581
582                 if (!ratelimit_test(&limit))
583                         log_error("Failed to get udev event: %m");
584                 if (!(revents & EPOLLIN))
585                         return 0;
586         }
587
588         /*
589          * libudev might filter-out devices which pass the bloom
590          * filter, so getting NULL here is not necessarily an error.
591          */
592         dev = udev_monitor_receive_device(m->udev_monitor);
593         if (!dev)
594                 return 0;
595
596         action = udev_device_get_action(dev);
597         if (!action) {
598                 log_error("Failed to get udev action string.");
599                 return 0;
600         }
601
602         if (streq(action, "remove") || !device_is_ready(dev))  {
603                 r = device_process_removed_device(m, dev);
604                 if (r < 0)
605                         log_error("Failed to process device remove event: %s", strerror(-r));
606
607                 r = swap_process_removed_device(m, dev);
608                 if (r < 0)
609                         log_error("Failed to process swap device remove event: %s", strerror(-r));
610
611         } else {
612                 r = device_process_new_device(m, dev);
613                 if (r < 0)
614                         log_error("Failed to process device new event: %s", strerror(-r));
615
616                 r = swap_process_new_device(m, dev);
617                 if (r < 0)
618                         log_error("Failed to process swap device new event: %s", strerror(-r));
619
620                 manager_dispatch_load_queue(m);
621
622                 device_set_path_plugged(m, dev);
623         }
624
625         return 0;
626 }
627
628 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
629         [DEVICE_DEAD] = "dead",
630         [DEVICE_PLUGGED] = "plugged"
631 };
632
633 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
634
635 const UnitVTable device_vtable = {
636         .object_size = sizeof(Device),
637         .sections =
638                 "Unit\0"
639                 "Device\0"
640                 "Install\0",
641
642         .no_instances = true,
643
644         .init = device_init,
645         .done = device_done,
646         .load = unit_load_fragment_and_dropin_optional,
647
648         .coldplug = device_coldplug,
649
650         .dump = device_dump,
651
652         .active_state = device_active_state,
653         .sub_state_to_string = device_sub_state_to_string,
654
655         .bus_interface = "org.freedesktop.systemd1.Device",
656         .bus_vtable = bus_device_vtable,
657
658         .following = device_following,
659         .following_set = device_following_set,
660
661         .enumerate = device_enumerate,
662         .shutdown = device_shutdown,
663
664         .status_message_formats = {
665                 .starting_stopping = {
666                         [0] = "Expecting device %s...",
667                 },
668                 .finished_start_job = {
669                         [JOB_DONE]       = "Found device %s.",
670                         [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
671                 },
672         },
673 };