summaryrefslogtreecommitdiffstats
path: root/src/libsystemd/sd-device
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-device')
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c10
-rw-r--r--src/libsystemd/sd-device/device-monitor.c23
-rw-r--r--src/libsystemd/sd-device/device-private.c125
-rw-r--r--src/libsystemd/sd-device/device-private.h3
-rw-r--r--src/libsystemd/sd-device/device-util.c39
-rw-r--r--src/libsystemd/sd-device/device-util.h13
-rw-r--r--src/libsystemd/sd-device/sd-device.c113
-rw-r--r--src/libsystemd/sd-device/test-device-util.c78
-rw-r--r--src/libsystemd/sd-device/test-sd-device-monitor.c4
-rw-r--r--src/libsystemd/sd-device/test-sd-device-thread.c3
-rw-r--r--src/libsystemd/sd-device/test-sd-device.c10
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);