LCOV - code coverage report
Current view: top level - core - device.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 316 538 58.7 %
Date: 2019-08-22 15:41:25 Functions: 29 36 80.6 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <errno.h>
       4             : #include <sys/epoll.h>
       5             : 
       6             : #include "alloc-util.h"
       7             : #include "bus-error.h"
       8             : #include "dbus-device.h"
       9             : #include "dbus-unit.h"
      10             : #include "device-private.h"
      11             : #include "device-util.h"
      12             : #include "device.h"
      13             : #include "log.h"
      14             : #include "parse-util.h"
      15             : #include "path-util.h"
      16             : #include "serialize.h"
      17             : #include "stat-util.h"
      18             : #include "string-util.h"
      19             : #include "swap.h"
      20             : #include "udev-util.h"
      21             : #include "unit-name.h"
      22             : #include "unit.h"
      23             : 
      24             : static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
      25             :         [DEVICE_DEAD] = UNIT_INACTIVE,
      26             :         [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
      27             :         [DEVICE_PLUGGED] = UNIT_ACTIVE,
      28             : };
      29             : 
      30             : static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata);
      31             : static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask);
      32             : 
      33        2904 : static void device_unset_sysfs(Device *d) {
      34             :         Hashmap *devices;
      35             :         Device *first;
      36             : 
      37        2904 :         assert(d);
      38             : 
      39        2904 :         if (!d->sysfs)
      40        1452 :                 return;
      41             : 
      42             :         /* Remove this unit from the chain of devices which share the
      43             :          * same sysfs path. */
      44        1452 :         devices = UNIT(d)->manager->devices_by_sysfs;
      45        1452 :         first = hashmap_get(devices, d->sysfs);
      46        1452 :         LIST_REMOVE(same_sysfs, first, d);
      47             : 
      48        1452 :         if (first)
      49         869 :                 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
      50             :         else
      51         583 :                 hashmap_remove(devices, d->sysfs);
      52             : 
      53        1452 :         d->sysfs = mfree(d->sysfs);
      54             : }
      55             : 
      56        1507 : static int device_set_sysfs(Device *d, const char *sysfs) {
      57        1507 :         _cleanup_free_ char *copy = NULL;
      58             :         Device *first;
      59             :         int r;
      60             : 
      61        1507 :         assert(d);
      62             : 
      63        1507 :         if (streq_ptr(d->sysfs, sysfs))
      64          55 :                 return 0;
      65             : 
      66        1452 :         r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &path_hash_ops);
      67        1452 :         if (r < 0)
      68           0 :                 return r;
      69             : 
      70        1452 :         copy = strdup(sysfs);
      71        1452 :         if (!copy)
      72           0 :                 return -ENOMEM;
      73             : 
      74        1452 :         device_unset_sysfs(d);
      75             : 
      76        1452 :         first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
      77        1452 :         LIST_PREPEND(same_sysfs, first, d);
      78             : 
      79        1452 :         r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
      80        1452 :         if (r < 0) {
      81           0 :                 LIST_REMOVE(same_sysfs, first, d);
      82           0 :                 return r;
      83             :         }
      84             : 
      85        1452 :         d->sysfs = TAKE_PTR(copy);
      86        1452 :         return 0;
      87             : }
      88             : 
      89        1452 : static void device_init(Unit *u) {
      90        1452 :         Device *d = DEVICE(u);
      91             : 
      92        1452 :         assert(d);
      93        1452 :         assert(UNIT(d)->load_state == UNIT_STUB);
      94             : 
      95             :         /* In contrast to all other unit types we timeout jobs waiting
      96             :          * for devices by default. This is because they otherwise wait
      97             :          * indefinitely for plugged in devices, something which cannot
      98             :          * happen for the other units since their operations time out
      99             :          * anyway. */
     100        1452 :         u->job_running_timeout = u->manager->default_timeout_start_usec;
     101             : 
     102        1452 :         u->ignore_on_isolate = true;
     103             : 
     104        1452 :         d->deserialized_state = _DEVICE_STATE_INVALID;
     105        1452 : }
     106             : 
     107        1452 : static void device_done(Unit *u) {
     108        1452 :         Device *d = DEVICE(u);
     109             : 
     110        1452 :         assert(d);
     111             : 
     112        1452 :         device_unset_sysfs(d);
     113        1452 :         d->wants_property = strv_free(d->wants_property);
     114        1452 : }
     115             : 
     116        1452 : static int device_load(Unit *u) {
     117             :         int r;
     118             : 
     119        1452 :         r = unit_load_fragment_and_dropin_optional(u);
     120        1452 :         if (r < 0)
     121           0 :                 return r;
     122             : 
     123        1452 :         if (!u->description) {
     124             :                 /* Generate a description based on the path, to be used until the
     125             :                    device is initialized properly */
     126           0 :                 r = unit_name_to_path(u->id, &u->description);
     127           0 :                 if (r < 0)
     128           0 :                         log_unit_debug_errno(u, r, "Failed to unescape name: %m");
     129             :         }
     130             : 
     131        1452 :         return 0;
     132             : }
     133             : 
     134        1452 : static void device_set_state(Device *d, DeviceState state) {
     135             :         DeviceState old_state;
     136        1452 :         assert(d);
     137             : 
     138        1452 :         if (d->state != state)
     139        1452 :                 bus_unit_send_pending_change_signal(UNIT(d), false);
     140             : 
     141        1452 :         old_state = d->state;
     142        1452 :         d->state = state;
     143             : 
     144        1452 :         if (state == DEVICE_DEAD)
     145           0 :                 device_unset_sysfs(d);
     146             : 
     147        1452 :         if (state != old_state)
     148        1452 :                 log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
     149             : 
     150        1452 :         unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], 0);
     151        1452 : }
     152             : 
     153        1452 : static int device_coldplug(Unit *u) {
     154        1452 :         Device *d = DEVICE(u);
     155             : 
     156        1452 :         assert(d);
     157        1452 :         assert(d->state == DEVICE_DEAD);
     158             : 
     159             :         /* First, let's put the deserialized state and found mask into effect, if we have it. */
     160             : 
     161        1452 :         if (d->deserialized_state < 0 ||
     162           0 :             (d->deserialized_state == d->state &&
     163           0 :              d->deserialized_found == d->found))
     164        1452 :                 return 0;
     165             : 
     166           0 :         d->found = d->deserialized_found;
     167           0 :         device_set_state(d, d->deserialized_state);
     168           0 :         return 0;
     169             : }
     170             : 
     171        1452 : static void device_catchup(Unit *u) {
     172        1452 :         Device *d = DEVICE(u);
     173             : 
     174        1452 :         assert(d);
     175             : 
     176             :         /* Second, let's update the state with the enumerated state if it's different */
     177        1452 :         if (d->enumerated_found == d->found)
     178           0 :                 return;
     179             : 
     180        1452 :         device_update_found_one(d, d->enumerated_found, DEVICE_FOUND_MASK);
     181             : }
     182             : 
     183             : static const struct {
     184             :         DeviceFound flag;
     185             :         const char *name;
     186             : } device_found_map[] = {
     187             :         { DEVICE_FOUND_UDEV,  "found-udev"  },
     188             :         { DEVICE_FOUND_MOUNT, "found-mount" },
     189             :         { DEVICE_FOUND_SWAP,  "found-swap"  },
     190             : };
     191             : 
     192         792 : static int device_found_to_string_many(DeviceFound flags, char **ret) {
     193         792 :         _cleanup_free_ char *s = NULL;
     194             :         unsigned i;
     195             : 
     196         792 :         assert(ret);
     197             : 
     198        3168 :         for (i = 0; i < ELEMENTSOF(device_found_map); i++) {
     199        2376 :                 if (!FLAGS_SET(flags, device_found_map[i].flag))
     200        1560 :                         continue;
     201             : 
     202         816 :                 if (!strextend_with_separator(&s, ",", device_found_map[i].name, NULL))
     203           0 :                         return -ENOMEM;
     204             :         }
     205             : 
     206         792 :         *ret = TAKE_PTR(s);
     207             : 
     208         792 :         return 0;
     209             : }
     210             : 
     211           0 : static int device_found_from_string_many(const char *name, DeviceFound *ret) {
     212           0 :         DeviceFound flags = 0;
     213             :         int r;
     214             : 
     215           0 :         assert(ret);
     216             : 
     217           0 :         for (;;) {
     218           0 :                 _cleanup_free_ char *word = NULL;
     219           0 :                 DeviceFound f = 0;
     220             :                 unsigned i;
     221             : 
     222           0 :                 r = extract_first_word(&name, &word, ",", 0);
     223           0 :                 if (r < 0)
     224           0 :                         return r;
     225           0 :                 if (r == 0)
     226           0 :                         break;
     227             : 
     228           0 :                 for (i = 0; i < ELEMENTSOF(device_found_map); i++)
     229           0 :                         if (streq(word, device_found_map[i].name)) {
     230           0 :                                 f = device_found_map[i].flag;
     231           0 :                                 break;
     232             :                         }
     233             : 
     234           0 :                 if (f == 0)
     235           0 :                         return -EINVAL;
     236             : 
     237           0 :                 flags |= f;
     238             :         }
     239             : 
     240           0 :         *ret = flags;
     241           0 :         return 0;
     242             : }
     243             : 
     244           0 : static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
     245           0 :         _cleanup_free_ char *s = NULL;
     246           0 :         Device *d = DEVICE(u);
     247             : 
     248           0 :         assert(u);
     249           0 :         assert(f);
     250           0 :         assert(fds);
     251             : 
     252           0 :         (void) serialize_item(f, "state", device_state_to_string(d->state));
     253             : 
     254           0 :         if (device_found_to_string_many(d->found, &s) >= 0)
     255           0 :                 (void) serialize_item(f, "found", s);
     256             : 
     257           0 :         return 0;
     258             : }
     259             : 
     260           0 : static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
     261           0 :         Device *d = DEVICE(u);
     262             :         int r;
     263             : 
     264           0 :         assert(u);
     265           0 :         assert(key);
     266           0 :         assert(value);
     267           0 :         assert(fds);
     268             : 
     269           0 :         if (streq(key, "state")) {
     270             :                 DeviceState state;
     271             : 
     272           0 :                 state = device_state_from_string(value);
     273           0 :                 if (state < 0)
     274           0 :                         log_unit_debug(u, "Failed to parse state value, ignoring: %s", value);
     275             :                 else
     276           0 :                         d->deserialized_state = state;
     277             : 
     278           0 :         } else if (streq(key, "found")) {
     279           0 :                 r = device_found_from_string_many(value, &d->deserialized_found);
     280           0 :                 if (r < 0)
     281           0 :                         log_unit_debug_errno(u, r, "Failed to parse found value '%s', ignoring: %m", value);
     282             : 
     283             :         } else
     284           0 :                 log_unit_debug(u, "Unknown serialization key: %s", key);
     285             : 
     286           0 :         return 0;
     287             : }
     288             : 
     289         792 : static void device_dump(Unit *u, FILE *f, const char *prefix) {
     290         792 :         Device *d = DEVICE(u);
     291         792 :         _cleanup_free_ char *s = NULL;
     292             : 
     293         792 :         assert(d);
     294             : 
     295         792 :         (void) device_found_to_string_many(d->found, &s);
     296             : 
     297        1584 :         fprintf(f,
     298             :                 "%sDevice State: %s\n"
     299             :                 "%sSysfs Path: %s\n"
     300             :                 "%sFound: %s\n",
     301             :                 prefix, device_state_to_string(d->state),
     302         792 :                 prefix, strna(d->sysfs),
     303             :                 prefix, strna(s));
     304             : 
     305         792 :         if (!strv_isempty(d->wants_property)) {
     306             :                 char **i;
     307             : 
     308           0 :                 STRV_FOREACH(i, d->wants_property)
     309           0 :                         fprintf(f, "%sudev SYSTEMD_WANTS: %s\n",
     310             :                                 prefix, *i);
     311             :         }
     312         792 : }
     313             : 
     314        7392 : _pure_ static UnitActiveState device_active_state(Unit *u) {
     315        7392 :         assert(u);
     316             : 
     317        7392 :         return state_translation_table[DEVICE(u)->state];
     318             : }
     319             : 
     320           0 : _pure_ static const char *device_sub_state_to_string(Unit *u) {
     321           0 :         assert(u);
     322             : 
     323           0 :         return device_state_to_string(DEVICE(u)->state);
     324             : }
     325             : 
     326        1507 : static int device_update_description(Unit *u, sd_device *dev, const char *path) {
     327        1507 :         _cleanup_free_ char *j = NULL;
     328             :         const char *model, *label, *desc;
     329             :         int r;
     330             : 
     331        1507 :         assert(u);
     332        1507 :         assert(path);
     333             : 
     334        1507 :         desc = path;
     335             : 
     336        3014 :         if (dev &&
     337        2915 :             (sd_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE", &model) >= 0 ||
     338        1408 :              sd_device_get_property_value(dev, "ID_MODEL", &model) >= 0)) {
     339         396 :                 desc = model;
     340             : 
     341             :                 /* Try to concatenate the device model string with a label, if there is one */
     342         792 :                 if (sd_device_get_property_value(dev, "ID_FS_LABEL", &label) >= 0 ||
     343         792 :                     sd_device_get_property_value(dev, "ID_PART_ENTRY_NAME", &label) >= 0 ||
     344         396 :                     sd_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER", &label) >= 0) {
     345             : 
     346         165 :                         desc = j = strjoin(model, " ", label);
     347         165 :                         if (!j)
     348           0 :                                 return log_oom();
     349             :                 }
     350             :         }
     351             : 
     352        1507 :         r = unit_set_description(u, desc);
     353        1507 :         if (r < 0)
     354           0 :                 return log_unit_error_errno(u, r, "Failed to set device description: %m");
     355             : 
     356        1507 :         return 0;
     357             : }
     358             : 
     359         572 : static int device_add_udev_wants(Unit *u, sd_device *dev) {
     360         572 :         _cleanup_strv_free_ char **added = NULL;
     361             :         const char *wants, *property;
     362         572 :         Device *d = DEVICE(u);
     363             :         int r;
     364             : 
     365         572 :         assert(d);
     366         572 :         assert(dev);
     367             : 
     368         572 :         property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
     369             : 
     370         572 :         r = sd_device_get_property_value(dev, property, &wants);
     371         572 :         if (r < 0)
     372         572 :                 return 0;
     373             : 
     374           0 :         for (;;) {
     375           0 :                 _cleanup_free_ char *word = NULL, *k = NULL;
     376             : 
     377           0 :                 r = extract_first_word(&wants, &word, NULL, EXTRACT_UNQUOTE);
     378           0 :                 if (r == 0)
     379           0 :                         break;
     380           0 :                 if (r == -ENOMEM)
     381           0 :                         return log_oom();
     382           0 :                 if (r < 0)
     383           0 :                         return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
     384             : 
     385           0 :                 if (unit_name_is_valid(word, UNIT_NAME_TEMPLATE) && d->sysfs) {
     386           0 :                         _cleanup_free_ char *escaped = NULL;
     387             : 
     388             :                         /* If the unit name is specified as template, then automatically fill in the sysfs path of the
     389             :                          * device as instance name, properly escaped. */
     390             : 
     391           0 :                         r = unit_name_path_escape(d->sysfs, &escaped);
     392           0 :                         if (r < 0)
     393           0 :                                 return log_unit_error_errno(u, r, "Failed to escape %s: %m", d->sysfs);
     394             : 
     395           0 :                         r = unit_name_replace_instance(word, escaped, &k);
     396           0 :                         if (r < 0)
     397           0 :                                 return log_unit_error_errno(u, r, "Failed to build %s instance of template %s: %m", escaped, word);
     398             :                 } else {
     399             :                         /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */
     400             : 
     401           0 :                         r = unit_name_mangle(word, UNIT_NAME_MANGLE_WARN, &k);
     402           0 :                         if (r < 0)
     403           0 :                                 return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
     404             :                 }
     405             : 
     406           0 :                 r = unit_add_dependency_by_name(u, UNIT_WANTS, k, true, UNIT_DEPENDENCY_UDEV);
     407           0 :                 if (r < 0)
     408           0 :                         return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
     409             : 
     410           0 :                 r = strv_push(&added, k);
     411           0 :                 if (r < 0)
     412           0 :                         return log_oom();
     413             : 
     414           0 :                 k = NULL;
     415             :         }
     416             : 
     417           0 :         if (d->state != DEVICE_DEAD) {
     418             :                 char **i;
     419             : 
     420             :                 /* So here's a special hack, to compensate for the fact that the udev database's reload cycles are not
     421             :                  * synchronized with our own reload cycles: when we detect that the SYSTEMD_WANTS property of a device
     422             :                  * changes while the device unit is already up, let's manually trigger any new units listed in it not
     423             :                  * seen before. This typically happens during the boot-time switch root transition, as udev devices
     424             :                  * will generally already be up in the initrd, but SYSTEMD_WANTS properties get then added through udev
     425             :                  * rules only available on the host system, and thus only when the initial udev coldplug trigger runs.
     426             :                  *
     427             :                  * We do this only if the device has been up already when we parse this, as otherwise the usual
     428             :                  * dependency logic that is run from the dead → plugged transition will trigger these deps. */
     429             : 
     430           0 :                 STRV_FOREACH(i, added) {
     431           0 :                         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
     432             : 
     433           0 :                         if (strv_contains(d->wants_property, *i)) /* Was this unit already listed before? */
     434           0 :                                 continue;
     435             : 
     436           0 :                         r = manager_add_job_by_name(u->manager, JOB_START, *i, JOB_FAIL, NULL, &error, NULL);
     437           0 :                         if (r < 0)
     438           0 :                                 log_unit_warning_errno(u, r, "Failed to enqueue SYSTEMD_WANTS= job, ignoring: %s", bus_error_message(&error, r));
     439             :                 }
     440             :         }
     441             : 
     442           0 :         strv_free(d->wants_property);
     443           0 :         d->wants_property = TAKE_PTR(added);
     444             : 
     445           0 :         return 0;
     446             : }
     447             : 
     448        1507 : static bool device_is_bound_by_mounts(Device *d, sd_device *dev) {
     449             :         const char *bound_by;
     450             :         int r;
     451             : 
     452        1507 :         assert(d);
     453        1507 :         assert(dev);
     454             : 
     455        1507 :         if (sd_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND", &bound_by) >= 0) {
     456           0 :                 r = parse_boolean(bound_by);
     457           0 :                 if (r < 0)
     458           0 :                         log_device_warning_errno(dev, r, "Failed to parse SYSTEMD_MOUNT_DEVICE_BOUND='%s' udev property, ignoring: %m", bound_by);
     459             : 
     460           0 :                 d->bind_mounts = r > 0;
     461             :         } else
     462        1507 :                 d->bind_mounts = false;
     463             : 
     464        1507 :         return d->bind_mounts;
     465             : }
     466             : 
     467           0 : static void device_upgrade_mount_deps(Unit *u) {
     468             :         Unit *other;
     469             :         Iterator i;
     470             :         void *v;
     471             :         int r;
     472             : 
     473             :         /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
     474             : 
     475           0 :         HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRED_BY], i) {
     476           0 :                 if (other->type != UNIT_MOUNT)
     477           0 :                         continue;
     478             : 
     479           0 :                 r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
     480           0 :                 if (r < 0)
     481           0 :                         log_unit_warning_errno(u, r, "Failed to add BindsTo= dependency between device and mount unit, ignoring: %m");
     482             :         }
     483           0 : }
     484             : 
     485        1507 : static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool main) {
     486        1507 :         _cleanup_free_ char *e = NULL;
     487        1507 :         const char *sysfs = NULL;
     488        1507 :         Unit *u = NULL;
     489             :         bool delete;
     490             :         int r;
     491             : 
     492        1507 :         assert(m);
     493        1507 :         assert(path);
     494             : 
     495        1507 :         if (dev) {
     496        1507 :                 r = sd_device_get_syspath(dev, &sysfs);
     497        1507 :                 if (r < 0) {
     498           0 :                         log_device_debug_errno(dev, r, "Couldn't get syspath from device, ignoring: %m");
     499           0 :                         return 0;
     500             :                 }
     501             :         }
     502             : 
     503        1507 :         r = unit_name_from_path(path, ".device", &e);
     504        1507 :         if (r < 0)
     505           0 :                 return log_device_error_errno(dev, r, "Failed to generate unit name from device path: %m");
     506             : 
     507        1507 :         u = manager_get_unit(m, e);
     508        1507 :         if (u) {
     509             :                 /* The device unit can still be present even if the device was unplugged: a mount unit can reference it
     510             :                  * hence preventing the GC to have garbaged it. That's desired since the device unit may have a
     511             :                  * dependency on the mount unit which was added during the loading of the later. When the device is
     512             :                  * plugged the sysfs might not be initialized yet, as we serialize the device's state but do not
     513             :                  * serialize the sysfs path across reloads/reexecs. Hence, when coming back from a reload/restart we
     514             :                  * might have the state valid, but not the sysfs path. Hence, let's filter out conflicting devices, but
     515             :                  * let's accept devices in any state with no sysfs path set. */
     516             : 
     517          55 :                 if (DEVICE(u)->state == DEVICE_PLUGGED &&
     518           0 :                     DEVICE(u)->sysfs &&
     519           0 :                     sysfs &&
     520           0 :                     !path_equal(DEVICE(u)->sysfs, sysfs)) {
     521           0 :                         log_unit_debug(u, "Device %s appeared twice with different sysfs paths %s and %s, ignoring the latter.",
     522             :                                        e, DEVICE(u)->sysfs, sysfs);
     523           0 :                         return -EEXIST;
     524             :                 }
     525             : 
     526          55 :                 delete = false;
     527             : 
     528             :                 /* Let's remove all dependencies generated due to udev properties. We'll re-add whatever is configured
     529             :                  * now below. */
     530          55 :                 unit_remove_dependencies(u, UNIT_DEPENDENCY_UDEV);
     531             :         } else {
     532        1452 :                 delete = true;
     533             : 
     534        1452 :                 r = unit_new_for_name(m, sizeof(Device), e, &u);
     535        1452 :                 if (r < 0) {
     536           0 :                         log_device_error_errno(dev, r, "Failed to allocate device unit %s: %m", e);
     537           0 :                         goto fail;
     538             :                 }
     539             : 
     540        1452 :                 unit_add_to_load_queue(u);
     541             :         }
     542             : 
     543             :         /* If this was created via some dependency and has not actually been seen yet ->sysfs will not be
     544             :          * initialized. Hence initialize it if necessary. */
     545        1507 :         if (sysfs) {
     546        1507 :                 r = device_set_sysfs(DEVICE(u), sysfs);
     547        1507 :                 if (r < 0) {
     548           0 :                         log_unit_error_errno(u, r, "Failed to set sysfs path %s: %m", sysfs);
     549           0 :                         goto fail;
     550             :                 }
     551             : 
     552             :                 /* The additional systemd udev properties we only interpret for the main object */
     553        1507 :                 if (main)
     554         572 :                         (void) device_add_udev_wants(u, dev);
     555             :         }
     556             : 
     557        1507 :         (void) device_update_description(u, dev, path);
     558             : 
     559             :         /* So the user wants the mount units to be bound to the device but a mount unit might has been seen by systemd
     560             :          * before the device appears on its radar. In this case the device unit is partially initialized and includes
     561             :          * the deps on the mount unit but at that time the "bind mounts" flag wasn't not present. Fix this up now. */
     562        1507 :         if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
     563           0 :                 device_upgrade_mount_deps(u);
     564             : 
     565             :         /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */
     566        1507 :         unit_add_to_dbus_queue(u);
     567             : 
     568        1507 :         return 0;
     569             : 
     570           0 : fail:
     571           0 :         if (delete)
     572           0 :                 unit_free(u);
     573             : 
     574           0 :         return r;
     575             : }
     576             : 
     577         572 : static int device_process_new(Manager *m, sd_device *dev) {
     578             :         const char *sysfs, *dn, *alias;
     579             :         dev_t devnum;
     580             :         int r;
     581             : 
     582         572 :         assert(m);
     583             : 
     584         572 :         if (sd_device_get_syspath(dev, &sysfs) < 0)
     585           0 :                 return 0;
     586             : 
     587             :         /* Add the main unit named after the sysfs path */
     588         572 :         r = device_setup_unit(m, dev, sysfs, true);
     589         572 :         if (r < 0)
     590           0 :                 return r;
     591             : 
     592             :         /* Add an additional unit for the device node */
     593         572 :         if (sd_device_get_devname(dev, &dn) >= 0)
     594         440 :                 (void) device_setup_unit(m, dev, dn, false);
     595             : 
     596             :         /* Add additional units for all symlinks */
     597         572 :         if (sd_device_get_devnum(dev, &devnum) >= 0) {
     598             :                 const char *p;
     599             : 
     600         792 :                 FOREACH_DEVICE_DEVLINK(dev, p) {
     601             :                         struct stat st;
     602             : 
     603         352 :                         if (PATH_STARTSWITH_SET(p, "/dev/block/", "/dev/char/"))
     604           0 :                                 continue;
     605             : 
     606             :                         /* Verify that the symlink in the FS actually belongs
     607             :                          * to this device. This is useful to deal with
     608             :                          * conflicting devices, e.g. when two disks want the
     609             :                          * same /dev/disk/by-label/xxx link because they have
     610             :                          * the same label. We want to make sure that the same
     611             :                          * device that won the symlink wins in systemd, so we
     612             :                          * check the device node major/minor */
     613         352 :                         if (stat(p, &st) >= 0 &&
     614         352 :                             ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
     615         352 :                              st.st_rdev != devnum))
     616           0 :                                 continue;
     617             : 
     618         352 :                         (void) device_setup_unit(m, dev, p, false);
     619             :                 }
     620             :         }
     621             : 
     622             :         /* Add additional units for all explicitly configured aliases */
     623         572 :         if (sd_device_get_property_value(dev, "SYSTEMD_ALIAS", &alias) < 0)
     624         495 :                 return 0;
     625             : 
     626          88 :         for (;;) {
     627         165 :                 _cleanup_free_ char *word = NULL;
     628             : 
     629         165 :                 r = extract_first_word(&alias, &word, NULL, EXTRACT_UNQUOTE);
     630         165 :                 if (r == 0)
     631          77 :                         break;
     632          88 :                 if (r == -ENOMEM)
     633           0 :                         return log_oom();
     634          88 :                 if (r < 0)
     635           0 :                         return log_device_warning_errno(dev, r, "Failed to parse SYSTEMD_ALIAS property: %m");
     636             : 
     637          88 :                 if (!path_is_absolute(word))
     638           0 :                         log_device_warning(dev, "SYSTEMD_ALIAS is not an absolute path, ignoring: %s", word);
     639          88 :                 else if (!path_is_normalized(word))
     640           0 :                         log_device_warning(dev, "SYSTEMD_ALIAS is not a normalized path, ignoring: %s", word);
     641             :                 else
     642          88 :                         (void) device_setup_unit(m, dev, word, false);
     643             :         }
     644             : 
     645          77 :         return 0;
     646             : }
     647             : 
     648        1452 : static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
     649        1452 :         assert(d);
     650             : 
     651             :         /* Didn't exist before, but does now? if so, generate a new invocation ID for it */
     652        1452 :         if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
     653        1452 :                 (void) unit_acquire_invocation_id(UNIT(d));
     654             : 
     655        1452 :         if (FLAGS_SET(now, DEVICE_FOUND_UDEV))
     656             :                 /* When the device is known to udev we consider it plugged. */
     657        1441 :                 device_set_state(d, DEVICE_PLUGGED);
     658          11 :         else if (now != DEVICE_NOT_FOUND && !FLAGS_SET(previous, DEVICE_FOUND_UDEV))
     659             :                 /* If the device has not been seen by udev yet, but is now referenced by the kernel, then we assume the
     660             :                  * kernel knows it now, and udev might soon too. */
     661          11 :                 device_set_state(d, DEVICE_TENTATIVE);
     662             :         else
     663             :                 /* If nobody sees the device, or if the device was previously seen by udev and now is only referenced
     664             :                  * from the kernel, then we consider the device is gone, the kernel just hasn't noticed it yet. */
     665           0 :                 device_set_state(d, DEVICE_DEAD);
     666        1452 : }
     667             : 
     668        2948 : static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
     669             :         Manager *m;
     670             : 
     671        2948 :         assert(d);
     672             : 
     673        2948 :         m = UNIT(d)->manager;
     674             : 
     675        4400 :         if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) {
     676             :                 DeviceFound n, previous;
     677             : 
     678             :                 /* When we are already running, then apply the new mask right-away, and trigger state changes
     679             :                  * right-away */
     680             : 
     681        1452 :                 n = (d->found & ~mask) | (found & mask);
     682        1452 :                 if (n == d->found)
     683           0 :                         return;
     684             : 
     685        1452 :                 previous = d->found;
     686        1452 :                 d->found = n;
     687             : 
     688        1452 :                 device_found_changed(d, previous, n);
     689             :         } else
     690             :                 /* We aren't running yet, let's apply the new mask to the shadow variable instead, which we'll apply as
     691             :                  * soon as we catch-up with the state. */
     692        1496 :                 d->enumerated_found = (d->enumerated_found & ~mask) | (found & mask);
     693             : }
     694             : 
     695         572 : static void device_update_found_by_sysfs(Manager *m, const char *sysfs, DeviceFound found, DeviceFound mask) {
     696             :         Device *d, *l, *n;
     697             : 
     698         572 :         assert(m);
     699         572 :         assert(sysfs);
     700             : 
     701         572 :         if (mask == 0)
     702           0 :                 return;
     703             : 
     704         572 :         l = hashmap_get(m->devices_by_sysfs, sysfs);
     705        2013 :         LIST_FOREACH_SAFE(same_sysfs, d, n, l)
     706        1441 :                 device_update_found_one(d, found, mask);
     707             : }
     708             : 
     709          55 : static int device_update_found_by_name(Manager *m, const char *path, DeviceFound found, DeviceFound mask) {
     710          55 :         _cleanup_free_ char *e = NULL;
     711             :         Unit *u;
     712             :         int r;
     713             : 
     714          55 :         assert(m);
     715          55 :         assert(path);
     716             : 
     717          55 :         if (mask == 0)
     718           0 :                 return 0;
     719             : 
     720          55 :         r = unit_name_from_path(path, ".device", &e);
     721          55 :         if (r < 0)
     722           0 :                 return log_error_errno(r, "Failed to generate unit name from device path: %m");
     723             : 
     724          55 :         u = manager_get_unit(m, e);
     725          55 :         if (!u)
     726           0 :                 return 0;
     727             : 
     728          55 :         device_update_found_one(DEVICE(u), found, mask);
     729          55 :         return 0;
     730             : }
     731             : 
     732         605 : static bool device_is_ready(sd_device *dev) {
     733             :         const char *ready;
     734             : 
     735         605 :         assert(dev);
     736             : 
     737         605 :         if (device_is_renaming(dev) > 0)
     738           0 :                 return false;
     739             : 
     740         605 :         if (sd_device_get_property_value(dev, "SYSTEMD_READY", &ready) < 0)
     741         561 :                 return true;
     742             : 
     743          44 :         return parse_boolean(ready) != 0;
     744             : }
     745             : 
     746         792 : static Unit *device_following(Unit *u) {
     747         792 :         Device *d = DEVICE(u);
     748         792 :         Device *other, *first = NULL;
     749             : 
     750         792 :         assert(d);
     751             : 
     752         792 :         if (startswith(u->id, "sys-"))
     753         348 :                 return NULL;
     754             : 
     755             :         /* Make everybody follow the unit that's named after the sysfs path */
     756         900 :         LIST_FOREACH_AFTER(same_sysfs, other, d)
     757         870 :                 if (startswith(UNIT(other)->id, "sys-"))
     758         414 :                         return UNIT(other);
     759             : 
     760          30 :         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
     761          24 :                 if (startswith(UNIT(other)->id, "sys-"))
     762          24 :                         return UNIT(other);
     763             : 
     764           0 :                 first = other;
     765             :         }
     766             : 
     767           6 :         return UNIT(first);
     768             : }
     769             : 
     770         792 : static int device_following_set(Unit *u, Set **_set) {
     771         792 :         Device *d = DEVICE(u), *other;
     772         792 :         _cleanup_set_free_ Set *set = NULL;
     773             :         int r;
     774             : 
     775         792 :         assert(d);
     776         792 :         assert(_set);
     777             : 
     778         792 :         if (LIST_JUST_US(same_sysfs, d)) {
     779          42 :                 *_set = NULL;
     780          42 :                 return 0;
     781             :         }
     782             : 
     783         750 :         set = set_new(NULL);
     784         750 :         if (!set)
     785           0 :                 return -ENOMEM;
     786             : 
     787        1800 :         LIST_FOREACH_AFTER(same_sysfs, other, d) {
     788        1050 :                 r = set_put(set, other);
     789        1050 :                 if (r < 0)
     790           0 :                         return r;
     791             :         }
     792             : 
     793        1800 :         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
     794        1050 :                 r = set_put(set, other);
     795        1050 :                 if (r < 0)
     796           0 :                         return r;
     797             :         }
     798             : 
     799         750 :         *_set = TAKE_PTR(set);
     800         750 :         return 1;
     801             : }
     802             : 
     803          14 : static void device_shutdown(Manager *m) {
     804          14 :         assert(m);
     805             : 
     806          14 :         m->device_monitor = sd_device_monitor_unref(m->device_monitor);
     807          14 :         m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
     808          14 : }
     809             : 
     810          11 : static void device_enumerate(Manager *m) {
     811          11 :         _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
     812             :         sd_device *dev;
     813             :         int r;
     814             : 
     815          11 :         assert(m);
     816             : 
     817          11 :         if (!m->device_monitor) {
     818          11 :                 r = sd_device_monitor_new(&m->device_monitor);
     819          11 :                 if (r < 0) {
     820           0 :                         log_error_errno(r, "Failed to allocate device monitor: %m");
     821           0 :                         goto fail;
     822             :                 }
     823             : 
     824             :                 /* This will fail if we are unprivileged, but that
     825             :                  * should not matter much, as user instances won't run
     826             :                  * during boot. */
     827          11 :                 (void) sd_device_monitor_set_receive_buffer_size(m->device_monitor, 128*1024*1024);
     828             : 
     829          11 :                 r = sd_device_monitor_filter_add_match_tag(m->device_monitor, "systemd");
     830          11 :                 if (r < 0) {
     831           0 :                         log_error_errno(r, "Failed to add udev tag match: %m");
     832           0 :                         goto fail;
     833             :                 }
     834             : 
     835          11 :                 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
     836          11 :                 if (r < 0) {
     837           0 :                         log_error_errno(r, "Failed to attach event to device monitor: %m");
     838           0 :                         goto fail;
     839             :                 }
     840             : 
     841          11 :                 r = sd_device_monitor_start(m->device_monitor, device_dispatch_io, m);
     842          11 :                 if (r < 0) {
     843           0 :                         log_error_errno(r, "Failed to start device monitor: %m");
     844           0 :                         goto fail;
     845             :                 }
     846             :         }
     847             : 
     848          11 :         r = sd_device_enumerator_new(&e);
     849          11 :         if (r < 0) {
     850           0 :                 log_error_errno(r, "Failed to allocate device enumerator: %m");
     851           0 :                 goto fail;
     852             :         }
     853             : 
     854          11 :         r = sd_device_enumerator_add_match_tag(e, "systemd");
     855          11 :         if (r < 0) {
     856           0 :                 log_error_errno(r, "Failed to set tag for device enumeration: %m");
     857           0 :                 goto fail;
     858             :         }
     859             : 
     860         616 :         FOREACH_DEVICE(e, dev) {
     861             :                 const char *sysfs;
     862             : 
     863         605 :                 if (!device_is_ready(dev))
     864          33 :                         continue;
     865             : 
     866         572 :                 (void) device_process_new(m, dev);
     867             : 
     868         572 :                 if (sd_device_get_syspath(dev, &sysfs) < 0)
     869           0 :                         continue;
     870             : 
     871         572 :                 device_update_found_by_sysfs(m, sysfs, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV);
     872             :         }
     873             : 
     874          11 :         return;
     875             : 
     876           0 : fail:
     877           0 :         device_shutdown(m);
     878             : }
     879             : 
     880           0 : static void device_propagate_reload_by_sysfs(Manager *m, const char *sysfs) {
     881             :         Device *d, *l, *n;
     882             :         int r;
     883             : 
     884           0 :         assert(m);
     885           0 :         assert(sysfs);
     886             : 
     887           0 :         l = hashmap_get(m->devices_by_sysfs, sysfs);
     888           0 :         LIST_FOREACH_SAFE(same_sysfs, d, n, l) {
     889           0 :                 if (d->state == DEVICE_DEAD)
     890           0 :                         continue;
     891             : 
     892           0 :                 r = manager_propagate_reload(m, UNIT(d), JOB_REPLACE, NULL);
     893           0 :                 if (r < 0)
     894           0 :                         log_warning_errno(r, "Failed to propagate reload, ignoring: %m");
     895             :         }
     896           0 : }
     897             : 
     898           0 : static int device_dispatch_io(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
     899           0 :         Manager *m = userdata;
     900             :         DeviceAction action;
     901             :         const char *sysfs;
     902             :         int r;
     903             : 
     904           0 :         assert(m);
     905           0 :         assert(dev);
     906             : 
     907           0 :         r = sd_device_get_syspath(dev, &sysfs);
     908           0 :         if (r < 0) {
     909           0 :                 log_device_error_errno(dev, r, "Failed to get device sys path: %m");
     910           0 :                 return 0;
     911             :         }
     912             : 
     913           0 :         r = device_get_action(dev, &action);
     914           0 :         if (r < 0) {
     915           0 :                 log_device_error_errno(dev, r, "Failed to get udev action: %m");
     916           0 :                 return 0;
     917             :         }
     918             : 
     919           0 :         if (action == DEVICE_ACTION_CHANGE)
     920           0 :                 device_propagate_reload_by_sysfs(m, sysfs);
     921             : 
     922             :         /* A change event can signal that a device is becoming ready, in particular if
     923             :          * the device is using the SYSTEMD_READY logic in udev
     924             :          * so we need to reach the else block of the following if, even for change events */
     925           0 :         if (action == DEVICE_ACTION_REMOVE) {
     926           0 :                 r = swap_process_device_remove(m, dev);
     927           0 :                 if (r < 0)
     928           0 :                         log_device_warning_errno(dev, r, "Failed to process swap device remove event, ignoring: %m");
     929             : 
     930             :                 /* If we get notified that a device was removed by
     931             :                  * udev, then it's completely gone, hence unset all
     932             :                  * found bits */
     933           0 :                 device_update_found_by_sysfs(m, sysfs, 0, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP);
     934             : 
     935           0 :         } else if (device_is_ready(dev)) {
     936             : 
     937           0 :                 (void) device_process_new(m, dev);
     938             : 
     939           0 :                 r = swap_process_device_new(m, dev);
     940           0 :                 if (r < 0)
     941           0 :                         log_device_warning_errno(dev, r, "Failed to process swap device new event, ignoring: %m");
     942             : 
     943           0 :                 manager_dispatch_load_queue(m);
     944             : 
     945             :                 /* The device is found now, set the udev found bit */
     946           0 :                 device_update_found_by_sysfs(m, sysfs, DEVICE_FOUND_UDEV, DEVICE_FOUND_UDEV);
     947             : 
     948             :         } else {
     949             :                 /* The device is nominally around, but not ready for
     950             :                  * us. Hence unset the udev bit, but leave the rest
     951             :                  * around. */
     952             : 
     953           0 :                 device_update_found_by_sysfs(m, sysfs, 0, DEVICE_FOUND_UDEV);
     954             :         }
     955             : 
     956           0 :         return 0;
     957             : }
     958             : 
     959         495 : static bool device_supported(void) {
     960             :         static int read_only = -1;
     961             : 
     962             :         /* If /sys is read-only we don't support device units, and any
     963             :          * attempts to start one should fail immediately. */
     964             : 
     965         495 :         if (read_only < 0)
     966           5 :                 read_only = path_is_read_only_fs("/sys");
     967             : 
     968         495 :         return read_only <= 0;
     969             : }
     970             : 
     971         440 : static int validate_node(Manager *m, const char *node, sd_device **ret) {
     972             :         struct stat st;
     973             :         int r;
     974             : 
     975         440 :         assert(m);
     976         440 :         assert(node);
     977         440 :         assert(ret);
     978             : 
     979             :         /* Validates a device node that showed up in /proc/swaps or /proc/self/mountinfo if it makes sense for us to
     980             :          * track. Note that this validator is fine within missing device nodes, but not with badly set up ones! */
     981             : 
     982         440 :         if (!path_startswith(node, "/dev")) {
     983         385 :                 *ret = NULL;
     984         385 :                 return 0; /* bad! */
     985             :         }
     986             : 
     987          55 :         if (stat(node, &st) < 0) {
     988           0 :                 if (errno != ENOENT)
     989           0 :                         return log_error_errno(errno, "Failed to stat() device node file %s: %m", node);
     990             : 
     991           0 :                 *ret = NULL;
     992           0 :                 return 1; /* good! (though missing) */
     993             : 
     994             :         } else {
     995          55 :                 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
     996             : 
     997          55 :                 r = device_new_from_stat_rdev(&dev, &st);
     998          55 :                 if (r == -ENOENT) {
     999           0 :                         *ret = NULL;
    1000           0 :                         return 1; /* good! (though missing) */
    1001          55 :                 } else if (r == -ENOTTY) {
    1002           0 :                         *ret = NULL;
    1003           0 :                         return 0; /* bad! (not a device node but some other kind of file system node) */
    1004          55 :                 } else if (r < 0)
    1005           0 :                         return log_error_errno(r, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
    1006             : 
    1007          55 :                 *ret = TAKE_PTR(dev);
    1008          55 :                 return 1; /* good! */
    1009             :         }
    1010             : }
    1011             : 
    1012         440 : void device_found_node(Manager *m, const char *node, DeviceFound found, DeviceFound mask) {
    1013             :         int r;
    1014             : 
    1015         440 :         assert(m);
    1016         440 :         assert(node);
    1017             : 
    1018         440 :         if (!device_supported())
    1019           0 :                 return;
    1020             : 
    1021         440 :         if (mask == 0)
    1022           0 :                 return;
    1023             : 
    1024             :         /* This is called whenever we find a device referenced in /proc/swaps or /proc/self/mounts. Such a device might
    1025             :          * be mounted/enabled at a time where udev has not finished probing it yet, and we thus haven't learned about
    1026             :          * it yet. In this case we will set the device unit to "tentative" state.
    1027             :          *
    1028             :          * This takes a pair of DeviceFound flags parameters. The 'mask' parameter is a bit mask that indicates which
    1029             :          * bits of 'found' to copy into the per-device DeviceFound flags field. Thus, this function may be used to set
    1030             :          * and unset individual bits in a single call, while merging partially with previous state. */
    1031             : 
    1032         440 :         if ((found & mask) != 0) {
    1033         440 :                 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
    1034             : 
    1035             :                 /* If the device is known in the kernel and newly appeared, then we'll create a device unit for it,
    1036             :                  * under the name referenced in /proc/swaps or /proc/self/mountinfo. But first, let's validate if
    1037             :                  * everything is alright with the device node. */
    1038             : 
    1039         440 :                 r = validate_node(m, node, &dev);
    1040         440 :                 if (r <= 0)
    1041         385 :                         return; /* Don't create a device unit for this if the device node is borked. */
    1042             : 
    1043          55 :                 (void) device_setup_unit(m, dev, node, false);
    1044             :         }
    1045             : 
    1046             :         /* Update the device unit's state, should it exist */
    1047          55 :         (void) device_update_found_by_name(m, node, found, mask);
    1048             : }
    1049             : 
    1050          33 : bool device_shall_be_bound_by(Unit *device, Unit *u) {
    1051          33 :         assert(device);
    1052          33 :         assert(u);
    1053             : 
    1054          33 :         if (u->type != UNIT_MOUNT)
    1055           0 :                 return false;
    1056             : 
    1057          33 :         return DEVICE(device)->bind_mounts;
    1058             : }
    1059             : 
    1060             : const UnitVTable device_vtable = {
    1061             :         .object_size = sizeof(Device),
    1062             :         .sections =
    1063             :                 "Unit\0"
    1064             :                 "Device\0"
    1065             :                 "Install\0",
    1066             : 
    1067             :         .gc_jobs = true,
    1068             : 
    1069             :         .init = device_init,
    1070             :         .done = device_done,
    1071             :         .load = device_load,
    1072             : 
    1073             :         .coldplug = device_coldplug,
    1074             :         .catchup = device_catchup,
    1075             : 
    1076             :         .serialize = device_serialize,
    1077             :         .deserialize_item = device_deserialize_item,
    1078             : 
    1079             :         .dump = device_dump,
    1080             : 
    1081             :         .active_state = device_active_state,
    1082             :         .sub_state_to_string = device_sub_state_to_string,
    1083             : 
    1084             :         .bus_vtable = bus_device_vtable,
    1085             : 
    1086             :         .following = device_following,
    1087             :         .following_set = device_following_set,
    1088             : 
    1089             :         .enumerate = device_enumerate,
    1090             :         .shutdown = device_shutdown,
    1091             :         .supported = device_supported,
    1092             : 
    1093             :         .status_message_formats = {
    1094             :                 .starting_stopping = {
    1095             :                         [0] = "Expecting device %s...",
    1096             :                 },
    1097             :                 .finished_start_job = {
    1098             :                         [JOB_DONE]       = "Found device %s.",
    1099             :                         [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
    1100             :                 },
    1101             :         },
    1102             : };

Generated by: LCOV version 1.14