chiark / gitweb /
udev: really exclude device-mapper from block device ownership event locking
[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_make_description(Unit *u, struct udev_device *dev, const char *path) {
187         const char *model;
188
189         assert(u);
190         assert(dev);
191         assert(path);
192
193         model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
194         if (!model)
195                 model = udev_device_get_property_value(dev, "ID_MODEL");
196
197         if (model) {
198                 const char *label;
199
200                 /* Try to concatenate the device model string with a label, if there is one */
201                 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
202                 if (!label)
203                         label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
204                 if (!label)
205                         label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
206
207                 if (label) {
208                         _cleanup_free_ char *j;
209
210                         j = strjoin(model, " ", label, NULL);
211                         if (j)
212                                 return unit_set_description(u, j);
213                 }
214
215                 return unit_set_description(u, model);
216         }
217
218         return unit_set_description(u, path);
219 }
220
221 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
222         const char *wants;
223         char *state, *w;
224         size_t l;
225         int r;
226
227         assert(u);
228         assert(dev);
229
230         wants = udev_device_get_property_value(
231                         dev,
232                         u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS");
233
234         if (!wants)
235                 return 0;
236
237         FOREACH_WORD_QUOTED(w, l, wants, state) {
238                 _cleanup_free_ char *n = NULL;
239                 char e[l+1];
240
241                 memcpy(e, w, l);
242                 e[l] = 0;
243
244                 n = unit_name_mangle(e, MANGLE_NOGLOB);
245                 if (!n)
246                         return -ENOMEM;
247
248                 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
249                 if (r < 0)
250                         return r;
251         }
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_func, string_compare_func);
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("Failed to load device unit: %s", strerror(-r));
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                 char *state, *w;
397                 size_t l;
398
399                 FOREACH_WORD_QUOTED(w, l, alias, state) {
400                         char e[l+1];
401
402                         memcpy(e, w, 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         }
411
412         return 0;
413 }
414
415 static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
416         const char *sysfs;
417         Device *d, *l;
418
419         assert(m);
420         assert(dev);
421
422         sysfs = udev_device_get_syspath(dev);
423         if (!sysfs)
424                 return;
425
426         l = hashmap_get(m->devices_by_sysfs, sysfs);
427         LIST_FOREACH(same_sysfs, d, l)
428                 device_set_state(d, DEVICE_PLUGGED);
429 }
430
431 static int device_process_removed_device(Manager *m, struct udev_device *dev) {
432         const char *sysfs;
433         Device *d;
434
435         assert(m);
436         assert(dev);
437
438         sysfs = udev_device_get_syspath(dev);
439         if (!sysfs)
440                 return -ENOMEM;
441
442         /* Remove all units of this sysfs path */
443         while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
444                 device_unset_sysfs(d);
445                 device_set_state(d, DEVICE_DEAD);
446         }
447
448         return 0;
449 }
450
451 static bool device_is_ready(struct udev_device *dev) {
452         const char *ready;
453
454         assert(dev);
455
456         ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
457         if (!ready)
458                 return true;
459
460         return parse_boolean(ready) != 0;
461 }
462
463 static int device_process_new_path(Manager *m, const char *path) {
464         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
465
466         assert(m);
467         assert(path);
468
469         dev = udev_device_new_from_syspath(m->udev, path);
470         if (!dev)
471                 return log_oom();
472
473         if (!device_is_ready(dev))
474                 return 0;
475
476         return device_process_new_device(m, dev);
477 }
478
479 static Unit *device_following(Unit *u) {
480         Device *d = DEVICE(u);
481         Device *other, *first = NULL;
482
483         assert(d);
484
485         if (startswith(u->id, "sys-"))
486                 return NULL;
487
488         /* Make everybody follow the unit that's named after the sysfs path */
489         for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
490                 if (startswith(UNIT(other)->id, "sys-"))
491                         return UNIT(other);
492
493         for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
494                 if (startswith(UNIT(other)->id, "sys-"))
495                         return UNIT(other);
496
497                 first = other;
498         }
499
500         return UNIT(first);
501 }
502
503 static int device_following_set(Unit *u, Set **_set) {
504         Device *d = DEVICE(u), *other;
505         Set *set;
506         int r;
507
508         assert(d);
509         assert(_set);
510
511         if (LIST_JUST_US(same_sysfs, d)) {
512                 *_set = NULL;
513                 return 0;
514         }
515
516         set = set_new(NULL, NULL);
517         if (!set)
518                 return -ENOMEM;
519
520         LIST_FOREACH_AFTER(same_sysfs, other, d) {
521                 r = set_put(set, other);
522                 if (r < 0)
523                         goto fail;
524         }
525
526         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
527                 r = set_put(set, other);
528                 if (r < 0)
529                         goto fail;
530         }
531
532         *_set = set;
533         return 1;
534
535 fail:
536         set_free(set);
537         return r;
538 }
539
540 static void device_shutdown(Manager *m) {
541         assert(m);
542
543         m->udev_event_source = sd_event_source_unref(m->udev_event_source);
544
545         if (m->udev_monitor) {
546                 udev_monitor_unref(m->udev_monitor);
547                 m->udev_monitor = NULL;
548         }
549
550         hashmap_free(m->devices_by_sysfs);
551         m->devices_by_sysfs = NULL;
552 }
553
554 static int device_enumerate(Manager *m) {
555         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
556         struct udev_list_entry *item = NULL, *first = NULL;
557         int r;
558
559         assert(m);
560
561         if (!m->udev_monitor) {
562                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
563                 if (!m->udev_monitor) {
564                         r = -ENOMEM;
565                         goto fail;
566                 }
567
568                 /* This will fail if we are unprivileged, but that
569                  * should not matter much, as user instances won't run
570                  * during boot. */
571                 udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
572
573                 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
574                 if (r < 0)
575                         goto fail;
576
577                 r = udev_monitor_enable_receiving(m->udev_monitor);
578                 if (r < 0)
579                         goto fail;
580
581                 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
582                 if (r < 0)
583                         goto fail;
584         }
585
586         e = udev_enumerate_new(m->udev);
587         if (!e) {
588                 r = -ENOMEM;
589                 goto fail;
590         }
591
592         r = udev_enumerate_add_match_tag(e, "systemd");
593         if (r < 0)
594                 goto fail;
595
596         r = udev_enumerate_add_match_is_initialized(e);
597         if (r < 0)
598                 goto fail;
599
600         r = udev_enumerate_scan_devices(e);
601         if (r < 0)
602                 goto fail;
603
604         first = udev_enumerate_get_list_entry(e);
605         udev_list_entry_foreach(item, first)
606                 device_process_new_path(m, udev_list_entry_get_name(item));
607
608         return 0;
609
610 fail:
611         device_shutdown(m);
612         return r;
613 }
614
615 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
616         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
617         Manager *m = userdata;
618         const char *action;
619         int r;
620
621         assert(m);
622
623         if (revents != EPOLLIN) {
624                 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
625
626                 if (!ratelimit_test(&limit))
627                         log_error("Failed to get udev event: %m");
628                 if (!(revents & EPOLLIN))
629                         return 0;
630         }
631
632         /*
633          * libudev might filter-out devices which pass the bloom
634          * filter, so getting NULL here is not necessarily an error.
635          */
636         dev = udev_monitor_receive_device(m->udev_monitor);
637         if (!dev)
638                 return 0;
639
640         action = udev_device_get_action(dev);
641         if (!action) {
642                 log_error("Failed to get udev action string.");
643                 return 0;
644         }
645
646         if (streq(action, "remove") || !device_is_ready(dev))  {
647                 r = device_process_removed_device(m, dev);
648                 if (r < 0)
649                         log_error("Failed to process device remove event: %s", strerror(-r));
650
651                 r = swap_process_removed_device(m, dev);
652                 if (r < 0)
653                         log_error("Failed to process swap device remove event: %s", strerror(-r));
654
655         } else {
656                 r = device_process_new_device(m, dev);
657                 if (r < 0)
658                         log_error("Failed to process device new event: %s", strerror(-r));
659
660                 r = swap_process_new_device(m, dev);
661                 if (r < 0)
662                         log_error("Failed to process swap device new event: %s", strerror(-r));
663
664                 manager_dispatch_load_queue(m);
665
666                 device_set_path_plugged(m, dev);
667         }
668
669         return 0;
670 }
671
672 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
673         [DEVICE_DEAD] = "dead",
674         [DEVICE_PLUGGED] = "plugged"
675 };
676
677 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
678
679 const UnitVTable device_vtable = {
680         .object_size = sizeof(Device),
681         .sections =
682                 "Unit\0"
683                 "Device\0"
684                 "Install\0",
685
686         .no_instances = true,
687
688         .init = device_init,
689         .done = device_done,
690         .load = unit_load_fragment_and_dropin_optional,
691
692         .coldplug = device_coldplug,
693
694         .dump = device_dump,
695
696         .active_state = device_active_state,
697         .sub_state_to_string = device_sub_state_to_string,
698
699         .bus_interface = "org.freedesktop.systemd1.Device",
700         .bus_vtable = bus_device_vtable,
701
702         .following = device_following,
703         .following_set = device_following_set,
704
705         .enumerate = device_enumerate,
706         .shutdown = device_shutdown,
707
708         .status_message_formats = {
709                 .starting_stopping = {
710                         [0] = "Expecting device %s...",
711                 },
712                 .finished_start_job = {
713                         [JOB_DONE]       = "Found device %s.",
714                         [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
715                 },
716         },
717 };