From 1707b41e7648dc2f43bf53f52112cc7092b988c6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 03:26:04 +0900 Subject: [PATCH 01/15] sd-device: protect more properties often set by kernel and internally used by udevd --- src/libsystemd/sd-device/device-util.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index b17993d5540..070e564a52c 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -110,6 +110,19 @@ 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"); + /* basic properties set by kernel, only in netlink event */ + "ACTION", "SEQNUM", "SYNTH_UUID", + /* basic properties set by kernel, both in netlink event and uevent file */ + "DEVPATH", "DEVPATH_OLD", "SUBSYSTEM", "DEVTYPE", "DRIVER", "MODALIAS", + /* device node */ + "DEVNAME", "DEVMODE", "DEVUID", "DEVGID", "MAJOR", "MINOR", + /* block device */ + "DISKSEQ", "PARTN", + /* network interface (INTERFACE_OLD is set by udevd) */ + "IFINDEX", "INTERFACE", "INTERFACE_OLD", + /* basic properties set by udevd */ + "DEVLINKS", "TAGS", "CURRENT_TAGS", "USEC_INITIALIZED", "UDEV_DATABASE_VERSION") && + /* Similar to SYNTH_UUID, but set based on KEY=VALUE arguments passed by userspace. + * See kernel's f36776fafbaa0094390dd4e7e3e29805e0b82730 (v4.13) */ + !startswith(property, "SYNTH_ARG_"); } From c7523292daa07aa2abdd85c9e5d75bf62cf75124 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 03:47:56 +0900 Subject: [PATCH 02/15] sd-device: reorder elements in sd_device object No functional change, just refactoring. --- src/libsystemd/sd-device/device-internal.h | 92 ++++++++++++---------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h index c79181d5bb6..cbd89849bde 100644 --- a/src/libsystemd/sd-device/device-internal.h +++ b/src/libsystemd/sd-device/device-internal.h @@ -13,6 +13,43 @@ struct sd_device { unsigned n_ref; + /* syspath */ + char *syspath; + const char *devpath; + const char *sysnum; + char *sysname; + + /* only set when device is passed through netlink */ + sd_device_action_t action; + uint64_t seqnum; + + /* basic kernel properties */ + char *subsystem; + char *driver_subsystem; /* only set for the 'drivers' subsystem */ + char *driver; + char *devtype; + + /* device node properties */ + char *devname; + dev_t devnum; + mode_t devmode; + uid_t devuid; + gid_t devgid; + + /* block device properties */ + uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach */ + + /* network interface properties */ + int ifindex; + + /* determined by devnnum, ifindex, subsystem, and sysname */ + char *device_id; + + /* sysfs attributes */ + Hashmap *sysattr_values; /* cached sysattr values */ + Set *sysattrs; /* names of sysattrs */ + Iterator sysattrs_iterator; + /* The database version indicates the supported features by the udev database. * This is saved and parsed in V field. * @@ -21,68 +58,38 @@ struct sd_device { */ unsigned database_version; - sd_device *parent; + /* when device is initialized by udevd */ + usec_t usec_initialized; - OrderedHashmap *properties; + /* properties */ + OrderedHashmap *properties; /* all properties set from uevent and by udevd */ Iterator properties_iterator; uint64_t properties_generation; /* changes whenever the properties are changed */ uint64_t properties_iterator_generation; /* generation when iteration was started */ + OrderedHashmap *properties_db; /* the subset of the properties that should be written to the db */ + char **properties_strv; /* the properties hashmap as a strv */ + char *properties_nulstr; /* the same as a nulstr */ + size_t properties_nulstr_len; - /* the subset of the properties that should be written to the db */ - OrderedHashmap *properties_db; - - Hashmap *sysattr_values; /* cached sysattr values */ - - Set *sysattrs; /* names of sysattrs */ - Iterator sysattrs_iterator; - + /* TAG keyword */ Set *all_tags, *current_tags; Iterator all_tags_iterator, current_tags_iterator; uint64_t all_tags_iterator_generation, current_tags_iterator_generation; /* generation when iteration was started */ uint64_t tags_generation; /* changes whenever the tags are changed */ + /* SYMLINK keyword */ Set *devlinks; Iterator devlinks_iterator; uint64_t devlinks_generation; /* changes whenever the devlinks are changed */ uint64_t devlinks_iterator_generation; /* generation when iteration was started */ int devlink_priority; + /* parent and child devices */ + sd_device *parent; Hashmap *children; Iterator children_iterator; bool children_enumerated; - int ifindex; - char *devtype; - char *devname; - dev_t devnum; - - char **properties_strv; /* the properties hashmap as a strv */ - char *properties_nulstr; /* the same as a nulstr */ - size_t properties_nulstr_len; - - char *syspath; - const char *devpath; - const char *sysnum; - char *sysname; - - char *subsystem; - char *driver_subsystem; /* only set for the 'drivers' subsystem */ - char *driver; - - char *device_id; - - usec_t usec_initialized; - - mode_t devmode; - uid_t devuid; - gid_t devgid; - - uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach */ - - /* only set when device is passed through netlink */ - sd_device_action_t action; - uint64_t seqnum; - bool parent_set:1; /* no need to try to reload parent */ bool sysattrs_read:1; /* don't try to re-read sysattrs once read */ bool property_tags_outdated:1; /* need to update TAGS= or CURRENT_TAGS= property */ @@ -92,7 +99,6 @@ struct sd_device { bool driver_set:1; /* don't reread driver */ bool uevent_loaded:1; /* don't reread uevent */ bool db_loaded; /* don't reread db */ - bool is_initialized:1; bool sealed:1; /* don't read more information from uevent/db */ bool db_persist:1; /* don't clean up the db when switching from initrd to real root */ From 0f52a1107e337cb67519b09646d90ff0b3c763a5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 9 Mar 2025 10:15:29 +0900 Subject: [PATCH 03/15] test-sd-device: use ASSERT_OK() and friends --- src/libsystemd/sd-device/test-sd-device.c | 522 +++++++++++----------- 1 file changed, 267 insertions(+), 255 deletions(-) diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index b5ef0dca355..705a10d159f 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -30,50 +30,51 @@ static void test_sd_device_one(sd_device *d) { usec_t usec; int ifindex, r; - assert_se(sd_device_get_syspath(d, &syspath) >= 0); - assert_se(path_startswith(syspath, "/sys")); - assert_se(sd_device_get_sysname(d, &sysname) >= 0); + ASSERT_OK(sd_device_get_syspath(d, &syspath)); + ASSERT_NOT_NULL(path_startswith(syspath, "/sys")); + ASSERT_OK(sd_device_get_sysname(d, &sysname)); log_info("%s(%s)", __func__, syspath); - assert_se(sd_device_new_from_syspath(&dev, syspath) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + ASSERT_OK(sd_device_new_from_syspath(&dev, syspath)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); - assert_se(sd_device_new_from_path(&dev, syspath) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + ASSERT_OK(sd_device_new_from_path(&dev, syspath)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); r = sd_device_get_ifindex(d, &ifindex); - if (r >= 0) { - assert_se(ifindex > 0); + if (r < 0) + ASSERT_ERROR(r, ENOENT); + else { + ASSERT_GT(ifindex, 0); r = sd_device_new_from_ifindex(&dev, ifindex); - if (r == -ENODEV) + if (r < 0) { + ASSERT_ERROR(r, ENODEV); log_device_warning_errno(d, r, "Failed to create sd-device object from ifindex %i. " "Maybe running on a non-host network namespace.", ifindex); - else { - assert_se(r >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + } else { + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); } /* This does not require the interface really exists on the network namespace. * Hence, this should always succeed. */ - assert_se(sd_device_new_from_ifname(&dev, sysname) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); - } else - assert_se(r == -ENOENT); + ASSERT_OK(sd_device_new_from_ifname(&dev, sysname)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); + } r = sd_device_get_subsystem(d, &subsystem); if (r < 0) - assert_se(r == -ENOENT); + ASSERT_ERROR(r, ENOENT); else { const char *name, *id; @@ -85,132 +86,145 @@ static void test_sd_device_one(sd_device *d) { name = sysname; r = sd_device_new_from_subsystem_sysname(&dev, subsystem, name); - if (r >= 0) { - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); - } else + if (r < 0) ASSERT_ERROR(r, ETOOMANYREFS); + else { + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); + } /* The device ID depends on subsystem. */ - assert_se(sd_device_get_device_id(d, &id) >= 0); + ASSERT_OK(sd_device_get_device_id(d, &id)); r = sd_device_new_from_device_id(&dev, id); - if (r == -ENODEV && ifindex > 0) - log_device_warning_errno(d, r, - "Failed to create sd-device object from device ID \"%s\". " - "Maybe running on a non-host network namespace.", id); - else if (r >= 0) { - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); - } else - ASSERT_ERROR(r, ETOOMANYREFS); + if (r < 0) { + if (r == -ENODEV && ifindex > 0) + log_device_warning_errno(d, r, + "Failed to create sd-device object from device ID \"%s\". " + "Maybe running on a non-host network namespace.", id); + else + ASSERT_ERROR(r, ETOOMANYREFS); + } else { + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); + } /* These require udev database, and reading database requires device ID. */ - r = sd_device_get_is_initialized(d); + ASSERT_OK((r = sd_device_get_is_initialized(d))); if (r > 0) { r = sd_device_get_usec_since_initialized(d, &usec); - assert_se((r >= 0 && usec > 0) || r == -ENODATA); - } else - assert(r == 0); + if (r < 0) + ASSERT_ERROR(r, ENODATA); + else + ASSERT_GT(usec, 0U); + } r = sd_device_get_property_value(d, "ID_NET_DRIVER", &val); - assert_se(r >= 0 || r == -ENOENT); + if (r < 0) + ASSERT_ERROR(r, ENOENT); } is_block = streq_ptr(subsystem, "block"); r = sd_device_get_devname(d, &devname); - if (r >= 0) { + if (r < 0) + ASSERT_ERROR(r, ENOENT); + else { r = sd_device_new_from_devname(&dev, devname); - if (r >= 0) { - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); - } else - assert_se(r == -ENODEV || ERRNO_IS_PRIVILEGE(r)); + if (r < 0) + ASSERT_TRUE(r == -ENODEV || ERRNO_IS_NEG_PRIVILEGE(r)); + else { + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); + } r = sd_device_new_from_path(&dev, devname); - if (r >= 0) { - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + if (r < 0) + ASSERT_TRUE(r == -ENODEV || ERRNO_IS_NEG_PRIVILEGE(r)); + else { + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); _cleanup_close_ int fd = -EBADF; fd = sd_device_open(d, O_CLOEXEC| O_NONBLOCK | (is_block ? O_RDONLY : O_NOCTTY | O_PATH)); - assert_se(fd >= 0 || ERRNO_IS_PRIVILEGE(fd)); - } else - assert_se(r == -ENODEV || ERRNO_IS_PRIVILEGE(r)); - } else - assert_se(r == -ENOENT); + ASSERT_TRUE(fd >= 0 || ERRNO_IS_NEG_PRIVILEGE(fd)); + } + } r = sd_device_get_devnum(d, &devnum); - if (r >= 0) { + if (r < 0) + ASSERT_ERROR(r, ENOENT); + else { _cleanup_free_ char *p = NULL; - assert_se(major(devnum) > 0); + ASSERT_GT(major(devnum), 0U); - assert_se(sd_device_new_from_devnum(&dev, is_block ? 'b' : 'c', devnum) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + ASSERT_OK(sd_device_new_from_devnum(&dev, is_block ? 'b' : 'c', devnum)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); - assert_se(asprintf(&p, "/dev/%s/%u:%u", is_block ? "block" : "char", major(devnum), minor(devnum)) >= 0); - assert_se(sd_device_new_from_devname(&dev, p) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); + ASSERT_OK(asprintf(&p, "/dev/%s/%u:%u", is_block ? "block" : "char", major(devnum), minor(devnum))); + ASSERT_OK(sd_device_new_from_devname(&dev, p)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); - assert_se(sd_device_new_from_path(&dev, p) >= 0); - assert_se(sd_device_get_syspath(dev, &val) >= 0); - assert_se(streq(syspath, val)); - dev = sd_device_unref(dev); - } else - assert_se(r == -ENOENT); + ASSERT_OK(sd_device_new_from_path(&dev, p)); + ASSERT_OK(sd_device_get_syspath(dev, &val)); + ASSERT_STREQ(syspath, val); + ASSERT_NULL((dev = sd_device_unref(dev))); + } - assert_se(sd_device_get_devpath(d, &val) >= 0); + ASSERT_OK(sd_device_get_devpath(d, &val)); - r = sd_device_get_devtype(d, &val); - assert_se(r >= 0 || r == -ENOENT); + r = sd_device_get_devtype(d, NULL); + if (r < 0) + ASSERT_ERROR(r, ENOENT); - r = sd_device_get_driver(d, &val); - assert_se(r >= 0 || r == -ENOENT); + r = sd_device_get_driver(d, NULL); + if (r < 0) + ASSERT_ERROR(r, ENOENT); r = sd_device_get_sysnum(d, &val); - if (r >= 0) { - assert_se(val > sysname); - assert_se(val < sysname + strlen(sysname)); - assert_se(in_charset(val, DIGITS)); - assert_se(!ascii_isdigit(val[-1])); + if (r < 0) + ASSERT_ERROR(r, ENOENT); + else { + ASSERT_TRUE(val > sysname); + ASSERT_TRUE(val < sysname + strlen(sysname)); + ASSERT_TRUE(in_charset(val, DIGITS)); + ASSERT_FALSE(ascii_isdigit(val[-1])); + r = device_get_sysnum_unsigned(d, NULL); - ASSERT_TRUE(r >= 0 || r == -ERANGE); /* sysnum may be too large. */ - } else - assert_se(r == -ENOENT); + if (r < 0) + ASSERT_ERROR(r, ERANGE); /* sysnum may be too large. */ + } r = sd_device_get_sysattr_value(d, "nsid", NULL); - if (r >= 0) { + if (r < 0) + ASSERT_TRUE(ERRNO_IS_NEG_PRIVILEGE(r) || IN_SET(r, -ENOENT, -EINVAL)); + else { unsigned x; - - assert_se(device_get_sysattr_unsigned(d, "nsid", NULL) >= 0); - r = device_get_sysattr_unsigned(d, "nsid", &x); - assert_se(r >= 0); - assert_se((x > 0) == (r > 0)); - } else - assert_se(ERRNO_IS_PRIVILEGE(r) || IN_SET(r, -ENOENT, -EINVAL)); + ASSERT_OK((r = device_get_sysattr_unsigned(d, "nsid", &x))); + ASSERT_EQ((x > 0), (r > 0)); + } } TEST(sd_device_enumerator_devices) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); /* On some CI environments, it seems some loop block devices and corresponding bdi devices sometimes * disappear during running this test. Let's exclude them here for stability. */ - assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); /* On CentOS CI, systemd-networkd-tests.py may be running when this test is invoked. The networkd * test creates and removes many network interfaces, and may interfere with this test. */ - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", false) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); FOREACH_DEVICE(e, d) test_sd_device_one(d); } @@ -218,8 +232,8 @@ TEST(sd_device_enumerator_devices) { TEST(sd_device_enumerator_subsystems) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); FOREACH_SUBSYSTEM(e, d) test_sd_device_one(d); } @@ -234,15 +248,15 @@ static void test_sd_device_enumerator_filter_subsystem_one( unsigned n_new_dev = 0, n_removed_dev = 0; sd_device *dev; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, subsystem, true) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, subsystem, true)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); FOREACH_DEVICE(e, d) { const char *syspath; sd_device *t; - assert_se(sd_device_get_syspath(d, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(d, &syspath)); t = hashmap_remove(h, syspath); if (!t) { @@ -250,17 +264,17 @@ static void test_sd_device_enumerator_filter_subsystem_one( n_new_dev++; } - assert_se(!sd_device_unref(t)); + ASSERT_NULL(sd_device_unref(t)); } HASHMAP_FOREACH(dev, h) { const char *syspath; - assert_se(sd_device_get_syspath(dev, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); log_warning("Device removed: subsystem:%s syspath:%s", subsystem, syspath); n_removed_dev++; - assert_se(!sd_device_unref(dev)); + ASSERT_NULL(sd_device_unref(dev)); } hashmap_free(h); @@ -276,34 +290,35 @@ static bool test_sd_device_enumerator_filter_subsystem_trial(void) { Hashmap *h; char *s; - assert_se(subsystems = hashmap_new(&string_hash_ops)); - assert_se(sd_device_enumerator_new(&e) >= 0); + ASSERT_NOT_NULL((subsystems = hashmap_new(&string_hash_ops))); + ASSERT_OK(sd_device_enumerator_new(&e)); /* See comments in TEST(sd_device_enumerator_devices). */ - assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", false) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); FOREACH_DEVICE(e, d) { const char *syspath, *subsystem; int r; - assert_se(sd_device_get_syspath(d, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(d, &syspath)); r = sd_device_get_subsystem(d, &subsystem); - assert_se(r >= 0 || r == -ENOENT); - if (r < 0) + if (r < 0) { + ASSERT_ERROR(r, ENOENT); continue; + } h = hashmap_get(subsystems, subsystem); if (!h) { char *str; - assert_se(str = strdup(subsystem)); - assert_se(h = hashmap_new(&string_hash_ops)); - assert_se(hashmap_put(subsystems, str, h) >= 0); + ASSERT_NOT_NULL((str = strdup(subsystem))); + ASSERT_NOT_NULL((h = hashmap_new(&string_hash_ops))); + ASSERT_OK(hashmap_put(subsystems, str, h)); } - assert_se(hashmap_put(h, syspath, d) >= 0); - assert_se(sd_device_ref(d)); + ASSERT_OK(hashmap_put(h, syspath, d)); + ASSERT_NOT_NULL(sd_device_ref(d)); log_debug("Added subsystem:%s syspath:%s", subsystem, syspath); } @@ -348,19 +363,19 @@ TEST(sd_device_enumerator_filter_subsystem) { * several times after the udev queue becomes empty. */ if (!udev_available() || (access("/run/udev", F_OK) < 0 && errno == ENOENT)) { - assert_se(test_sd_device_enumerator_filter_subsystem_trial_many()); + ASSERT_TRUE(test_sd_device_enumerator_filter_subsystem_trial_many()); return; } _cleanup_(sd_event_unrefp) sd_event *event = NULL; - assert_se(sd_event_default(&event) >= 0); - assert_se(sd_event_add_inotify(event, NULL, "/run/udev" , IN_DELETE, on_inotify, NULL) >= 0); + ASSERT_OK(sd_event_default(&event)); + ASSERT_OK(sd_event_add_inotify(event, NULL, "/run/udev" , IN_DELETE, on_inotify, NULL)); if (udev_queue_is_empty() == 0) { log_debug("udev queue is not empty, waiting for all queued events to be processed."); - assert_se(sd_event_loop(event) >= 0); + ASSERT_OK(sd_event_loop(event)); } else - assert_se(test_sd_device_enumerator_filter_subsystem_trial_many()); + ASSERT_TRUE(test_sd_device_enumerator_filter_subsystem_trial_many()); } TEST(sd_device_enumerator_add_match_sysattr) { @@ -368,21 +383,20 @@ TEST(sd_device_enumerator_add_match_sysattr) { sd_device *dev; int ifindex; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "hoge", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "foo", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "bar", false) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "baz", false) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "hoge", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "foo", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "bar", false)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "baz", false)); - dev = sd_device_enumerator_get_device_first(e); - assert_se(dev); - assert_se(sd_device_get_ifindex(dev, &ifindex) >= 0); - assert_se(ifindex == 1); + ASSERT_NOT_NULL((dev = sd_device_enumerator_get_device_first(e))); + ASSERT_OK(sd_device_get_ifindex(dev, &ifindex)); + ASSERT_EQ(ifindex, 1); - assert_se(!sd_device_enumerator_get_device_next(e)); + ASSERT_NULL(sd_device_enumerator_get_device_next(e)); } TEST(sd_device_enumerator_add_match_property) { @@ -390,20 +404,19 @@ TEST(sd_device_enumerator_add_match_property) { sd_device *dev; int ifindex; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true) >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "IFINDE*", "1*") >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "IFINDE*", "hoge") >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "IFINDE*", NULL) >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "AAAAA", "BBBB") >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "FOOOO", NULL) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true)); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "IFINDE*", "1*")); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "IFINDE*", "hoge")); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "IFINDE*", NULL)); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "AAAAA", "BBBB")); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "FOOOO", NULL)); - dev = sd_device_enumerator_get_device_first(e); - assert_se(dev); - assert_se(sd_device_get_ifindex(dev, &ifindex) >= 0); - assert_se(ifindex == 1); + ASSERT_NOT_NULL((dev = sd_device_enumerator_get_device_first(e))); + ASSERT_OK(sd_device_get_ifindex(dev, &ifindex)); + ASSERT_EQ(ifindex, 1); } TEST(sd_device_enumerator_add_match_property_required) { @@ -411,37 +424,36 @@ TEST(sd_device_enumerator_add_match_property_required) { sd_device *dev; int ifindex; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", true) >= 0); - assert_se(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true) >= 0); - assert_se(sd_device_enumerator_add_match_property_required(e, "IFINDE*", "1*") >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", true)); + ASSERT_OK(sd_device_enumerator_add_match_sysattr(e, "ifindex", "1", true)); + ASSERT_OK(sd_device_enumerator_add_match_property_required(e, "IFINDE*", "1*")); /* Only one required match which should be satisfied. */ - dev = sd_device_enumerator_get_device_first(e); - assert_se(dev); - assert_se(sd_device_get_ifindex(dev, &ifindex) >= 0); - assert_se(ifindex == 1); + ASSERT_NOT_NULL((dev = sd_device_enumerator_get_device_first(e))); + ASSERT_OK(sd_device_get_ifindex(dev, &ifindex)); + ASSERT_EQ(ifindex, 1); /* Now let's add a bunch of garbage properties which should not be satisfied. */ - assert_se(sd_device_enumerator_add_match_property_required(e, "IFINDE*", "hoge") >= 0); - assert_se(sd_device_enumerator_add_match_property_required(e, "IFINDE*", NULL) >= 0); - assert_se(sd_device_enumerator_add_match_property_required(e, "AAAAA", "BBBB") >= 0); - assert_se(sd_device_enumerator_add_match_property_required(e, "FOOOO", NULL) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_property_required(e, "IFINDE*", "hoge")); + ASSERT_OK(sd_device_enumerator_add_match_property_required(e, "IFINDE*", NULL)); + ASSERT_OK(sd_device_enumerator_add_match_property_required(e, "AAAAA", "BBBB")); + ASSERT_OK(sd_device_enumerator_add_match_property_required(e, "FOOOO", NULL)); - assert_se(!sd_device_enumerator_get_device_first(e)); + ASSERT_NULL(sd_device_enumerator_get_device_first(e)); } static void check_parent_match(sd_device_enumerator *e, sd_device *dev) { const char *syspath; bool found = false; - assert_se(sd_device_get_syspath(dev, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); FOREACH_DEVICE(e, d) { const char *s; - assert_se(sd_device_get_syspath(d, &s) >= 0); + ASSERT_OK(sd_device_get_syspath(d, &s)); if (streq(s, syspath)) { found = true; break; @@ -451,8 +463,8 @@ static void check_parent_match(sd_device_enumerator *e, sd_device *dev) { if (!found) { log_device_debug(dev, "not enumerated, already removed??"); /* If the original device not found, then the device should be already removed. */ - assert_se(access(syspath, F_OK) < 0); - assert_se(errno == ENOENT); + ASSERT_FAIL(access(syspath, F_OK)); + ASSERT_EQ(errno, ENOENT); } } @@ -460,41 +472,41 @@ TEST(sd_device_enumerator_add_match_parent) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; int r; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); /* See comments in TEST(sd_device_enumerator_devices). */ - assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", false) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); if (!slow_tests_enabled()) - assert_se(sd_device_enumerator_add_match_subsystem(e, "block", true) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); FOREACH_DEVICE(e, dev) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *p = NULL; const char *syspath; sd_device *parent; - assert_se(sd_device_get_syspath(dev, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); r = sd_device_get_parent(dev, &parent); if (r < 0) { - assert_se(ERRNO_IS_DEVICE_ABSENT(r)); + ASSERT_TRUE(ERRNO_IS_NEG_DEVICE_ABSENT(r)); continue; } log_debug("> %s", syspath); - assert_se(sd_device_enumerator_new(&p) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(p) >= 0); - assert_se(sd_device_enumerator_add_match_parent(p, parent) >= 0); + ASSERT_OK(sd_device_enumerator_new(&p)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(p)); + ASSERT_OK(sd_device_enumerator_add_match_parent(p, parent)); check_parent_match(p, dev); /* If the device does not have subsystem, then it is not enumerated. */ r = sd_device_get_subsystem(parent, NULL); if (r < 0) { - assert_se(r == -ENOENT); + ASSERT_ERROR(r, ENOENT); continue; } check_parent_match(p, parent); @@ -542,49 +554,49 @@ TEST(sd_device_get_child) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; int r; - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); /* See comments in TEST(sd_device_enumerator_devices). */ - assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "net", false) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); if (!slow_tests_enabled()) - assert_se(sd_device_enumerator_add_match_subsystem(e, "block", true) >= 0); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); FOREACH_DEVICE(e, dev) { const char *syspath, *parent_syspath, *expected_suffix, *suffix; sd_device *parent; bool found = false; - assert_se(sd_device_get_syspath(dev, &syspath) >= 0); + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); r = sd_device_get_parent(dev, &parent); if (r < 0) { - assert_se(ERRNO_IS_DEVICE_ABSENT(r)); + ASSERT_TRUE(ERRNO_IS_NEG_DEVICE_ABSENT(r)); continue; } - assert_se(sd_device_get_syspath(parent, &parent_syspath) >= 0); - assert_se(expected_suffix = path_startswith(syspath, parent_syspath)); + ASSERT_OK(sd_device_get_syspath(parent, &parent_syspath)); + ASSERT_NOT_NULL((expected_suffix = path_startswith(syspath, parent_syspath))); log_debug("> %s", syspath); FOREACH_DEVICE_CHILD_WITH_SUFFIX(parent, child, suffix) { const char *s; - assert_se(child); - assert_se(suffix); + ASSERT_NOT_NULL(child); + ASSERT_NOT_NULL(suffix); if (!streq(suffix, expected_suffix)) continue; - assert_se(sd_device_get_syspath(child, &s) >= 0); - assert_se(streq(s, syspath)); + ASSERT_OK(sd_device_get_syspath(child, &s)); + ASSERT_STREQ(s, syspath); found = true; break; } - assert_se(found); + ASSERT_TRUE(found); } } @@ -602,42 +614,42 @@ TEST(sd_device_new_from_nulstr) { const char *nulstr; size_t len; - assert_se(sd_device_new_from_syspath(&device, "/sys/class/net/lo") >= 0); + ASSERT_OK(sd_device_new_from_syspath(&device, "/sys/class/net/lo")); /* Yeah, of course, setting devlink to the loopback interface is nonsense. But this is just a * test for generating and parsing nulstr. For issue #17772. */ NULSTR_FOREACH(devlink, devlinks) { log_device_info(device, "setting devlink: %s", devlink); - assert_se(device_add_devlink(device, devlink) >= 0); - assert_se(set_contains(device->devlinks, devlink)); + ASSERT_OK(device_add_devlink(device, devlink)); + ASSERT_TRUE(set_contains(device->devlinks, devlink)); } /* For issue #23799 */ - assert_se(device_add_tag(device, "tag1", false) >= 0); - assert_se(device_add_tag(device, "tag2", false) >= 0); - assert_se(device_add_tag(device, "current-tag1", true) >= 0); - assert_se(device_add_tag(device, "current-tag2", true) >= 0); + ASSERT_OK(device_add_tag(device, "tag1", false)); + ASSERT_OK(device_add_tag(device, "tag2", false)); + ASSERT_OK(device_add_tag(device, "current-tag1", true)); + ASSERT_OK(device_add_tag(device, "current-tag2", true)); /* These properties are necessary for device_new_from_nulstr(). See device_verify(). */ - assert_se(device_add_property_internal(device, "SEQNUM", "1") >= 0); - assert_se(device_add_property_internal(device, "ACTION", "change") >= 0); + ASSERT_OK(device_add_property_internal(device, "SEQNUM", "1")); + ASSERT_OK(device_add_property_internal(device, "ACTION", "change")); - assert_se(device_get_properties_nulstr(device, &nulstr, &len) >= 0); - assert_se(nulstr_copy = newdup(char, nulstr, len)); - assert_se(device_new_from_nulstr(&from_nulstr, nulstr_copy, len) >= 0); + ASSERT_OK(device_get_properties_nulstr(device, &nulstr, &len)); + ASSERT_NOT_NULL((nulstr_copy = newdup(char, nulstr, len))); + ASSERT_OK(device_new_from_nulstr(&from_nulstr, nulstr_copy, len)); - assert_se(sd_device_has_tag(from_nulstr, "tag1") == 1); - assert_se(sd_device_has_tag(from_nulstr, "tag2") == 1); - assert_se(sd_device_has_tag(from_nulstr, "current-tag1") == 1); - assert_se(sd_device_has_tag(from_nulstr, "current-tag2") == 1); - assert_se(sd_device_has_current_tag(from_nulstr, "tag1") == 0); - assert_se(sd_device_has_current_tag(from_nulstr, "tag2") == 0); - assert_se(sd_device_has_current_tag(from_nulstr, "current-tag1") == 1); - assert_se(sd_device_has_current_tag(from_nulstr, "current-tag2") == 1); + ASSERT_OK_POSITIVE(sd_device_has_tag(from_nulstr, "tag1")); + ASSERT_OK_POSITIVE(sd_device_has_tag(from_nulstr, "tag2")); + ASSERT_OK_POSITIVE(sd_device_has_tag(from_nulstr, "current-tag1")); + ASSERT_OK_POSITIVE(sd_device_has_tag(from_nulstr, "current-tag2")); + ASSERT_OK_ZERO(sd_device_has_current_tag(from_nulstr, "tag1")); + ASSERT_OK_ZERO(sd_device_has_current_tag(from_nulstr, "tag2")); + ASSERT_OK_POSITIVE(sd_device_has_current_tag(from_nulstr, "current-tag1")); + ASSERT_OK_POSITIVE(sd_device_has_current_tag(from_nulstr, "current-tag2")); NULSTR_FOREACH(devlink, devlinks) { log_device_info(from_nulstr, "checking devlink: %s", devlink); - assert_se(set_contains(from_nulstr->devlinks, devlink)); + ASSERT_TRUE(set_contains(from_nulstr->devlinks, devlink)); } } @@ -646,43 +658,44 @@ TEST(sd_device_new_from_path) { _cleanup_(rm_rf_physical_and_freep) char *tmpdir = NULL; int r; - assert_se(mkdtemp_malloc("/tmp/test-sd-device.XXXXXXX", &tmpdir) >= 0); + ASSERT_OK(mkdtemp_malloc("/tmp/test-sd-device.XXXXXXX", &tmpdir)); - assert_se(sd_device_enumerator_new(&e) >= 0); - assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0); - assert_se(sd_device_enumerator_add_match_subsystem(e, "block", true) >= 0); - assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0); - assert_se(sd_device_enumerator_add_match_property(e, "DEVNAME", "*") >= 0); + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); + ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); + ASSERT_OK(sd_device_enumerator_add_match_property(e, "DEVNAME", "*")); FOREACH_DEVICE(e, dev) { _cleanup_(sd_device_unrefp) sd_device *d = NULL; const char *syspath, *devpath, *sysname, *s; _cleanup_free_ char *path = NULL; - assert_se(sd_device_get_sysname(dev, &sysname) >= 0); + ASSERT_OK(sd_device_get_sysname(dev, &sysname)); log_debug("%s(%s)", __func__, sysname); - assert_se(sd_device_get_syspath(dev, &syspath) >= 0); - assert_se(sd_device_new_from_path(&d, syspath) >= 0); - assert_se(sd_device_get_syspath(d, &s) >= 0); - assert_se(streq(s, syspath)); - d = sd_device_unref(d); + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); + ASSERT_OK(sd_device_new_from_path(&d, syspath)); + ASSERT_OK(sd_device_get_syspath(d, &s)); + ASSERT_STREQ(s, syspath); + ASSERT_NULL((d = sd_device_unref(d))); - assert_se(sd_device_get_devname(dev, &devpath) >= 0); + ASSERT_OK(sd_device_get_devname(dev, &devpath)); r = sd_device_new_from_path(&d, devpath); - if (r >= 0) { - assert_se(sd_device_get_syspath(d, &s) >= 0); - assert_se(streq(s, syspath)); - d = sd_device_unref(d); - } else - assert_se(r == -ENODEV || ERRNO_IS_PRIVILEGE(r)); + if (r < 0) + ASSERT_TRUE(r == -ENODEV || ERRNO_IS_NEG_PRIVILEGE(r)); + else { + ASSERT_OK(sd_device_get_syspath(d, &s)); + ASSERT_STREQ(s, syspath); + ASSERT_NULL((d = sd_device_unref(d))); + } - assert_se(path = path_join(tmpdir, sysname)); - assert_se(symlink(syspath, path) >= 0); - assert_se(sd_device_new_from_path(&d, path) >= 0); - assert_se(sd_device_get_syspath(d, &s) >= 0); - assert_se(streq(s, syspath)); + ASSERT_NOT_NULL((path = path_join(tmpdir, sysname))); + ASSERT_OK_ERRNO(symlink(syspath, path)); + ASSERT_OK(sd_device_new_from_path(&d, path)); + ASSERT_OK(sd_device_get_syspath(d, &s)); + ASSERT_STREQ(s, syspath); } } @@ -693,16 +706,15 @@ static void test_devname_from_devnum_one(const char *path) { log_debug("> %s", path); if (stat(path, &st) < 0) { - assert_se(errno == ENOENT); log_notice("Path %s not found, skipping test", path); return; } - assert_se(devname_from_devnum(st.st_mode, st.st_rdev, &resolved) >= 0); - assert_se(path_equal(path, resolved)); - resolved = mfree(resolved); - assert_se(devname_from_stat_rdev(&st, &resolved) >= 0); - assert_se(path_equal(path, resolved)); + ASSERT_OK(devname_from_devnum(st.st_mode, st.st_rdev, &resolved)); + ASSERT_TRUE(path_equal(path, resolved)); + ASSERT_NULL((resolved = mfree(resolved))); + ASSERT_OK(devname_from_stat_rdev(&st, &resolved)); + ASSERT_TRUE(path_equal(path, resolved)); } TEST(devname_from_devnum) { From 32b0e689d62d991576355a90cf5dc7b5ee3adb19 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 9 Mar 2025 11:00:37 +0900 Subject: [PATCH 04/15] test: do not pass return value to log_error_errno() on success --- src/shared/tests.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/tests.h b/src/shared/tests.h index 173d64fa77d..8d0e6a4bcf3 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -335,8 +335,8 @@ static inline int run_test_table(void) { ({ \ typeof(expr) _result = (expr); \ if (_result >= 0) { \ - log_error_errno(_result, "%s:%i: Assertion failed: expected \"%s\" to fail, but it succeeded", \ - PROJECT_FILE, __LINE__, #expr); \ + log_error("%s:%i: Assertion failed: expected \"%s\" to fail, but it succeeded.", \ + PROJECT_FILE, __LINE__, #expr); \ abort(); \ } \ }) From bec2f4dc3e2714409be6ba7e099eb524d475110a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 07:03:45 +0900 Subject: [PATCH 05/15] sd_device: introduce device_get_ifname() sd-device replaces '!' in sysname with '/'. Hence, sysname and ifname may be different. Let's get network interface name through INTERFACE property. --- src/libsystemd/sd-device/device-private.h | 1 + src/libsystemd/sd-device/sd-device.c | 15 +++++++++++++++ src/libsystemd/sd-device/test-sd-device.c | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index 7d925aa581d..dea77286339 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -21,6 +21,7 @@ int device_opendir(sd_device *device, const char *subdir, DIR **ret); int device_get_sysnum_unsigned(sd_device *device, unsigned *ret); int device_get_property_bool(sd_device *device, const char *key); int device_get_property_int(sd_device *device, const char *key, int *ret); +int device_get_ifname(sd_device *device, const char **ret); int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value); int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value); static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 181a9256dd2..b7b308b3908 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -871,6 +871,21 @@ _public_ int sd_device_get_ifindex(sd_device *device, int *ifindex) { return 0; } +int device_get_ifname(sd_device *device, const char **ret) { + int r; + + assert_return(device, -EINVAL); + + /* First, check if the device is a network interface. */ + r = sd_device_get_ifindex(device, NULL); + if (r < 0) + return r; + + /* The sysname and ifname may be different, as '!' in sysname are replaced with '/'. + * For network interfaces, we can use INTERFACE property. */ + return sd_device_get_property_value(device, "INTERFACE", ret); +} + _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) { int r; diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index 705a10d159f..b2b04562cde 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -52,6 +52,14 @@ static void test_sd_device_one(sd_device *d) { else { ASSERT_GT(ifindex, 0); + const char *ifname; + ASSERT_OK(device_get_ifname(d, &ifname)); + ASSERT_NOT_NULL(endswith(syspath, ifname)); + if (strchr(sysname, '/')) + ASSERT_FALSE(streq(ifname, sysname)); + else + ASSERT_STREQ(ifname, sysname); + r = sd_device_new_from_ifindex(&dev, ifindex); if (r < 0) { ASSERT_ERROR(r, ENODEV); From e3bc8d3449d5b7259556227526c4ba58ecf7feef Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 08:16:10 +0900 Subject: [PATCH 06/15] udev-builtin-net_driver: use correct interface name Previously, when the interface name contains '!', the builtin command failed to get the driver of the interface. --- src/udev/udev-builtin-net_driver.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/udev/udev-builtin-net_driver.c b/src/udev/udev-builtin-net_driver.c index 5e35b39ee45..832ed6fdee7 100644 --- a/src/udev/udev-builtin-net_driver.c +++ b/src/udev/udev-builtin-net_driver.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "alloc-util.h" +#include "device-private.h" #include "device-util.h" #include "errno-util.h" #include "ethtool-util.h" @@ -13,16 +14,16 @@ static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); _cleanup_close_ int ethtool_fd = -EBADF; _cleanup_free_ char *driver = NULL; - const char *sysname; + const char *ifname; int r; - r = sd_device_get_sysname(dev, &sysname); + r = device_get_ifname(dev, &ifname); if (r < 0) - return log_device_warning_errno(dev, r, "Failed to get sysname: %m"); + return log_device_warning_errno(dev, r, "Failed to get network interface name: %m"); - r = ethtool_get_driver(ðtool_fd, sysname, &driver); + r = ethtool_get_driver(ðtool_fd, ifname, &driver); if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) { - log_device_debug_errno(dev, r, "Querying driver name via ethtool API is not supported by device '%s', ignoring: %m", sysname); + log_device_debug_errno(dev, r, "Querying driver name via ethtool API is not supported by device '%s', ignoring: %m", ifname); return 0; } if (r == -ENODEV) { @@ -30,7 +31,7 @@ static int builtin_net_driver_set_driver(UdevEvent *event, int argc, char **argv return 0; } if (r < 0) - return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", sysname); + return log_device_warning_errno(dev, r, "Failed to get driver for '%s': %m", ifname); return udev_builtin_add_property(event, "ID_NET_DRIVER", driver); } From 4352457a9697da0466c03915aa10bc64ee4a328b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 08:19:45 +0900 Subject: [PATCH 07/15] udev-event: set INTERFACE/INTERFACE_OLD property on rename only when the device is a network interface This does not change any behavior, as currently udevd only supports renaming for network interfaces. Closes #26156. --- src/udev/udev-event.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 7d9153061f7..9a50acafe96 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -96,11 +96,8 @@ static int device_rename(sd_device *device, const char *name) { if (r < 0) return r; - r = sd_device_get_property_value(device, "INTERFACE", &s); - if (r == -ENOENT) + if (device_get_ifname(device, &s) < 0) return 0; - if (r < 0) - return r; /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */ r = device_add_property_internal(device, "INTERFACE_OLD", s); From b3157fc91262b6b9ed07556a3da1d40396f53fe9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 08:22:54 +0900 Subject: [PATCH 08/15] udev-event: fix filtering logic of renaming network interface The device sysname may be different from the network interface name. --- src/udev/udev-event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 9a50acafe96..d8bdf835b21 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -135,9 +135,9 @@ static int rename_netif(UdevEvent *event) { return 0; } - r = sd_device_get_sysname(dev, &s); + r = device_get_ifname(dev, &s); if (r < 0) - return log_device_warning_errno(dev, r, "Failed to get sysname: %m"); + return log_device_warning_errno(dev, r, "Failed to get ifname: %m"); if (streq(event->name, s)) return 0; /* The interface name is already requested name. */ @@ -242,9 +242,9 @@ static int assign_altnames(UdevEvent *event) { if (r < 0) return log_device_warning_errno(dev, r, "Failed to get ifindex: %m"); - r = sd_device_get_sysname(dev, &s); + r = device_get_ifname(dev, &s); if (r < 0) - return log_device_warning_errno(dev, r, "Failed to get sysname: %m"); + return log_device_warning_errno(dev, r, "Failed to get ifname: %m"); /* Filter out the current interface name. */ strv_remove(event->altnames, s); From b15053de8934ab0803ead56f9483b6950a3fe0f0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 07:25:28 +0900 Subject: [PATCH 09/15] udev/net: fix assignment of ID_NET_NAME= E.g. sd_device object of network interface 'hoge!foo' has sysname 'hoge/foo'. So, previously udevd assigned 'hoge/foo' rather than 'hoge!foo' to ID_NET_NAME, hence even when renaming is not requested, such interface was renamed to 'hoge_foo' (note '/' cannot be used in network interface name, hence escaped to underbar). --- man/systemd.net-naming-scheme.xml | 10 ++++ src/shared/netif-naming-scheme.c | 1 + src/shared/netif-naming-scheme.h | 2 + src/udev/net/link-config.c | 5 +- src/udev/udev-builtin-net_setup_link.c | 6 ++- .../TEST-17-UDEV.netif-INTERFACE-property.sh | 46 +++++++++++++++++++ 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100755 test/units/TEST-17-UDEV.netif-INTERFACE-property.sh diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml index 6e77af99293..96688ed3c91 100644 --- a/man/systemd.net-naming-scheme.xml +++ b/man/systemd.net-naming-scheme.xml @@ -540,6 +540,16 @@ + + + v258 + + When no renaming is requested, ID_NET_NAME property is now + equivalent to INTERFACE property. + + + + Note that latest may be used to denote the latest scheme known (to this diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c index 67b7eb4d904..8e05598c5e8 100644 --- a/src/shared/netif-naming-scheme.c +++ b/src/shared/netif-naming-scheme.c @@ -25,6 +25,7 @@ static const NamingScheme naming_schemes[] = { { "v254", NAMING_V254 }, { "v255", NAMING_V255 }, { "v257", NAMING_V257 }, + { "v258", NAMING_V258 }, /* … add more schemes here, as the logic to name devices is updated … */ EXTRA_NET_NAMING_MAP diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h index 3ab1d752c87..5ead1f85d78 100644 --- a/src/shared/netif-naming-scheme.h +++ b/src/shared/netif-naming-scheme.h @@ -45,6 +45,7 @@ typedef enum NamingSchemeFlags { NAMING_SR_IOV_R = 1 << 17, /* Use "r" suffix for SR-IOV VF representors */ NAMING_FIRMWARE_NODE_SUN = 1 << 18, /* Use firmware_node/sun to get PCI slot number */ NAMING_DEVICETREE_PORT_ALIASES = 1 << 19, /* Include aliases of OF nodes of a netdev itself, not just its parent. See PR #33958. */ + NAMING_USE_INTERFACE_PROPERTY = 1 << 20, /* Use INTERFACE udev property, rather than sysname, when no renaming is requested. */ /* And now the masks that combine the features above */ NAMING_V238 = 0, @@ -65,6 +66,7 @@ typedef enum NamingSchemeFlags { * systemd version 255, naming scheme "v255". */ NAMING_V255 = NAMING_V254 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT, NAMING_V257 = NAMING_V255 | NAMING_FIRMWARE_NODE_SUN | NAMING_DEVICETREE_PORT_ALIASES, + NAMING_V258 = NAMING_V257 | NAMING_USE_INTERFACE_PROPERTY, EXTRA_NET_NAMING_SCHEMES diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 3400286566f..b3bb164bbe5 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -400,7 +400,7 @@ int link_new(LinkConfigContext *ctx, UdevEvent *event, Link **ret) { .event = udev_event_ref(event), }; - r = sd_device_get_sysname(dev, &link->ifname); + r = device_get_ifname(dev, &link->ifname); if (r < 0) return r; @@ -804,6 +804,9 @@ static int link_generate_new_name(Link *link) { log_link_debug(link, "Policies didn't yield a name and Name= is not given, not renaming."); no_rename: + if (!naming_scheme_has(NAMING_USE_INTERFACE_PROPERTY)) + return sd_device_get_sysname(device, &link->new_name); + link->new_name = link->ifname; return 0; } diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index 0062a85db58..0d59a72a062 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -35,7 +35,11 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv) { /* Set ID_NET_NAME= with the current interface name. */ const char *value; - if (sd_device_get_sysname(dev, &value) >= 0) + if (naming_scheme_has(NAMING_USE_INTERFACE_PROPERTY)) + r = device_get_ifname(dev, &value); + else + r = sd_device_get_sysname(dev, &value); + if (r >= 0) (void) udev_builtin_add_property(event, "ID_NET_NAME", value); return 0; diff --git a/test/units/TEST-17-UDEV.netif-INTERFACE-property.sh b/test/units/TEST-17-UDEV.netif-INTERFACE-property.sh new file mode 100755 index 00000000000..deb115626d9 --- /dev/null +++ b/test/units/TEST-17-UDEV.netif-INTERFACE-property.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -ex +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +mkdir -p /run/systemd/network/ +cat >/run/systemd/network/10-rename-test.link < Date: Thu, 6 Mar 2025 06:53:37 +0900 Subject: [PATCH 10/15] udev/net: replace device_unsigned_attribute() with device_get_sysattr_unsigned() They are completely equivalent, except for logging. This also drops duplicated log messages on failure paths. --- src/udev/net/link-config.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index b3bb164bbe5..ec760c80f18 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -325,22 +325,6 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) { return 0; } -static int device_unsigned_attribute(sd_device *device, const char *attr, unsigned *type) { - const char *s; - int r; - - r = sd_device_get_sysattr_value(device, attr, &s); - if (r < 0) - return log_device_debug_errno(device, r, "Failed to query %s: %m", attr); - - r = safe_atou(s, type); - if (r < 0) - return log_device_warning_errno(device, r, "Failed to parse %s \"%s\": %m", attr, s); - - log_device_debug(device, "Device has %s=%u", attr, *type); - return 0; -} - int link_config_load(LinkConfigContext *ctx) { _cleanup_strv_free_ char **files = NULL; int r; @@ -412,13 +396,17 @@ int link_new(LinkConfigContext *ctx, UdevEvent *event, Link **ret) { if (r < 0) return r; - r = device_unsigned_attribute(dev, "name_assign_type", &link->name_assign_type); + r = device_get_sysattr_unsigned(dev, "name_assign_type", &link->name_assign_type); if (r < 0) log_link_debug_errno(link, r, "Failed to get \"name_assign_type\" attribute, ignoring: %m"); + else + log_link_debug(link, "Device has name_assign_type attribute: %u", link->name_assign_type); - r = device_unsigned_attribute(dev, "addr_assign_type", &link->addr_assign_type); + r = device_get_sysattr_unsigned(dev, "addr_assign_type", &link->addr_assign_type); if (r < 0) log_link_debug_errno(link, r, "Failed to get \"addr_assign_type\" attribute, ignoring: %m"); + else + log_link_debug(link, "Device has addr_assign_type attribute: %u", link->addr_assign_type); r = rtnl_get_link_info(&event->rtnl, link->ifindex, &link->iftype, &link->flags, &link->kind, &link->hw_addr, &link->permanent_hw_addr); From f0ebc0c5bfd5350e40a80ad9ea5a777bb3dfa695 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 12:11:43 +0900 Subject: [PATCH 11/15] tests: introduce ASSERT_PTR_EQ() --- src/shared/tests.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shared/tests.h b/src/shared/tests.h index 8d0e6a4bcf3..07c4eeefbdd 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -418,6 +418,16 @@ static inline int run_test_table(void) { } \ }) +#define ASSERT_PTR_EQ(expr1, expr2) \ + ({ \ + const void *_expr1 = (expr1), *_expr2 = (expr2); \ + if (_expr1 != _expr2) { \ + log_error("%s:%i: Assertion failed: expected \"%s == %s\", got \"0x%p != 0x%p\"", \ + PROJECT_FILE, __LINE__, #expr1, #expr2, _expr1, _expr2); \ + abort(); \ + } \ + }) + /* DECIMAL_STR_FMT() uses _Generic which cannot be used in string concatenation so we have to format the * input into strings first and then format those into the final assertion message. */ From 3841288e5f8583208550f8215443bf8da6080fd1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 11:48:54 +0900 Subject: [PATCH 12/15] test-netlink: use ASSERT_OK() and friends --- src/libsystemd/sd-netlink/test-netlink.c | 549 +++++++++++------------ 1 file changed, 271 insertions(+), 278 deletions(-) diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index d51b7cf76ba..2aeb5eefee3 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -30,20 +30,20 @@ TEST(message_newlink_bridge) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; uint32_t cost; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1) >= 0); - assert_se(sd_rtnl_message_link_set_family(message, AF_BRIDGE) >= 0); - assert_se(sd_netlink_message_open_container(message, IFLA_PROTINFO) >= 0); - assert_se(sd_netlink_message_append_u32(message, IFLA_BRPORT_COST, 10) >= 0); - assert_se(sd_netlink_message_close_container(message) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1)); + ASSERT_OK(sd_rtnl_message_link_set_family(message, AF_BRIDGE)); + ASSERT_OK(sd_netlink_message_open_container(message, IFLA_PROTINFO)); + ASSERT_OK(sd_netlink_message_append_u32(message, IFLA_BRPORT_COST, 10)); + ASSERT_OK(sd_netlink_message_close_container(message)); - assert_se(sd_netlink_message_rewind(message, rtnl) >= 0); + ASSERT_OK(sd_netlink_message_rewind(message, rtnl)); - assert_se(sd_netlink_message_enter_container(message, IFLA_PROTINFO) >= 0); - assert_se(sd_netlink_message_read_u32(message, IFLA_BRPORT_COST, &cost) >= 0); - assert_se(cost == 10); - assert_se(sd_netlink_message_exit_container(message) >= 0); + ASSERT_OK(sd_netlink_message_enter_container(message, IFLA_PROTINFO)); + ASSERT_OK(sd_netlink_message_read_u32(message, IFLA_BRPORT_COST, &cost)); + ASSERT_EQ(cost, 10U); + ASSERT_OK(sd_netlink_message_exit_container(message)); } TEST(message_getlink) { @@ -56,33 +56,33 @@ TEST(message_getlink) { const char *str_data; struct ether_addr eth_data; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); ifindex = (int) if_nametoindex("lo"); /* we'd really like to test NEWLINK, but let's not mess with the running kernel */ - assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex)); + ASSERT_OK_EQ(sd_netlink_call(rtnl, message, 0, &reply), 1); /* u8 */ - assert_se(sd_netlink_message_read_u8(reply, IFLA_CARRIER, &u8_data) >= 0); - assert_se(sd_netlink_message_read_u8(reply, IFLA_OPERSTATE, &u8_data) >= 0); - assert_se(sd_netlink_message_read_u8(reply, IFLA_LINKMODE, &u8_data) >= 0); + ASSERT_OK(sd_netlink_message_read_u8(reply, IFLA_CARRIER, &u8_data)); + ASSERT_OK(sd_netlink_message_read_u8(reply, IFLA_OPERSTATE, &u8_data)); + ASSERT_OK(sd_netlink_message_read_u8(reply, IFLA_LINKMODE, &u8_data)); /* u16 */ - assert_se(sd_netlink_message_get_type(reply, &u16_data) >= 0); - assert_se(u16_data == RTM_NEWLINK); + ASSERT_OK(sd_netlink_message_get_type(reply, &u16_data)); + ASSERT_EQ(u16_data, RTM_NEWLINK); /* u32 */ - assert_se(sd_netlink_message_read_u32(reply, IFLA_MTU, &u32_data) >= 0); - assert_se(sd_netlink_message_read_u32(reply, IFLA_GROUP, &u32_data) >= 0); - assert_se(sd_netlink_message_read_u32(reply, IFLA_TXQLEN, &u32_data) >= 0); - assert_se(sd_netlink_message_read_u32(reply, IFLA_NUM_TX_QUEUES, &u32_data) >= 0); + ASSERT_OK(sd_netlink_message_read_u32(reply, IFLA_MTU, &u32_data)); + ASSERT_OK(sd_netlink_message_read_u32(reply, IFLA_GROUP, &u32_data)); + ASSERT_OK(sd_netlink_message_read_u32(reply, IFLA_TXQLEN, &u32_data)); + ASSERT_OK(sd_netlink_message_read_u32(reply, IFLA_NUM_TX_QUEUES, &u32_data)); /* string */ - assert_se(sd_netlink_message_read_string(reply, IFLA_IFNAME, &str_data) >= 0); + ASSERT_OK(sd_netlink_message_read_string(reply, IFLA_IFNAME, &str_data)); /* ether_addr */ - assert_se(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, ð_data) >= 0); + ASSERT_OK(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, ð_data)); } TEST(message_address) { @@ -94,21 +94,20 @@ TEST(message_address) { const char *label; int r; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl) >= 0); ifindex = (int) if_nametoindex("lo"); - assert_se(sd_rtnl_message_new_addr(rtnl, &message, RTM_GETADDR, ifindex, AF_INET) >= 0); - assert_se(sd_netlink_message_set_request_dump(message, true) >= 0); + ASSERT_OK(sd_rtnl_message_new_addr(rtnl, &message, RTM_GETADDR, ifindex, AF_INET) >= 0); + ASSERT_OK(sd_netlink_message_set_request_dump(message, true) >= 0); - r = sd_netlink_call(rtnl, message, 0, &reply); - assert_se(r >= 0); + ASSERT_OK((r = sd_netlink_call(rtnl, message, 0, &reply))); /* If the loopback device is down we won't get any results. */ if (r > 0) { - assert_se(sd_netlink_message_read_in_addr(reply, IFA_LOCAL, &in_data) >= 0); - assert_se(sd_netlink_message_read_in_addr(reply, IFA_ADDRESS, &in_data) >= 0); - assert_se(sd_netlink_message_read_string(reply, IFA_LABEL, &label) >= 0); - assert_se(sd_netlink_message_read_cache_info(reply, IFA_CACHEINFO, &cache) >= 0); + ASSERT_OK(sd_netlink_message_read_in_addr(reply, IFA_LOCAL, &in_data)); + ASSERT_OK(sd_netlink_message_read_in_addr(reply, IFA_ADDRESS, &in_data)); + ASSERT_OK(sd_netlink_message_read_string(reply, IFA_LABEL, &label)); + ASSERT_OK(sd_netlink_message_read_cache_info(reply, IFA_CACHEINFO, &cache)); } } @@ -118,36 +117,36 @@ TEST(message_route) { struct in_addr addr, addr_data; uint32_t index = 2, u32_data; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl) >= 0); - assert_se(sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC) >= 0); + ASSERT_OK(sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC) >= 0); addr.s_addr = htobe32(INADDR_LOOPBACK); - assert_se(sd_netlink_message_append_in_addr(req, RTA_GATEWAY, &addr) >= 0); - assert_se(sd_netlink_message_append_u32(req, RTA_OIF, index) >= 0); + ASSERT_OK(sd_netlink_message_append_in_addr(req, RTA_GATEWAY, &addr) >= 0); + ASSERT_OK(sd_netlink_message_append_u32(req, RTA_OIF, index) >= 0); - assert_se(sd_netlink_message_rewind(req, rtnl) >= 0); + ASSERT_OK(sd_netlink_message_rewind(req, rtnl) >= 0); - assert_se(sd_netlink_message_read_in_addr(req, RTA_GATEWAY, &addr_data) >= 0); - assert_se(addr_data.s_addr == addr.s_addr); + ASSERT_OK(sd_netlink_message_read_in_addr(req, RTA_GATEWAY, &addr_data) >= 0); + ASSERT_EQ(addr_data.s_addr, addr.s_addr); - assert_se(sd_netlink_message_read_u32(req, RTA_OIF, &u32_data) >= 0); - assert_se(u32_data == index); + ASSERT_OK(sd_netlink_message_read_u32(req, RTA_OIF, &u32_data) >= 0); + ASSERT_EQ(u32_data, index); - assert_se((req = sd_netlink_message_unref(req)) == NULL); + ASSERT_NULL((req = sd_netlink_message_unref(req))); } static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { const char *data; - assert_se(rtnl); - assert_se(m); + ASSERT_NOT_NULL(rtnl); + ASSERT_NOT_NULL(m); - assert_se(streq_ptr(userdata, "foo")); + ASSERT_STREQ(userdata, "foo"); - assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0); - assert_se(streq(data, "lo")); + ASSERT_OK(sd_netlink_message_read_string(m, IFLA_IFNAME, &data)); + ASSERT_STREQ(data, "lo"); log_info("%s: got link info about %s", __func__, data); return 1; @@ -160,21 +159,21 @@ TEST(netlink_event_loop) { _cleanup_free_ char *userdata = NULL; int ifindex; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); ifindex = (int) if_nametoindex("lo"); - assert_se(userdata = strdup("foo")); + ASSERT_NOT_NULL((userdata = strdup("foo"))); - assert_se(sd_event_default(&event) >= 0); - assert_se(sd_netlink_attach_event(rtnl, event, 0) >= 0); + ASSERT_OK(sd_event_default(&event)); + ASSERT_OK(sd_netlink_attach_event(rtnl, event, 0)); - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, userdata, 0, NULL) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, userdata, 0, NULL)); - assert_se(sd_event_run(event, 0) >= 0); + ASSERT_OK(sd_event_run(event, 0)); - assert_se(sd_netlink_detach_event(rtnl) >= 0); - assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + ASSERT_OK(sd_netlink_detach_event(rtnl)); + ASSERT_NULL((rtnl = sd_netlink_unref(rtnl))); } static void test_async_destroy(void *userdata) { @@ -189,45 +188,45 @@ TEST(netlink_call_async) { const char *description; int ifindex; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); ifindex = (int) if_nametoindex("lo"); - assert_se(userdata = strdup("foo")); + ASSERT_NOT_NULL((userdata = strdup("foo"))); - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, test_async_destroy, userdata, 0, "hogehoge") >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_netlink_call_async(rtnl, &slot, m, link_handler, test_async_destroy, userdata, 0, "hogehoge")); - assert_se(sd_netlink_slot_get_netlink(slot) == rtnl); + ASSERT_PTR_EQ(sd_netlink_slot_get_netlink(slot), rtnl); - assert_se(sd_netlink_slot_get_userdata(slot) == userdata); - assert_se(sd_netlink_slot_set_userdata(slot, NULL) == userdata); - assert_se(sd_netlink_slot_get_userdata(slot) == NULL); - assert_se(sd_netlink_slot_set_userdata(slot, userdata) == NULL); - assert_se(sd_netlink_slot_get_userdata(slot) == userdata); + ASSERT_PTR_EQ(sd_netlink_slot_get_userdata(slot), userdata); + ASSERT_PTR_EQ(sd_netlink_slot_set_userdata(slot, NULL), userdata); + ASSERT_NULL(sd_netlink_slot_get_userdata(slot)); + ASSERT_NULL(sd_netlink_slot_set_userdata(slot, userdata)); + ASSERT_PTR_EQ(sd_netlink_slot_get_userdata(slot), userdata); - assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 1); - assert_se(destroy_callback == test_async_destroy); - assert_se(sd_netlink_slot_set_destroy_callback(slot, NULL) >= 0); - assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 0); - assert_se(destroy_callback == NULL); - assert_se(sd_netlink_slot_set_destroy_callback(slot, test_async_destroy) >= 0); - assert_se(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback) == 1); - assert_se(destroy_callback == test_async_destroy); + ASSERT_OK_EQ(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback), 1); + ASSERT_PTR_EQ(destroy_callback, test_async_destroy); + ASSERT_OK(sd_netlink_slot_set_destroy_callback(slot, NULL)); + ASSERT_OK_ZERO(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback)); + ASSERT_NULL(destroy_callback); + ASSERT_OK(sd_netlink_slot_set_destroy_callback(slot, test_async_destroy)); + ASSERT_OK_EQ(sd_netlink_slot_get_destroy_callback(slot, &destroy_callback), 1); + ASSERT_PTR_EQ(destroy_callback, test_async_destroy); - assert_se(sd_netlink_slot_get_floating(slot) == 0); - assert_se(sd_netlink_slot_set_floating(slot, 1) == 1); - assert_se(sd_netlink_slot_get_floating(slot) == 1); + ASSERT_OK_ZERO(sd_netlink_slot_get_floating(slot)); + ASSERT_OK_EQ(sd_netlink_slot_set_floating(slot, 1), 1); + ASSERT_OK_EQ(sd_netlink_slot_get_floating(slot), 1); - assert_se(sd_netlink_slot_get_description(slot, &description) == 1); - assert_se(streq(description, "hogehoge")); - assert_se(sd_netlink_slot_set_description(slot, NULL) >= 0); - assert_se(sd_netlink_slot_get_description(slot, &description) == 0); - assert_se(description == NULL); + ASSERT_OK_EQ(sd_netlink_slot_get_description(slot, &description), 1); + ASSERT_STREQ(description, "hogehoge"); + ASSERT_OK(sd_netlink_slot_set_description(slot, NULL)); + ASSERT_OK_ZERO(sd_netlink_slot_get_description(slot, &description)); + ASSERT_NULL(description); - assert_se(sd_netlink_wait(rtnl, 0) >= 0); - assert_se(sd_netlink_process(rtnl, &reply) >= 0); + ASSERT_OK(sd_netlink_wait(rtnl, 0)); + ASSERT_OK(sd_netlink_process(rtnl, &reply)); - assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + ASSERT_NULL((rtnl = sd_netlink_unref(rtnl))); } struct test_async_object { @@ -236,7 +235,7 @@ struct test_async_object { }; static struct test_async_object *test_async_object_free(struct test_async_object *t) { - assert_se(t); + ASSERT_NOT_NULL(t); free(t->ifname); return mfree(t); @@ -249,14 +248,14 @@ static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata struct test_async_object *t = userdata; const char *data; - assert_se(rtnl); - assert_se(m); - assert_se(userdata); + ASSERT_NOT_NULL(rtnl); + ASSERT_NOT_NULL(m); + ASSERT_NOT_NULL(userdata); log_info("%s: got link info about %s", __func__, t->ifname); - assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0); - assert_se(streq(data, "lo")); + ASSERT_OK(sd_netlink_message_read_string(m, IFLA_IFNAME, &data)); + ASSERT_STREQ(data, "lo"); return 1; } @@ -264,7 +263,7 @@ static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata static void test_async_object_destroy(void *userdata) { struct test_async_object *t = userdata; - assert_se(userdata); + ASSERT_NOT_NULL(userdata); log_info("%s: n_ref=%u", __func__, t->n_ref); test_async_object_unref(t); @@ -277,66 +276,61 @@ TEST(async_destroy_callback) { _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL; int ifindex; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); ifindex = (int) if_nametoindex("lo"); - assert_se(t = new(struct test_async_object, 1)); + ASSERT_NOT_NULL((t = new(struct test_async_object, 1))); *t = (struct test_async_object) { .n_ref = 1, }; - assert_se(t->ifname = strdup("lo")); + ASSERT_NOT_NULL((t->ifname = strdup("lo"))); /* destroy callback is called after processing message */ - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL)); - assert_se(t->n_ref == 1); - assert_se(test_async_object_ref(t)); - assert_se(t->n_ref == 2); + ASSERT_EQ(t->n_ref, 1U); + ASSERT_PTR_EQ(test_async_object_ref(t), t); + ASSERT_EQ(t->n_ref, 2U); - assert_se(sd_netlink_wait(rtnl, 0) >= 0); - assert_se(sd_netlink_process(rtnl, &reply) == 1); - assert_se(t->n_ref == 1); + ASSERT_OK(sd_netlink_wait(rtnl, 0)); + ASSERT_OK_EQ(sd_netlink_process(rtnl, &reply), 1); + ASSERT_EQ(t->n_ref, 1U); - assert_se(!sd_netlink_message_unref(m)); + ASSERT_NULL(sd_netlink_message_unref(m)); /* destroy callback is called when asynchronous call is cancelled, that is, slot is freed. */ - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_netlink_call_async(rtnl, &slot, m, link_handler2, test_async_object_destroy, t, 0, NULL)); - assert_se(t->n_ref == 1); - assert_se(test_async_object_ref(t)); - assert_se(t->n_ref == 2); + ASSERT_EQ(t->n_ref, 1U); + ASSERT_PTR_EQ(test_async_object_ref(t), t); + ASSERT_EQ(t->n_ref, 2U); - assert_se(!(slot = sd_netlink_slot_unref(slot))); - assert_se(t->n_ref == 1); + ASSERT_NULL((slot = sd_netlink_slot_unref(slot))); + ASSERT_EQ(t->n_ref, 1U); - assert_se(!sd_netlink_message_unref(m)); + ASSERT_NULL(sd_netlink_message_unref(m)); /* destroy callback is also called by sd_netlink_unref() */ - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL)); - assert_se(t->n_ref == 1); - assert_se(test_async_object_ref(t)); - assert_se(t->n_ref == 2); + ASSERT_EQ(t->n_ref, 1U); + ASSERT_PTR_EQ(test_async_object_ref(t), t); + ASSERT_EQ(t->n_ref, 2U); - assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); - assert_se(t->n_ref == 1); + ASSERT_NULL((rtnl = sd_netlink_unref(rtnl))); + ASSERT_EQ(t->n_ref, 1U); } static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { - int *counter = userdata; - int r; + int r, *counter = userdata; (*counter)--; - r = sd_netlink_message_get_errno(m); - + ASSERT_OK((r = sd_netlink_message_get_errno(m))); log_info_errno(r, "%d left in pipe. got reply: %m", *counter); - - assert_se(r >= 0); - return 1; } @@ -345,24 +339,24 @@ TEST(pipe) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL; int ifindex, counter = 0; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); ifindex = (int) if_nametoindex("lo"); - assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0); - assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex)); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex)); counter++; - assert_se(sd_netlink_call_async(rtnl, NULL, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0); + ASSERT_OK(sd_netlink_call_async(rtnl, NULL, m1, pipe_handler, NULL, &counter, 0, NULL)); counter++; - assert_se(sd_netlink_call_async(rtnl, NULL, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0); + ASSERT_OK(sd_netlink_call_async(rtnl, NULL, m2, pipe_handler, NULL, &counter, 0, NULL)); while (counter > 0) { - assert_se(sd_netlink_wait(rtnl, 0) >= 0); - assert_se(sd_netlink_process(rtnl, NULL) >= 0); + ASSERT_OK(sd_netlink_wait(rtnl, 0)); + ASSERT_OK(sd_netlink_process(rtnl, NULL)); } - assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + ASSERT_NULL((rtnl = sd_netlink_unref(rtnl))); } TEST(message_container) { @@ -372,74 +366,74 @@ TEST(message_container) { uint32_t u32_data; const char *string_data; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0)); - assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); - assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0); - assert_se(sd_netlink_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0); - assert_se(sd_netlink_message_close_container(m) >= 0); - assert_se(sd_netlink_message_close_container(m) >= 0); + ASSERT_OK(sd_netlink_message_open_container(m, IFLA_LINKINFO)); + ASSERT_OK(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan")); + ASSERT_OK(sd_netlink_message_append_u16(m, IFLA_VLAN_ID, 100)); + ASSERT_OK(sd_netlink_message_close_container(m)); + ASSERT_OK(sd_netlink_message_close_container(m)); - assert_se(sd_netlink_message_rewind(m, rtnl) >= 0); + ASSERT_OK(sd_netlink_message_rewind(m, rtnl)); - assert_se(sd_netlink_message_enter_container(m, IFLA_LINKINFO) >= 0); - assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0); - assert_se(streq("vlan", string_data)); + ASSERT_OK(sd_netlink_message_enter_container(m, IFLA_LINKINFO)); + ASSERT_OK(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data)); + ASSERT_STREQ("vlan", string_data); - assert_se(sd_netlink_message_enter_container(m, IFLA_INFO_DATA) >= 0); - assert_se(sd_netlink_message_read_u16(m, IFLA_VLAN_ID, &u16_data) >= 0); - assert_se(sd_netlink_message_exit_container(m) >= 0); + ASSERT_OK(sd_netlink_message_enter_container(m, IFLA_INFO_DATA)); + ASSERT_OK(sd_netlink_message_read_u16(m, IFLA_VLAN_ID, &u16_data)); + ASSERT_OK(sd_netlink_message_exit_container(m)); - assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0); - assert_se(streq("vlan", string_data)); - assert_se(sd_netlink_message_exit_container(m) >= 0); + ASSERT_OK(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data)); + ASSERT_STREQ("vlan", string_data); + ASSERT_OK(sd_netlink_message_exit_container(m)); - assert_se(sd_netlink_message_read_u32(m, IFLA_LINKINFO, &u32_data) < 0); + ASSERT_FAIL(sd_netlink_message_read_u32(m, IFLA_LINKINFO, &u32_data)); } TEST(sd_netlink_add_match) { _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *s1 = NULL, *s2 = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0); - assert_se(sd_netlink_add_match(rtnl, &s2, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0); - assert_se(sd_netlink_add_match(rtnl, NULL, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0); + ASSERT_OK(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL, NULL)); + ASSERT_OK(sd_netlink_add_match(rtnl, &s2, RTM_NEWLINK, link_handler, NULL, NULL, NULL)); + ASSERT_OK(sd_netlink_add_match(rtnl, NULL, RTM_NEWLINK, link_handler, NULL, NULL, NULL)); - assert_se(!(s1 = sd_netlink_slot_unref(s1))); - assert_se(!(s2 = sd_netlink_slot_unref(s2))); + ASSERT_NULL((s1 = sd_netlink_slot_unref(s1))); + ASSERT_NULL((s2 = sd_netlink_slot_unref(s2))); - assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + ASSERT_NULL((rtnl = sd_netlink_unref(rtnl))); } TEST(dump_addresses) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0); - assert_se(sd_netlink_message_set_request_dump(req, true) >= 0); - assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0); + ASSERT_OK(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC)); + ASSERT_OK(sd_netlink_message_set_request_dump(req, true)); + ASSERT_OK(sd_netlink_call(rtnl, req, 0, &reply)); for (sd_netlink_message *m = reply; m; m = sd_netlink_message_next(m)) { uint16_t type; unsigned char scope, flags; int family, ifindex; - assert_se(sd_netlink_message_get_type(m, &type) >= 0); - assert_se(type == RTM_NEWADDR); + ASSERT_OK(sd_netlink_message_get_type(m, &type)); + ASSERT_EQ(type, RTM_NEWADDR); - assert_se(sd_rtnl_message_addr_get_ifindex(m, &ifindex) >= 0); - assert_se(sd_rtnl_message_addr_get_family(m, &family) >= 0); - assert_se(sd_rtnl_message_addr_get_scope(m, &scope) >= 0); - assert_se(sd_rtnl_message_addr_get_flags(m, &flags) >= 0); + ASSERT_OK(sd_rtnl_message_addr_get_ifindex(m, &ifindex)); + ASSERT_OK(sd_rtnl_message_addr_get_family(m, &family)); + ASSERT_OK(sd_rtnl_message_addr_get_scope(m, &scope)); + ASSERT_OK(sd_rtnl_message_addr_get_flags(m, &flags)); - assert_se(ifindex > 0); - assert_se(IN_SET(family, AF_INET, AF_INET6)); + ASSERT_GT(ifindex, 0); + ASSERT_TRUE(IN_SET(family, AF_INET, AF_INET6)); log_info("got IPv%i address on ifindex %i", family == AF_INET ? 4 : 6, ifindex); } @@ -449,51 +443,51 @@ TEST(sd_netlink_message_get_errno) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0); - assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); + ASSERT_OK(message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m)); + ASSERT_ERROR(sd_netlink_message_get_errno(m), ETIMEDOUT); } TEST(message_array) { _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - assert_se(sd_genl_socket_open(&genl) >= 0); - assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); + ASSERT_OK(sd_genl_socket_open(&genl)); + ASSERT_OK(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m)); - assert_se(sd_netlink_message_open_container(m, CTRL_ATTR_MCAST_GROUPS) >= 0); + ASSERT_OK(sd_netlink_message_open_container(m, CTRL_ATTR_MCAST_GROUPS)); for (unsigned i = 0; i < 10; i++) { char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)]; uint32_t id = i + 1000; xsprintf(name, "hoge%" PRIu32, id); - assert_se(sd_netlink_message_open_array(m, i + 1) >= 0); - assert_se(sd_netlink_message_append_u32(m, CTRL_ATTR_MCAST_GRP_ID, id) >= 0); - assert_se(sd_netlink_message_append_string(m, CTRL_ATTR_MCAST_GRP_NAME, name) >= 0); - assert_se(sd_netlink_message_close_container(m) >= 0); + ASSERT_OK(sd_netlink_message_open_array(m, i + 1)); + ASSERT_OK(sd_netlink_message_append_u32(m, CTRL_ATTR_MCAST_GRP_ID, id)); + ASSERT_OK(sd_netlink_message_append_string(m, CTRL_ATTR_MCAST_GRP_NAME, name)); + ASSERT_OK(sd_netlink_message_close_container(m)); } - assert_se(sd_netlink_message_close_container(m) >= 0); + ASSERT_OK(sd_netlink_message_close_container(m)); message_seal(m); - assert_se(sd_netlink_message_rewind(m, genl) >= 0); + ASSERT_OK(sd_netlink_message_rewind(m, genl)); - assert_se(sd_netlink_message_enter_container(m, CTRL_ATTR_MCAST_GROUPS) >= 0); + ASSERT_OK(sd_netlink_message_enter_container(m, CTRL_ATTR_MCAST_GROUPS)); for (unsigned i = 0; i < 10; i++) { char expected[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)]; const char *name; uint32_t id; - assert_se(sd_netlink_message_enter_array(m, i + 1) >= 0); - assert_se(sd_netlink_message_read_u32(m, CTRL_ATTR_MCAST_GRP_ID, &id) >= 0); - assert_se(sd_netlink_message_read_string(m, CTRL_ATTR_MCAST_GRP_NAME, &name) >= 0); - assert_se(sd_netlink_message_exit_container(m) >= 0); + ASSERT_OK(sd_netlink_message_enter_array(m, i + 1)); + ASSERT_OK(sd_netlink_message_read_u32(m, CTRL_ATTR_MCAST_GRP_ID, &id)); + ASSERT_OK(sd_netlink_message_read_string(m, CTRL_ATTR_MCAST_GRP_NAME, &name)); + ASSERT_OK(sd_netlink_message_exit_container(m)); - assert_se(id == i + 1000); + ASSERT_EQ(id, i + 1000); xsprintf(expected, "hoge%" PRIu32, id); - assert_se(streq(name, expected)); + ASSERT_STREQ(name, expected); } - assert_se(sd_netlink_message_exit_container(m) >= 0); + ASSERT_OK(sd_netlink_message_exit_container(m)); } TEST(message_strv) { @@ -502,31 +496,31 @@ TEST(message_strv) { _cleanup_strv_free_ char **names_in = NULL, **names_out; const char *p; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1)); for (unsigned i = 0; i < 10; i++) { char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)]; xsprintf(name, "hoge%" PRIu32, i + 1000); - assert_se(strv_extend(&names_in, name) >= 0); + ASSERT_OK(strv_extend(&names_in, name)); } - assert_se(sd_netlink_message_open_container(m, IFLA_PROP_LIST) >= 0); - assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, (const char**) names_in) >= 0); - assert_se(sd_netlink_message_close_container(m) >= 0); + ASSERT_OK(sd_netlink_message_open_container(m, IFLA_PROP_LIST)); + ASSERT_OK(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, (const char**) names_in)); + ASSERT_OK(sd_netlink_message_close_container(m)); message_seal(m); - assert_se(sd_netlink_message_rewind(m, rtnl) >= 0); + ASSERT_OK(sd_netlink_message_rewind(m, rtnl)); - assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0); - assert_se(strv_equal(names_in, names_out)); + ASSERT_OK(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out)); + ASSERT_TRUE(strv_equal(names_in, names_out)); - assert_se(sd_netlink_message_enter_container(m, IFLA_PROP_LIST) >= 0); - assert_se(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p) >= 0); - assert_se(streq(p, "hoge1009")); - assert_se(sd_netlink_message_exit_container(m) >= 0); + ASSERT_OK(sd_netlink_message_enter_container(m, IFLA_PROP_LIST)); + ASSERT_OK(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p)); + ASSERT_STREQ(p, "hoge1009"); + ASSERT_OK(sd_netlink_message_exit_container(m)); } static int genl_ctrl_match_callback(sd_netlink *genl, sd_netlink_message *m, void *userdata) { @@ -534,26 +528,26 @@ static int genl_ctrl_match_callback(sd_netlink *genl, sd_netlink_message *m, voi uint16_t id; uint8_t cmd; - assert_se(genl); - assert_se(m); + ASSERT_NOT_NULL(genl); + ASSERT_NOT_NULL(m); - assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); - assert_se(streq(name, CTRL_GENL_NAME)); + ASSERT_OK(sd_genl_message_get_family_name(genl, m, &name)); + ASSERT_STREQ(name, CTRL_GENL_NAME); - assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); + ASSERT_OK(sd_genl_message_get_command(genl, m, &cmd)); switch (cmd) { case CTRL_CMD_NEWFAMILY: case CTRL_CMD_DELFAMILY: - assert_se(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name) >= 0); - assert_se(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id) >= 0); + ASSERT_OK(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name)); + ASSERT_OK(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id)); log_debug("%s: %s (id=%"PRIu16") family is %s.", __func__, name, id, cmd == CTRL_CMD_NEWFAMILY ? "added" : "removed"); break; case CTRL_CMD_NEWMCAST_GRP: case CTRL_CMD_DELMCAST_GRP: - assert_se(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name) >= 0); - assert_se(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id) >= 0); + ASSERT_OK(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name)); + ASSERT_OK(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id)); log_debug("%s: multicast group for %s (id=%"PRIu16") family is %s.", __func__, name, id, cmd == CTRL_CMD_NEWMCAST_GRP ? "added" : "removed"); break; @@ -572,36 +566,35 @@ TEST(genl) { uint8_t cmd; int r; - assert_se(sd_genl_socket_open(&genl) >= 0); - assert_se(sd_event_default(&event) >= 0); - assert_se(sd_netlink_attach_event(genl, event, 0) >= 0); + ASSERT_OK(sd_genl_socket_open(&genl)); + ASSERT_OK(sd_event_default(&event)); + ASSERT_OK(sd_netlink_attach_event(genl, event, 0)); - assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); - assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); - assert_se(streq(name, CTRL_GENL_NAME)); - assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); - assert_se(cmd == CTRL_CMD_GETFAMILY); + ASSERT_OK(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m)); + ASSERT_OK(sd_genl_message_get_family_name(genl, m, &name)); + ASSERT_STREQ(name, CTRL_GENL_NAME); + ASSERT_OK(sd_genl_message_get_command(genl, m, &cmd)); + ASSERT_EQ(cmd, CTRL_CMD_GETFAMILY); - assert_se(sd_genl_add_match(genl, NULL, CTRL_GENL_NAME, "notify", 0, genl_ctrl_match_callback, NULL, NULL, "genl-ctrl-notify") >= 0); + ASSERT_OK(sd_genl_add_match(genl, NULL, CTRL_GENL_NAME, "notify", 0, genl_ctrl_match_callback, NULL, NULL, "genl-ctrl-notify")); - m = sd_netlink_message_unref(m); - assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0); - assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) == -EOPNOTSUPP); + ASSERT_NULL((m = sd_netlink_message_unref(m))); + ASSERT_FAIL(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m)); + ASSERT_ERROR(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m), EOPNOTSUPP); /* These families may not be supported by kernel. Hence, ignore results. */ (void) sd_genl_message_new(genl, FOU_GENL_NAME, 0, &m); - m = sd_netlink_message_unref(m); + ASSERT_NULL((m = sd_netlink_message_unref(m))); (void) sd_genl_message_new(genl, L2TP_GENL_NAME, 0, &m); - m = sd_netlink_message_unref(m); + ASSERT_NULL((m = sd_netlink_message_unref(m))); (void) sd_genl_message_new(genl, MACSEC_GENL_NAME, 0, &m); - m = sd_netlink_message_unref(m); + ASSERT_NULL((m = sd_netlink_message_unref(m))); (void) sd_genl_message_new(genl, NL80211_GENL_NAME, 0, &m); - m = sd_netlink_message_unref(m); + ASSERT_NULL((m = sd_netlink_message_unref(m))); (void) sd_genl_message_new(genl, NETLBL_NLTYPE_UNLABELED_NAME, 0, &m); for (;;) { - r = sd_event_run(event, 500 * USEC_PER_MSEC); - assert_se(r >= 0); + ASSERT_OK((r = sd_event_run(event, 500 * USEC_PER_MSEC))); if (r == 0) return; } @@ -614,10 +607,10 @@ static void remove_dummy_interfacep(int *ifindex) { if (!ifindex || *ifindex <= 0) return; - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_DELLINK, *ifindex) >= 0); - assert_se(sd_netlink_call(rtnl, message, 0, NULL) == 1); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &message, RTM_DELLINK, *ifindex)); + ASSERT_OK_EQ(sd_netlink_call(rtnl, message, 0, NULL), 1); } TEST(rtnl_set_link_name) { @@ -630,28 +623,28 @@ TEST(rtnl_set_link_name) { if (geteuid() != 0) return (void) log_tests_skipped("not root"); - assert_se(sd_netlink_open(&rtnl) >= 0); + ASSERT_OK(sd_netlink_open(&rtnl)); - assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 0) >= 0); - assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink") >= 0); - assert_se(sd_netlink_message_open_container(message, IFLA_LINKINFO) >= 0); - assert_se(sd_netlink_message_append_string(message, IFLA_INFO_KIND, "dummy") >= 0); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 0)); + ASSERT_OK(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink")); + ASSERT_OK(sd_netlink_message_open_container(message, IFLA_LINKINFO)); + ASSERT_OK(sd_netlink_message_append_string(message, IFLA_INFO_KIND, "dummy")); r = sd_netlink_call(rtnl, message, 0, &reply); if (r == -EPERM) return (void) log_tests_skipped("missing required capabilities"); if (r == -EOPNOTSUPP) return (void) log_tests_skipped("dummy network interface is not supported"); - assert_se(r >= 0); + ASSERT_OK(r); - message = sd_netlink_message_unref(message); - reply = sd_netlink_message_unref(reply); + ASSERT_NULL((message = sd_netlink_message_unref(message))); + ASSERT_NULL((reply = sd_netlink_message_unref(reply))); - assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, 0) >= 0); - assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink") >= 0); - assert_se(sd_netlink_call(rtnl, message, 0, &reply) == 1); + ASSERT_OK(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, 0)); + ASSERT_OK(sd_netlink_message_append_string(message, IFLA_IFNAME, "test-netlink")); + ASSERT_OK_EQ(sd_netlink_call(rtnl, message, 0, &reply), 1); - assert_se(sd_rtnl_message_link_get_ifindex(reply, &ifindex) >= 0); - assert_se(ifindex > 0); + ASSERT_OK(sd_rtnl_message_link_get_ifindex(reply, &ifindex)); + ASSERT_GT(ifindex, 0); /* Test that the new name (which is currently an alternative name) is * restored as an alternative name on error. Create an error by using @@ -662,45 +655,45 @@ TEST(rtnl_set_link_name) { return (void) log_tests_skipped("missing required capabilities"); if (r == -EOPNOTSUPP) return (void) log_tests_skipped("alternative name is not supported"); - assert_se(r >= 0); + ASSERT_OK(r); - assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0); - assert_se(strv_contains(alternative_names, "testlongalternativename")); - assert_se(strv_contains(alternative_names, "test-shortname")); + ASSERT_OK(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names)); + ASSERT_TRUE(strv_contains(alternative_names, "testlongalternativename")); + ASSERT_TRUE(strv_contains(alternative_names, "test-shortname")); - assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename", NULL) == -EINVAL); - assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname", STRV_MAKE("testlongalternativename", "test-shortname", "test-additional-name")) >= 0); + ASSERT_ERROR(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename", NULL), EINVAL); + ASSERT_OK(rtnl_set_link_name(&rtnl, ifindex, "test-shortname", STRV_MAKE("testlongalternativename", "test-shortname", "test-additional-name"))); - alternative_names = strv_free(alternative_names); - assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0); - assert_se(strv_contains(alternative_names, "testlongalternativename")); - assert_se(strv_contains(alternative_names, "test-additional-name")); - assert_se(!strv_contains(alternative_names, "test-shortname")); + ASSERT_NULL((alternative_names = strv_free(alternative_names))); + ASSERT_OK(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names)); + ASSERT_TRUE(strv_contains(alternative_names, "testlongalternativename")); + ASSERT_TRUE(strv_contains(alternative_names, "test-additional-name")); + ASSERT_FALSE(strv_contains(alternative_names, "test-shortname")); - assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0); + ASSERT_OK(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"))); - alternative_names = strv_free(alternative_names); - assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0); - assert_se(!strv_contains(alternative_names, "testlongalternativename")); - assert_se(strv_contains(alternative_names, "test-additional-name")); - assert_se(!strv_contains(alternative_names, "test-shortname")); + ASSERT_NULL((alternative_names = strv_free(alternative_names))); + ASSERT_OK(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names)); + ASSERT_FALSE(strv_contains(alternative_names, "testlongalternativename")); + ASSERT_TRUE(strv_contains(alternative_names, "test-additional-name")); + ASSERT_FALSE(strv_contains(alternative_names, "test-shortname")); _cleanup_free_ char *resolved = NULL; - assert_se(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved) == ifindex); - assert_se(streq_ptr(resolved, "test-shortname")); - resolved = mfree(resolved); + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved), ifindex); + ASSERT_STREQ(resolved, "test-shortname"); + ASSERT_NULL((resolved = mfree(resolved))); - assert_se(rtnl_rename_link(&rtnl, "test-shortname", "test-shortname") >= 0); - assert_se(rtnl_rename_link(&rtnl, "test-shortname", "test-shortname2") >= 0); - assert_se(rtnl_rename_link(NULL, "test-shortname2", "test-shortname3") >= 0); + ASSERT_OK(rtnl_rename_link(&rtnl, "test-shortname", "test-shortname")); + ASSERT_OK(rtnl_rename_link(&rtnl, "test-shortname", "test-shortname2")); + ASSERT_OK(rtnl_rename_link(NULL, "test-shortname2", "test-shortname3")); - assert_se(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved) == ifindex); - assert_se(streq_ptr(resolved, "test-shortname3")); - resolved = mfree(resolved); + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved), ifindex); + ASSERT_STREQ(resolved, "test-shortname3"); + ASSERT_NULL((resolved = mfree(resolved))); - assert_se(rtnl_resolve_link_alternative_name(&rtnl, "test-shortname3", &resolved) == ifindex); - assert_se(streq_ptr(resolved, "test-shortname3")); - resolved = mfree(resolved); + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-shortname3", &resolved), ifindex); + ASSERT_STREQ(resolved, "test-shortname3"); + ASSERT_NULL((resolved = mfree(resolved))); } DEFINE_TEST_MAIN(LOG_DEBUG); From 0e44a7c085866eb3f2a9a9df9f2b2c6237525413 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 06:30:15 +0900 Subject: [PATCH 13/15] netlink-util: merge rtnl_get_link_info() and rtnl_get_ifname_full() into rtnl_get_link_info_full() Then, this makes rtnl_get_ifname_full() and friends as inline wrappers of rtnl_get_link_info_full(). --- src/libsystemd-network/test-ndisc-send.c | 7 +-- src/libsystemd/sd-device/sd-device.c | 2 +- src/libsystemd/sd-netlink/netlink-util.c | 54 +++++++----------- src/libsystemd/sd-netlink/netlink-util.h | 72 +++++++++++++++++++----- src/libsystemd/sd-netlink/test-netlink.c | 5 +- 5 files changed, 84 insertions(+), 56 deletions(-) diff --git a/src/libsystemd-network/test-ndisc-send.c b/src/libsystemd-network/test-ndisc-send.c index 1b1b27d6347..85897e3797f 100644 --- a/src/libsystemd-network/test-ndisc-send.c +++ b/src/libsystemd-network/test-ndisc-send.c @@ -297,12 +297,7 @@ static int parse_argv(int argc, char *argv[]) { if (arg_set_source_mac) { struct hw_addr_data hw_addr; - r = rtnl_get_link_info(&rtnl, arg_ifindex, - /* ret_iftype = */ NULL, - /* ret_flags = */ NULL, - /* ret_kind = */ NULL, - &hw_addr, - /* ret_permanent_hw_addr = */ NULL); + r = rtnl_get_link_hw_addr(&rtnl, arg_ifindex, &hw_addr); if (r < 0) return log_error_errno(r, "Failed to get the source link-layer address: %m"); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index b7b308b3908..75bf545aff2 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -366,7 +366,7 @@ _public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) { assert_return(ret, -EINVAL); assert_return(ifindex > 0, -EINVAL); - r = rtnl_get_ifname_full(NULL, ifindex, &ifname, NULL); + r = rtnl_get_ifname(NULL, ifindex, &ifname); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 5aa6da7b83e..56104a5b649 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -52,34 +52,6 @@ static int parse_newlink_message( return ifindex; } -int rtnl_get_ifname_full(sd_netlink **rtnl, int ifindex, char **ret_name, char ***ret_altnames) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; - _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; - int r; - - assert(ifindex > 0); - - /* This is similar to if_indextoname(), but also optionally provides alternative names. */ - - if (!rtnl) - rtnl = &our_rtnl; - if (!*rtnl) { - r = sd_netlink_open(rtnl); - if (r < 0) - return r; - } - - r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex); - if (r < 0) - return r; - - r = sd_netlink_call(*rtnl, message, 0, &reply); - if (r < 0) - return r; - - return parse_newlink_message(reply, ret_name, ret_altnames); -} - int rtnl_resolve_ifname_full( sd_netlink **rtnl, ResolveInterfaceNameFlag flags, @@ -490,9 +462,11 @@ int rtnl_set_link_alternative_names_by_ifname( return 0; } -int rtnl_get_link_info( +int rtnl_get_link_info_full( sd_netlink **rtnl, int ifindex, + char **ret_name, + char ***ret_altnames, unsigned short *ret_iftype, unsigned *ret_flags, char **ret_kind, @@ -500,18 +474,18 @@ int rtnl_get_link_info( struct hw_addr_data *ret_permanent_hw_addr) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; struct hw_addr_data addr = HW_ADDR_NULL, perm_addr = HW_ADDR_NULL; - _cleanup_free_ char *kind = NULL; + _cleanup_free_ char *name = NULL, *kind = NULL; + _cleanup_strv_free_ char **altnames = NULL; unsigned short iftype; unsigned flags; int r; - assert(rtnl); assert(ifindex > 0); - if (!ret_iftype && !ret_flags && !ret_kind && !ret_hw_addr && !ret_permanent_hw_addr) - return 0; - + if (!rtnl) + rtnl = &our_rtnl; if (!*rtnl) { r = sd_netlink_open(rtnl); if (r < 0) @@ -528,6 +502,12 @@ int rtnl_get_link_info( if (r < 0) return r; + r = parse_newlink_message(reply, ret_name ? &name : NULL, ret_altnames ? &altnames : NULL); + if (r < 0) + return r; + if (r != ifindex) + return -EIO; + if (ret_iftype) { r = sd_rtnl_message_link_get_type(reply, &iftype); if (r < 0) @@ -565,6 +545,10 @@ int rtnl_get_link_info( return r; } + if (ret_name) + *ret_name = TAKE_PTR(name); + if (ret_altnames) + *ret_altnames = TAKE_PTR(altnames); if (ret_iftype) *ret_iftype = iftype; if (ret_flags) @@ -575,7 +559,7 @@ int rtnl_get_link_info( *ret_hw_addr = addr; if (ret_permanent_hw_addr) *ret_permanent_hw_addr = perm_addr; - return 0; + return ifindex; } int rtnl_log_parse_error(int r) { diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 4ba64f0f933..a31c0208ae2 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -19,7 +19,65 @@ typedef struct RouteVia { union in_addr_union address; } _packed_ RouteVia; -int rtnl_get_ifname_full(sd_netlink **rtnl, int ifindex, char **ret_name, char ***ret_altnames); +int rtnl_get_link_info_full( + sd_netlink **rtnl, + int ifindex, + char **ret_name, + char ***ret_altnames, + unsigned short *ret_iftype, + unsigned *ret_flags, + char **ret_kind, + struct hw_addr_data *ret_hw_addr, + struct hw_addr_data *ret_permanent_hw_addr); + +static inline int rtnl_get_ifname_full(sd_netlink **rtnl, int ifindex, char **ret_name, char ***ret_altnames) { + return rtnl_get_link_info_full( + rtnl, + ifindex, + ret_name, + ret_altnames, + /* ret_iftype = */ NULL, + /* ret_flags = */ NULL, + /* ret_kind = */ NULL, + /* ret_hw_addr = */ NULL, + /* ret_permanent_hw_addr = */ NULL); +} +static inline int rtnl_get_ifname(sd_netlink **rtnl, int ifindex, char **ret) { + return rtnl_get_ifname_full(rtnl, ifindex, ret, NULL); +} +static inline int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) { + return rtnl_get_ifname_full(rtnl, ifindex, NULL, ret); +} +static inline int rtnl_get_link_info( + sd_netlink **rtnl, + int ifindex, + unsigned short *ret_iftype, + unsigned *ret_flags, + char **ret_kind, + struct hw_addr_data *ret_hw_addr, + struct hw_addr_data *ret_permanent_hw_addr) { + + return rtnl_get_link_info_full( + rtnl, + ifindex, + /* ret_name = */ NULL, + /* ret_altnames = */ NULL, + ret_iftype, + ret_flags, + ret_kind, + ret_hw_addr, + ret_permanent_hw_addr); +} +static inline int rtnl_get_link_hw_addr(sd_netlink **rtnl, int ifindex, struct hw_addr_data *ret) { + return rtnl_get_link_info( + rtnl, + ifindex, + /* ret_iftype = */ NULL, + /* ret_flags = */ NULL, + /* ret_kind = */ NULL, + ret, + /* ret_permanent_hw_addr = */ NULL); +} typedef enum ResolveInterfaceNameFlag { RESOLVE_IFNAME_MAIN = 1 << 0, /* resolve main interface name */ @@ -51,9 +109,6 @@ int rtnl_set_link_properties( uint32_t mtu, uint32_t gso_max_size, size_t gso_max_segments); -static inline int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) { - return rtnl_get_ifname_full(rtnl, ifindex, NULL, ret); -} int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char* const *alternative_names); int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); @@ -77,15 +132,6 @@ static inline int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char * return r; } -int rtnl_get_link_info( - sd_netlink **rtnl, - int ifindex, - unsigned short *ret_iftype, - unsigned *ret_flags, - char **ret_kind, - struct hw_addr_data *ret_hw_addr, - struct hw_addr_data *ret_permanent_hw_addr); - int rtnl_log_parse_error(int r); int rtnl_log_create_error(int r); diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 2aeb5eefee3..7c1bd0d9df4 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -673,12 +673,13 @@ TEST(rtnl_set_link_name) { ASSERT_OK(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename"))); ASSERT_NULL((alternative_names = strv_free(alternative_names))); - ASSERT_OK(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names)); + ASSERT_OK_EQ(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names), ifindex); ASSERT_FALSE(strv_contains(alternative_names, "testlongalternativename")); ASSERT_TRUE(strv_contains(alternative_names, "test-additional-name")); ASSERT_FALSE(strv_contains(alternative_names, "test-shortname")); _cleanup_free_ char *resolved = NULL; + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", NULL), ifindex); ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved), ifindex); ASSERT_STREQ(resolved, "test-shortname"); ASSERT_NULL((resolved = mfree(resolved))); @@ -687,10 +688,12 @@ TEST(rtnl_set_link_name) { ASSERT_OK(rtnl_rename_link(&rtnl, "test-shortname", "test-shortname2")); ASSERT_OK(rtnl_rename_link(NULL, "test-shortname2", "test-shortname3")); + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", NULL), ifindex); ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-additional-name", &resolved), ifindex); ASSERT_STREQ(resolved, "test-shortname3"); ASSERT_NULL((resolved = mfree(resolved))); + ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-shortname3", NULL), ifindex); ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl, "test-shortname3", &resolved), ifindex); ASSERT_STREQ(resolved, "test-shortname3"); ASSERT_NULL((resolved = mfree(resolved))); From 472ad6af943852e6ca904fbebdc6b53bf04ddd57 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 9 Mar 2025 09:24:52 +0900 Subject: [PATCH 14/15] netlink-util: allow to call rtnl_set_link_name() and friends with NULL rtnl --- src/libsystemd/sd-netlink/netlink-util.c | 39 +++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 56104a5b649..19097e2f926 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -131,7 +131,7 @@ int rtnl_resolve_ifname_full( return -ENODEV; } -static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { +static int set_link_name(sd_netlink *rtnl, int ifindex, const char *name) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; @@ -141,13 +141,7 @@ static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { /* Assign the requested name. */ - if (!*rtnl) { - r = sd_netlink_open(rtnl); - if (r < 0) - return r; - } - - r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex); + r = sd_rtnl_message_new_link(rtnl, &message, RTM_SETLINK, ifindex); if (r < 0) return r; @@ -155,7 +149,7 @@ static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { if (r < 0) return r; - return sd_netlink_call(*rtnl, message, 0, NULL); + return sd_netlink_call(rtnl, message, 0, NULL); } int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name) { @@ -186,7 +180,7 @@ int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_n if (ifindex < 0) return ifindex; - return set_link_name(rtnl, ifindex, new_name); + return set_link_name(*rtnl, ifindex, new_name); } int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const *alternative_names) { @@ -194,7 +188,6 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* c bool altname_deleted = false; int r; - assert(rtnl); assert(ifindex > 0); if (isempty(name) && strv_isempty(alternative_names)) @@ -203,6 +196,10 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* c if (name && !ifname_valid(name)) return -EINVAL; + _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; + if (!rtnl) + rtnl = &our_rtnl; + /* If the requested name is already assigned as an alternative name, then first drop it. */ r = rtnl_get_link_alternative_names(rtnl, ifindex, &original_altnames); if (r < 0) @@ -219,7 +216,7 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* c altname_deleted = true; } - r = set_link_name(rtnl, ifindex, name); + r = set_link_name(*rtnl, ifindex, name); if (r < 0) goto fail; } @@ -281,10 +278,9 @@ int rtnl_set_link_properties( uint32_t mtu, uint32_t gso_max_size, size_t gso_max_segments) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; + int r; - assert(rtnl); assert(ifindex > 0); if (!alias && @@ -297,12 +293,16 @@ int rtnl_set_link_properties( gso_max_segments == 0) return 0; + _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; + if (!rtnl) + rtnl = &our_rtnl; if (!*rtnl) { r = sd_netlink_open(rtnl); if (r < 0) return r; } + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex); if (r < 0) return r; @@ -368,22 +368,24 @@ static int rtnl_update_link_alternative_names( int ifindex, char* const *alternative_names) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; - assert(rtnl); assert(ifindex > 0); assert(IN_SET(nlmsg_type, RTM_NEWLINKPROP, RTM_DELLINKPROP)); if (strv_isempty(alternative_names)) return 0; + _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; + if (!rtnl) + rtnl = &our_rtnl; if (!*rtnl) { r = sd_netlink_open(rtnl); if (r < 0) return r; } + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; r = sd_rtnl_message_new_link(*rtnl, &message, nlmsg_type, ifindex); if (r < 0) return r; @@ -420,7 +422,6 @@ int rtnl_set_link_alternative_names_by_ifname( const char *ifname, char* const *alternative_names) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; int r; assert(rtnl); @@ -429,12 +430,16 @@ int rtnl_set_link_alternative_names_by_ifname( if (strv_isempty(alternative_names)) return 0; + _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL; + if (!rtnl) + rtnl = &our_rtnl; if (!*rtnl) { r = sd_netlink_open(rtnl); if (r < 0) return r; } + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, 0); if (r < 0) return r; From 2ee01dbc0585d444571b439711cbcb1e2fcd82c7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Mar 2025 06:35:45 +0900 Subject: [PATCH 15/15] netlink-util: move several function prototypes --- src/libsystemd/sd-netlink/netlink-util.h | 41 ++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index a31c0208ae2..752c84c824d 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -92,26 +92,6 @@ int rtnl_resolve_ifname_full( const char *name, char **ret_name, char ***ret_altnames); - -int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name); -int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names); -static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) { - return rtnl_set_link_name(rtnl, ifindex, NULL, alternative_names); -} -int rtnl_set_link_properties( - sd_netlink **rtnl, - int ifindex, - const char *alias, - const struct hw_addr_data *hw_addr, - uint32_t txqueues, - uint32_t rxqueues, - uint32_t txqueuelen, - uint32_t mtu, - uint32_t gso_max_size, - size_t gso_max_segments); -int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); -int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char* const *alternative_names); -int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); static inline int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char **ret) { return rtnl_resolve_ifname_full(rtnl, RESOLVE_IFNAME_ALTERNATIVE, name, ret, NULL); } @@ -132,6 +112,27 @@ static inline int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char * return r; } +int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); +int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char* const *alternative_names); +int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names); +int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name); +int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names); +static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) { + return rtnl_set_link_name(rtnl, ifindex, NULL, alternative_names); +} + +int rtnl_set_link_properties( + sd_netlink **rtnl, + int ifindex, + const char *alias, + const struct hw_addr_data *hw_addr, + uint32_t txqueues, + uint32_t rxqueues, + uint32_t txqueuelen, + uint32_t mtu, + uint32_t gso_max_size, + size_t gso_max_segments); + int rtnl_log_parse_error(int r); int rtnl_log_create_error(int r);