From: Benjamin Marzinski <bmarzins@redhat.com>
To: Martin Wilck <martin.wilck@suse.com>
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>,
dm-devel@lists.linux.dev, Martin Wilck <mwilck@suse.com>
Subject: Re: [PATCH 18/21] libmpathutil: add wrapper code for libudev
Date: Thu, 18 Dec 2025 19:38:12 -0500 [thread overview]
Message-ID: <aUSedLFHsg6xRGRR@redhat.com> (raw)
In-Reply-To: <20251217212113.234959-19-mwilck@suse.com>
On Wed, Dec 17, 2025 at 10:21:10PM +0100, Martin Wilck wrote:
> The libudev documentation [1] states that libudev is not thread-safe and
> shouldn't be used from multithreaded programs. While the man page also
> states that using libudev in multithreaded programs is unsafe even if
> locking is used, there's not much else we can do in multipath-tools to
> mitigate the problem, as we are using libudev in multiple threads all over
> the place.
Ugh. I'm a little confused on what exactly could go wrong. Do you know
what they are concerned with, that locking cannot fix? It sounds like
the functions themselves are safe to call from multiple threads, as long
as they are working on separate data. If they were manipulating global
state that wouldn't be true.
> Add wrapper code that wraps all calls to libudev in a critical section
> holding a specific mutex.
>
> [1] https://man7.org/linux/man-pages/man3/libudev.3.html
I assume that there must be times when use call a udev outside of the
vecs lock. Did you check how often that is? Not that would be great to
pile even more work on the vecs lock.
Also, git flagged some whitespace errors.
>
> Signed-off-by: Martin Wilck <mwilck@suse.com>
> ---
> libmpathutil/libmpathutil.version | 62 +++
> libmpathutil/mt-libudev.c | 776 ++++++++++++++++++++++++++++++
> libmpathutil/mt-libudev.h | 120 +++++
> libmpathutil/mt-udev-wrap.h | 90 ++++
> 4 files changed, 1048 insertions(+)
> create mode 100644 libmpathutil/mt-libudev.c
> create mode 100644 libmpathutil/mt-libudev.h
> create mode 100644 libmpathutil/mt-udev-wrap.h
>
> diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version
> index 14aa083..4ce1da6 100644
> --- a/libmpathutil/libmpathutil.version
> +++ b/libmpathutil/libmpathutil.version
> @@ -93,6 +93,68 @@ global:
> log_thread_stop;
> logsink;
> msort;
> +
> + mt_udev_ref;
> + mt_udev_unref;
> + mt_udev_new;
> +
> + mt_udev_list_entry_get_next;
> + mt_udev_list_entry_get_by_name;
> + mt_udev_list_entry_get_name;
> + mt_udev_list_entry_get_value;
> +
> + mt_udev_device_ref;
> + mt_udev_device_unref;
> +
> + mt_udev_device_new_from_syspath;
> + mt_udev_device_new_from_devnum;
> + mt_udev_device_new_from_subsystem_sysname;
> + mt_udev_device_new_from_device_id;
> + mt_udev_device_new_from_environment;
> +
> + mt_udev_device_get_udev;
> + mt_udev_device_get_parent;
> + mt_udev_device_get_parent_with_subsystem_devtype;
> + mt_udev_device_get_devpath;
> + mt_udev_device_get_subsystem;
> + mt_udev_device_get_devtype;
> + mt_udev_device_get_syspath;
> + mt_udev_device_get_sysname;
> + mt_udev_device_get_devnum;
> + mt_udev_device_get_is_initialized;
> + mt_udev_device_get_property_value;
> + mt_udev_device_get_seqnum;
> + mt_udev_device_set_sysattr_value;
> + mt_udev_device_get_sysattr_value;
> + mt_udev_device_get_driver;
> + mt_udev_device_get_devnode;
> +
> + mt_udev_device_get_properties_list_entry;
> +
> + mt_udev_monitor_new_from_netlink;
> + mt_udev_monitor_enable_receiving;
> + mt_udev_monitor_get_fd;
> + mt_udev_monitor_receive_device;
> + mt_udev_monitor_filter_add_match_subsystem_devtype;
> + mt_udev_monitor_ref;
> + mt_udev_monitor_unref;
> + mt_udev_monitor_set_receive_buffer_size;
> +
> + mt_udev_enumerate_new;
> + mt_udev_enumerate_ref;
> + mt_udev_enumerate_unref;
> + mt_udev_enumerate_add_match_subsystem;
> + mt_udev_enumerate_scan_devices;
> + mt_udev_enumerate_get_list_entry;
> + mt_udev_enumerate_add_nomatch_subsystem;
> + mt_udev_enumerate_add_match_sysattr;
> + mt_udev_enumerate_add_nomatch_sysattr;
> + mt_udev_enumerate_add_match_property;
> + mt_udev_enumerate_add_match_tag;
> + mt_udev_enumerate_add_match_parent;
> + mt_udev_enumerate_add_match_is_initialized;
> + mt_udev_enumerate_add_syspath;
> +
> normalize_timespec;
> parse_devt;
> print_strbuf;
> diff --git a/libmpathutil/mt-libudev.c b/libmpathutil/mt-libudev.c
> new file mode 100644
> index 0000000..2e37c7d
> --- /dev/null
> +++ b/libmpathutil/mt-libudev.c
> @@ -0,0 +1,776 @@
> +#include "mt-libudev.h"
> +#include <stddef.h>
> +#include <libudev.h>
> +#include "util.h"
> +
> +static pthread_mutex_t libudev_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +struct udev *mt_udev_ref(struct udev *udev)
> +{
> + struct udev *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_ref(udev);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev *mt_udev_unref(struct udev *udev)
> +{
> + struct udev *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_unref(udev);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev *mt_udev_new(void)
> +{
> + struct udev *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_new();
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *mt_udev_list_entry_get_next(struct udev_list_entry *list_entry)
> +{
> + struct udev_list_entry *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_list_entry_get_next(list_entry);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *
> +mt_udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name)
> +{
> + struct udev_list_entry *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_list_entry_get_by_name(list_entry, name);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_list_entry_get_name(struct udev_list_entry *list_entry)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_list_entry_get_name(list_entry);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_list_entry_get_value(struct udev_list_entry *list_entry)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_list_entry_get_value(list_entry);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *
> +mt_udev_device_new_from_syspath(struct udev *udev, const char *syspath)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_new_from_syspath(udev, syspath);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *
> +mt_udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_new_from_devnum(udev, type, devnum);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *
> +mt_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem,
> + const char *sysname)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_new_from_subsystem_sysname(udev, subsystem, sysname);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_new_from_device_id(struct udev *udev, char *id)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_new_from_device_id(udev, id);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_new_from_environment(struct udev *udev)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_new_from_environment(udev);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_ref(struct udev_device *udev_device)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_ref(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_unref(struct udev_device *udev_device)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_unref(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev *mt_udev_device_get_udev(struct udev_device *udev_device)
> +{
> + struct udev *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_udev(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_get_parent(struct udev_device *udev_device)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_parent(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_device_get_parent_with_subsystem_devtype(
> + struct udev_device *udev_device, const char *subsystem, const char *devtype)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_parent_with_subsystem_devtype(udev_device,
> + subsystem, devtype);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_devpath(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_devpath(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_subsystem(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_subsystem(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_devtype(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_devtype(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_syspath(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_syspath(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_sysname(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_sysname(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +dev_t mt_udev_device_get_devnum(struct udev_device *udev_device)
> +{
> + dev_t ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_devnum(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +unsigned long long mt_udev_device_get_seqnum(struct udev_device *udev_device)
> +{
> + unsigned long long ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_seqnum(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_driver(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_driver(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_devnode(struct udev_device *udev_device)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_devnode(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_device_get_is_initialized(struct udev_device *udev_device)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_is_initialized(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *
> +mt_udev_device_get_property_value(struct udev_device *udev_device, const char *key)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_property_value(udev_device, key);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +const char *mt_udev_device_get_sysattr_value(struct udev_device *udev_device,
> + const char *sysattr)
> +{
> + const char *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_sysattr_value(udev_device, sysattr);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_device_set_sysattr_value(struct udev_device *udev_device,
> + const char *sysattr, char *value)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_set_sysattr_value(udev_device, sysattr, value);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *
> +mt_udev_device_get_properties_list_entry(struct udev_device *udev_device)
> +{
> + struct udev_list_entry *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_properties_list_entry(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +/*
> + * multipath-tools doesn't use these, and some of them aren't available
> + * in older libudev versions. Keeping the code here in case we will
> + * need it in the future.
> +
> +struct udev_list_entry *mt_udev_device_get_devlinks_list_entry(struct
> +udev_device *udev_device)
> +{
> + struct udev_list_entry *ret;
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_devlinks_list_entry(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *mt_udev_device_get_tags_list_entry(struct udev_device
> +*udev_device)
> +{
> + struct udev_list_entry *ret;
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_tags_list_entry(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *mt_udev_device_get_current_tags_list_entry(struct
> +udev_device *udev_device)
> +{
> + struct udev_list_entry *ret;
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_current_tags_list_entry(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *mt_udev_device_get_sysattr_list_entry(struct
> +udev_device *udev_device)
> +{
> + struct udev_list_entry *ret;
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_device_get_sysattr_list_entry(udev_device);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +*/
> +
> +struct udev_monitor *
> +mt_udev_monitor_new_from_netlink(struct udev *udev, const char *name)
> +{
> + struct udev_monitor *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_new_from_netlink(udev, name);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_monitor *mt_udev_monitor_ref(struct udev_monitor *udev_monitor)
> +{
> + struct udev_monitor *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_ref(udev_monitor);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_monitor *mt_udev_monitor_unref(struct udev_monitor *udev_monitor)
> +{
> + struct udev_monitor *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_unref(udev_monitor);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_enable_receiving(udev_monitor);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_monitor_get_fd(struct udev_monitor *udev_monitor)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_get_fd(udev_monitor);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_device *mt_udev_monitor_receive_device(struct udev_monitor *udev_monitor)
> +{
> + struct udev_device *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_receive_device(udev_monitor);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_monitor_filter_add_match_subsystem_devtype(
> + struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor,
> + subsystem, devtype);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_monitor_set_receive_buffer_size(udev_monitor, size);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_enumerate *mt_udev_enumerate_new(struct udev *udev)
> +{
> + struct udev_enumerate *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_new(udev);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_enumerate *mt_udev_enumerate_ref(struct udev_enumerate *udev_enumerate)
> +{
> + struct udev_enumerate *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_ref(udev_enumerate);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_enumerate *mt_udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
> +{
> + struct udev_enumerate *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_unref(udev_enumerate);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate,
> + const char *subsystem)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate,
> + const char *subsystem)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate,
> + const char *sysattr, const char *value)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate,
> + const char *sysattr, const char *value)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate,
> + const char *property, const char *value)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_property(udev_enumerate, property, value);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate,
> + const char *tag)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_tag(udev_enumerate, tag);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate,
> + struct udev_device *parent)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_parent(udev_enumerate, parent);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_match_is_initialized(udev_enumerate);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate,
> + const char *syspath)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_add_syspath(udev_enumerate, syspath);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +int mt_udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
> +{
> + int ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_scan_devices(udev_enumerate);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> +
> +struct udev_list_entry *
> +mt_udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
> +{
> + struct udev_list_entry *ret;
> +
> + pthread_mutex_lock(&libudev_mutex);
> + pthread_cleanup_push(cleanup_mutex, &libudev_mutex);
> +
> + ret = udev_enumerate_get_list_entry(udev_enumerate);
> +
> + pthread_cleanup_pop(1);
> + return ret;
> +}
> diff --git a/libmpathutil/mt-libudev.h b/libmpathutil/mt-libudev.h
> new file mode 100644
> index 0000000..1c1e748
> --- /dev/null
> +++ b/libmpathutil/mt-libudev.h
> @@ -0,0 +1,120 @@
> +#ifndef MT_LIBUDEV_H
> +#define MT_LIBUDEV_H
> +
> +#include <pthread.h>
> +#include <stdarg.h> /* for va_list */
> +#include <sys/types.h> /* For dev_t */
> +
> +struct udev;
> +struct udev_list_entry;
> +struct udev_device;
> +struct udev_monitor;
> +struct udev_enumerate;
> +
> +struct udev *mt_udev_ref(struct udev *udev);
> +struct udev *mt_udev_unref(struct udev *udev);
> +struct udev *mt_udev_new(void);
> +
> +struct udev_list_entry *
> +mt_udev_list_entry_get_next(struct udev_list_entry *list_entry);
> +struct udev_list_entry *
> +mt_udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name);
> +const char *mt_udev_list_entry_get_name(struct udev_list_entry *list_entry);
> +const char *mt_udev_list_entry_get_value(struct udev_list_entry *list_entry);
> +
> +struct udev_device *
> +mt_udev_device_new_from_syspath(struct udev *udev, const char *syspath);
> +struct udev_device *
> +mt_udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
> +struct udev_device *
> +mt_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem,
> + const char *sysname);
> +/*
> + * Some older libudev versions don't use "const" for the id argument,
> + * therefore we can't use it here, either.
> + */
> +struct udev_device *mt_udev_device_new_from_device_id(struct udev *udev, char *id);
> +struct udev_device *mt_udev_device_new_from_environment(struct udev *udev);
> +
> +struct udev_device *mt_udev_device_ref(struct udev_device *udev_device);
> +struct udev_device *mt_udev_device_unref(struct udev_device *udev_device);
> +struct udev *mt_udev_device_get_udev(struct udev_device *udev_device);
> +struct udev_device *mt_udev_device_get_parent(struct udev_device *udev_device);
> +struct udev_device *mt_udev_device_get_parent_with_subsystem_devtype(
> + struct udev_device *udev_device, const char *subsystem,
> + const char *devtype);
> +const char *mt_udev_device_get_devpath(struct udev_device *udev_device);
> +const char *mt_udev_device_get_subsystem(struct udev_device *udev_device);
> +const char *mt_udev_device_get_devtype(struct udev_device *udev_device);
> +const char *mt_udev_device_get_syspath(struct udev_device *udev_device);
> +const char *mt_udev_device_get_sysname(struct udev_device *udev_device);
> +int mt_udev_device_get_is_initialized(struct udev_device *udev_device);
> +const char *
> +mt_udev_device_get_property_value(struct udev_device *udev_device, const char *key);
> +dev_t mt_udev_device_get_devnum(struct udev_device *udev_device);
> +unsigned long long int mt_udev_device_get_seqnum(struct udev_device *udev_device);
> +const char *mt_udev_device_get_driver(struct udev_device *udev_device);
> +const char *mt_udev_device_get_devnode(struct udev_device *udev_device);
> +const char *mt_udev_device_get_sysattr_value(struct udev_device *udev_device,
> + const char *sysattr);
> +/*
> + * libudev-215 (Debian jessie) doesn't use "const" for the value argument,
> + * therefore we can't use it here, either.
> + */
> +int mt_udev_device_set_sysattr_value(struct udev_device *udev_device,
> + const char *sysattr, char *value);
> +
> +struct udev_list_entry *
> +mt_udev_device_get_properties_list_entry(struct udev_device *udev_device);
> +/*
> + * multipath-tools doesn't use these, and some of them aren't available
> + * in older libudev versions.
> +
> + struct udev_list_entry *mt_udev_device_get_devlinks_list_entry(struct
> + udev_device *udev_device); struct udev_list_entry
> + *mt_udev_device_get_tags_list_entry(struct udev_device *udev_device); struct
> + udev_list_entry *mt_udev_device_get_current_tags_list_entry(struct udev_device
> + *udev_device); struct udev_list_entry
> + *mt_udev_device_get_sysattr_list_entry(struct udev_device *udev_device);
> +*/
> +struct udev_monitor *
> +mt_udev_monitor_new_from_netlink(struct udev *udev, const char *name);
> +struct udev_monitor *mt_udev_monitor_ref(struct udev_monitor *udev_monitor);
> +struct udev_monitor *mt_udev_monitor_unref(struct udev_monitor *udev_monitor);
> +int mt_udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
> +int mt_udev_monitor_get_fd(struct udev_monitor *udev_monitor);
> +struct udev_device *
> +mt_udev_monitor_receive_device(struct udev_monitor *udev_monitor);
> +int mt_udev_monitor_filter_add_match_subsystem_devtype(
> + struct udev_monitor *udev_monitor, const char *subsystem,
> + const char *devtype);
> +int mt_udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor,
> + int size);
> +
> +struct udev_enumerate *mt_udev_enumerate_new(struct udev *udev);
> +struct udev_enumerate *mt_udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
> +struct udev_enumerate *
> +mt_udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
> +int mt_udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate,
> + const char *subsystem);
> +int mt_udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate,
> + const char *subsystem);
> +int mt_udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate,
> + const char *sysattr, const char *value);
> +int mt_udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate,
> + const char *sysattr, const char *value);
> +int mt_udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate,
> + const char *property, const char *value);
> +int mt_udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate,
> + const char *tag);
> +int mt_udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate,
> + struct udev_device *parent);
> +int mt_udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate);
> +int mt_udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate,
> + const char *syspath);
> +int mt_udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
> +int mt_udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate);
> +struct udev_list_entry *
> +mt_udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
> +
> +#endif
> diff --git a/libmpathutil/mt-udev-wrap.h b/libmpathutil/mt-udev-wrap.h
> new file mode 100644
> index 0000000..f232821
> --- /dev/null
> +++ b/libmpathutil/mt-udev-wrap.h
> @@ -0,0 +1,90 @@
> +#ifndef MT_LIBUDEV_WRAP_HPP
> +#define MT_LIBUDEV_WRAP_HPP
> +#include "mt-libudev.h"
> +
> +#define udev_ref(udev) mt_udev_ref(udev)
> +#define udev_unref(udev) mt_udev_unref(udev)
> +#define udev_new() mt_udev_new()
> +
> +#define udev_list_entry_get_next(list_entry) mt_udev_list_entry_get_next(list_entry)
> +#define udev_list_entry_get_by_name(list_entry, name) mt_udev_list_entry_get_by_name(list_entry, name)
> +#define udev_list_entry_get_name(list_entry) mt_udev_list_entry_get_name(list_entry)
> +#define udev_list_entry_get_value(list_entry) mt_udev_list_entry_get_value(list_entry)
> +
> +#define udev_list_entry_foreach(list_entry, first_entry) \
> + for (list_entry = first_entry; \
> + list_entry; \
> + list_entry = udev_list_entry_get_next(list_entry))
> +
> +#define udev_device_new_from_syspath(udev, syspath) mt_udev_device_new_from_syspath(udev, syspath)
> +#define udev_device_new_from_devnum(udev, type, devnum) mt_udev_device_new_from_devnum(udev, type, devnum)
> +#define udev_device_new_from_subsystem_sysname(udev, subsystem, sysname) \
> + mt_udev_device_new_from_subsystem_sysname(udev, subsystem, sysname)
> +#define udev_device_new_from_device_id(udev, id) mt_udev_device_new_from_device_id(udev, id)
> +#define udev_device_new_from_environment(udev) mt_udev_device_new_from_environment(udev)
> +
> +#define udev_device_ref(udev_device) mt_udev_device_ref(udev_device)
> +#define udev_device_unref(udev_device) mt_udev_device_unref(udev_device)
> +#define udev_device_get_udev(udev_device) mt_udev_device_get_udev(udev_device)
> +#define udev_device_get_parent(udev_device) mt_udev_device_get_parent(udev_device)
> +#define udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype) \
> + mt_udev_device_get_parent_with_subsystem_devtype(udev_device, subsystem, devtype)
> +#define udev_device_get_devpath(udev_device) mt_udev_device_get_devpath(udev_device)
> +#define udev_device_get_subsystem(udev_device) mt_udev_device_get_subsystem(udev_device)
> +#define udev_device_get_devtype(udev_device) mt_udev_device_get_devtype(udev_device)
> +#define udev_device_get_syspath(udev_device) mt_udev_device_get_syspath(udev_device)
> +#define udev_device_get_sysname(udev_device) mt_udev_device_get_sysname(udev_device)
> +#define udev_device_get_is_initialized(udev_device) mt_udev_device_get_is_initialized(udev_device)
> +#define udev_device_get_property_value(udev_device, key) mt_udev_device_get_property_value(udev_device, key)
> +#define udev_device_get_devnum(udev_device) mt_udev_device_get_devnum(udev_device)
> +#define udev_device_get_seqnum(udev_device) mt_udev_device_get_seqnum(udev_device)
> +#define udev_device_get_driver(udev_device) mt_udev_device_get_driver(udev_device)
> +#define udev_device_get_devnode(udev_device) mt_udev_device_get_devnode(udev_device)
> +#define udev_device_get_sysattr_value(udev_device, sysattr) \
> + mt_udev_device_get_sysattr_value(udev_device, sysattr)
> +#define udev_device_set_sysattr_value(udev_device, sysattr, value) \
> + mt_udev_device_set_sysattr_value(udev_device, sysattr, value)
> +
> +#define udev_device_get_devlinks_list_entry(udev_device) mt_udev_device_get_devlinks_list_entry(udev_device)
> +#define udev_device_get_properties_list_entry(udev_device) mt_udev_device_get_properties_list_entry(udev_device)
> +#define udev_device_get_tags_list_entry(udev_device) mt_udev_device_get_tags_list_entry(udev_device)
> +#define udev_device_get_current_tags_list_entry(udev_device) mt_udev_device_get_current_tags_list_entry(udev_device)
> +#define udev_device_get_sysattr_list_entry(udev_device) mt_udev_device_get_sysattr_list_entry(udev_device)
> +
> +#define udev_monitor_new_from_netlink(udev, name) mt_udev_monitor_new_from_netlink(udev, name)
> +#define udev_monitor_ref(udev_monitor) mt_udev_monitor_ref(udev_monitor)
> +#define udev_monitor_unref(udev_monitor) mt_udev_monitor_unref(udev_monitor)
> +#define udev_monitor_enable_receiving(udev_monitor) mt_udev_monitor_enable_receiving(udev_monitor)
> +#define udev_monitor_get_fd(udev_monitor) mt_udev_monitor_get_fd(udev_monitor)
> +#define udev_monitor_receive_device(udev_monitor) mt_udev_monitor_receive_device(udev_monitor)
> +#define udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsystem, devtype) \
> + mt_udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsystem, devtype)
> +#define udev_monitor_set_receive_buffer_size(udev_monitor, size) \
> + mt_udev_monitor_set_receive_buffer_size(udev_monitor, size)
> +
> +#define udev_enumerate_new(udev) mt_udev_enumerate_new(udev)
> +#define udev_enumerate_unref(udev_enumerate) mt_udev_enumerate_unref(udev_enumerate)
> +#define udev_enumerate_add_match_subsystem(udev_enumerate, subsystem) \
> + mt_udev_enumerate_add_match_subsystem(udev_enumerate, subsystem)
> +#define udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem) \
> + mt_udev_enumerate_add_nomatch_subsystem(udev_enumerate, subsystem)
> +#define udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value) \
> + mt_udev_enumerate_add_match_sysattr(udev_enumerate, sysattr, value)
> +#define udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value) \
> + mt_udev_enumerate_add_nomatch_sysattr(udev_enumerate, sysattr, value)
> +#define udev_enumerate_add_match_property(udev_enumerate, property, value) \
> + mt_udev_enumerate_add_match_property(udev_enumerate, property, value)
> +#define udev_enumerate_add_match_tag(udev_enumerate, tag) mt_udev_enumerate_add_match_tag(udev_enumerate, tag)
> +#define udev_enumerate_add_match_parent(udev_enumerate, parent) \
> + mt_udev_enumerate_add_match_parent(udev_enumerate, parent)
> +#define udev_enumerate_add_match_is_initialized(udev_enumerate) \
> + mt_udev_enumerate_add_match_is_initialized(udev_enumerate)
> +#define udev_enumerate_add_syspath(udev_enumerate, syspath) \
> + mt_udev_enumerate_add_syspath(udev_enumerate, syspath)
> +
> +#define udev_enumerate_scan_devices(udev_enumerate) mt_udev_enumerate_scan_devices(udev_enumerate)
> +#define udev_enumerate_scan_device(udev_enumerate, syspath) \
> + mt_udev_enumerate_scan_device(udev_enumerate, syspath)
> +#define udev_enumerate_get_list_entry(udev_enumerate) mt_udev_enumerate_get_list_entry(udev_enumerate)
> +
> +#endif
> --
> 2.52.0
next prev parent reply other threads:[~2025-12-19 0:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-17 21:20 [PATCH 00/21] Multipath-tools: various bug fixes Martin Wilck
2025-12-17 21:20 ` [PATCH 01/21] libmultipath: drop drop_multipath Martin Wilck
2025-12-17 21:20 ` [PATCH 02/21] libmultipath: don't access path members in free_pgvec() Martin Wilck
2025-12-17 21:20 ` [PATCH 03/21] multipathd: free paths in checker_finished() Martin Wilck
2025-12-18 23:34 ` Benjamin Marzinski
2025-12-18 23:40 ` Martin Wilck
2025-12-19 10:38 ` Martin Wilck
2025-12-17 21:20 ` [PATCH 04/21] libmultipath: don't touch mpvec in remove_map() Martin Wilck
2025-12-17 21:20 ` [PATCH 05/21] libmpathutil: constify find_slot() Martin Wilck
2025-12-17 21:20 ` [PATCH 06/21] libmultipath: don't free paths in orphan_paths() Martin Wilck
2025-12-17 21:20 ` [PATCH 07/21] libmultipath: free orphaned paths in check_removed_paths() Martin Wilck
2025-12-17 21:21 ` [PATCH 08/21] libmultipath: remove free_paths argument from free_pathgroup() Martin Wilck
2025-12-17 21:21 ` [PATCH 09/21] libmultipath: fix numeric value of free_paths in free_multipaths() Martin Wilck
2025-12-19 0:10 ` Benjamin Marzinski
2025-12-17 21:21 ` [PATCH 10/21] libmultipath: remove free_paths argument from free_pgvec() Martin Wilck
2025-12-17 21:21 ` [PATCH 11/21] libmultipath: remove free_paths argument from free_multipathvec() Martin Wilck
2025-12-17 21:21 ` [PATCH 12/21] libmultipath: free_multipath: fix FREE_PATHS case Martin Wilck
2025-12-19 0:15 ` Benjamin Marzinski
2025-12-17 21:21 ` [PATCH 13/21] multipath-tools: Fix ISO C23 errors with strchr() Martin Wilck
2025-12-17 21:21 ` [PATCH 14/21] libmultipath: simplify sysfs_get_target_nodename() Martin Wilck
2025-12-17 21:21 ` [PATCH 15/21] multipathd: join the init_unwinder dummy thread Martin Wilck
2025-12-17 21:21 ` [PATCH 16/21] kpartx: fix some memory leaks Martin Wilck
2025-12-17 21:21 ` [PATCH 17/21] libmpathutil: use union for bitfield Martin Wilck
2025-12-19 0:17 ` Benjamin Marzinski
2025-12-19 8:08 ` Martin Wilck
2025-12-17 21:21 ` [PATCH 18/21] libmpathutil: add wrapper code for libudev Martin Wilck
2025-12-19 0:38 ` Benjamin Marzinski [this message]
2025-12-19 8:06 ` Martin Wilck
2025-12-19 17:27 ` Benjamin Marzinski
2025-12-17 21:21 ` [PATCH 19/21] multipath-tools: use the libudev wrapper functions Martin Wilck
2025-12-17 21:21 ` [PATCH 20/21] Makefile: add functionality to determine cmocka version Martin Wilck
2025-12-17 21:21 ` [PATCH 21/21] multipath-tools tests: adaptations for cmocka 2.0 Martin Wilck
2025-12-19 0:40 ` [PATCH 00/21] Multipath-tools: various bug fixes Benjamin Marzinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aUSedLFHsg6xRGRR@redhat.com \
--to=bmarzins@redhat.com \
--cc=christophe.varoqui@opensvc.com \
--cc=dm-devel@lists.linux.dev \
--cc=martin.wilck@suse.com \
--cc=mwilck@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox