LCOV - code coverage report
Current view: top level - core - device.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 273 412 66.3 %
Date: 2015-07-29 18:47:03 Functions: 24 28 85.7 %

          Line data    Source code
       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_TENTATIVE] = UNIT_ACTIVATING,
      38             :         [DEVICE_PLUGGED] = UNIT_ACTIVE,
      39             : };
      40             : 
      41             : static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
      42             : 
      43        1100 : static void device_unset_sysfs(Device *d) {
      44             :         Hashmap *devices;
      45             :         Device *first;
      46             : 
      47        1100 :         assert(d);
      48             : 
      49        1100 :         if (!d->sysfs)
      50         550 :                 return;
      51             : 
      52             :         /* Remove this unit from the chain of devices which share the
      53             :          * same sysfs path. */
      54         550 :         devices = UNIT(d)->manager->devices_by_sysfs;
      55         550 :         first = hashmap_get(devices, d->sysfs);
      56         550 :         LIST_REMOVE(same_sysfs, first, d);
      57             : 
      58         550 :         if (first)
      59         340 :                 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
      60             :         else
      61         210 :                 hashmap_remove(devices, d->sysfs);
      62             : 
      63         550 :         free(d->sysfs);
      64         550 :         d->sysfs = NULL;
      65             : }
      66             : 
      67         580 : static int device_set_sysfs(Device *d, const char *sysfs) {
      68             :         Device *first;
      69             :         char *copy;
      70             :         int r;
      71             : 
      72         580 :         assert(d);
      73             : 
      74         580 :         if (streq_ptr(d->sysfs, sysfs))
      75          30 :                 return 0;
      76             : 
      77         550 :         r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &string_hash_ops);
      78         550 :         if (r < 0)
      79           0 :                 return r;
      80             : 
      81         550 :         copy = strdup(sysfs);
      82         550 :         if (!copy)
      83           0 :                 return -ENOMEM;
      84             : 
      85         550 :         device_unset_sysfs(d);
      86             : 
      87         550 :         first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
      88         550 :         LIST_PREPEND(same_sysfs, first, d);
      89             : 
      90         550 :         r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
      91         550 :         if (r < 0) {
      92           0 :                 LIST_REMOVE(same_sysfs, first, d);
      93           0 :                 free(copy);
      94           0 :                 return r;
      95             :         }
      96             : 
      97         550 :         d->sysfs = copy;
      98             : 
      99         550 :         return 0;
     100             : }
     101             : 
     102         550 : static void device_init(Unit *u) {
     103         550 :         Device *d = DEVICE(u);
     104             : 
     105         550 :         assert(d);
     106         550 :         assert(UNIT(d)->load_state == UNIT_STUB);
     107             : 
     108             :         /* In contrast to all other unit types we timeout jobs waiting
     109             :          * for devices by default. This is because they otherwise wait
     110             :          * indefinitely for plugged in devices, something which cannot
     111             :          * happen for the other units since their operations time out
     112             :          * anyway. */
     113         550 :         u->job_timeout = u->manager->default_timeout_start_usec;
     114             : 
     115         550 :         u->ignore_on_isolate = true;
     116         550 :         u->ignore_on_snapshot = true;
     117         550 : }
     118             : 
     119         550 : static void device_done(Unit *u) {
     120         550 :         Device *d = DEVICE(u);
     121             : 
     122         550 :         assert(d);
     123             : 
     124         550 :         device_unset_sysfs(d);
     125         550 : }
     126             : 
     127         550 : static void device_set_state(Device *d, DeviceState state) {
     128             :         DeviceState old_state;
     129         550 :         assert(d);
     130             : 
     131         550 :         old_state = d->state;
     132         550 :         d->state = state;
     133             : 
     134         550 :         if (state != old_state)
     135         550 :                 log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
     136             : 
     137         550 :         unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
     138         550 : }
     139             : 
     140         550 : static int device_coldplug(Unit *u) {
     141         550 :         Device *d = DEVICE(u);
     142             : 
     143         550 :         assert(d);
     144         550 :         assert(d->state == DEVICE_DEAD);
     145             : 
     146         550 :         if (d->found & DEVICE_FOUND_UDEV)
     147             :                 /* If udev says the device is around, it's around */
     148         550 :                 device_set_state(d, DEVICE_PLUGGED);
     149           0 :         else if (d->found != DEVICE_NOT_FOUND && d->deserialized_state != DEVICE_PLUGGED)
     150             :                 /* If a device is found in /proc/self/mountinfo or
     151             :                  * /proc/swaps, and was not yet announced via udev,
     152             :                  * it's "tentatively" around. */
     153           0 :                 device_set_state(d, DEVICE_TENTATIVE);
     154             : 
     155         550 :         return 0;
     156             : }
     157             : 
     158           0 : static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
     159           0 :         Device *d = DEVICE(u);
     160             : 
     161           0 :         assert(u);
     162           0 :         assert(f);
     163           0 :         assert(fds);
     164             : 
     165           0 :         unit_serialize_item(u, f, "state", device_state_to_string(d->state));
     166             : 
     167           0 :         return 0;
     168             : }
     169             : 
     170           0 : static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
     171           0 :         Device *d = DEVICE(u);
     172             : 
     173           0 :         assert(u);
     174           0 :         assert(key);
     175           0 :         assert(value);
     176           0 :         assert(fds);
     177             : 
     178           0 :         if (streq(key, "state")) {
     179             :                 DeviceState state;
     180             : 
     181           0 :                 state = device_state_from_string(value);
     182           0 :                 if (state < 0)
     183           0 :                         log_unit_debug(u, "Failed to parse state value: %s", value);
     184             :                 else
     185           0 :                         d->deserialized_state = state;
     186             :         } else
     187           0 :                 log_unit_debug(u, "Unknown serialization key: %s", key);
     188             : 
     189           0 :         return 0;
     190             : }
     191             : 
     192         220 : static void device_dump(Unit *u, FILE *f, const char *prefix) {
     193         220 :         Device *d = DEVICE(u);
     194             : 
     195         220 :         assert(d);
     196             : 
     197         220 :         fprintf(f,
     198             :                 "%sDevice State: %s\n"
     199             :                 "%sSysfs Path: %s\n",
     200             :                 prefix, device_state_to_string(d->state),
     201         220 :                 prefix, strna(d->sysfs));
     202         220 : }
     203             : 
     204        2090 : _pure_ static UnitActiveState device_active_state(Unit *u) {
     205        2090 :         assert(u);
     206             : 
     207        2090 :         return state_translation_table[DEVICE(u)->state];
     208             : }
     209             : 
     210           0 : _pure_ static const char *device_sub_state_to_string(Unit *u) {
     211           0 :         assert(u);
     212             : 
     213           0 :         return device_state_to_string(DEVICE(u)->state);
     214             : }
     215             : 
     216         580 : static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
     217             :         const char *model;
     218             :         int r;
     219             : 
     220         580 :         assert(u);
     221         580 :         assert(dev);
     222         580 :         assert(path);
     223             : 
     224         580 :         model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
     225         580 :         if (!model)
     226         480 :                 model = udev_device_get_property_value(dev, "ID_MODEL");
     227             : 
     228         580 :         if (model) {
     229             :                 const char *label;
     230             : 
     231             :                 /* Try to concatenate the device model string with a label, if there is one */
     232         340 :                 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
     233         340 :                 if (!label)
     234         340 :                         label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
     235         340 :                 if (!label)
     236         340 :                         label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
     237             : 
     238         340 :                 if (label) {
     239         160 :                         _cleanup_free_ char *j;
     240             : 
     241         160 :                         j = strjoin(model, " ", label, NULL);
     242         160 :                         if (j)
     243         160 :                                 r = unit_set_description(u, j);
     244             :                         else
     245           0 :                                 r = -ENOMEM;
     246             :                 } else
     247         180 :                         r = unit_set_description(u, model);
     248             :         } else
     249         240 :                 r = unit_set_description(u, path);
     250             : 
     251         580 :         if (r < 0)
     252           0 :                 log_unit_error_errno(u, r, "Failed to set device description: %m");
     253             : 
     254         580 :         return r;
     255             : }
     256             : 
     257         210 : static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
     258             :         const char *wants;
     259             :         const char *word, *state;
     260             :         size_t l;
     261             :         int r;
     262             :         const char *property;
     263             : 
     264         210 :         assert(u);
     265         210 :         assert(dev);
     266             : 
     267         210 :         property = u->manager->running_as == MANAGER_USER ? "MANAGER_USER_WANTS" : "SYSTEMD_WANTS";
     268         210 :         wants = udev_device_get_property_value(dev, property);
     269         210 :         if (!wants)
     270         210 :                 return 0;
     271             : 
     272           0 :         FOREACH_WORD_QUOTED(word, l, wants, state) {
     273           0 :                 _cleanup_free_ char *n = NULL;
     274           0 :                 char e[l+1];
     275             : 
     276           0 :                 memcpy(e, word, l);
     277           0 :                 e[l] = 0;
     278             : 
     279           0 :                 r = unit_name_mangle(e, UNIT_NAME_NOGLOB, &n);
     280           0 :                 if (r < 0)
     281           0 :                         return log_unit_error_errno(u, r, "Failed to mangle unit name: %m");
     282             : 
     283           0 :                 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
     284           0 :                 if (r < 0)
     285           0 :                         return log_unit_error_errno(u, r, "Failed to add wants dependency: %m");
     286             :         }
     287           0 :         if (!isempty(state))
     288           0 :                 log_unit_warning(u, "Property %s on %s has trailing garbage, ignoring.", property, strna(udev_device_get_syspath(dev)));
     289             : 
     290           0 :         return 0;
     291             : }
     292             : 
     293         580 : static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
     294        1160 :         _cleanup_free_ char *e = NULL;
     295         580 :         const char *sysfs = NULL;
     296         580 :         Unit *u = NULL;
     297             :         bool delete;
     298             :         int r;
     299             : 
     300         580 :         assert(m);
     301         580 :         assert(path);
     302             : 
     303         580 :         if (dev) {
     304         580 :                 sysfs = udev_device_get_syspath(dev);
     305         580 :                 if (!sysfs)
     306           0 :                         return 0;
     307             :         }
     308             : 
     309         580 :         r = unit_name_from_path(path, ".device", &e);
     310         580 :         if (r < 0)
     311           0 :                 return log_error_errno(r, "Failed to generate unit name from device path: %m");
     312             : 
     313         580 :         u = manager_get_unit(m, e);
     314             : 
     315         580 :         if (u &&
     316          30 :             sysfs &&
     317          60 :             DEVICE(u)->sysfs &&
     318          30 :             !path_equal(DEVICE(u)->sysfs, sysfs)) {
     319           0 :                 log_unit_debug(u, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
     320           0 :                 return -EEXIST;
     321             :         }
     322             : 
     323         580 :         if (!u) {
     324         550 :                 delete = true;
     325             : 
     326         550 :                 u = unit_new(m, sizeof(Device));
     327         550 :                 if (!u)
     328           0 :                         return log_oom();
     329             : 
     330         550 :                 r = unit_add_name(u, e);
     331         550 :                 if (r < 0)
     332           0 :                         goto fail;
     333             : 
     334         550 :                 unit_add_to_load_queue(u);
     335             :         } else
     336          30 :                 delete = false;
     337             : 
     338             :         /* If this was created via some dependency and has not
     339             :          * actually been seen yet ->sysfs will not be
     340             :          * initialized. Hence initialize it if necessary. */
     341         580 :         if (sysfs) {
     342         580 :                 r = device_set_sysfs(DEVICE(u), sysfs);
     343         580 :                 if (r < 0)
     344           0 :                         goto fail;
     345             : 
     346         580 :                 (void) device_update_description(u, dev, path);
     347             : 
     348             :                 /* The additional systemd udev properties we only interpret
     349             :                  * for the main object */
     350         580 :                 if (main)
     351         210 :                         (void) device_add_udev_wants(u, dev);
     352             :         }
     353             : 
     354             : 
     355             :         /* Note that this won't dispatch the load queue, the caller
     356             :          * has to do that if needed and appropriate */
     357             : 
     358         580 :         unit_add_to_dbus_queue(u);
     359         580 :         return 0;
     360             : 
     361             : fail:
     362           0 :         log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
     363             : 
     364           0 :         if (delete)
     365           0 :                 unit_free(u);
     366             : 
     367           0 :         return r;
     368             : }
     369             : 
     370         210 : static int device_process_new(Manager *m, struct udev_device *dev) {
     371             :         const char *sysfs, *dn, *alias;
     372         210 :         struct udev_list_entry *item = NULL, *first = NULL;
     373             :         int r;
     374             : 
     375         210 :         assert(m);
     376             : 
     377         210 :         sysfs = udev_device_get_syspath(dev);
     378         210 :         if (!sysfs)
     379           0 :                 return 0;
     380             : 
     381             :         /* Add the main unit named after the sysfs path */
     382         210 :         r = device_setup_unit(m, dev, sysfs, true);
     383         210 :         if (r < 0)
     384           0 :                 return r;
     385             : 
     386             :         /* Add an additional unit for the device node */
     387         210 :         dn = udev_device_get_devnode(dev);
     388         210 :         if (dn)
     389          90 :                 (void) device_setup_unit(m, dev, dn, false);
     390             : 
     391             :         /* Add additional units for all symlinks */
     392         210 :         first = udev_device_get_devlinks_list_entry(dev);
     393         390 :         udev_list_entry_foreach(item, first) {
     394             :                 const char *p;
     395             :                 struct stat st;
     396             : 
     397             :                 /* Don't bother with the /dev/block links */
     398         180 :                 p = udev_list_entry_get_name(item);
     399             : 
     400         360 :                 if (path_startswith(p, "/dev/block/") ||
     401         180 :                     path_startswith(p, "/dev/char/"))
     402           0 :                         continue;
     403             : 
     404             :                 /* Verify that the symlink in the FS actually belongs
     405             :                  * to this device. This is useful to deal with
     406             :                  * conflicting devices, e.g. when two disks want the
     407             :                  * same /dev/disk/by-label/xxx link because they have
     408             :                  * the same label. We want to make sure that the same
     409             :                  * device that won the symlink wins in systemd, so we
     410             :                  * check the device node major/minor */
     411         180 :                 if (stat(p, &st) >= 0)
     412         360 :                         if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
     413         180 :                             st.st_rdev != udev_device_get_devnum(dev))
     414           0 :                                 continue;
     415             : 
     416         180 :                 (void) device_setup_unit(m, dev, p, false);
     417             :         }
     418             : 
     419             :         /* Add additional units for all explicitly configured
     420             :          * aliases */
     421         210 :         alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
     422         210 :         if (alias) {
     423             :                 const char *word, *state;
     424             :                 size_t l;
     425             : 
     426         160 :                 FOREACH_WORD_QUOTED(word, l, alias, state) {
     427          90 :                         char e[l+1];
     428             : 
     429          90 :                         memcpy(e, word, l);
     430          90 :                         e[l] = 0;
     431             : 
     432          90 :                         if (path_is_absolute(e))
     433          90 :                                 (void) device_setup_unit(m, dev, e, false);
     434             :                         else
     435           0 :                                 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
     436             :                 }
     437          70 :                 if (!isempty(state))
     438           0 :                         log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
     439             :         }
     440             : 
     441         210 :         return 0;
     442             : }
     443             : 
     444         560 : static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
     445             :         DeviceFound n, previous;
     446             : 
     447         560 :         assert(d);
     448             : 
     449         560 :         n = add ? (d->found | found) : (d->found & ~found);
     450         560 :         if (n == d->found)
     451           0 :                 return;
     452             : 
     453         560 :         previous = d->found;
     454         560 :         d->found = n;
     455             : 
     456         560 :         if (!now)
     457         560 :                 return;
     458             : 
     459           0 :         if (d->found & DEVICE_FOUND_UDEV)
     460             :                 /* When the device is known to udev we consider it
     461             :                  * plugged. */
     462           0 :                 device_set_state(d, DEVICE_PLUGGED);
     463           0 :         else if (d->found != DEVICE_NOT_FOUND && (previous & DEVICE_FOUND_UDEV) == 0)
     464             :                 /* If the device has not been seen by udev yet, but is
     465             :                  * now referenced by the kernel, then we assume the
     466             :                  * kernel knows it now, and udev might soon too. */
     467           0 :                 device_set_state(d, DEVICE_TENTATIVE);
     468             :         else
     469             :                 /* If nobody sees the device, or if the device was
     470             :                  * previously seen by udev and now is only referenced
     471             :                  * from the kernel, then we consider the device is
     472             :                  * gone, the kernel just hasn't noticed it yet. */
     473           0 :                 device_set_state(d, DEVICE_DEAD);
     474             : }
     475             : 
     476         210 : static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
     477             :         Device *d, *l;
     478             : 
     479         210 :         assert(m);
     480         210 :         assert(sysfs);
     481             : 
     482         210 :         if (found == DEVICE_NOT_FOUND)
     483           0 :                 return 0;
     484             : 
     485         210 :         l = hashmap_get(m->devices_by_sysfs, sysfs);
     486         760 :         LIST_FOREACH(same_sysfs, d, l)
     487         550 :                 device_update_found_one(d, add, found, now);
     488             : 
     489         210 :         return 0;
     490             : }
     491             : 
     492          10 : static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
     493          20 :         _cleanup_free_ char *e = NULL;
     494             :         Unit *u;
     495             :         int r;
     496             : 
     497          10 :         assert(m);
     498          10 :         assert(path);
     499             : 
     500          10 :         if (found == DEVICE_NOT_FOUND)
     501           0 :                 return 0;
     502             : 
     503          10 :         r = unit_name_from_path(path, ".device", &e);
     504          10 :         if (r < 0)
     505           0 :                 return log_error_errno(r, "Failed to generate unit name from device path: %m");
     506             : 
     507          10 :         u = manager_get_unit(m, e);
     508          10 :         if (!u)
     509           0 :                 return 0;
     510             : 
     511          10 :         device_update_found_one(DEVICE(u), add, found, now);
     512          10 :         return 0;
     513             : }
     514             : 
     515         210 : static bool device_is_ready(struct udev_device *dev) {
     516             :         const char *ready;
     517             : 
     518         210 :         assert(dev);
     519             : 
     520         210 :         ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
     521         210 :         if (!ready)
     522         210 :                 return true;
     523             : 
     524           0 :         return parse_boolean(ready) != 0;
     525             : }
     526             : 
     527         220 : static Unit *device_following(Unit *u) {
     528         220 :         Device *d = DEVICE(u);
     529         220 :         Device *other, *first = NULL;
     530             : 
     531         220 :         assert(d);
     532             : 
     533         220 :         if (startswith(u->id, "sys-"))
     534         112 :                 return NULL;
     535             : 
     536             :         /* Make everybody follow the unit that's named after the sysfs path */
     537         300 :         for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
     538         300 :                 if (startswith(UNIT(other)->id, "sys-"))
     539         108 :                         return UNIT(other);
     540             : 
     541           0 :         for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
     542           0 :                 if (startswith(UNIT(other)->id, "sys-"))
     543           0 :                         return UNIT(other);
     544             : 
     545           0 :                 first = other;
     546             :         }
     547             : 
     548           0 :         return UNIT(first);
     549             : }
     550             : 
     551         220 : static int device_following_set(Unit *u, Set **_set) {
     552         220 :         Device *d = DEVICE(u), *other;
     553             :         Set *set;
     554             :         int r;
     555             : 
     556         220 :         assert(d);
     557         220 :         assert(_set);
     558             : 
     559         220 :         if (LIST_JUST_US(same_sysfs, d)) {
     560          20 :                 *_set = NULL;
     561          20 :                 return 0;
     562             :         }
     563             : 
     564         200 :         set = set_new(NULL);
     565         200 :         if (!set)
     566           0 :                 return -ENOMEM;
     567             : 
     568         528 :         LIST_FOREACH_AFTER(same_sysfs, other, d) {
     569         328 :                 r = set_put(set, other);
     570         328 :                 if (r < 0)
     571           0 :                         goto fail;
     572             :         }
     573             : 
     574         528 :         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
     575         328 :                 r = set_put(set, other);
     576         328 :                 if (r < 0)
     577           0 :                         goto fail;
     578             :         }
     579             : 
     580         200 :         *_set = set;
     581         200 :         return 1;
     582             : 
     583             : fail:
     584           0 :         set_free(set);
     585           0 :         return r;
     586             : }
     587             : 
     588          11 : static void device_shutdown(Manager *m) {
     589          11 :         assert(m);
     590             : 
     591          11 :         m->udev_event_source = sd_event_source_unref(m->udev_event_source);
     592             : 
     593          11 :         if (m->udev_monitor) {
     594          10 :                 udev_monitor_unref(m->udev_monitor);
     595          10 :                 m->udev_monitor = NULL;
     596             :         }
     597             : 
     598          11 :         hashmap_free(m->devices_by_sysfs);
     599          11 :         m->devices_by_sysfs = NULL;
     600          11 : }
     601             : 
     602          10 : static int device_enumerate(Manager *m) {
     603          20 :         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
     604          10 :         struct udev_list_entry *item = NULL, *first = NULL;
     605             :         int r;
     606             : 
     607          10 :         assert(m);
     608             : 
     609          10 :         if (!m->udev_monitor) {
     610          10 :                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
     611          10 :                 if (!m->udev_monitor) {
     612           0 :                         r = -ENOMEM;
     613           0 :                         goto fail;
     614             :                 }
     615             : 
     616             :                 /* This will fail if we are unprivileged, but that
     617             :                  * should not matter much, as user instances won't run
     618             :                  * during boot. */
     619          10 :                 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
     620             : 
     621          10 :                 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
     622          10 :                 if (r < 0)
     623           0 :                         goto fail;
     624             : 
     625          10 :                 r = udev_monitor_enable_receiving(m->udev_monitor);
     626          10 :                 if (r < 0)
     627           0 :                         goto fail;
     628             : 
     629          10 :                 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
     630          10 :                 if (r < 0)
     631           0 :                         goto fail;
     632             : 
     633          10 :                 (void) sd_event_source_set_description(m->udev_event_source, "device");
     634             :         }
     635             : 
     636          10 :         e = udev_enumerate_new(m->udev);
     637          10 :         if (!e) {
     638           0 :                 r = -ENOMEM;
     639           0 :                 goto fail;
     640             :         }
     641             : 
     642          10 :         r = udev_enumerate_add_match_tag(e, "systemd");
     643          10 :         if (r < 0)
     644           0 :                 goto fail;
     645             : 
     646          10 :         r = udev_enumerate_add_match_is_initialized(e);
     647          10 :         if (r < 0)
     648           0 :                 goto fail;
     649             : 
     650          10 :         r = udev_enumerate_scan_devices(e);
     651          10 :         if (r < 0)
     652           0 :                 goto fail;
     653             : 
     654          10 :         first = udev_enumerate_get_list_entry(e);
     655         220 :         udev_list_entry_foreach(item, first) {
     656         420 :                 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
     657             :                 const char *sysfs;
     658             : 
     659         210 :                 sysfs = udev_list_entry_get_name(item);
     660             : 
     661         210 :                 dev = udev_device_new_from_syspath(m->udev, sysfs);
     662         210 :                 if (!dev) {
     663           0 :                         log_oom();
     664           0 :                         continue;
     665             :                 }
     666             : 
     667         210 :                 if (!device_is_ready(dev))
     668           0 :                         continue;
     669             : 
     670         210 :                 (void) device_process_new(m, dev);
     671             : 
     672         210 :                 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
     673             :         }
     674             : 
     675          10 :         return 0;
     676             : 
     677             : fail:
     678           0 :         log_error_errno(r, "Failed to enumerate devices: %m");
     679             : 
     680           0 :         device_shutdown(m);
     681           0 :         return r;
     682             : }
     683             : 
     684           0 : static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
     685           0 :         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
     686           0 :         Manager *m = userdata;
     687             :         const char *action, *sysfs;
     688             :         int r;
     689             : 
     690           0 :         assert(m);
     691             : 
     692           0 :         if (revents != EPOLLIN) {
     693             :                 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
     694             : 
     695           0 :                 if (!ratelimit_test(&limit))
     696           0 :                         log_error_errno(errno, "Failed to get udev event: %m");
     697           0 :                 if (!(revents & EPOLLIN))
     698           0 :                         return 0;
     699             :         }
     700             : 
     701             :         /*
     702             :          * libudev might filter-out devices which pass the bloom
     703             :          * filter, so getting NULL here is not necessarily an error.
     704             :          */
     705           0 :         dev = udev_monitor_receive_device(m->udev_monitor);
     706           0 :         if (!dev)
     707           0 :                 return 0;
     708             : 
     709           0 :         sysfs = udev_device_get_syspath(dev);
     710           0 :         if (!sysfs) {
     711           0 :                 log_error("Failed to get udev sys path.");
     712           0 :                 return 0;
     713             :         }
     714             : 
     715           0 :         action = udev_device_get_action(dev);
     716           0 :         if (!action) {
     717           0 :                 log_error("Failed to get udev action string.");
     718           0 :                 return 0;
     719             :         }
     720             : 
     721           0 :         if (streq(action, "remove"))  {
     722           0 :                 r = swap_process_device_remove(m, dev);
     723           0 :                 if (r < 0)
     724           0 :                         log_error_errno(r, "Failed to process swap device remove event: %m");
     725             : 
     726             :                 /* If we get notified that a device was removed by
     727             :                  * udev, then it's completely gone, hence unset all
     728             :                  * found bits */
     729           0 :                 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
     730             : 
     731           0 :         } else if (device_is_ready(dev)) {
     732             : 
     733           0 :                 (void) device_process_new(m, dev);
     734             : 
     735           0 :                 r = swap_process_device_new(m, dev);
     736           0 :                 if (r < 0)
     737           0 :                         log_error_errno(r, "Failed to process swap device new event: %m");
     738             : 
     739           0 :                 manager_dispatch_load_queue(m);
     740             : 
     741             :                 /* The device is found now, set the udev found bit */
     742           0 :                 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
     743             : 
     744             :         } else {
     745             :                 /* The device is nominally around, but not ready for
     746             :                  * us. Hence unset the udev bit, but leave the rest
     747             :                  * around. */
     748             : 
     749           0 :                 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
     750             :         }
     751             : 
     752           0 :         return 0;
     753             : }
     754             : 
     755         300 : static bool device_supported(void) {
     756             :         static int read_only = -1;
     757             : 
     758             :         /* If /sys is read-only we don't support device units, and any
     759             :          * attempts to start one should fail immediately. */
     760             : 
     761         300 :         if (read_only < 0)
     762           4 :                 read_only = path_is_read_only_fs("/sys");
     763             : 
     764         300 :         return read_only <= 0;
     765             : }
     766             : 
     767         290 : int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
     768         580 :         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
     769             :         struct stat st;
     770             : 
     771         290 :         assert(m);
     772         290 :         assert(node);
     773             : 
     774         290 :         if (!device_supported())
     775           0 :                 return 0;
     776             : 
     777             :         /* This is called whenever we find a device referenced in
     778             :          * /proc/swaps or /proc/self/mounts. Such a device might be
     779             :          * mounted/enabled at a time where udev has not finished
     780             :          * probing it yet, and we thus haven't learned about it
     781             :          * yet. In this case we will set the device unit to
     782             :          * "tentative" state. */
     783             : 
     784         290 :         if (add) {
     785         290 :                 if (!path_startswith(node, "/dev"))
     786         280 :                         return 0;
     787             : 
     788             :                 /* We make an extra check here, if the device node
     789             :                  * actually exists. If it's missing, then this is an
     790             :                  * indication that device was unplugged but is still
     791             :                  * referenced in /proc/swaps or
     792             :                  * /proc/self/mountinfo. Note that this check doesn't
     793             :                  * really cover all cases where a device might be gone
     794             :                  * away, since drives that can have a medium inserted
     795             :                  * will still have a device node even when the medium
     796             :                  * is not there... */
     797             : 
     798          10 :                 if (stat(node, &st) >= 0) {
     799          10 :                         if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
     800           0 :                                 return 0;
     801             : 
     802          10 :                         dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
     803          10 :                         if (!dev && errno != ENOENT)
     804           0 :                                 return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
     805             : 
     806           0 :                 } else if (errno != ENOENT)
     807           0 :                         return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
     808             : 
     809             :                 /* If the device is known in the kernel and newly
     810             :                  * appeared, then we'll create a device unit for it,
     811             :                  * under the name referenced in /proc/swaps or
     812             :                  * /proc/self/mountinfo. */
     813             : 
     814          10 :                 (void) device_setup_unit(m, dev, node, false);
     815             :         }
     816             : 
     817             :         /* Update the device unit's state, should it exist */
     818          10 :         return device_update_found_by_name(m, node, add, found, now);
     819             : }
     820             : 
     821             : static const char* const device_state_table[_DEVICE_STATE_MAX] = {
     822             :         [DEVICE_DEAD] = "dead",
     823             :         [DEVICE_TENTATIVE] = "tentative",
     824             :         [DEVICE_PLUGGED] = "plugged",
     825             : };
     826             : 
     827        1330 : DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
     828             : 
     829             : const UnitVTable device_vtable = {
     830             :         .object_size = sizeof(Device),
     831             :         .sections =
     832             :                 "Unit\0"
     833             :                 "Device\0"
     834             :                 "Install\0",
     835             : 
     836             :         .no_instances = true,
     837             : 
     838             :         .init = device_init,
     839             :         .done = device_done,
     840             :         .load = unit_load_fragment_and_dropin_optional,
     841             : 
     842             :         .coldplug = device_coldplug,
     843             : 
     844             :         .serialize = device_serialize,
     845             :         .deserialize_item = device_deserialize_item,
     846             : 
     847             :         .dump = device_dump,
     848             : 
     849             :         .active_state = device_active_state,
     850             :         .sub_state_to_string = device_sub_state_to_string,
     851             : 
     852             :         .bus_interface = "org.freedesktop.systemd1.Device",
     853             :         .bus_vtable = bus_device_vtable,
     854             : 
     855             :         .following = device_following,
     856             :         .following_set = device_following_set,
     857             : 
     858             :         .enumerate = device_enumerate,
     859             :         .shutdown = device_shutdown,
     860             :         .supported = device_supported,
     861             : 
     862             :         .status_message_formats = {
     863             :                 .starting_stopping = {
     864             :                         [0] = "Expecting device %s...",
     865             :                 },
     866             :                 .finished_start_job = {
     867             :                         [JOB_DONE]       = "Found device %s.",
     868             :                         [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
     869             :                 },
     870             :         },
     871             : };

Generated by: LCOV version 1.11