diff options
Diffstat (limited to 'src/libsystemd/sd-device')
-rw-r--r-- | src/libsystemd/sd-device/device-enumerator.c | 10 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-monitor.c | 23 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-private.c | 125 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-private.h | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-util.c | 39 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-util.h | 13 | ||||
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 113 | ||||
-rw-r--r-- | src/libsystemd/sd-device/test-device-util.c | 78 | ||||
-rw-r--r-- | src/libsystemd/sd-device/test-sd-device-monitor.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-device/test-sd-device-thread.c | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-device/test-sd-device.c | 10 |
11 files changed, 272 insertions, 149 deletions
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c index 15c5c42..71ab3d8 100644 --- a/src/libsystemd/sd-device/device-enumerator.c +++ b/src/libsystemd/sd-device/device-enumerator.c @@ -370,12 +370,8 @@ static int enumerator_sort_devices(sd_device_enumerator *enumerator) { HASHMAP_FOREACH_KEY(device, syspath, enumerator->devices_by_syspath) { _cleanup_free_ char *p = NULL; - const char *subsys; - if (sd_device_get_subsystem(device, &subsys) < 0) - continue; - - if (!streq(subsys, *prioritized_subsystem)) + if (!device_in_subsystem(device, *prioritized_subsystem)) continue; devices[n++] = sd_device_ref(device); @@ -662,10 +658,8 @@ static int enumerator_add_parent_devices( continue; r = device_enumerator_add_device(enumerator, device); - if (r < 0) + if (r <= 0) /* r == 0 means the device already exists, then no need to go further up. */ return r; - if (r == 0) /* Exists already? Then no need to go further up. */ - return 0; } } diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c index bb4f9bd..a7ef03a 100644 --- a/src/libsystemd/sd-device/device-monitor.c +++ b/src/libsystemd/sd-device/device-monitor.c @@ -47,7 +47,7 @@ struct sd_device_monitor { union sockaddr_union snl_trusted_sender; bool bound; - UidRange *mapped_userns_uid_range; + UIDRange *mapped_userns_uid_range; Hashmap *subsystem_filter; Set *tag_filter; @@ -402,8 +402,7 @@ static sd_device_monitor *device_monitor_free(sd_device_monitor *m) { DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_monitor, sd_device_monitor, device_monitor_free); static int check_subsystem_filter(sd_device_monitor *m, sd_device *device) { - const char *s, *subsystem, *d, *devtype = NULL; - int r; + const char *s, *d; assert(m); assert(device); @@ -411,20 +410,14 @@ static int check_subsystem_filter(sd_device_monitor *m, sd_device *device) { if (hashmap_isempty(m->subsystem_filter)) return true; - r = sd_device_get_subsystem(device, &subsystem); - if (r < 0) - return r; - - r = sd_device_get_devtype(device, &devtype); - if (r < 0 && r != -ENOENT) - return r; - HASHMAP_FOREACH_KEY(d, s, m->subsystem_filter) { - if (!streq(s, subsystem)) + if (!device_in_subsystem(device, s)) continue; - if (!d || streq_ptr(d, devtype)) - return true; + if (d && !device_is_devtype(device, d)) + continue; + + return true; } return false; @@ -480,7 +473,7 @@ static bool check_sender_uid(sd_device_monitor *m, uid_t uid) { return true; if (!m->mapped_userns_uid_range) { - r = uid_range_load_userns(&m->mapped_userns_uid_range, NULL); + r = uid_range_load_userns(/* path = */ NULL, UID_RANGE_USERNS_INSIDE, &m->mapped_userns_uid_range); if (r < 0) log_monitor_errno(m, r, "Failed to load UID ranges mapped to the current user namespace, ignoring: %m"); } diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index 0edabfb..cd85ec9 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -768,55 +768,96 @@ static bool device_has_info(sd_device *device) { return false; } +bool device_should_have_db(sd_device *device) { + assert(device); + + if (device_has_info(device)) + return true; + + if (major(device->devnum) != 0) + return true; + + if (device->ifindex != 0) + return true; + + return false; +} + void device_set_db_persist(sd_device *device) { assert(device); device->db_persist = true; } -int device_update_db(sd_device *device) { +static int device_get_db_path(sd_device *device, char **ret) { const char *id; char *path; - _cleanup_fclose_ FILE *f = NULL; - _cleanup_(unlink_and_freep) char *path_tmp = NULL; - bool has_info; int r; assert(device); - - has_info = device_has_info(device); + assert(ret); r = device_get_device_id(device, &id); if (r < 0) return r; - path = strjoina("/run/udev/data/", id); + path = path_join("/run/udev/data/", id); + if (!path) + return -ENOMEM; + + *ret = path; + return 0; +} + +int device_has_db(sd_device *device) { + _cleanup_free_ char *path = NULL; + int r; + + assert(device); + + r = device_get_db_path(device, &path); + if (r < 0) + return r; + + return access(path, F_OK) >= 0; +} + +int device_update_db(sd_device *device) { + _cleanup_(unlink_and_freep) char *path = NULL, *path_tmp = NULL; + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(device); /* do not store anything for otherwise empty devices */ - if (!has_info && major(device->devnum) == 0 && device->ifindex == 0) { - if (unlink(path) < 0 && errno != ENOENT) - return -errno; + if (!device_should_have_db(device)) + return device_delete_db(device); - return 0; - } + r = device_get_db_path(device, &path); + if (r < 0) + return r; /* write a database file */ r = mkdir_parents(path, 0755); if (r < 0) - return r; + return log_device_debug_errno(device, r, + "sd-device: Failed to create parent directories of '%s': %m", + path); r = fopen_temporary(path, &f, &path_tmp); if (r < 0) - return r; + return log_device_debug_errno(device, r, + "sd-device: Failed to create temporary file for database file '%s': %m", + path); /* set 'sticky' bit to indicate that we should not clean the database when we transition from initrd * to the real root */ - if (fchmod(fileno(f), device->db_persist ? 01644 : 0644) < 0) { - r = -errno; - goto fail; - } + if (fchmod(fileno(f), device->db_persist ? 01644 : 0644) < 0) + return log_device_debug_errno(device, errno, + "sd-device: Failed to chmod temporary database file '%s': %m", + path_tmp); - if (has_info) { + if (device_has_info(device)) { const char *property, *value, *ct; if (major(device->devnum) > 0) { @@ -846,45 +887,55 @@ int device_update_db(sd_device *device) { r = fflush_and_check(f); if (r < 0) - goto fail; + return log_device_debug_errno(device, r, + "sd-device: Failed to flush temporary database file '%s': %m", + path_tmp); - if (rename(path_tmp, path) < 0) { - r = -errno; - goto fail; - } + if (rename(path_tmp, path) < 0) + return log_device_debug_errno(device, errno, + "sd-device: Failed to rename temporary database file '%s' to '%s': %m", + path_tmp, path); - path_tmp = mfree(path_tmp); + log_device_debug(device, "sd-device: Created database file '%s' for '%s'.", path, device->devpath); - log_device_debug(device, "sd-device: Created %s file '%s' for '%s'", has_info ? "db" : "empty", - path, device->devpath); + path_tmp = mfree(path_tmp); + path = mfree(path); return 0; - -fail: - (void) unlink(path); - - return log_device_debug_errno(device, r, "sd-device: Failed to create %s file '%s' for '%s'", has_info ? "db" : "empty", path, device->devpath); } int device_delete_db(sd_device *device) { - const char *id; - char *path; + _cleanup_free_ char *path = NULL; int r; assert(device); - r = device_get_device_id(device, &id); + r = device_get_db_path(device, &path); if (r < 0) return r; - path = strjoina("/run/udev/data/", id); - if (unlink(path) < 0 && errno != ENOENT) return -errno; return 0; } +int device_read_db_internal(sd_device *device, bool force) { + _cleanup_free_ char *path = NULL; + int r; + + assert(device); + + if (device->db_loaded || (!force && device->sealed)) + return 0; + + r = device_get_db_path(device, &path); + if (r < 0) + return r; + + return device_read_db_internal_filename(device, path); +} + static const char* const device_action_table[_SD_DEVICE_ACTION_MAX] = { [SD_DEVICE_ADD] = "add", [SD_DEVICE_REMOVE] = "remove", diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index e8a6d52..85e8609 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -24,6 +24,7 @@ int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, uns static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { return device_get_sysattr_unsigned_full(device, sysattr, 0, ret_value); } +int device_get_sysattr_u32(sd_device *device, const char *sysattr, uint32_t *ret_value); int device_get_sysattr_bool(sd_device *device, const char *sysattr); int device_get_device_id(sd_device *device, const char **ret); int device_get_devlink_priority(sd_device *device, int *ret); @@ -61,6 +62,8 @@ int device_get_properties_strv(sd_device *device, char ***ret); int device_clone_with_db(sd_device *device, sd_device **ret); int device_tag_index(sd_device *dev, sd_device *dev_old, bool add); +bool device_should_have_db(sd_device *device); +int device_has_db(sd_device *device); int device_update_db(sd_device *device); int device_delete_db(sd_device *device); int device_read_db_internal_filename(sd_device *device, const char *filename); /* For fuzzer */ diff --git a/src/libsystemd/sd-device/device-util.c b/src/libsystemd/sd-device/device-util.c index 529eff2..123629c 100644 --- a/src/libsystemd/sd-device/device-util.c +++ b/src/libsystemd/sd-device/device-util.c @@ -9,7 +9,6 @@ int devname_from_devnum(mode_t mode, dev_t devnum, char **ret) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL; - _cleanup_free_ char *s = NULL; const char *devname; int r; @@ -26,15 +25,10 @@ int devname_from_devnum(mode_t mode, dev_t devnum, char **ret) { if (r < 0) return r; - s = strdup(devname); - if (!s) - return -ENOMEM; - - *ret = TAKE_PTR(s); - return 0; + return strdup_to(ret, devname); } -int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret) { +int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret_devname) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -EBADF; int r; @@ -47,19 +41,16 @@ int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret) { if (fd < 0) return fd; - if (ret) { + if (ret_devname) { const char *devname; - char *s; r = sd_device_get_devname(dev, &devname); if (r < 0) return r; - s = strdup(devname); - if (!s) - return -ENOMEM; - - *ret = s; + r = strdup_to(ret_devname, devname); + if (r < 0) + return r; } return TAKE_FD(fd); @@ -139,3 +130,21 @@ char** device_make_log_fields(sd_device *device) { return TAKE_PTR(strv); } + +bool device_in_subsystem(sd_device *device, const char *subsystem) { + const char *s = NULL; + + assert(device); + + (void) sd_device_get_subsystem(device, &s); + return streq_ptr(s, subsystem); +} + +bool device_is_devtype(sd_device *device, const char *devtype) { + const char *s = NULL; + + assert(device); + + (void) sd_device_get_devtype(device, &s); + return streq_ptr(s, devtype); +} diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index bf86ddc..b17993d 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -10,6 +10,7 @@ #include "alloc-util.h" #include "log.h" #include "macro.h" +#include "strv.h" #define device_unref_and_replace(a, b) \ unref_and_replace_full(a, b, sd_device_ref, sd_device_unref) @@ -99,6 +100,16 @@ static inline int devname_from_stat_rdev(const struct stat *st, char **ret) { assert(st); return devname_from_devnum(st->st_mode, st->st_rdev, ret); } -int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret); +int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret_devname); char** device_make_log_fields(sd_device *device); + +bool device_in_subsystem(sd_device *device, const char *subsystem); +bool device_is_devtype(sd_device *device, const char *devtype); + +static inline bool device_property_can_set(const char *property) { + return property && + !STR_IN_SET(property, + "ACTION", "DEVLINKS", "DEVNAME", "DEVPATH", "DEVTYPE", "DRIVER", + "IFINDEX", "MAJOR", "MINOR", "SEQNUM", "SUBSYSTEM", "TAGS"); +} diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 01e66b4..d8d1518 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -214,7 +214,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { /* Only operate on sysfs, i.e. refuse going down into /sys/fs/cgroup/ or similar places where * things are not arranged as kobjects in kernel, and hence don't necessarily have * kobject/attribute structure. */ - r = getenv_bool_secure("SYSTEMD_DEVICE_VERIFY_SYSFS"); + r = secure_getenv_bool("SYSTEMD_DEVICE_VERIFY_SYSFS"); if (r < 0 && r != -ENXIO) log_debug_errno(r, "Failed to parse $SYSTEMD_DEVICE_VERIFY_SYSFS value: %m"); if (r != 0) { @@ -283,7 +283,7 @@ _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) { int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_free_ char *syspath = NULL; - const char *t, *subsystem = NULL; + const char *t; dev_t n; int r; @@ -314,10 +314,7 @@ int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) if (n != devnum) return -ENXIO; - r = sd_device_get_subsystem(dev, &subsystem); - if (r < 0 && r != -ENOENT) - return r; - if (streq_ptr(subsystem, "block") != !!S_ISBLK(mode)) + if (device_in_subsystem(dev, "block") != !!S_ISBLK(mode)) return -ENXIO; *ret = TAKE_PTR(dev); @@ -348,17 +345,11 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) { assert_return(ret, -EINVAL); assert_return(ifname, -EINVAL); - r = parse_ifindex(ifname); - if (r > 0) - return sd_device_new_from_ifindex(ret, r); - - if (ifname_valid(ifname)) { - r = device_new_from_main_ifname(ret, ifname); - if (r >= 0) - return r; - } + r = device_new_from_main_ifname(ret, ifname); + if (r >= 0) + return r; - r = rtnl_resolve_link_alternative_name(NULL, ifname, &main_name); + r = rtnl_resolve_ifname_full(NULL, RESOLVE_IFNAME_ALTERNATIVE | RESOLVE_IFNAME_NUMERIC, ifname, &main_name, NULL); if (r < 0) return r; @@ -367,14 +358,15 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) { _public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) { _cleanup_(sd_device_unrefp) sd_device *dev = NULL; - char ifname[IF_NAMESIZE]; + _cleanup_free_ char *ifname = NULL; int r, i; assert_return(ret, -EINVAL); assert_return(ifindex > 0, -EINVAL); - if (format_ifname(ifindex, ifname) < 0) - return -ENODEV; + r = rtnl_get_ifname_full(NULL, ifindex, &ifname, NULL); + if (r < 0) + return r; r = device_new_from_main_ifname(&dev, ifname); if (r < 0) @@ -1222,37 +1214,27 @@ _public_ int sd_device_get_devtype(sd_device *device, const char **devtype) { return !!device->devtype; } -_public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *subsystem, const char *devtype, sd_device **ret) { - sd_device *parent = NULL; +_public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *device, const char *subsystem, const char *devtype, sd_device **ret) { int r; - assert_return(child, -EINVAL); + assert_return(device, -EINVAL); assert_return(subsystem, -EINVAL); - r = sd_device_get_parent(child, &parent); - while (r >= 0) { - const char *parent_subsystem = NULL; + for (;;) { + r = sd_device_get_parent(device, &device); + if (r < 0) + return r; - (void) sd_device_get_subsystem(parent, &parent_subsystem); - if (streq_ptr(parent_subsystem, subsystem)) { - const char *parent_devtype = NULL; + if (!device_in_subsystem(device, subsystem)) + continue; - if (!devtype) - break; + if (devtype && !device_is_devtype(device, devtype)) + continue; - (void) sd_device_get_devtype(parent, &parent_devtype); - if (streq_ptr(parent_devtype, devtype)) - break; - } - r = sd_device_get_parent(parent, &parent); + if (ret) + *ret = device; + return 0; } - - if (r < 0) - return r; - - if (ret) - *ret = parent; - return 0; } _public_ int sd_device_get_devnum(sd_device *device, dev_t *devnum) { @@ -1778,24 +1760,6 @@ int device_read_db_internal_filename(sd_device *device, const char *filename) { return 0; } -int device_read_db_internal(sd_device *device, bool force) { - const char *id, *path; - int r; - - assert(device); - - if (device->db_loaded || (!force && device->sealed)) - return 0; - - r = device_get_device_id(device, &id); - if (r < 0) - return r; - - path = strjoina("/run/udev/data/", id); - - return device_read_db_internal_filename(device, path); -} - _public_ int sd_device_get_is_initialized(sd_device *device) { int r; @@ -2454,6 +2418,25 @@ int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, uns return v > 0; } +int device_get_sysattr_u32(sd_device *device, const char *sysattr, uint32_t *ret_value) { + const char *value; + int r; + + r = sd_device_get_sysattr_value(device, sysattr, &value); + if (r < 0) + return r; + + uint32_t v; + r = safe_atou32(value, &v); + if (r < 0) + return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr); + + if (ret_value) + *ret_value = v; + /* We return "true" if the value is positive. */ + return v > 0; +} + int device_get_sysattr_bool(sd_device *device, const char *sysattr) { const char *value; int r; @@ -2506,7 +2489,7 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, /* drop trailing newlines */ while (len > 0 && strchr(NEWLINE, _value[len - 1])) - len --; + len--; /* value length is limited to 4k */ if (len > 4096) @@ -2609,7 +2592,7 @@ _public_ int sd_device_trigger_with_uuid( _public_ int sd_device_open(sd_device *device, int flags) { _cleanup_close_ int fd = -EBADF, fd2 = -EBADF; - const char *devname, *subsystem = NULL; + const char *devname; uint64_t q, diskseq = 0; struct stat st; dev_t devnum; @@ -2630,10 +2613,6 @@ _public_ int sd_device_open(sd_device *device, int flags) { if (r < 0) return r; - r = sd_device_get_subsystem(device, &subsystem); - if (r < 0 && r != -ENOENT) - return r; - fd = open(devname, FLAGS_SET(flags, O_PATH) ? flags : O_CLOEXEC|O_NOFOLLOW|O_PATH); if (fd < 0) return -errno; @@ -2644,7 +2623,7 @@ _public_ int sd_device_open(sd_device *device, int flags) { if (st.st_rdev != devnum) return -ENXIO; - if (streq_ptr(subsystem, "block") ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode)) + if (device_in_subsystem(device, "block") ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode)) return -ENXIO; /* If flags has O_PATH, then we cannot check diskseq. Let's return earlier. */ diff --git a/src/libsystemd/sd-device/test-device-util.c b/src/libsystemd/sd-device/test-device-util.c index bc8ab66..f7c9deb 100644 --- a/src/libsystemd/sd-device/test-device-util.c +++ b/src/libsystemd/sd-device/test-device-util.c @@ -1,23 +1,91 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "device-util.h" +#include "mountpoint-util.h" #include "tests.h" TEST(log_device_full) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; int r; + (void) sd_device_new_from_subsystem_sysname(&dev, "net", "lo"); + for (int level = LOG_ERR; level <= LOG_DEBUG; level++) { - log_device_full(NULL, level, "test level=%d: %m", level); + log_device_full(dev, level, "test level=%d: %m", level); - r = log_device_full_errno(NULL, level, EUCLEAN, "test level=%d errno=EUCLEAN: %m", level); + r = log_device_full_errno(dev, level, EUCLEAN, "test level=%d errno=EUCLEAN: %m", level); assert_se(r == -EUCLEAN); - r = log_device_full_errno(NULL, level, 0, "test level=%d errno=0: %m", level); + r = log_device_full_errno(dev, level, 0, "test level=%d errno=0: %m", level); assert_se(r == 0); - r = log_device_full_errno(NULL, level, SYNTHETIC_ERRNO(ENODATA), "test level=%d errno=S(ENODATA): %m", level); + r = log_device_full_errno(dev, level, SYNTHETIC_ERRNO(ENODATA), "test level=%d errno=S(ENODATA).", level); assert_se(r == -ENODATA); } } -DEFINE_TEST_MAIN(LOG_INFO); +TEST(device_in_subsystem) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + int r; + + r = sd_device_new_from_subsystem_sysname(&dev, "net", "lo"); + if (r == -ENODEV) + return (void) log_tests_skipped("net/lo does not exist"); + assert_se(r >= 0); + + assert_se(device_in_subsystem(dev, "net")); + assert_se(!device_in_subsystem(dev, "disk")); + assert_se(!device_in_subsystem(dev, "subsystem")); + assert_se(!device_in_subsystem(dev, "")); + assert_se(!device_in_subsystem(dev, NULL)); + + dev = sd_device_unref(dev); + + assert_se(sd_device_new_from_syspath(&dev, "/sys/class/net") >= 0); + assert_se(!device_in_subsystem(dev, "net")); + assert_se(!device_in_subsystem(dev, "disk")); + assert_se(device_in_subsystem(dev, "subsystem")); + assert_se(!device_in_subsystem(dev, "")); + assert_se(!device_in_subsystem(dev, NULL)); + + dev = sd_device_unref(dev); + + assert_se(sd_device_new_from_syspath(&dev, "/sys/class") >= 0); + assert_se(!device_in_subsystem(dev, "net")); + assert_se(!device_in_subsystem(dev, "disk")); + assert_se(!device_in_subsystem(dev, "subsystem")); + assert_se(!device_in_subsystem(dev, "")); + assert_se(device_in_subsystem(dev, NULL)); +} + +TEST(device_is_devtype) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + + assert_se(sd_device_enumerator_new(&e) >= 0); + assert_se(sd_device_enumerator_add_match_subsystem(e, "disk", true) >= 0); + + FOREACH_DEVICE(e, d) { + const char *t; + + assert_se(sd_device_get_devtype(d, &t) >= 0); + assert_se(device_is_devtype(d, t)); + assert_se(!device_is_devtype(d, "hoge")); + assert_se(!device_is_devtype(d, "")); + assert_se(!device_is_devtype(d, NULL)); + } + + assert_se(sd_device_new_from_syspath(&dev, "/sys/class/net") >= 0); + assert_se(!device_is_devtype(dev, "hoge")); + assert_se(!device_is_devtype(dev, "")); + assert_se(device_is_devtype(dev, NULL)); +} + +static int intro(void) { + if (path_is_mount_point("/sys") <= 0) + return log_tests_skipped("/sys is not mounted"); + + return EXIT_SUCCESS; +} + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); diff --git a/src/libsystemd/sd-device/test-sd-device-monitor.c b/src/libsystemd/sd-device/test-sd-device-monitor.c index e124e00..3dbf987 100644 --- a/src/libsystemd/sd-device/test-sd-device-monitor.c +++ b/src/libsystemd/sd-device/test-sd-device-monitor.c @@ -10,6 +10,7 @@ #include "device-private.h" #include "device-util.h" #include "macro.h" +#include "mountpoint-util.h" #include "path-util.h" #include "stat-util.h" #include "string-util.h" @@ -298,6 +299,9 @@ int main(int argc, char *argv[]) { if (getuid() != 0) return log_tests_skipped("not root"); + if (path_is_mount_point("/sys") <= 0) + return log_tests_skipped("/sys is not mounted"); + if (path_is_read_only_fs("/sys") > 0) return log_tests_skipped("Running in container"); diff --git a/src/libsystemd/sd-device/test-sd-device-thread.c b/src/libsystemd/sd-device/test-sd-device-thread.c index c99d179..539dabd 100644 --- a/src/libsystemd/sd-device/test-sd-device-thread.c +++ b/src/libsystemd/sd-device/test-sd-device-thread.c @@ -8,6 +8,7 @@ #include "sd-device.h" #include "device-util.h" +#include "tests.h" #define handle_error_errno(error, msg) \ ({ \ @@ -30,6 +31,8 @@ int main(int argc, char *argv[]) { int r; r = sd_device_new_from_syspath(&loopback, "/sys/class/net/lo"); + if (r == -ENODEV) + return log_tests_skipped("Loopback device not found"); if (r < 0) return handle_error_errno(r, "Failed to create loopback device object"); diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index bce99b5..9fde1a0 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -11,6 +11,7 @@ #include "errno-util.h" #include "fd-util.h" #include "hashmap.h" +#include "mountpoint-util.h" #include "nulstr-util.h" #include "path-util.h" #include "rm-rf.h" @@ -675,4 +676,11 @@ TEST(devname_from_devnum) { } } -DEFINE_TEST_MAIN(LOG_INFO); +static int intro(void) { + if (path_is_mount_point("/sys") <= 0) + return log_tests_skipped("/sys is not mounted"); + + return EXIT_SUCCESS; +} + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); |