diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-09-15 22:36:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-15 22:36:38 +0200 |
commit | 32397af3d435aab0895889d9b89a6950b6246a80 (patch) | |
tree | 1682a56b48d04d6519e6f7acd19bc5688d672a56 /src | |
parent | 903511951892008b991991962fef2e8ecc65bc6c (diff) | |
parent | 8aae9a66fae7aa7f1f7563f0bf14f9ab3de916bd (diff) | |
download | systemd-32397af3d435aab0895889d9b89a6950b6246a80.tar.gz |
Merge pull request #9928 from yuwata/libudev-cleanups
libudev: coding style updates
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/mount-util.c | 36 | ||||
-rw-r--r-- | src/basic/mount-util.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 2 | ||||
-rw-r--r-- | src/libudev/libudev-device-internal.h | 4 | ||||
-rw-r--r-- | src/libudev/libudev-device-private.c | 44 | ||||
-rw-r--r-- | src/libudev/libudev-device.c | 211 | ||||
-rw-r--r-- | src/libudev/libudev-enumerate.c | 52 | ||||
-rw-r--r-- | src/libudev/libudev-hwdb.c | 46 | ||||
-rw-r--r-- | src/libudev/libudev-monitor.c | 778 | ||||
-rw-r--r-- | src/libudev/libudev-private.h | 20 | ||||
-rw-r--r-- | src/libudev/libudev-queue.c | 94 | ||||
-rw-r--r-- | src/libudev/libudev.c | 50 | ||||
-rw-r--r-- | src/libudev/libudev.h | 2 | ||||
-rw-r--r-- | src/systemd/sd-device.h | 2 |
14 files changed, 619 insertions, 724 deletions
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 1f9590ccb6..ae62d3090e 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -951,3 +951,39 @@ int mount_option_mangle( return 0; } + +int dev_is_devtmpfs(void) { + _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; + char line[LINE_MAX], *e; + int mount_id, r; + + r = path_get_mnt_id("/dev", &mount_id); + if (r < 0) + return r; + + proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); + if (!proc_self_mountinfo) + return -errno; + + (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER); + + FOREACH_LINE(line, proc_self_mountinfo, return -errno) { + int mid; + + if (sscanf(line, "%i", &mid) != 1) + continue; + + if (mid != mount_id) + continue; + + e = strstr(line, " - "); + if (!e) + continue; + + /* accept any name that starts with the currently expected type */ + if (startswith(e + 3, "devtmpfs")) + return true; + } + + return false; +} diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h index 3cfea3bb20..ad8c47cb32 100644 --- a/src/basic/mount-util.h +++ b/src/basic/mount-util.h @@ -54,3 +54,5 @@ int mount_option_mangle( unsigned long mount_flags, unsigned long *ret_mount_flags, char **ret_remaining_options); + +int dev_is_devtmpfs(void); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index c61e98fe72..b020e0d55a 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1822,7 +1822,7 @@ static void device_remove_sysattr_value(sd_device *device, const char *_key) { /* set the attribute and save it in the cache. If a NULL value is passed the * attribute is cleared from the cache */ -_public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, char *_value) { +_public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *_value) { _cleanup_close_ int fd = -1; _cleanup_free_ char *value = NULL; const char *syspath; diff --git a/src/libudev/libudev-device-internal.h b/src/libudev/libudev-device-internal.h index 45763f2c99..73db709e93 100644 --- a/src/libudev/libudev-device-internal.h +++ b/src/libudev/libudev-device-internal.h @@ -18,7 +18,7 @@ struct udev_device { sd_device *device; /* legacy */ - int refcount; + unsigned n_ref; struct udev_device *parent; bool parent_set; @@ -36,4 +36,4 @@ struct udev_device { bool sysattrs_read; }; -struct udev_device *udev_device_new(struct udev *udev); +struct udev_device *udev_device_new(struct udev *udev, sd_device *device); diff --git a/src/libudev/libudev-device-private.c b/src/libudev/libudev-device-private.c index 22b421299a..a7868a11cb 100644 --- a/src/libudev/libudev-device-private.c +++ b/src/libudev/libudev-device-private.c @@ -200,79 +200,59 @@ int udev_device_rename(struct udev_device *udev_device, const char *name) { } struct udev_device *udev_device_shallow_clone(struct udev_device *old_device) { - struct udev_device *device; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; assert(old_device); - device = udev_device_new(old_device->udev); - if (!device) - return NULL; - - r = device_shallow_clone(old_device->device, &device->device); + r = device_shallow_clone(old_device->device, &device); if (r < 0) { - udev_device_unref(device); errno = -r; return NULL; } - return device; + return udev_device_new(old_device->udev, device); } struct udev_device *udev_device_clone_with_db(struct udev_device *udev_device_old) { - struct udev_device *udev_device; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; assert(udev_device_old); - udev_device = udev_device_new(udev_device_old->udev); - if (!udev_device) - return NULL; - - r = device_clone_with_db(udev_device_old->device, &udev_device->device); + r = device_clone_with_db(udev_device_old->device, &device); if (r < 0) { - udev_device_unref(udev_device); errno = -r; return NULL; } - return udev_device; + return udev_device_new(udev_device_old->udev, device); } struct udev_device *udev_device_new_from_nulstr(struct udev *udev, char *nulstr, ssize_t buflen) { - struct udev_device *device; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - device = udev_device_new(udev); - if (!device) - return NULL; - - r = device_new_from_nulstr(&device->device, (uint8_t*)nulstr, buflen); + r = device_new_from_nulstr(&device, (uint8_t*)nulstr, buflen); if (r < 0) { - udev_device_unref(device); errno = -r; return NULL; } - return device; + return udev_device_new(udev, device); } struct udev_device *udev_device_new_from_synthetic_event(struct udev *udev, const char *syspath, const char *action) { - struct udev_device *device; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - device = udev_device_new(udev); - if (!device) - return NULL; - - r = device_new_from_synthetic_event(&device->device, syspath, action); + r = device_new_from_synthetic_event(&device, syspath, action); if (r < 0) { - udev_device_unref(device); errno = -r; return NULL; } - return device; + return udev_device_new(udev, device); } int udev_device_copy_properties(struct udev_device *udev_device_dst, struct udev_device *udev_device_src) { diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index e6d6f70510..2cd5b48fea 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -45,8 +45,7 @@ * * Returns: the kernel event sequence number, or 0 if there is no sequence number available. **/ -_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) -{ +_public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) { const char *seqnum; unsigned long long ret; int r; @@ -78,8 +77,7 @@ _public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_ * * Returns: the dev_t number. **/ -_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) -{ +_public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) { dev_t devnum; int r; @@ -102,8 +100,7 @@ _public_ dev_t udev_device_get_devnum(struct udev_device *udev_device) * * Returns: the driver name string, or #NULL if there is no driver attached. **/ -_public_ const char *udev_device_get_driver(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_driver(struct udev_device *udev_device) { const char *driver; int r; @@ -126,8 +123,7 @@ _public_ const char *udev_device_get_driver(struct udev_device *udev_device) * * Returns: the devtype name of the udev device, or #NULL if it cannot be determined **/ -_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_devtype(struct udev_device *udev_device) { const char *devtype; int r; @@ -151,8 +147,7 @@ _public_ const char *udev_device_get_devtype(struct udev_device *udev_device) * * Returns: the subsystem name of the udev device, or #NULL if it cannot be determined **/ -_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) { const char *subsystem; int r; @@ -177,8 +172,7 @@ _public_ const char *udev_device_get_subsystem(struct udev_device *udev_device) * * Returns: the property string, or #NULL if there is no such property. **/ -_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) -{ +_public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) { const char *value = NULL; int r; @@ -193,16 +187,23 @@ _public_ const char *udev_device_get_property_value(struct udev_device *udev_dev return value; } -struct udev_device *udev_device_new(struct udev *udev) { +struct udev_device *udev_device_new(struct udev *udev, sd_device *device) { struct udev_device *udev_device; - udev_device = new0(struct udev_device, 1); + assert(device); + + udev_device = new(struct udev_device, 1); if (!udev_device) { errno = ENOMEM; return NULL; } - udev_device->refcount = 1; - udev_device->udev = udev; + + *udev_device = (struct udev_device) { + .n_ref = 1, + .udev = udev, + .device = sd_device_ref(device), + }; + udev_list_init(udev, &udev_device->properties, true); udev_list_init(udev, &udev_device->tags, true); udev_list_init(udev, &udev_device->sysattrs, true); @@ -226,21 +227,16 @@ struct udev_device *udev_device_new(struct udev *udev) { * Returns: a new udev device, or #NULL, if it does not exist **/ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath) { - struct udev_device *udev_device; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - udev_device = udev_device_new(udev); - if (!udev_device) - return NULL; - - r = sd_device_new_from_syspath(&udev_device->device, syspath); + r = sd_device_new_from_syspath(&device, syspath); if (r < 0) { errno = -r; - udev_device_unref(udev_device); return NULL; } - return udev_device; + return udev_device_new(udev, device); } /** @@ -259,23 +255,17 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con * * Returns: a new udev device, or #NULL, if it does not exist **/ -_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) -{ - struct udev_device *udev_device; +_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - udev_device = udev_device_new(udev); - if (!udev_device) - return NULL; - - r = sd_device_new_from_devnum(&udev_device->device, type, devnum); + r = sd_device_new_from_devnum(&device, type, devnum); if (r < 0) { errno = -r; - udev_device_unref(udev_device); return NULL; } - return udev_device; + return udev_device_new(udev, device); } /** @@ -296,23 +286,17 @@ _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char * * Returns: a new udev device, or #NULL, if it does not exist **/ -_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) -{ - struct udev_device *udev_device; +_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - udev_device = udev_device_new(udev); - if (!udev_device) - return NULL; - - r = sd_device_new_from_device_id(&udev_device->device, id); + r = sd_device_new_from_device_id(&device, id); if (r < 0) { errno = -r; - udev_device_unref(udev_device); return NULL; } - return udev_device; + return udev_device_new(udev, device); } /** @@ -330,23 +314,17 @@ _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, c * * Returns: a new udev device, or #NULL, if it does not exist **/ -_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) -{ - struct udev_device *udev_device; +_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - udev_device = udev_device_new(udev); - if (!udev_device) - return NULL; - - r = sd_device_new_from_subsystem_sysname(&udev_device->device, subsystem, sysname); + r = sd_device_new_from_subsystem_sysname(&device, subsystem, sysname); if (r < 0) { errno = -r; - udev_device_unref(udev_device); return NULL; } - return udev_device; + return udev_device_new(udev, device); } /** @@ -363,47 +341,32 @@ _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev * * Returns: a new udev device, or #NULL, if it does not exist **/ -_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) -{ - struct udev_device *udev_device; +_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; int r; - udev_device = udev_device_new(udev); - if (!udev_device) - return NULL; - - r = device_new_from_strv(&udev_device->device, environ); + r = device_new_from_strv(&device, environ); if (r < 0) { errno = -r; - udev_device_unref(udev_device); return NULL; } - return udev_device; + return udev_device_new(udev, device); } -static struct udev_device *device_new_from_parent(struct udev_device *child) -{ - struct udev_device *parent; +static struct udev_device *device_new_from_parent(struct udev_device *child) { + sd_device *parent; int r; assert_return_errno(child, NULL, EINVAL); - parent = udev_device_new(child->udev); - if (!parent) - return NULL; - - r = sd_device_get_parent(child->device, &parent->device); + r = sd_device_get_parent(child->device, &parent); if (r < 0) { errno = -r; - udev_device_unref(parent); return NULL; } - /* the parent is unref'ed with the child, so take a ref from libudev as well */ - sd_device_ref(parent->device); - - return parent; + return udev_device_new(child->udev, parent); } /** @@ -424,8 +387,7 @@ static struct udev_device *device_new_from_parent(struct udev_device *child) * * Returns: a new udev device, or #NULL, if it no parent exist. **/ -_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) -{ +_public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); if (!udev_device->parent_set) { @@ -458,8 +420,7 @@ _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_dev * * Returns: a new udev device, or #NULL if no matching parent exists. **/ -_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) -{ +_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) { sd_device *parent; int r; @@ -494,13 +455,26 @@ _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struc * * Returns: the udev library context **/ -_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) -{ +_public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); return udev_device->udev; } +static struct udev_device *udev_device_free(struct udev_device *udev_device) { + assert(udev_device); + + sd_device_unref(udev_device->device); + udev_device_unref(udev_device->parent); + + udev_list_cleanup(&udev_device->properties); + udev_list_cleanup(&udev_device->sysattrs); + udev_list_cleanup(&udev_device->tags); + udev_list_cleanup(&udev_device->devlinks); + + return mfree(udev_device); +} + /** * udev_device_ref: * @udev_device: udev device @@ -509,13 +483,6 @@ _public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) * * Returns: the passed udev device **/ -_public_ struct udev_device *udev_device_ref(struct udev_device *udev_device) -{ - if (udev_device) - udev_device->refcount++; - - return udev_device; -} /** * udev_device_unref: @@ -526,22 +493,7 @@ _public_ struct udev_device *udev_device_ref(struct udev_device *udev_device) * * Returns: #NULL **/ -_public_ struct udev_device *udev_device_unref(struct udev_device *udev_device) -{ - if (udev_device && (-- udev_device->refcount) == 0) { - sd_device_unref(udev_device->device); - udev_device_unref(udev_device->parent); - - udev_list_cleanup(&udev_device->properties); - udev_list_cleanup(&udev_device->sysattrs); - udev_list_cleanup(&udev_device->tags); - udev_list_cleanup(&udev_device->devlinks); - - free(udev_device); - } - - return NULL; -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device, udev_device, udev_device_free); /** * udev_device_get_devpath: @@ -552,8 +504,7 @@ _public_ struct udev_device *udev_device_unref(struct udev_device *udev_device) * * Returns: the devpath of the udev device **/ -_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_devpath(struct udev_device *udev_device) { const char *devpath; int r; @@ -577,8 +528,7 @@ _public_ const char *udev_device_get_devpath(struct udev_device *udev_device) * * Returns: the sys path of the udev device **/ -_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_syspath(struct udev_device *udev_device) { const char *syspath; int r; @@ -601,8 +551,7 @@ _public_ const char *udev_device_get_syspath(struct udev_device *udev_device) * * Returns: the name string of the device **/ -_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_sysname(struct udev_device *udev_device) { const char *sysname; int r; @@ -625,8 +574,7 @@ _public_ const char *udev_device_get_sysname(struct udev_device *udev_device) * * Returns: the trailing number string of the device name **/ -_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) { const char *sysnum; int r; @@ -650,8 +598,7 @@ _public_ const char *udev_device_get_sysnum(struct udev_device *udev_device) * * Returns: the device node file name of the udev device, or #NULL if no device node exists **/ -_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) -{ +_public_ const char *udev_device_get_devnode(struct udev_device *udev_device) { const char *devnode; int r; @@ -679,8 +626,7 @@ _public_ const char *udev_device_get_devnode(struct udev_device *udev_device) * * Returns: the first entry of the device node link list **/ -_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) -{ +_public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); if (device_get_devlinks_generation(udev_device->device) != udev_device->devlinks_generation || @@ -711,8 +657,7 @@ _public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev * * Returns: the first entry of the property list **/ -_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) -{ +_public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); if (device_get_properties_generation(udev_device->device) != udev_device->properties_generation || @@ -768,8 +713,7 @@ _public_ const char *udev_device_get_action(struct udev_device *udev_device) { * * Returns: the number of microseconds since the device was first seen. **/ -_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) -{ +_public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device) { usec_t ts; int r; @@ -777,7 +721,7 @@ _public_ unsigned long long int udev_device_get_usec_since_initialized(struct ud r = sd_device_get_usec_since_initialized(udev_device->device, &ts); if (r < 0) { - errno = EINVAL; + errno = -r; return 0; } @@ -794,8 +738,7 @@ _public_ unsigned long long int udev_device_get_usec_since_initialized(struct ud * * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value. **/ -_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) -{ +_public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr) { const char *value; int r; @@ -820,8 +763,7 @@ _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_devi * * Returns: Negative error code on failure or 0 on success. **/ -_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value) -{ +_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, const char *value) { int r; assert_return(udev_device, -EINVAL); @@ -843,8 +785,7 @@ _public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, cons * * Returns: the first entry of the property list **/ -_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) -{ +_public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); if (!udev_device->sysattrs_read) { @@ -874,8 +815,7 @@ _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_ * * Returns: 1 if the device is set up. 0 otherwise. **/ -_public_ int udev_device_get_is_initialized(struct udev_device *udev_device) -{ +_public_ int udev_device_get_is_initialized(struct udev_device *udev_device) { int r, initialized; assert_return(udev_device, -EINVAL); @@ -883,7 +823,6 @@ _public_ int udev_device_get_is_initialized(struct udev_device *udev_device) r = sd_device_get_is_initialized(udev_device->device, &initialized); if (r < 0) { errno = -r; - return 0; } @@ -901,8 +840,7 @@ _public_ int udev_device_get_is_initialized(struct udev_device *udev_device) * * Returns: the first entry of the tag list **/ -_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) -{ +_public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device) { assert_return_errno(udev_device, NULL, EINVAL); if (device_get_tags_generation(udev_device->device) != udev_device->tags_generation || @@ -930,9 +868,8 @@ _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_dev * * Returns: 1 if the tag is found. 0 otherwise. **/ -_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) -{ +_public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag) { assert_return(udev_device, 0); - return sd_device_has_tag(udev_device->device, tag); + return sd_device_has_tag(udev_device->device, tag) > 0; } diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index e9f0f2e47e..41318d0a8d 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -33,7 +33,7 @@ */ struct udev_enumerate { struct udev *udev; - int refcount; + unsigned n_ref; struct udev_list devices_list; bool devices_uptodate:1; @@ -49,33 +49,45 @@ struct udev_enumerate { * Returns: an enumeration context. **/ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { - _cleanup_free_ struct udev_enumerate *udev_enumerate = NULL; + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + struct udev_enumerate *udev_enumerate; int r; - udev_enumerate = new0(struct udev_enumerate, 1); - if (!udev_enumerate) { - errno = ENOMEM; + r = sd_device_enumerator_new(&e); + if (r < 0) { + errno = -r; return NULL; } - r = sd_device_enumerator_new(&udev_enumerate->enumerator); + r = sd_device_enumerator_allow_uninitialized(e); if (r < 0) { errno = -r; return NULL; } - r = sd_device_enumerator_allow_uninitialized(udev_enumerate->enumerator); - if (r < 0) { - errno = -r; + udev_enumerate = new(struct udev_enumerate, 1); + if (!udev_enumerate) { + errno = ENOMEM; return NULL; } - udev_enumerate->refcount = 1; - udev_enumerate->udev = udev; + *udev_enumerate = (struct udev_enumerate) { + .udev = udev, + .n_ref = 1, + .enumerator = TAKE_PTR(e), + }; udev_list_init(udev, &udev_enumerate->devices_list, false); - return TAKE_PTR(udev_enumerate); + return udev_enumerate; +} + +static struct udev_enumerate *udev_enumerate_free(struct udev_enumerate *udev_enumerate) { + assert(udev_enumerate); + + udev_list_cleanup(&udev_enumerate->devices_list); + sd_device_enumerator_unref(udev_enumerate->enumerator); + return mfree(udev_enumerate); } /** @@ -86,12 +98,6 @@ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { * * Returns: the passed enumeration context **/ -_public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate) - udev_enumerate->refcount++; - - return udev_enumerate; -} /** * udev_enumerate_unref: @@ -102,15 +108,7 @@ _public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_e * * Returns: #NULL **/ -_public_ struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate) { - if (udev_enumerate && (-- udev_enumerate->refcount) == 0) { - udev_list_cleanup(&udev_enumerate->devices_list); - sd_device_enumerator_unref(udev_enumerate->enumerator); - free(udev_enumerate); - } - - return NULL; -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_enumerate, udev_enumerate, udev_enumerate_free); /** * udev_enumerate_get_udev: diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index d13cc4dfb5..1b478a6c4b 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -19,17 +19,14 @@ * Opaque object representing the hardware database. */ struct udev_hwdb { - struct udev *udev; - int refcount; - + unsigned n_ref; sd_hwdb *hwdb; - struct udev_list properties_list; }; /** * udev_hwdb_new: - * @udev: udev library context + * @udev: udev library context (unused) * * Create a hardware database context to query properties for devices. * @@ -46,20 +43,30 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { return NULL; } - hwdb = new0(struct udev_hwdb, 1); + hwdb = new(struct udev_hwdb, 1); if (!hwdb) { errno = ENOMEM; return NULL; } - hwdb->refcount = 1; - hwdb->hwdb = TAKE_PTR(hwdb_internal); + *hwdb = (struct udev_hwdb) { + .n_ref = 1, + .hwdb = TAKE_PTR(hwdb_internal), + }; udev_list_init(udev, &hwdb->properties_list, true); return hwdb; } +static struct udev_hwdb *udev_hwdb_free(struct udev_hwdb *hwdb) { + assert(hwdb); + + sd_hwdb_unref(hwdb->hwdb); + udev_list_cleanup(&hwdb->properties_list); + return mfree(hwdb); +} + /** * udev_hwdb_ref: * @hwdb: context @@ -68,12 +75,6 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { * * Returns: the passed enumeration context **/ -_public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) { - if (!hwdb) - return NULL; - hwdb->refcount++; - return hwdb; -} /** * udev_hwdb_unref: @@ -84,16 +85,7 @@ _public_ struct udev_hwdb *udev_hwdb_ref(struct udev_hwdb *hwdb) { * * Returns: #NULL **/ -_public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) { - if (!hwdb) - return NULL; - hwdb->refcount--; - if (hwdb->refcount > 0) - return NULL; - sd_hwdb_unref(hwdb->hwdb); - udev_list_cleanup(&hwdb->properties_list); - return mfree(hwdb); -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_hwdb, udev_hwdb, udev_hwdb_free); /** * udev_hwdb_get_properties_list_entry: @@ -112,10 +104,8 @@ _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev const char *key, *value; struct udev_list_entry *e; - if (!hwdb || !modalias) { - errno = EINVAL; - return NULL; - } + assert_return_errno(hwdb, NULL, EINVAL); + assert_return_errno(modalias, NULL, EINVAL); udev_list_cleanup(&hwdb->properties_list); diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index f0b5081392..ea44308351 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -14,15 +14,20 @@ #include "libudev.h" #include "alloc-util.h" +#include "device-private.h" +#include "device-util.h" #include "fd-util.h" #include "fileio.h" #include "format-util.h" -#include "libudev-private.h" +#include "hashmap.h" #include "libudev-device-internal.h" +#include "libudev-private.h" #include "missing.h" #include "mount-util.h" +#include "set.h" #include "socket-util.h" #include "string-util.h" +#include "strv.h" /** * SECTION:libudev-monitor @@ -38,14 +43,14 @@ */ struct udev_monitor { struct udev *udev; - int refcount; + unsigned n_ref; int sock; union sockaddr_union snl; union sockaddr_union snl_trusted_sender; union sockaddr_union snl_destination; socklen_t addrlen; - struct udev_list filter_subsystem_list; - struct udev_list filter_tag_list; + Hashmap *subsystem_filter; + Set *tag_filter; bool bound; }; @@ -63,98 +68,47 @@ struct udev_monitor_netlink_header { * magic to protect against daemon <-> library message format mismatch * used in the kernel from socket filter rules; needs to be stored in network order */ - unsigned int magic; + unsigned magic; /* total length of header structure known to the sender */ - unsigned int header_size; + unsigned header_size; /* properties string buffer */ - unsigned int properties_off; - unsigned int properties_len; + unsigned properties_off; + unsigned properties_len; /* * hashes of primary device properties strings, to let libudev subscribers * use in-kernel socket filters; values need to be stored in network order */ - unsigned int filter_subsystem_hash; - unsigned int filter_devtype_hash; - unsigned int filter_tag_bloom_hi; - unsigned int filter_tag_bloom_lo; + unsigned filter_subsystem_hash; + unsigned filter_devtype_hash; + unsigned filter_tag_bloom_hi; + unsigned filter_tag_bloom_lo; }; -static struct udev_monitor *udev_monitor_new(struct udev *udev) { - struct udev_monitor *udev_monitor; - - udev_monitor = new0(struct udev_monitor, 1); - if (udev_monitor == NULL) { - errno = ENOMEM; - return NULL; - } - udev_monitor->refcount = 1; - udev_monitor->udev = udev; - udev_list_init(udev, &udev_monitor->filter_subsystem_list, false); - udev_list_init(udev, &udev_monitor->filter_tag_list, true); - return udev_monitor; -} - -/* we consider udev running when /dev is on devtmpfs */ -static bool udev_has_devtmpfs(struct udev *udev) { - - _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX], *e; - int mount_id, r; - - r = path_get_mnt_id("/dev", &mount_id); - if (r < 0) { - if (r != -EOPNOTSUPP) - log_debug_errno(r, "name_to_handle_at on /dev: %m"); - - return false; - } - - f = fopen("/proc/self/mountinfo", "re"); - if (!f) - return false; - - FOREACH_LINE(line, f, return false) { - int mid; - - if (sscanf(line, "%i", &mid) != 1) - continue; - - if (mid != mount_id) - continue; - - e = strstr(line, " - "); - if (!e) - continue; - - /* accept any name that starts with the currently expected type */ - if (startswith(e + 3, "devtmpfs")) - return true; - } - - return false; -} - -static void monitor_set_nl_address(struct udev_monitor *udev_monitor) { +static int udev_monitor_set_nl_address(struct udev_monitor *udev_monitor) { union sockaddr_union snl; socklen_t addrlen; - int r; assert(udev_monitor); - /* get the address the kernel has assigned us - * it is usually, but not necessarily the pid - */ + /* Get the address the kernel has assigned us. + * It is usually, but not necessarily the pid. */ addrlen = sizeof(struct sockaddr_nl); - r = getsockname(udev_monitor->sock, &snl.sa, &addrlen); - if (r >= 0) - udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid; + if (getsockname(udev_monitor->sock, &snl.sa, &addrlen) < 0) + return -errno; + + udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid; + return 0; } struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) { - struct udev_monitor *udev_monitor; - unsigned int group; + _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor = NULL; + _cleanup_close_ int sock = -1; + unsigned group; + int r; - if (name == NULL) + assert_return_errno(!name || STR_IN_SET(name, "udev", "kernel"), NULL, EINVAL); + + if (!name) group = UDEV_MONITOR_NONE; else if (streq(name, "udev")) { /* @@ -169,42 +123,52 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c * We do not set a netlink multicast group here, so the socket * will not receive any messages. */ - if (access("/run/udev/control", F_OK) < 0 && !udev_has_devtmpfs(udev)) { - log_debug("the udev service seems not to be active, disable the monitor"); + if (access("/run/udev/control", F_OK) < 0 && dev_is_devtmpfs() <= 0) { + log_debug("The udev service seems not to be active, disabling the monitor"); group = UDEV_MONITOR_NONE; } else group = UDEV_MONITOR_UDEV; - } else if (streq(name, "kernel")) + } else { + assert(streq(name, "kernel")); group = UDEV_MONITOR_KERNEL; - else { - errno = EINVAL; - return NULL; } - udev_monitor = udev_monitor_new(udev); - if (udev_monitor == NULL) - return NULL; - if (fd < 0) { - udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); - if (udev_monitor->sock < 0) { - log_debug_errno(errno, "error getting socket: %m"); - return mfree(udev_monitor); + sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); + if (sock < 0) { + log_debug_errno(errno, "Failed to create socket: %m"); + return NULL; } - } else { - udev_monitor->bound = true; - udev_monitor->sock = fd; - monitor_set_nl_address(udev_monitor); } - udev_monitor->snl.nl.nl_family = AF_NETLINK; - udev_monitor->snl.nl.nl_groups = group; + udev_monitor = new(struct udev_monitor, 1); + if (!udev_monitor) { + errno = ENOMEM; + return NULL; + } + + *udev_monitor = (struct udev_monitor) { + .udev = udev, + .n_ref = 1, + .sock = fd >= 0 ? fd : TAKE_FD(sock), + .bound = fd >= 0, + .snl.nl.nl_family = AF_NETLINK, + .snl.nl.nl_groups = group, + + /* default destination for sending */ + .snl_destination.nl.nl_family = AF_NETLINK, + .snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV, + }; - /* default destination for sending */ - udev_monitor->snl_destination.nl.nl_family = AF_NETLINK; - udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV; + if (fd >= 0) { + r = udev_monitor_set_nl_address(udev_monitor); + if (r < 0) { + log_debug_errno(r, "Failed to set netlink address: %m"); + return NULL; + } + } - return udev_monitor; + return TAKE_PTR(udev_monitor); } /** @@ -233,27 +197,23 @@ _public_ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, c return udev_monitor_new_from_netlink_fd(udev, name, -1); } -static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i, - unsigned short code, unsigned int data) -{ - struct sock_filter *ins = &inss[*i]; - - ins->code = code; - ins->k = data; - (*i)++; +static void bpf_stmt(struct sock_filter *ins, unsigned *i, + unsigned short code, unsigned data) { + ins[(*i)++] = (struct sock_filter) { + .code = code, + .k = data, + }; } -static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i, - unsigned short code, unsigned int data, - unsigned short jt, unsigned short jf) -{ - struct sock_filter *ins = &inss[*i]; - - ins->code = code; - ins->jt = jt; - ins->jf = jf; - ins->k = data; - (*i)++; +static void bpf_jmp(struct sock_filter *ins, unsigned *i, + unsigned short code, unsigned data, + unsigned short jt, unsigned short jf) { + ins[(*i)++] = (struct sock_filter) { + .code = code, + .jt = jt, + .jf = jf, + .k = data, + }; } /** @@ -265,20 +225,18 @@ static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i, * * Returns: 0 on success, otherwise a negative error value. */ -_public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) -{ - struct sock_filter ins[512]; +_public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) { + struct sock_filter ins[512] = {}; struct sock_fprog filter; - unsigned int i; - struct udev_list_entry *list_entry; - int err; + const char *subsystem, *devtype, *tag; + unsigned i = 0; + Iterator it; - if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL && - udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL) - return 0; + assert_return(udev_monitor, -EINVAL); - memzero(ins, sizeof(ins)); - i = 0; + if (hashmap_isempty(udev_monitor->subsystem_filter) && + set_isempty(udev_monitor->tag_filter)) + return 0; /* load magic in A */ bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic)); @@ -287,17 +245,12 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) /* wrong magic, pass packet */ bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); - if (udev_list_get_entry(&udev_monitor->filter_tag_list) != NULL) { - int tag_matches; - - /* count tag matches, to calculate end of tag match block */ - tag_matches = 0; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) - tag_matches++; + if (!set_isempty(udev_monitor->tag_filter)) { + int tag_matches = set_size(udev_monitor->tag_filter); /* add all tags matches */ - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) { - uint64_t tag_bloom_bits = util_string_bloom64(udev_list_entry_get_name(list_entry)); + SET_FOREACH(tag, udev_monitor->tag_filter, it) { + uint64_t tag_bloom_bits = util_string_bloom64(tag); uint32_t tag_bloom_hi = tag_bloom_bits >> 32; uint32_t tag_bloom_lo = tag_bloom_bits & 0xffffffff; @@ -322,23 +275,23 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) } /* add all subsystem matches */ - if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) != NULL) { - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) { - unsigned int hash = util_string_hash32(udev_list_entry_get_name(list_entry)); + if (!hashmap_isempty(udev_monitor->subsystem_filter)) { + HASHMAP_FOREACH_KEY(devtype, subsystem, udev_monitor->subsystem_filter, it) { + uint32_t hash = util_string_hash32(subsystem); /* load device subsystem value in A */ bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_subsystem_hash)); - if (udev_list_entry_get_value(list_entry) == NULL) { + if (!devtype) { /* jump if subsystem does not match */ bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1); } else { + hash = util_string_hash32(devtype); + /* jump if subsystem does not match */ bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 3); - /* load device devtype value in A */ bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, filter_devtype_hash)); /* jump if value does not match */ - hash = util_string_hash32(udev_list_entry_get_value(list_entry)); bpf_jmp(ins, &i, BPF_JMP|BPF_JEQ|BPF_K, hash, 0, 1); } @@ -357,15 +310,20 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) bpf_stmt(ins, &i, BPF_RET|BPF_K, 0xffffffff); /* install filter */ - memzero(&filter, sizeof(filter)); - filter.len = i; - filter.filter = ins; - err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); - return err < 0 ? -errno : 0; + filter = (struct sock_fprog) { + .len = i, + .filter = ins, + }; + if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0) + return -errno; + + return 0; } -int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender) -{ +int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct udev_monitor *sender) { + assert_return(udev_monitor, -EINVAL); + assert_return(sender, -EINVAL); + udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid; return 0; } @@ -378,29 +336,30 @@ int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct * * Returns: 0 on success, otherwise a negative error value. */ -_public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) -{ - int err = 0; +_public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) { const int on = 1; + int r; - udev_monitor_filter_update(udev_monitor); + assert_return(udev_monitor, -EINVAL); + + r = udev_monitor_filter_update(udev_monitor); + if (r < 0) + return log_debug_errno(r, "Failed to update filter: %m"); if (!udev_monitor->bound) { - err = bind(udev_monitor->sock, - &udev_monitor->snl.sa, sizeof(struct sockaddr_nl)); - if (err == 0) - udev_monitor->bound = true; + if (bind(udev_monitor->sock, &udev_monitor->snl.sa, sizeof(struct sockaddr_nl)) < 0) + return log_debug_errno(errno, "Failed to bind udev monitor socket to event source: %m"); + + udev_monitor->bound = true; } - if (err >= 0) - monitor_set_nl_address(udev_monitor); - else - return log_debug_errno(errno, "bind failed: %m"); + r = udev_monitor_set_nl_address(udev_monitor); + if (r < 0) + return log_debug_errno(r, "Failed to set address: %m"); /* enable receiving of sender credentials */ - err = setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - if (err < 0) - log_debug_errno(errno, "setting SO_PASSCRED failed: %m"); + if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) + return log_debug_errno(errno, "Failed to set socket option SO_PASSCRED: %m"); return 0; } @@ -415,23 +374,29 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) * * Returns: 0 on success, otherwise -1 on error. */ -_public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) -{ - if (udev_monitor == NULL) - return -EINVAL; +_public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size) { + assert_return(udev_monitor, -EINVAL); + if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)) < 0) return -errno; return 0; } -int udev_monitor_disconnect(struct udev_monitor *udev_monitor) -{ - int err; +int udev_monitor_disconnect(struct udev_monitor *udev_monitor) { + assert(udev_monitor); + + udev_monitor->sock = safe_close(udev_monitor->sock); + return 0; +} + +static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) { + assert(udev_monitor); - err = close(udev_monitor->sock); - udev_monitor->sock = -1; - return err < 0 ? -errno : 0; + udev_monitor_disconnect(udev_monitor); + hashmap_free_free_free(udev_monitor->subsystem_filter); + set_free_free(udev_monitor->tag_filter); + return mfree(udev_monitor); } /** @@ -442,13 +407,6 @@ int udev_monitor_disconnect(struct udev_monitor *udev_monitor) * * Returns: the passed udev monitor **/ -_public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor) -{ - if (udev_monitor == NULL) - return NULL; - udev_monitor->refcount++; - return udev_monitor; -} /** * udev_monitor_unref: @@ -460,19 +418,7 @@ _public_ struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor * * Returns: #NULL **/ -_public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor) -{ - if (udev_monitor == NULL) - return NULL; - udev_monitor->refcount--; - if (udev_monitor->refcount > 0) - return NULL; - if (udev_monitor->sock >= 0) - close(udev_monitor->sock); - udev_list_cleanup(&udev_monitor->filter_subsystem_list); - udev_list_cleanup(&udev_monitor->filter_tag_list); - return mfree(udev_monitor); -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_monitor_free); /** * udev_monitor_get_udev: @@ -482,10 +428,9 @@ _public_ struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monit * * Returns: the udev library context **/ -_public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) -{ - if (udev_monitor == NULL) - return NULL; +_public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) { + assert_return(udev_monitor, NULL); + return udev_monitor->udev; } @@ -497,230 +442,228 @@ _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) * * Returns: the socket file descriptor **/ -_public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) -{ - if (udev_monitor == NULL) - return -EINVAL; +_public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) { + assert_return(udev_monitor, -EINVAL); + return udev_monitor->sock; } -static int passes_filter(struct udev_monitor *udev_monitor, struct udev_device *udev_device) -{ - struct udev_list_entry *list_entry; +static int passes_filter(struct udev_monitor *udev_monitor, sd_device *device) { + const char *tag, *subsystem, *devtype, *s, *d = NULL; + Iterator i; + int r; + + assert_return(udev_monitor, -EINVAL); + assert_return(device, -EINVAL); - if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL) + if (hashmap_isempty(udev_monitor->subsystem_filter)) goto tag; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_subsystem_list)) { - const char *subsys = udev_list_entry_get_name(list_entry); - const char *dsubsys = udev_device_get_subsystem(udev_device); - const char *devtype; - const char *ddevtype; - if (!streq(dsubsys, subsys)) + r = sd_device_get_subsystem(device, &s); + if (r < 0) + return r; + + r = sd_device_get_devtype(device, &d); + if (r < 0 && r != -ENOENT) + return r; + + HASHMAP_FOREACH_KEY(devtype, subsystem, udev_monitor->subsystem_filter, i) { + if (!streq(s, subsystem)) continue; - devtype = udev_list_entry_get_value(list_entry); - if (devtype == NULL) + if (!devtype) goto tag; - ddevtype = udev_device_get_devtype(udev_device); - if (ddevtype == NULL) + + if (!d) continue; - if (streq(ddevtype, devtype)) + + if (streq(d, devtype)) goto tag; } + return 0; tag: - if (udev_list_get_entry(&udev_monitor->filter_tag_list) == NULL) + if (set_isempty(udev_monitor->tag_filter)) return 1; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_monitor->filter_tag_list)) { - const char *tag = udev_list_entry_get_name(list_entry); - if (udev_device_has_tag(udev_device, tag)) + SET_FOREACH(tag, udev_monitor->tag_filter, i) + if (sd_device_has_tag(device, tag) > 0) return 1; - } + return 0; } -/** - * udev_monitor_receive_device: - * @udev_monitor: udev monitor - * - * Receive data from the udev monitor socket, allocate a new udev - * device, fill in the received data, and return the device. - * - * Only socket connections with uid=0 are accepted. - * - * The monitor socket is by default set to NONBLOCK. A variant of poll() on - * the file descriptor returned by udev_monitor_get_fd() should to be used to - * wake up when new devices arrive, or alternatively the file descriptor - * switched into blocking mode. - * - * The initial refcount is 1, and needs to be decremented to - * release the resources of the udev device. - * - * Returns: a new udev device, or #NULL, in case of an error - **/ -_public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) -{ - struct udev_device *udev_device; - struct msghdr smsg; - struct iovec iov; - char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; - struct cmsghdr *cmsg; - union sockaddr_union snl; - struct ucred *cred; +static int udev_monitor_receive_device_one(struct udev_monitor *udev_monitor, sd_device **ret) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; union { struct udev_monitor_netlink_header nlh; char raw[8192]; } buf; - ssize_t buflen; - ssize_t bufpos; + struct iovec iov = { + .iov_base = &buf, + .iov_len = sizeof(buf) + }; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + union sockaddr_union snl; + struct msghdr smsg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cred_msg, + .msg_controllen = sizeof(cred_msg), + .msg_name = &snl, + .msg_namelen = sizeof(snl), + }; + struct cmsghdr *cmsg; + struct ucred *cred; + ssize_t buflen, bufpos; bool is_initialized = false; + int r; -retry: - if (udev_monitor == NULL) { - errno = EINVAL; - return NULL; - } - iov.iov_base = &buf; - iov.iov_len = sizeof(buf); - memzero(&smsg, sizeof(struct msghdr)); - smsg.msg_iov = &iov; - smsg.msg_iovlen = 1; - smsg.msg_control = cred_msg; - smsg.msg_controllen = sizeof(cred_msg); - smsg.msg_name = &snl; - smsg.msg_namelen = sizeof(snl); + assert(ret); buflen = recvmsg(udev_monitor->sock, &smsg, 0); if (buflen < 0) { if (errno != EINTR) - log_debug("unable to receive message"); - return NULL; + log_debug_errno(errno, "Failed to receive message: %m"); + return -errno; } - if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) { - log_debug("invalid message length"); - errno = EINVAL; - return NULL; - } + if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) + return log_debug_errno(EINVAL, "Invalid message length."); - if (snl.nl.nl_groups == 0) { + if (snl.nl.nl_groups == UDEV_MONITOR_NONE) { /* unicast message, check if we trust the sender */ if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 || - snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) { - log_debug("unicast netlink message ignored"); - errno = EAGAIN; - return NULL; - } + snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) + return log_debug_errno(EAGAIN, "Unicast netlink message ignored."); + } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) { - if (snl.nl.nl_pid > 0) { - log_debug("multicast kernel netlink message from PID %"PRIu32" ignored", - snl.nl.nl_pid); - errno = EAGAIN; - return NULL; - } + if (snl.nl.nl_pid > 0) + return log_debug_errno(EAGAIN, "Multicast kernel netlink message from PID %"PRIu32" ignored.", snl.nl.nl_pid); } cmsg = CMSG_FIRSTHDR(&smsg); - if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - log_debug("no sender credentials received, message ignored"); - errno = EAGAIN; - return NULL; - } + if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) + return log_debug_errno(EAGAIN, "No sender credentials received, message ignored."); - cred = (struct ucred *)CMSG_DATA(cmsg); - if (cred->uid != 0) { - log_debug("sender uid="UID_FMT", message ignored", cred->uid); - errno = EAGAIN; - return NULL; - } + cred = (struct ucred*) CMSG_DATA(cmsg); + if (cred->uid != 0) + return log_debug_errno(EAGAIN, "Sender uid="UID_FMT", message ignored.", cred->uid); - if (memcmp(buf.raw, "libudev", 8) == 0) { + if (streq(buf.raw, "libudev")) { /* udev message needs proper version magic */ - if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) { - log_debug("unrecognized message signature (%x != %x)", - buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC)); - errno = EAGAIN; - return NULL; - } - if (buf.nlh.properties_off+32 > (size_t)buflen) { - log_debug("message smaller than expected (%u > %zd)", - buf.nlh.properties_off+32, buflen); - errno = EAGAIN; - return NULL; - } + if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) + return log_debug_errno(EAGAIN, "Invalid message signature (%x != %x)", + buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC)); + + if (buf.nlh.properties_off+32 > (size_t) buflen) + return log_debug_errno(EAGAIN, "Invalid message length (%u > %zd)", + buf.nlh.properties_off+32, buflen); bufpos = buf.nlh.properties_off; /* devices received from udev are always initialized */ is_initialized = true; + } else { /* kernel message with header */ bufpos = strlen(buf.raw) + 1; - if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) { - log_debug("invalid message length"); - errno = EAGAIN; - return NULL; - } + if ((size_t) bufpos < sizeof("a@/d") || bufpos >= buflen) + return log_debug_errno(EAGAIN, "Invalid message length"); /* check message header */ - if (strstr(buf.raw, "@/") == NULL) { - log_debug("unrecognized message header"); - errno = EAGAIN; - return NULL; - } + if (!strstr(buf.raw, "@/")) + return log_debug_errno(EAGAIN, "Invalid message header"); } - udev_device = udev_device_new_from_nulstr(udev_monitor->udev, &buf.raw[bufpos], buflen - bufpos); - if (!udev_device) { - log_debug_errno(errno, "could not create device: %m"); - return NULL; - } + r = device_new_from_nulstr(&device, (uint8_t*) &buf.raw[bufpos], buflen - bufpos); + if (r < 0) + return log_debug_errno(r, "Failed to create device: %m"); if (is_initialized) - udev_device_set_is_initialized(udev_device); + device_set_is_initialized(device); /* skip device, if it does not pass the current filter */ - if (!passes_filter(udev_monitor, udev_device)) { - struct pollfd pfd[1]; - int rc; + if (passes_filter(udev_monitor, device) <= 0) + return 0; - udev_device_unref(udev_device); + *ret = TAKE_PTR(device); + return 1; +} - /* if something is queued, get next device */ - pfd[0].fd = udev_monitor->sock; - pfd[0].events = POLLIN; - rc = poll(pfd, 1, 0); - if (rc > 0) - goto retry; +int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) { + struct pollfd pfd = { + .fd = udev_monitor->sock, + .events = POLLIN, + }; + int r; - errno = EAGAIN; - return NULL; - } + assert(udev_monitor); + assert(ret); - return udev_device; + for (;;) { + /* r == 0 means a device is received but it does not pass the current filter. */ + r = udev_monitor_receive_device_one(udev_monitor, ret); + if (r != 0) + return r; + + for (;;) { + /* wait next message */ + r = poll(&pfd, 1, 0); + if (r < 0) { + if (IN_SET(errno, EINTR, EAGAIN)) + continue; + + return -errno; + } else if (r == 0) + return -EAGAIN; + + /* receive next message */ + break; + } + } } -int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) { - _cleanup_(udev_device_unrefp) struct udev_device *udev_device = NULL; +/** + * udev_monitor_receive_device: + * @udev_monitor: udev monitor + * + * Receive data from the udev monitor socket, allocate a new udev + * device, fill in the received data, and return the device. + * + * Only socket connections with uid=0 are accepted. + * + * The monitor socket is by default set to NONBLOCK. A variant of poll() on + * the file descriptor returned by udev_monitor_get_fd() should to be used to + * wake up when new devices arrive, or alternatively the file descriptor + * switched into blocking mode. + * + * The initial refcount is 1, and needs to be decremented to + * release the resources of the udev device. + * + * Returns: a new udev device, or #NULL, in case of an error + **/ +_public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; + int r; - assert(ret); + assert_return(udev_monitor, NULL); - udev_device = udev_monitor_receive_device(udev_monitor); - if (!udev_device) - return -errno; + r = udev_monitor_receive_sd_device(udev_monitor, &device); + if (r < 0) { + errno = -r; + return NULL; + } - *ret = sd_device_ref(udev_device->device); - return 0; + return udev_device_new(udev_monitor->udev, device); } -int udev_monitor_send_device(struct udev_monitor *udev_monitor, - struct udev_monitor *destination, struct udev_device *udev_device) -{ - const char *buf, *val; - ssize_t blen, count; +static int udev_monitor_send_sd_device( + struct udev_monitor *udev_monitor, + struct udev_monitor *destination, + sd_device *device) { + struct udev_monitor_netlink_header nlh = { .prefix = "libudev", .magic = htobe32(UDEV_MONITOR_MAGIC), @@ -733,27 +676,37 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, .msg_iov = iov, .msg_iovlen = 2, }; - struct udev_list_entry *list_entry; uint64_t tag_bloom_bits; + const char *buf, *val; + ssize_t count; + size_t blen; + int r; - blen = udev_device_get_properties_monitor_buf(udev_device, &buf); + assert(udev_monitor); + assert(device); + + r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen); + if (r < 0) + return log_debug_errno(r, "Failed to get device properties: %m"); if (blen < 32) { - log_debug("device buffer is too small to contain a valid device"); + log_debug("Device buffer is too small to contain a valid device"); return -EINVAL; } /* fill in versioned header */ - val = udev_device_get_subsystem(udev_device); + r = sd_device_get_subsystem(device, &val); + if (r < 0) + return log_debug_errno(r, "Failed to get device subsystem: %m"); nlh.filter_subsystem_hash = htobe32(util_string_hash32(val)); - val = udev_device_get_devtype(udev_device); - if (val != NULL) + if (sd_device_get_devtype(device, &val) >= 0 && val) nlh.filter_devtype_hash = htobe32(util_string_hash32(val)); /* add tag bloom filter */ tag_bloom_bits = 0; - udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device)) - tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry)); + FOREACH_DEVICE_TAG(device, val) + tag_bloom_bits |= util_string_bloom64(val); + if (tag_bloom_bits > 0) { nlh.filter_tag_bloom_hi = htobe32(tag_bloom_bits >> 32); nlh.filter_tag_bloom_lo = htobe32(tag_bloom_bits & 0xffffffff); @@ -762,8 +715,10 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, /* add properties list */ nlh.properties_off = iov[0].iov_len; nlh.properties_len = blen; - iov[1].iov_base = (char *)buf; - iov[1].iov_len = blen; + iov[1] = (struct iovec) { + .iov_base = (char*) buf, + .iov_len = blen, + }; /* * Use custom address for target, or the default one. @@ -771,24 +726,30 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, * If we send to a multicast group, we will get * ECONNREFUSED, which is expected. */ - if (destination) - smsg.msg_name = &destination->snl; - else - smsg.msg_name = &udev_monitor->snl_destination; + smsg.msg_name = destination ? &destination->snl : &udev_monitor->snl_destination; smsg.msg_namelen = sizeof(struct sockaddr_nl); count = sendmsg(udev_monitor->sock, &smsg, 0); if (count < 0) { if (!destination && errno == ECONNREFUSED) { - log_debug("passed device to netlink monitor %p", udev_monitor); + log_debug("Passed device to netlink monitor %p", udev_monitor); return 0; } else - return -errno; + return log_debug_errno(errno, "Failed to send device to netlink monitor %p", udev_monitor); } - log_debug("passed %zi byte device to netlink monitor %p", count, udev_monitor); + log_debug("Passed %zi byte device to netlink monitor %p", count, udev_monitor); return count; } +int udev_monitor_send_device( + struct udev_monitor *udev_monitor, + struct udev_monitor *destination, + struct udev_device *udev_device) { + assert(udev_device); + + return udev_monitor_send_sd_device(udev_monitor, destination, udev_device->device); +} + /** * udev_monitor_filter_add_match_subsystem_devtype: * @udev_monitor: the monitor @@ -802,14 +763,32 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, * * Returns: 0 on success, otherwise a negative error value. */ -_public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) -{ - if (udev_monitor == NULL) - return -EINVAL; - if (subsystem == NULL) - return -EINVAL; - if (udev_list_entry_add(&udev_monitor->filter_subsystem_list, subsystem, devtype) == NULL) +_public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype) { + _cleanup_free_ char *s = NULL, *d = NULL; + int r; + + assert_return(udev_monitor, -EINVAL); + assert_return(subsystem, -EINVAL); + + s = strdup(subsystem); + if (!s) return -ENOMEM; + + if (devtype) { + d = strdup(devtype); + if (!d) + return -ENOMEM; + } + + r = hashmap_ensure_allocated(&udev_monitor->subsystem_filter, NULL); + if (r < 0) + return r; + + r = hashmap_put(udev_monitor->subsystem_filter, s, d); + if (r < 0) + return r; + + s = d = NULL; return 0; } @@ -825,14 +804,28 @@ _public_ int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor * * Returns: 0 on success, otherwise a negative error value. */ -_public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) -{ - if (udev_monitor == NULL) - return -EINVAL; - if (tag == NULL) - return -EINVAL; - if (udev_list_entry_add(&udev_monitor->filter_tag_list, tag, NULL) == NULL) +_public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag) { + _cleanup_free_ char *t = NULL; + int r; + + assert_return(udev_monitor, -EINVAL); + assert_return(tag, -EINVAL); + + t = strdup(tag); + if (!t) return -ENOMEM; + + r = set_ensure_allocated(&udev_monitor->tag_filter, &string_hash_ops); + if (r < 0) + return r; + + r = set_put(udev_monitor->tag_filter, t); + if (r == -EEXIST) + return 0; + if (r < 0) + return r; + + TAKE_PTR(t); return 0; } @@ -844,11 +837,14 @@ _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor * * Returns: 0 on success, otherwise a negative error value. */ -_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) -{ +_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) { static const struct sock_fprog filter = { 0, NULL }; - udev_list_cleanup(&udev_monitor->filter_subsystem_list); + assert_return(udev_monitor, -EINVAL); + + udev_monitor->subsystem_filter = hashmap_free_free_free(udev_monitor->subsystem_filter); + udev_monitor->tag_filter = set_free_free(udev_monitor->tag_filter); + if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0) return -errno; diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index 60968b9a2e..9b1bf82609 100644 --- a/src/libudev/libudev-private.h +++ b/src/libudev/libudev-private.h @@ -16,9 +16,6 @@ #define READ_END 0 #define WRITE_END 1 -/* libudev.c */ -int udev_get_rules_path(struct udev *udev, char **path[], usec_t *ts_usec[]); - /* libudev-device.c */ struct udev_device *udev_device_new_from_nulstr(struct udev *udev, char *nulstr, ssize_t buflen); struct udev_device *udev_device_new_from_synthetic_event(struct udev *udev, const char *syspath, const char *action); @@ -40,7 +37,6 @@ void udev_device_set_is_initialized(struct udev_device *udev_device); int udev_device_add_tag(struct udev_device *udev_device, const char *tag); void udev_device_remove_tag(struct udev_device *udev_device, const char *tag); void udev_device_cleanup_tags_list(struct udev_device *udev_device); -usec_t udev_device_get_usec_initialized(struct udev_device *udev_device); void udev_device_ensure_usec_initialized(struct udev_device *udev_device, struct udev_device *old_device); int udev_device_get_devlink_priority(struct udev_device *udev_device); int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio); @@ -48,11 +44,8 @@ int udev_device_get_watch_handle(struct udev_device *udev_device); int udev_device_set_watch_handle(struct udev_device *udev_device, int handle); int udev_device_get_ifindex(struct udev_device *udev_device); void udev_device_set_info_loaded(struct udev_device *device); -bool udev_device_get_db_persist(struct udev_device *udev_device); void udev_device_set_db_persist(struct udev_device *udev_device); void udev_device_read_db(struct udev_device *udev_device); - -/* libudev-device-private.c */ int udev_device_update_db(struct udev_device *udev_device); int udev_device_delete_db(struct udev_device *udev_device); int udev_device_tag_index(struct udev_device *dev, struct udev_device *dev_old, bool add); @@ -101,19 +94,6 @@ void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num); entry != NULL; \ entry = tmp, tmp = udev_list_entry_get_next(tmp)) -/* libudev-queue.c */ -unsigned long long int udev_get_kernel_seqnum(struct udev *udev); -int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum); -ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size); -ssize_t udev_queue_skip_devpath(FILE *queue_file); - -/* libudev-queue-private.c */ -struct udev_queue_export *udev_queue_export_new(struct udev *udev); -struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export); -void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export); -int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device); -int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device); - /* libudev-util.c */ #define UTIL_PATH_SIZE 1024 #define UTIL_NAME_SIZE 512 diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index c45abfd520..832f3b3da5 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -28,7 +28,7 @@ */ struct udev_queue { struct udev *udev; - int refcount; + unsigned n_ref; int fd; }; @@ -41,22 +41,31 @@ struct udev_queue { * * Returns: the udev queue context, or #NULL on error. **/ -_public_ struct udev_queue *udev_queue_new(struct udev *udev) -{ +_public_ struct udev_queue *udev_queue_new(struct udev *udev) { struct udev_queue *udev_queue; - udev_queue = new0(struct udev_queue, 1); + udev_queue = new(struct udev_queue, 1); if (udev_queue == NULL) { errno = ENOMEM; return NULL; } - udev_queue->refcount = 1; - udev_queue->udev = udev; - udev_queue->fd = -1; + *udev_queue = (struct udev_queue) { + .udev = udev, + .n_ref = 1, + .fd = -1, + }; + return udev_queue; } +static struct udev_queue *udev_queue_free(struct udev_queue *udev_queue) { + assert(udev_queue); + + safe_close(udev_queue->fd); + return mfree(udev_queue); +} + /** * udev_queue_ref: * @udev_queue: udev queue context @@ -65,14 +74,6 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev) * * Returns: the same udev queue context. **/ -_public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue) -{ - if (udev_queue == NULL) - return NULL; - - udev_queue->refcount++; - return udev_queue; -} /** * udev_queue_unref: @@ -83,19 +84,7 @@ _public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue) * * Returns: #NULL **/ -_public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue) -{ - if (udev_queue == NULL) - return NULL; - - udev_queue->refcount--; - if (udev_queue->refcount > 0) - return NULL; - - safe_close(udev_queue->fd); - - return mfree(udev_queue); -} +DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_free); /** * udev_queue_get_udev: @@ -105,12 +94,9 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue) * * Returns: the udev library context. **/ -_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) -{ - if (udev_queue == NULL) { - errno = EINVAL; - return NULL; - } +_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) { + assert_return_errno(udev_queue, NULL, EINVAL); + return udev_queue->udev; } @@ -122,8 +108,7 @@ _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) * * Returns: 0. **/ -_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) -{ +_public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) { return 0; } @@ -135,8 +120,7 @@ _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue * * * Returns: 0. **/ -_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) -{ +_public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) { return 0; } @@ -148,8 +132,7 @@ _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *ud * * Returns: a flag indicating if udev is active. **/ -_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) -{ +_public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) { return access("/run/udev/control", F_OK) >= 0; } @@ -161,8 +144,7 @@ _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) * * Returns: a flag indicating if udev is currently handling events. **/ -_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) -{ +_public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) { return access("/run/udev/queue", F_OK) < 0; } @@ -178,8 +160,7 @@ _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) * Returns: a flag indicating if udev is currently handling events. **/ _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, - unsigned long long int start, unsigned long long int end) -{ + unsigned long long int start, unsigned long long int end) { return udev_queue_get_queue_is_empty(udev_queue); } @@ -193,8 +174,7 @@ _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_ * * Returns: a flag indicating if udev is currently handling events. **/ -_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) -{ +_public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) { return udev_queue_get_queue_is_empty(udev_queue); } @@ -206,8 +186,7 @@ _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, un * * Returns: NULL. **/ -_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) -{ +_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) { errno = ENODATA; return NULL; } @@ -219,8 +198,9 @@ _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_qu * Returns: a file descriptor to watch for a queue to become empty. */ _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { - int fd; - int r; + _cleanup_close_ int fd = -1; + + assert_return(udev_queue, -EINVAL); if (udev_queue->fd >= 0) return udev_queue->fd; @@ -229,15 +209,11 @@ _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { if (fd < 0) return -errno; - r = inotify_add_watch(fd, "/run/udev" , IN_DELETE); - if (r < 0) { - r = -errno; - close(fd); - return r; - } + if (inotify_add_watch(fd, "/run/udev" , IN_DELETE) < 0) + return -errno; - udev_queue->fd = fd; - return fd; + udev_queue->fd = TAKE_FD(fd); + return udev_queue->fd; } /** @@ -249,7 +225,7 @@ _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { _public_ int udev_queue_flush(struct udev_queue *udev_queue) { int r; - assert(udev_queue); + assert_return(udev_queue, -EINVAL); if (udev_queue->fd < 0) return -EINVAL; diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index 8af97fe16d..4554b922e3 100644 --- a/src/libudev/libudev.c +++ b/src/libudev/libudev.c @@ -18,9 +18,6 @@ /** * SECTION:libudev * @short_description: libudev context - * - * The context contains the default values read from the udev config file, - * and is passed to all library operations. */ /** @@ -29,10 +26,7 @@ * Opaque object representing the library context. */ struct udev { - int refcount; - void (*log_fn)(struct udev *udev, - int priority, const char *file, int line, const char *fn, - const char *format, va_list args); + unsigned n_ref; void *userdata; }; @@ -46,8 +40,8 @@ struct udev { * Returns: stored userdata **/ _public_ void *udev_get_userdata(struct udev *udev) { - if (udev == NULL) - return NULL; + assert_return(udev, NULL); + return udev->userdata; } @@ -59,8 +53,9 @@ _public_ void *udev_get_userdata(struct udev *udev) { * Store custom @userdata in the library context. **/ _public_ void udev_set_userdata(struct udev *udev, void *userdata) { - if (udev == NULL) + if (!udev) return; + udev->userdata = userdata; } @@ -77,12 +72,15 @@ _public_ void udev_set_userdata(struct udev *udev, void *userdata) { _public_ struct udev *udev_new(void) { struct udev *udev; - udev = new0(struct udev, 1); + udev = new(struct udev, 1); if (!udev) { errno = ENOMEM; return NULL; } - udev->refcount = 1; + + *udev = (struct udev) { + .n_ref = 1, + }; return udev; } @@ -95,12 +93,7 @@ _public_ struct udev *udev_new(void) { * * Returns: the passed udev library context **/ -_public_ struct udev *udev_ref(struct udev *udev) { - if (udev == NULL) - return NULL; - udev->refcount++; - return udev; -} +DEFINE_PUBLIC_TRIVIAL_REF_FUNC(struct udev, udev); /** * udev_unref: @@ -112,11 +105,17 @@ _public_ struct udev *udev_ref(struct udev *udev) { * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise. **/ _public_ struct udev *udev_unref(struct udev *udev) { - if (udev == NULL) + if (!udev) return NULL; - udev->refcount--; - if (udev->refcount > 0) + + assert(udev->n_ref > 0); + udev->n_ref--; + if (udev->n_ref > 0) + /* This is different from our convetion, but let's keep backward + * compatibility. So, do not use DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC() + * macro to define this function. */ return udev; + return mfree(udev); } @@ -128,10 +127,11 @@ _public_ struct udev *udev_unref(struct udev *udev) { * This function is deprecated. * **/ -_public_ void udev_set_log_fn(struct udev *udev, - void (*log_fn)(struct udev *udev, - int priority, const char *file, int line, const char *fn, - const char *format, va_list args)) { +_public_ void udev_set_log_fn( + struct udev *udev, + void (*log_fn)(struct udev *udev, + int priority, const char *file, int line, const char *fn, + const char *format, va_list args)) { return; } diff --git a/src/libudev/libudev.h b/src/libudev/libudev.h index fa4eaeb969..fa2a35d1f9 100644 --- a/src/libudev/libudev.h +++ b/src/libudev/libudev.h @@ -90,7 +90,7 @@ const char *udev_device_get_action(struct udev_device *udev_device); unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device); unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device); const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr); -int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value); +int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, const char *value); int udev_device_has_tag(struct udev_device *udev_device, const char *tag); /* diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h index 3a51c135d4..406db8866d 100644 --- a/src/systemd/sd-device.h +++ b/src/systemd/sd-device.h @@ -68,7 +68,7 @@ int sd_device_has_tag(sd_device *device, const char *tag); int sd_device_get_property_value(sd_device *device, const char *key, const char **value); int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, const char **_value); -int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, char *value); +int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *value); /* device enumerator */ |