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