From 50d2158901fcc7207be1a50643772a8ba229742c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:06:02 +0900 Subject: [PATCH 01/33] libudev-monitor: use safe_close() in udev_monitor_disconnect() --- src/libudev/libudev-monitor.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index f0b5081392..fe4595930f 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -425,13 +425,11 @@ _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_moni 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); - err = close(udev_monitor->sock); - udev_monitor->sock = -1; - return err < 0 ? -errno : 0; + udev_monitor->sock = safe_close(udev_monitor->sock); + return 0; } /** From 3c6ac219296aaba8ef99644b1185326ed114392d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:07:48 +0900 Subject: [PATCH 02/33] libudev: use DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC() macro where applicable --- src/libudev/libudev-device-internal.h | 2 +- src/libudev/libudev-device.c | 40 +++++++++++---------------- src/libudev/libudev-enumerate.c | 28 ++++++++----------- src/libudev/libudev-hwdb.c | 29 ++++++++----------- src/libudev/libudev-monitor.c | 34 ++++++++--------------- src/libudev/libudev-queue.c | 33 +++++++--------------- src/libudev/libudev.c | 23 +++++++-------- 7 files changed, 73 insertions(+), 116 deletions(-) diff --git a/src/libudev/libudev-device-internal.h b/src/libudev/libudev-device-internal.h index 45763f2c99..974601f79f 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; diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index e6d6f70510..ce8acd59b2 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -201,7 +201,7 @@ struct udev_device *udev_device_new(struct udev *udev) { errno = ENOMEM; return NULL; } - udev_device->refcount = 1; + udev_device->n_ref = 1; udev_device->udev = udev; udev_list_init(udev, &udev_device->properties, true); udev_list_init(udev, &udev_device->tags, true); @@ -501,6 +501,20 @@ _public_ struct udev *udev_device_get_udev(struct udev_device *udev_device) 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 +523,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 +533,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: diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index e9f0f2e47e..6b0e5850bd 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; @@ -70,7 +70,7 @@ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { return NULL; } - udev_enumerate->refcount = 1; + udev_enumerate->n_ref = 1; udev_enumerate->udev = udev; udev_list_init(udev, &udev_enumerate->devices_list, false); @@ -78,6 +78,14 @@ _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev) { return TAKE_PTR(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); +} + /** * udev_enumerate_ref: * @udev_enumerate: context @@ -86,12 +94,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 +104,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..a6e7ce4b85 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -20,7 +20,7 @@ */ struct udev_hwdb { struct udev *udev; - int refcount; + unsigned n_ref; sd_hwdb *hwdb; @@ -52,7 +52,7 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { return NULL; } - hwdb->refcount = 1; + hwdb->n_ref = 1; hwdb->hwdb = TAKE_PTR(hwdb_internal); udev_list_init(udev, &hwdb->properties_list, true); @@ -60,6 +60,14 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) { 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 +76,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 +86,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: diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index fe4595930f..f93854dc45 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -38,7 +38,7 @@ */ struct udev_monitor { struct udev *udev; - int refcount; + unsigned n_ref; int sock; union sockaddr_union snl; union sockaddr_union snl_trusted_sender; @@ -87,7 +87,7 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev) { errno = ENOMEM; return NULL; } - udev_monitor->refcount = 1; + udev_monitor->n_ref = 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); @@ -432,6 +432,15 @@ int udev_monitor_disconnect(struct udev_monitor *udev_monitor) { return 0; } +static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) { + assert(udev_monitor); + + udev_monitor_disconnect(udev_monitor); + udev_list_cleanup(&udev_monitor->filter_subsystem_list); + udev_list_cleanup(&udev_monitor->filter_tag_list); + return mfree(udev_monitor); +} + /** * udev_monitor_ref: * @udev_monitor: udev monitor @@ -440,13 +449,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: @@ -458,19 +460,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: diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index c45abfd520..4c60c886e7 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; }; @@ -51,12 +51,19 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev) return NULL; } - udev_queue->refcount = 1; + udev_queue->n_ref = 1; udev_queue->udev = udev; udev_queue->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 +72,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 +82,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: diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index 8af97fe16d..1df0968780 100644 --- a/src/libudev/libudev.c +++ b/src/libudev/libudev.c @@ -29,7 +29,7 @@ * Opaque object representing the library context. */ struct udev { - int refcount; + unsigned n_ref; void (*log_fn)(struct udev *udev, int priority, const char *file, int line, const char *fn, const char *format, va_list args); @@ -82,7 +82,7 @@ _public_ struct udev *udev_new(void) { errno = ENOMEM; return NULL; } - udev->refcount = 1; + udev->n_ref = 1; return udev; } @@ -95,12 +95,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 +107,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); } From ff6f97f0cf54d30edb5b17e50f57a12351e2e904 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:13:39 +0900 Subject: [PATCH 03/33] libudev: drop outdated comments --- src/libudev/libudev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index 1df0968780..c451a616ff 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. */ /** From 2454727d5acc369f6954fc68ba6c90e41ec60027 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:14:02 +0900 Subject: [PATCH 04/33] libudev: drop unused element in udev struct --- src/libudev/libudev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index c451a616ff..f67b8fccc4 100644 --- a/src/libudev/libudev.c +++ b/src/libudev/libudev.c @@ -27,9 +27,6 @@ */ struct udev { unsigned n_ref; - void (*log_fn)(struct udev *udev, - int priority, const char *file, int line, const char *fn, - const char *format, va_list args); void *userdata; }; From 5ccb44a53f998c56699af34ff6f129d366f34fc7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:14:42 +0900 Subject: [PATCH 05/33] libudev: use structured initializer --- src/libudev/libudev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index f67b8fccc4..0c3524a209 100644 --- a/src/libudev/libudev.c +++ b/src/libudev/libudev.c @@ -71,12 +71,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->n_ref = 1; + + *udev = (struct udev) { + .n_ref = 1, + }; return udev; } From bc54df90e4eec1b5ab1596c1c758593821485676 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 28 Aug 2018 13:15:03 +0900 Subject: [PATCH 06/33] libudev: modernize code a bit --- src/libudev/libudev.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libudev/libudev.c b/src/libudev/libudev.c index 0c3524a209..4554b922e3 100644 --- a/src/libudev/libudev.c +++ b/src/libudev/libudev.c @@ -40,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; } @@ -53,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; } @@ -126,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; } From ccda7f87f5528e3fa697138b9ad334a25e45bce4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:39:46 +0900 Subject: [PATCH 07/33] libudev-queue: use structured initializer --- src/libudev/libudev-queue.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index 4c60c886e7..a62ba5ebfe 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -41,19 +41,21 @@ 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->n_ref = 1; - udev_queue->udev = udev; - udev_queue->fd = -1; + *udev_queue = (struct udev_queue) { + .udev = udev, + .n_ref = 1, + .fd = -1, + }; + return udev_queue; } From d35c0e8d534399faa252a5f44a96c35f887f8bfd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:41:22 +0900 Subject: [PATCH 08/33] libudev-queue: use assert_return() --- src/libudev/libudev-queue.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index a62ba5ebfe..e7d8ffea4c 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -94,12 +94,9 @@ DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_queue, udev_queue, udev_queue_f * * 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; } @@ -238,7 +235,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; From 2dac88a9d165f7597a4906dcc34ee62590c240da Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:42:18 +0900 Subject: [PATCH 09/33] libudev-queue: use _cleanup_ attribute and TAKE_FD() --- src/libudev/libudev-queue.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index e7d8ffea4c..99b35d7e49 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -205,8 +205,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; @@ -215,15 +216,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; } /** From 09f638ebd9f4118fa3d200b593291a19dc635523 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:43:38 +0900 Subject: [PATCH 10/33] libudev-queue: drop prototypes of nonexistent functions --- src/libudev/libudev-private.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index af24b7b423..5e18b02534 100644 --- a/src/libudev/libudev-private.h +++ b/src/libudev/libudev-private.h @@ -101,19 +101,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 From f8cdabc0ec7c22f65c2cb6a085146f3c882f8cb4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:43:59 +0900 Subject: [PATCH 11/33] libudev-queue: coding style fixes --- src/libudev/libudev-queue.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c index 99b35d7e49..832f3b3da5 100644 --- a/src/libudev/libudev-queue.c +++ b/src/libudev/libudev-queue.c @@ -108,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; } @@ -121,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; } @@ -134,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; } @@ -147,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; } @@ -164,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); } @@ -179,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); } @@ -192,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; } From b485aa58527fd024c30af528b2d56fcf76d69ad2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:55:25 +0900 Subject: [PATCH 12/33] libudev-hwdb: drop unused 'struct udev *udev' in udev_hwdb struct --- src/libudev/libudev-hwdb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index a6e7ce4b85..e253baa249 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; 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. * From 68b80b8557a020ec89e423506f7aeaced59de70a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:57:04 +0900 Subject: [PATCH 13/33] libudev-hwdb: use structured initializer --- src/libudev/libudev-hwdb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index e253baa249..7d423750b4 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -43,14 +43,16 @@ _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->n_ref = 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); From 2b19953a0da315220c00ed9a5a48bf78c9517d2c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 13:57:58 +0900 Subject: [PATCH 14/33] libudev-hwdb: use assert_return_errno() --- src/libudev/libudev-hwdb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libudev/libudev-hwdb.c b/src/libudev/libudev-hwdb.c index 7d423750b4..1b478a6c4b 100644 --- a/src/libudev/libudev-hwdb.c +++ b/src/libudev/libudev-hwdb.c @@ -104,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); From 60fdee32bdacab0b2ca0fd50c1f7a4dabf190fc0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:09:17 +0900 Subject: [PATCH 15/33] libudev-enumerate: use structured initializer --- src/libudev/libudev-enumerate.c | 38 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c index 6b0e5850bd..41318d0a8d 100644 --- a/src/libudev/libudev-enumerate.c +++ b/src/libudev/libudev-enumerate.c @@ -49,33 +49,37 @@ 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); + r = sd_device_enumerator_new(&e); + if (r < 0) { + errno = -r; + return NULL; + } + + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) { + errno = -r; + return NULL; + } + + udev_enumerate = new(struct udev_enumerate, 1); if (!udev_enumerate) { errno = ENOMEM; return NULL; } - r = sd_device_enumerator_new(&udev_enumerate->enumerator); - if (r < 0) { - errno = -r; - return NULL; - } - - r = sd_device_enumerator_allow_uninitialized(udev_enumerate->enumerator); - if (r < 0) { - errno = -r; - return NULL; - } - - udev_enumerate->n_ref = 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) { From 71074e3a101dcc9b93adde68f87ac3620802bb50 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:16:43 +0900 Subject: [PATCH 16/33] libudev-device: use structured initializer --- src/libudev/libudev-device.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index ce8acd59b2..7de7c52527 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -196,13 +196,17 @@ _public_ const char *udev_device_get_property_value(struct udev_device *udev_dev struct udev_device *udev_device_new(struct udev *udev) { struct udev_device *udev_device; - udev_device = new0(struct udev_device, 1); + udev_device = new(struct udev_device, 1); if (!udev_device) { errno = ENOMEM; return NULL; } - udev_device->n_ref = 1; - udev_device->udev = udev; + + *udev_device = (struct udev_device) { + .n_ref = 1, + .udev = udev, + }; + udev_list_init(udev, &udev_device->properties, true); udev_list_init(udev, &udev_device->tags, true); udev_list_init(udev, &udev_device->sysattrs, true); From 1b6374d285124f42606d40f36c78695c42264dd1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:30:24 +0900 Subject: [PATCH 17/33] libudev-device: use original negative errno --- src/libudev/libudev-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index 7de7c52527..6398cd2fab 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -773,7 +773,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; } From 33a03e6effb01693adf3f609760e6b34a8db659a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:31:41 +0900 Subject: [PATCH 18/33] libudev-device: fix return value of udev_device_has_tag() --- src/libudev/libudev-device.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index 6398cd2fab..29f7f0ebde 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -926,9 +926,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; } From 76387b9abb6f6b49b81adf8ef08a87cc6843dc48 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:32:05 +0900 Subject: [PATCH 19/33] libudev-device: coding style fixes --- src/libudev/libudev-device.c | 82 ++++++++++++------------------------ 1 file changed, 27 insertions(+), 55 deletions(-) diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c index 29f7f0ebde..18dbe03739 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; @@ -263,8 +257,7 @@ _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) -{ +_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) { struct udev_device *udev_device; int r; @@ -300,8 +293,7 @@ _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) -{ +_public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, const char *id) { struct udev_device *udev_device; int r; @@ -334,8 +326,7 @@ _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) -{ +_public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) { struct udev_device *udev_device; int r; @@ -367,8 +358,7 @@ _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) -{ +_public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) { struct udev_device *udev_device; int r; @@ -386,8 +376,7 @@ _public_ struct udev_device *udev_device_new_from_environment(struct udev *udev) return udev_device; } -static struct udev_device *device_new_from_parent(struct udev_device *child) -{ +static struct udev_device *device_new_from_parent(struct udev_device *child) { struct udev_device *parent; int r; @@ -428,8 +417,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) { @@ -462,8 +450,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; @@ -498,8 +485,7 @@ _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; @@ -548,8 +534,7 @@ DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_device, udev_device, udev_devic * * 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; @@ -573,8 +558,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; @@ -597,8 +581,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; @@ -621,8 +604,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; @@ -646,8 +628,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; @@ -675,8 +656,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 || @@ -707,8 +687,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 || @@ -764,8 +743,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; @@ -790,8 +768,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; @@ -816,8 +793,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, char *value) { int r; assert_return(udev_device, -EINVAL); @@ -839,8 +815,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) { @@ -870,8 +845,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); @@ -879,7 +853,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; } @@ -897,8 +870,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 || From 536cbd7fa6e1d33b5c7f968f3bc18c9aae611b51 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:43:43 +0900 Subject: [PATCH 20/33] libudev: drop a prototype of unexistent function --- src/libudev/libudev-private.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index 5e18b02534..29b0cfb2da 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); From a7e9db150b960f4344666ddc2e81ad932f367cab Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 14:44:01 +0900 Subject: [PATCH 21/33] libudev-device: drop prototypes of unexistent functions --- src/libudev/libudev-private.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index 29b0cfb2da..4361a76b42 100644 --- a/src/libudev/libudev-private.h +++ b/src/libudev/libudev-private.h @@ -37,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); @@ -45,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); From 02e7ae2fdcdc15ee129c59b859943dbefc3eb2ef Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 16:11:13 +0900 Subject: [PATCH 22/33] libudev-device: create sd_device at first in udev_device_new_from_*() --- src/libudev/libudev-device-internal.h | 2 +- src/libudev/libudev-device-private.c | 44 +++++----------- src/libudev/libudev-device.c | 74 ++++++++------------------- 3 files changed, 35 insertions(+), 85 deletions(-) diff --git a/src/libudev/libudev-device-internal.h b/src/libudev/libudev-device-internal.h index 974601f79f..73db709e93 100644 --- a/src/libudev/libudev-device-internal.h +++ b/src/libudev/libudev-device-internal.h @@ -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 18dbe03739..95ad5ced57 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -187,9 +187,11 @@ _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; + assert(device); + udev_device = new(struct udev_device, 1); if (!udev_device) { errno = ENOMEM; @@ -199,6 +201,7 @@ struct udev_device *udev_device_new(struct 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); @@ -224,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); } /** @@ -258,21 +256,16 @@ _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; + _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); } /** @@ -294,21 +287,16 @@ _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; + _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); } /** @@ -327,21 +315,16 @@ _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; + _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); } /** @@ -359,44 +342,31 @@ _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; + _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; + 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); } /** From 7f79720711111de37427aa02c0c29e6823cc882b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 16:40:47 +0900 Subject: [PATCH 23/33] libudev-monitor: use 'unsigned' instead of 'unsigned int' --- src/libudev/libudev-monitor.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index f93854dc45..9b4b3067c6 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -63,20 +63,20 @@ 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) { @@ -152,7 +152,7 @@ static void monitor_set_nl_address(struct udev_monitor *udev_monitor) { 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; + unsigned group; if (name == NULL) group = UDEV_MONITOR_NONE; @@ -233,9 +233,8 @@ _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) -{ +static inline void bpf_stmt(struct sock_filter *inss, unsigned *i, + unsigned short code, unsigned data) { struct sock_filter *ins = &inss[*i]; ins->code = code; @@ -243,8 +242,8 @@ static inline void bpf_stmt(struct sock_filter *inss, unsigned int *i, (*i)++; } -static inline void bpf_jmp(struct sock_filter *inss, unsigned int *i, - unsigned short code, unsigned int data, +static inline void bpf_jmp(struct sock_filter *inss, unsigned *i, + unsigned short code, unsigned data, unsigned short jt, unsigned short jf) { struct sock_filter *ins = &inss[*i]; @@ -269,7 +268,7 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) { struct sock_filter ins[512]; struct sock_fprog filter; - unsigned int i; + unsigned i; struct udev_list_entry *list_entry; int err; @@ -324,7 +323,7 @@ _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)); + uint32_t hash = util_string_hash32(udev_list_entry_get_name(list_entry)); /* 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)); From 3d01fa902c3804417126c2b846f671c710669ce8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 16:43:01 +0900 Subject: [PATCH 24/33] libudev-monitor: use structured initializer in bpf_*() This also drop inline attribute from the functions. --- src/libudev/libudev-monitor.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 9b4b3067c6..f83115c95c 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -233,26 +233,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 *i, - unsigned short code, unsigned 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 *i, - unsigned short code, unsigned 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, + }; } /** From be1791ad6a09d08f6234ba53e45d022e3269dffd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 13 Aug 2018 17:59:44 +0900 Subject: [PATCH 25/33] libudev-monitor: rename udev_has_devtmpfs() and move it to mount-util.c As the function itself is quite generic. --- src/basic/mount-util.c | 36 ++++++++++++++++++++++++++++++ src/basic/mount-util.h | 2 ++ src/libudev/libudev-monitor.c | 42 +---------------------------------- 3 files changed, 39 insertions(+), 41 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/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index f83115c95c..5ca035d43c 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -94,46 +94,6 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev) { 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) { union sockaddr_union snl; socklen_t addrlen; @@ -169,7 +129,7 @@ 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)) { + if (access("/run/udev/control", F_OK) < 0 && dev_is_devtmpfs() <= 0) { log_debug("the udev service seems not to be active, disable the monitor"); group = UDEV_MONITOR_NONE; } else From a062a72f1b2e3c14d1c58afed4dfd8c268ac744d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 16:47:30 +0900 Subject: [PATCH 26/33] libudev-monitor: rename monitor_set_nl_address() and make it return negative errno --- src/libudev/libudev-monitor.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 5ca035d43c..0df112d245 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -94,20 +94,20 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev) { return udev_monitor; } -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) { @@ -154,7 +154,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c } else { udev_monitor->bound = true; udev_monitor->sock = fd; - monitor_set_nl_address(udev_monitor); + udev_monitor_set_nl_address(udev_monitor); } udev_monitor->snl.nl.nl_family = AF_NETLINK; @@ -349,7 +349,7 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor) } if (err >= 0) - monitor_set_nl_address(udev_monitor); + udev_monitor_set_nl_address(udev_monitor); else return log_debug_errno(errno, "bind failed: %m"); From 5e1e4c247b5cacfa52eb44f76cfbeac16f30e54a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 16:51:58 +0900 Subject: [PATCH 27/33] libudev-monitor: use structured initializer --- src/libudev/libudev-monitor.c | 85 ++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 0df112d245..8ea4a2947e 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -17,12 +17,13 @@ #include "fd-util.h" #include "fileio.h" #include "format-util.h" -#include "libudev-private.h" #include "libudev-device-internal.h" +#include "libudev-private.h" #include "missing.h" #include "mount-util.h" #include "socket-util.h" #include "string-util.h" +#include "strv.h" /** * SECTION:libudev-monitor @@ -79,21 +80,6 @@ struct udev_monitor_netlink_header { 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->n_ref = 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; -} - static int udev_monitor_set_nl_address(struct udev_monitor *udev_monitor) { union sockaddr_union snl; socklen_t addrlen; @@ -111,10 +97,14 @@ static int udev_monitor_set_nl_address(struct udev_monitor *udev_monitor) { } struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd) { - struct udev_monitor *udev_monitor; + _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")) { /* @@ -130,41 +120,54 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c * will not receive any messages. */ if (access("/run/udev/control", F_OK) < 0 && dev_is_devtmpfs() <= 0) { - log_debug("the udev service seems not to be active, disable the monitor"); + 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; - udev_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; + } - /* default destination for sending */ - udev_monitor->snl_destination.nl.nl_family = AF_NETLINK; - udev_monitor->snl_destination.nl.nl_groups = UDEV_MONITOR_UDEV; + *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, - return udev_monitor; + /* default destination for sending */ + .snl_destination.nl.nl_family = AF_NETLINK, + .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; + } + } + + udev_list_init(udev, &udev_monitor->filter_subsystem_list, false); + udev_list_init(udev, &udev_monitor->filter_tag_list, true); + + return TAKE_PTR(udev_monitor); } /** From 759d9f3f8d07af2940bb3783acc3985ee47adfa5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 17:00:40 +0900 Subject: [PATCH 28/33] libudev-monitor: use Hashmap or Set to store filters --- src/libudev/libudev-monitor.c | 190 ++++++++++++++++++++-------------- 1 file changed, 114 insertions(+), 76 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 8ea4a2947e..02ee1f4969 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -17,10 +17,12 @@ #include "fd-util.h" #include "fileio.h" #include "format-util.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" @@ -45,8 +47,8 @@ struct udev_monitor { 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; }; @@ -164,9 +166,6 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c } } - udev_list_init(udev, &udev_monitor->filter_subsystem_list, false); - udev_list_init(udev, &udev_monitor->filter_tag_list, true); - return TAKE_PTR(udev_monitor); } @@ -224,21 +223,19 @@ static void bpf_jmp(struct sock_filter *ins, unsigned *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 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) + assert_return(udev_monitor, -EINVAL); + + if (hashmap_isempty(udev_monitor->subsystem_filter) && + set_isempty(udev_monitor->tag_filter)) return 0; - memzero(ins, sizeof(ins)); - i = 0; - /* load magic in A */ bpf_stmt(ins, &i, BPF_LD|BPF_W|BPF_ABS, offsetof(struct udev_monitor_netlink_header, magic)); /* jump if magic matches */ @@ -246,17 +243,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; @@ -281,23 +273,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)) { - uint32_t 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); } @@ -316,11 +308,14 @@ _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) @@ -395,8 +390,8 @@ static struct udev_monitor *udev_monitor_free(struct udev_monitor *udev_monitor) assert(udev_monitor); udev_monitor_disconnect(udev_monitor); - udev_list_cleanup(&udev_monitor->filter_subsystem_list); - udev_list_cleanup(&udev_monitor->filter_tag_list); + hashmap_free_free_free(udev_monitor->subsystem_filter); + set_free_free(udev_monitor->tag_filter); return mfree(udev_monitor); } @@ -451,41 +446,49 @@ _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) 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; - if (udev_list_get_entry(&udev_monitor->filter_subsystem_list) == NULL) + assert_return(udev_monitor, -EINVAL); + assert_return(device, -EINVAL); + + 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; } @@ -630,7 +633,7 @@ retry: udev_device_set_is_initialized(udev_device); /* skip device, if it does not pass the current filter */ - if (!passes_filter(udev_monitor, udev_device)) { + if (!passes_filter(udev_monitor, udev_device->device)) { struct pollfd pfd[1]; int rc; @@ -749,14 +752,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; } @@ -772,14 +793,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; } @@ -791,11 +826,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; From 23c457a7fba0b71f7873675f04d3338d309a15cf Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 17:04:10 +0900 Subject: [PATCH 29/33] libudev-monitor: re-implement udev_monitor_receive_sd_device() --- src/libudev/libudev-monitor.c | 289 +++++++++++++++++----------------- 1 file changed, 141 insertions(+), 148 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 02ee1f4969..2bd820e92d 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -14,6 +14,8 @@ #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" @@ -492,6 +494,137 @@ tag: return 0; } +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; + 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; + + assert(ret); + + buflen = recvmsg(udev_monitor->sock, &smsg, 0); + if (buflen < 0) { + if (errno != EINTR) + log_debug_errno(errno, "Failed to receive message: %m"); + return -errno; + } + + if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) + return log_debug_errno(EINVAL, "Invalid message length."); + + 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) + return log_debug_errno(EAGAIN, "Unicast netlink message ignored."); + + } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) { + 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 || 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) + return log_debug_errno(EAGAIN, "Sender uid="UID_FMT", message ignored.", cred->uid); + + if (streq(buf.raw, "libudev")) { + /* udev message needs proper version magic */ + 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) + return log_debug_errno(EAGAIN, "Invalid message length"); + + /* check message header */ + if (!strstr(buf.raw, "@/")) + return log_debug_errno(EAGAIN, "Invalid message header"); + } + + 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) + device_set_is_initialized(device); + + /* skip device, if it does not pass the current filter */ + if (passes_filter(udev_monitor, device) <= 0) + return 0; + + *ret = TAKE_PTR(device); + return 1; +} + +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; + + assert(udev_monitor); + assert(ret); + + 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; + } + } +} + /** * udev_monitor_receive_device: * @udev_monitor: udev monitor @@ -511,159 +644,19 @@ tag: * * 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; - union { - struct udev_monitor_netlink_header nlh; - char raw[8192]; - } buf; - ssize_t buflen; - ssize_t bufpos; - bool is_initialized = false; +_public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; + 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_return(udev_monitor, NULL); - buflen = recvmsg(udev_monitor->sock, &smsg, 0); - if (buflen < 0) { - if (errno != EINTR) - log_debug("unable to receive message"); + r = udev_monitor_receive_sd_device(udev_monitor, &device); + if (r < 0) { + errno = -r; return NULL; } - if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) { - log_debug("invalid message length"); - errno = EINVAL; - return NULL; - } - - if (snl.nl.nl_groups == 0) { - /* 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; - } - } 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; - } - } - - cmsg = CMSG_FIRSTHDR(&smsg); - if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - log_debug("no sender credentials received, message ignored"); - errno = EAGAIN; - return NULL; - } - - cred = (struct ucred *)CMSG_DATA(cmsg); - if (cred->uid != 0) { - log_debug("sender uid="UID_FMT", message ignored", cred->uid); - errno = EAGAIN; - return NULL; - } - - if (memcmp(buf.raw, "libudev", 8) == 0) { - /* 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; - } - - 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; - } - - /* check message header */ - if (strstr(buf.raw, "@/") == NULL) { - log_debug("unrecognized message header"); - errno = EAGAIN; - return NULL; - } - } - - 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; - } - - if (is_initialized) - udev_device_set_is_initialized(udev_device); - - /* skip device, if it does not pass the current filter */ - if (!passes_filter(udev_monitor, udev_device->device)) { - struct pollfd pfd[1]; - int rc; - - udev_device_unref(udev_device); - - /* 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; - - errno = EAGAIN; - return NULL; - } - - return udev_device; -} - -int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) { - _cleanup_(udev_device_unrefp) struct udev_device *udev_device = NULL; - - assert(ret); - - udev_device = udev_monitor_receive_device(udev_monitor); - if (!udev_device) - return -errno; - - *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, From a9808d844549fe4563e1ce373a75ebd17e35b72a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 17:05:22 +0900 Subject: [PATCH 30/33] libudev-monitor: introduce udev_monitor_send_sd_device() And use it in udev_monitor_send_device(). --- src/libudev/libudev-monitor.c | 62 ++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 2bd820e92d..c733340c5f 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -659,11 +659,11 @@ _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *ud 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), @@ -676,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); @@ -705,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. @@ -714,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 From e38242b03ab740ed62469cf7a748ebb580270ac7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 17:10:27 +0900 Subject: [PATCH 31/33] libudev-monitor: add missing error checks in udev_monitor_enable_receiving() --- src/libudev/libudev-monitor.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index c733340c5f..257621e050 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -334,29 +334,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) - udev_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; } From 7f9e03952ac4c8050925f6093dded44e57dbbc7c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 24 Aug 2018 17:12:04 +0900 Subject: [PATCH 32/33] libudev-monitor: use assert_return() in many places --- src/libudev/libudev-monitor.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 257621e050..ea44308351 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -320,8 +320,10 @@ _public_ int udev_monitor_filter_update(struct udev_monitor *udev_monitor) { 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; } @@ -372,10 +374,9 @@ _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; @@ -427,10 +428,9 @@ DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(struct udev_monitor, udev_monitor, udev_mon * * 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; } @@ -442,10 +442,9 @@ _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; } From 8aae9a66fae7aa7f1f7563f0bf14f9ab3de916bd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 11 Sep 2018 12:42:18 +0900 Subject: [PATCH 33/33] sd-device,libudev: make an argument for *_set_sysattr_value() const --- TODO | 2 -- src/libsystemd/sd-device/sd-device.c | 2 +- src/libudev/libudev-device.c | 2 +- src/libudev/libudev.h | 2 +- src/systemd/sd-device.h | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 65dc51b225..4dcd102ec5 100644 --- a/TODO +++ b/TODO @@ -438,8 +438,6 @@ Features: * hostnamectl: show root image uuid -* sysfs set api in libudev is not const - * Find a solution for SMACK capabilities stuff: http://lists.freedesktop.org/archives/systemd-devel/2014-December/026188.html 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.c b/src/libudev/libudev-device.c index 95ad5ced57..2cd5b48fea 100644 --- a/src/libudev/libudev-device.c +++ b/src/libudev/libudev-device.c @@ -763,7 +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); 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 */