Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package umockdev for openSUSE:Factory checked in at 2022-02-01 14:02:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/umockdev (Old) and /work/SRC/openSUSE:Factory/.umockdev.new.1898 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "umockdev" Tue Feb 1 14:02:41 2022 rev:8 rq:949863 version:0.17.5 Changes: -------- --- /work/SRC/openSUSE:Factory/umockdev/umockdev.changes 2021-12-30 15:56:00.140681458 +0100 +++ /work/SRC/openSUSE:Factory/.umockdev.new.1898/umockdev.changes 2022-02-01 14:03:08.307998117 +0100 @@ -1,0 +2,21 @@ +Sat Jan 29 09:31:58 UTC 2022 - Dominique Leuenberger <dims...@opensuse.org> + +- BuildRequire pkgconfig(udev) instead of udev: this allows OBS to + properly shotcut through the -mini flavors. + +------------------------------------------------------------------- +Wed Jan 19 23:28:55 UTC 2022 - Atri Bhattacharya <badshah...@gmail.com> + +- Update to version 0.17.5: + * Relax overzealous stat nlink unit test. +- Changes from versions 0.17.2 through to 0.17.4: + * Include udev properties in emulated netlink messages, to work + with recent libudev (gh#martinpitt/umockdev#165). + * tests: Work around broken HIDIOCGRDESCSIZE ioctl on big-endian + architectures. + * preload: Wrap statx() and fstatat(), to fix ls and other tools + on recent glibc versions (gh#martinpitt/umockdev#160). +- Enable tests in a %check section; add BuildRequires: udev, + required for tests. + +------------------------------------------------------------------- Old: ---- umockdev-0.17.1.tar.xz New: ---- umockdev-0.17.5.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ umockdev.spec ++++++ --- /var/tmp/diff_new_pack.jUaSrP/_old 2022-02-01 14:03:08.859994332 +0100 +++ /var/tmp/diff_new_pack.jUaSrP/_new 2022-02-01 14:03:08.863994305 +0100 @@ -1,7 +1,7 @@ # # spec file for package umockdev # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define shlib libumockdev0 %define shlibpre libumockdev-preload0 Name: umockdev -Version: 0.17.1 +Version: 0.17.5 Release: 0 Summary: Mock hardware devices for creating unit tests and bug reporting License: LGPL-2.1-or-later @@ -38,6 +38,8 @@ # BuildRequires: pkgconfig(gudev-1.0) BuildRequires: pkgconfig(libpcap) BuildRequires: pkgconfig(libudev) +# For tests +BuildRequires: pkgconfig(udev) %description umockdev mocks Linux devices for creating integration tests for hardware @@ -97,6 +99,9 @@ %install %meson_install +%check +%meson_test + %post -n %{shlib} -p /sbin/ldconfig %postun -n %{shlib} -p /sbin/ldconfig %post -n %{shlibpre} -p /sbin/ldconfig ++++++ umockdev-0.17.1.tar.xz -> umockdev-0.17.5.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/NEWS new/umockdev-0.17.5/NEWS --- old/umockdev-0.17.1/NEWS 2021-12-14 07:27:23.384868000 +0100 +++ new/umockdev-0.17.5/NEWS 2022-01-18 11:19:51.448499200 +0100 @@ -1,3 +1,17 @@ +## [0.17.5] - 2022-01-18 +- Relax overzealous stat nlink unit test + +## [0.17.4] - 2022-01-18 +- Include udev properties in emulated netlink messages, to work with recent + libudev (#165) + +## [0.17.3] - 2022-01-11 +- tests: Work around broken HIDIOCGRDESCSIZE ioctl on big-endian architectures + +## [0.17.2] - 2022-01-10 +- preload: Wrap statx() and fstatat(), to fix `ls` and other tools on + recent glibc versions. (#160) + ## [0.17.1] - 2021-12-14 - Fix /sys/dev/* symlinks; regression from 0.15.3 (#155) @@ -510,7 +524,7 @@ - Fix building with automake 1.11.3 and Vala 0.16. - Generalize ioctl recording and emulation for ioctls with simple structs, i. e. no pointer fields. This makes it much easier to add more ioctls in the - future. + future. - Store return values of ioctls in records, as they are not always 0 (like EVIOCGBIT) - Add support for ioctl ranges (like EVIOCGABS) and ioctls with variable length diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/meson.build new/umockdev-0.17.5/meson.build --- old/umockdev-0.17.1/meson.build 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/meson.build 2022-01-18 11:19:51.456499300 +0100 @@ -22,6 +22,8 @@ '-Werror=uninitialized', # experimental: first check this on all Debian architectures '-Wcast-align', + # older gcc versions don't know about all the -Wanalyzer errors which we want to quiesce + '-Wno-error=pragmas', language: 'c') # let's not clutter the code with too many #ifdefs @@ -37,6 +39,11 @@ conf.set('PACKAGE_NAME', meson.project_name()) conf.set_quoted('VERSION', meson.project_version()) +# glibc versions somewhere between 2.28 and 2.34 +if cc.has_function('__fxstatat', prefix: '#include <sys/stat.h>') + add_project_arguments('-DHAVE_FXSTATAT', language: 'c') +endif + # # dependencies # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/ioctl_tree.c new/umockdev-0.17.5/src/ioctl_tree.c --- old/umockdev-0.17.1/src/ioctl_tree.c 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/ioctl_tree.c 2022-01-18 11:19:51.456499300 +0100 @@ -19,6 +19,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <stdint.h> #include <assert.h> #include <errno.h> #include <linux/ioctl.h> @@ -338,9 +339,16 @@ ioctl_node_list_append(ioctl_node_list * list, ioctl_tree * element) { if (list->n == list->capacity) { + assert(list->capacity < SIZE_MAX / 2); list->capacity *= 2; - list->items = realloc(list->items, list->capacity * sizeof(ioctl_tree *)); + /* HACK: -fanalyzer incorrectly treats this as memory leak */ +#pragma GCC diagnostic push +#if !defined(__clang__) +#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" +#endif + list->items = reallocarray(list->items, list->capacity, sizeof(ioctl_tree *)); assert(list->items != NULL); +#pragma GCC diagnostic pop } list->items[list->n++] = element; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/ioctl_tree.h new/umockdev-0.17.5/src/ioctl_tree.h --- old/umockdev-0.17.1/src/ioctl_tree.h 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/ioctl_tree.h 2022-01-18 11:19:51.456499300 +0100 @@ -46,7 +46,7 @@ typedef struct { ssize_t n; - ssize_t capacity; + size_t capacity; ioctl_tree **items; } ioctl_node_list; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/libumockdev-preload.c new/umockdev-0.17.5/src/libumockdev-preload.c --- old/umockdev-0.17.1/src/libumockdev-preload.c 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/libumockdev-preload.c 2022-01-18 11:19:51.456499300 +0100 @@ -35,6 +35,7 @@ #include <dlfcn.h> #include <limits.h> #include <stdarg.h> +#include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -195,13 +196,13 @@ return buf; } -static dev_t -get_rdev(const char *nodename) +static bool +get_rdev_maj_min(const char *nodename, uint32_t *major, uint32_t *minor) { static char buf[PATH_MAX]; static char link[PATH_MAX]; int name_offset; - int major, minor, orig_errno; + int orig_errno; name_offset = snprintf(buf, sizeof(buf), "%s/dev/.node/", getenv("UMOCKDEV_DIR")); buf[sizeof(buf) - 1] = 0; @@ -217,15 +218,26 @@ if (readlink(buf, link, sizeof(link)) < 0) { DBG(DBG_PATH, "get_rdev %s: cannot read link %s: %m\n", nodename, buf); errno = orig_errno; - return (dev_t) 0; + return false; } errno = orig_errno; - if (sscanf(link, "%i:%i", &major, &minor) != 2) { + if (sscanf(link, "%u:%u", major, minor) != 2) { DBG(DBG_PATH, "get_rdev %s: cannot decode major/minor from '%s'\n", nodename, link); - return (dev_t) 0; + return false; } - DBG(DBG_PATH, "get_rdev %s: got major/minor %i:%i\n", nodename, major, minor); - return makedev(major, minor); + DBG(DBG_PATH, "get_rdev %s: got major/minor %u:%u\n", nodename, *major, *minor); + return true; +} + +static dev_t +get_rdev(const char *nodename) +{ + unsigned major, minor; + + if (get_rdev_maj_min(nodename, &major, &minor)) + return makedev(major, minor); + else + return (dev_t) 0; } static dev_t @@ -1164,6 +1176,20 @@ return r; \ } +#define STAT_ADJUST_MODE \ + if (ret == 0 && p != path && strncmp(path, "/dev/", 5) == 0 \ + && is_emulated_device(p, st->st_mode)) { \ + st->st_mode &= ~S_IFREG; \ + if (st->st_mode & S_ISVTX) { \ + st->st_mode = S_IFBLK | (st->st_mode & ~S_IFMT); \ + DBG(DBG_PATH, " %s is an emulated block device\n", path); \ + } else { \ + st->st_mode = S_IFCHR | (st->st_mode & ~S_IFMT); \ + DBG(DBG_PATH, " %s is an emulated char device\n", path); \ + } \ + st->st_rdev = get_rdev(path + 5); \ + } \ + /* wrapper template for stat family; note that we abuse the sticky bit in * the emulated /dev to indicate a block device (the sticky bit has no * real functionality for device nodes) */ @@ -1182,18 +1208,27 @@ DBG(DBG_PATH, "testbed wrapped " #prefix "stat" #suffix "(%s) -> %s\n", path, p); \ ret = _ ## prefix ## stat ## suffix(p, st); \ TRAP_PATH_UNLOCK; \ - if (ret == 0 && p != path && strncmp(path, "/dev/", 5) == 0 \ - && is_emulated_device(p, st->st_mode)) { \ - st->st_mode &= ~S_IFREG; \ - if (st->st_mode & S_ISVTX) { \ - st->st_mode &= ~S_ISVTX; st->st_mode |= S_IFBLK; \ - DBG(DBG_PATH, " %s is an emulated block device\n", path); \ - } else { \ - st->st_mode |= S_IFCHR; \ - DBG(DBG_PATH, " %s is an emulated char device\n", path); \ - } \ - st->st_rdev = get_rdev(path + 5); \ + STAT_ADJUST_MODE; \ + return ret; \ +} + +/* wrapper template for fstatat family */ +#define WRAP_FSTATAT(prefix, suffix) \ +int prefix ## fstatat ## suffix (int dirfd, const char *path, struct stat ## suffix *st, int flags) \ +{ \ + const char *p; \ + libc_func(prefix ## fstatat ## suffix, int, int, const char*, struct stat ## suffix *, int); \ + int ret; \ + TRAP_PATH_LOCK; \ + p = trap_path(path); \ + if (p == NULL) { \ + TRAP_PATH_UNLOCK; \ + return -1; \ } \ + DBG(DBG_PATH, "testbed wrapped " #prefix "fstatat" #suffix "(%s) -> %s\n", path, p); \ + ret = _ ## prefix ## fstatat ## suffix(dirfd, p, st, flags); \ + TRAP_PATH_UNLOCK; \ + STAT_ADJUST_MODE; \ return ret; \ } @@ -1218,21 +1253,31 @@ DBG(DBG_PATH, "testbed wrapped " #prefix "stat" #suffix "(%s) -> %s\n", path, p); \ ret = _ ## prefix ## stat ## suffix(ver, p, st); \ TRAP_PATH_UNLOCK; \ - if (ret == 0 && p != path && strncmp(path, "/dev/", 5) == 0 \ - && is_emulated_device(p, st->st_mode)) { \ - st->st_mode &= ~S_IFREG; \ - if (st->st_mode & S_ISVTX) { \ - st->st_mode &= ~S_ISVTX; st->st_mode |= S_IFBLK; \ - DBG(DBG_PATH, " %s is an emulated block device\n", path); \ - } else { \ - st->st_mode |= S_IFCHR; \ - DBG(DBG_PATH, " %s is an emulated char device\n", path); \ - } \ - st->st_rdev = get_rdev(path + 5); \ + STAT_ADJUST_MODE; \ + return ret; \ +} + +/* wrapper template for __fxstatat family */ +#define WRAP_VERFSTATAT(prefix, suffix) \ +int prefix ## fxstatat ## suffix (int ver, int dirfd, const char *path, struct stat ## suffix *st, int flags) \ +{ \ + const char *p; \ + libc_func(prefix ## fxstatat ## suffix, int, int, int, const char*, struct stat ## suffix *, int); \ + int ret; \ + TRAP_PATH_LOCK; \ + p = trap_path(path); \ + if (p == NULL) { \ + TRAP_PATH_UNLOCK; \ + return -1; \ } \ + DBG(DBG_PATH, "testbed wrapped " #prefix "fxstatat" #suffix "(%s) -> %s\n", path, p); \ + ret = _ ## prefix ## fxstatat ## suffix(ver, dirfd, p, st, flags); \ + TRAP_PATH_UNLOCK; \ + STAT_ADJUST_MODE; \ return ret; \ } + /* wrapper template for open family */ #define WRAP_OPEN(prefix, suffix) \ int prefix ## open ## suffix (const char *path, int flags, ...) \ @@ -1319,10 +1364,12 @@ WRAP_2ARGS(int, -1, access, int); WRAP_STAT(,); WRAP_STAT(l,); +WRAP_FSTATAT(,); #ifdef __GLIBC__ WRAP_STAT(,64); WRAP_STAT(l,64); +WRAP_FSTATAT(,64); WRAP_FOPEN(,64); #endif @@ -1336,6 +1383,48 @@ WRAP_VERSTAT(__x, 64); WRAP_VERSTAT(__lx,); WRAP_VERSTAT(__lx, 64); + +#ifdef HAVE_FXSTATAT +WRAP_VERFSTATAT(__,); +WRAP_VERFSTATAT(__,64); +#endif + +int statx(int dirfd, const char *pathname, int flags, unsigned mask, struct statx * stx) +{ + const char *p; + libc_func(statx, int, int, const char *, int, unsigned, struct statx *); + int r; + + TRAP_PATH_LOCK; + p = trap_path(pathname); + DBG(DBG_PATH, "testbed wrapped statx (%s) -> %s\n", pathname, p ?: "NULL"); + if (p == NULL) + r = -1; + else + r = _statx(dirfd, p, flags, mask, stx); + TRAP_PATH_UNLOCK; + + if (r == 0 && p != pathname && strncmp(pathname, "/dev/", 5) == 0 + && is_emulated_device(p, stx->stx_mode)) { + if (stx->stx_mode & S_ISVTX) { + stx->stx_mode = S_IFBLK | (stx->stx_mode & ~S_IFMT); + DBG(DBG_PATH, " %s is an emulated block device (statx)\n", pathname); + } else { + stx->stx_mode = S_IFCHR | (stx->stx_mode & ~S_IFMT); + DBG(DBG_PATH, " %s is an emulated char device (statx)\n", pathname); + } + unsigned maj, min; + if (get_rdev_maj_min(pathname + 5, &maj, &min)) { + stx->stx_rdev_major = maj; + stx->stx_rdev_minor = min; + } else { + stx->stx_rdev_major = stx->stx_rdev_minor = 0; + } + + } + return r; +} + #endif int __open_2(const char *path, int flags); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/uevent_sender.c new/umockdev-0.17.5/src/uevent_sender.c --- old/umockdev-0.17.1/src/uevent_sender.c 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/uevent_sender.c 2022-01-18 11:19:51.456499300 +0100 @@ -199,29 +199,35 @@ return h; } -static ssize_t -append_property(char *array, size_t size, ssize_t offset, const char *name, const char *value) +static size_t +append_property(char *array, size_t size, size_t offset, const char *name, const char *value) { int r; assert(offset < size); r = snprintf(array + offset, size - offset, "%s%s", name, value); - // include the NUL terminator in the string length, as we need to keep it as a separator between keys - ++r; + if (r < 0) { + fprintf(stderr, "ERROR: snprintf failed"); + abort(); + } if (r + offset >= size) { fprintf(stderr, "ERROR: uevent_sender_send: Property buffer overflow\n"); abort(); - } + } - return r; + /* this is already true as snprintf always writes the NUL, but -fanalyzer complains about use-of-uninitialized-value */ + array[offset + r] = '\0'; + + /* include the NUL terminator in the string length, as we need to keep it as a separator between keys */ + return r + 1; } -/* this mirrors the code from systemd/src/libudev/libudev-monitor.c, - * udev_monitor_send_device() */ +/* this mirrors the code from systemd/src/libsystemd/sd-device/device-monitor.c, + * device_monitor_send_device() */ void -uevent_sender_send(uevent_sender * sender, const char *devpath, const char *action) +uevent_sender_send(uevent_sender * sender, const char *devpath, const char *action, const char *properties) { - char props[1024]; - ssize_t count; + char buffer[1024]; + size_t buffer_len = 0; struct msghdr smsg; struct iovec iov[2]; const char *subsystem; @@ -245,16 +251,29 @@ devtype = udev_device_get_devtype(device); /* build NUL-terminated property array */ - count = 0; - count += append_property(props, sizeof (props), count, "ACTION=", action); - count += append_property(props, sizeof (props), count, "DEVPATH=", udev_device_get_devpath(device)); - count += append_property(props, sizeof (props), count, "SUBSYSTEM=", subsystem); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "ACTION=", action); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "DEVPATH=", udev_device_get_devpath(device)); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "SUBSYSTEM=", subsystem); snprintf(seqnumstr, sizeof(seqnumstr), "%llu", seqnum++); - count += append_property(props, sizeof (props), count, "SEQNUM=", seqnumstr); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "SEQNUM=", seqnumstr); if (devname) - count += append_property(props, sizeof (props), count, "DEVNAME=", devname); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "DEVNAME=", devname); if (devtype) - count += append_property(props, sizeof (props), count, "DEVTYPE=", devtype); + buffer_len += append_property(buffer, sizeof buffer, buffer_len, "DEVTYPE=", devtype); + + /* append udevd (userland) properties, replace \n with \0 */ + /* FIXME: more sensible API */ + size_t properties_len = properties ? strlen(properties) : 0; + if (properties_len > 0) { + size_t prop_ofs = buffer_len; + buffer_len += append_property(buffer, sizeof buffer, buffer_len, properties, ""); + for (size_t i = prop_ofs; i < buffer_len - 1; ++i) + if (buffer[i] == '\n') + buffer[i] = '\0'; + /* avoid empty property at the end from final line break */ + if (properties[strlen(properties) - 1] == '\n') + --buffer_len; + } /* add versioned header */ memset(&nlh, 0x00, sizeof(struct udev_monitor_netlink_header)); @@ -275,9 +294,9 @@ /* add properties list */ nlh.properties_off = iov[0].iov_len; - nlh.properties_len = count; - iov[1].iov_base = props; - iov[1].iov_len = count; + nlh.properties_len = buffer_len; + iov[1].iov_base = buffer; + iov[1].iov_len = buffer_len; /* send message */ memset(&smsg, 0x00, sizeof(struct msghdr)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/uevent_sender.h new/umockdev-0.17.5/src/uevent_sender.h --- old/umockdev-0.17.1/src/uevent_sender.h 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/uevent_sender.h 2022-01-18 11:19:51.456499300 +0100 @@ -23,6 +23,6 @@ uevent_sender *uevent_sender_open(const char *rootpath); void uevent_sender_close(uevent_sender * sender); -void uevent_sender_send(uevent_sender * sender, const char *devpath, const char *action); +void uevent_sender_send(uevent_sender * sender, const char *devpath, const char *action, const char *properties); #endif /* __UEVENT_SENDER_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/uevent_sender.vapi new/umockdev-0.17.5/src/uevent_sender.vapi --- old/umockdev-0.17.1/src/uevent_sender.vapi 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/uevent_sender.vapi 2022-01-18 11:19:51.456499300 +0100 @@ -6,6 +6,6 @@ public class sender { [CCode (cname="uevent_sender_open")] public sender (string rootpath); - public void send (string devpath, string action); + public void send (string devpath, string action, string properties); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/umockdev-spi.vala new/umockdev-0.17.5/src/umockdev-spi.vala --- old/umockdev-0.17.1/src/umockdev-spi.vala 2021-12-14 07:27:23.396868000 +0100 +++ new/umockdev-0.17.5/src/umockdev-spi.vala 2022-01-18 11:19:51.456499300 +0100 @@ -74,11 +74,7 @@ internal long iter_ioctl_vector(ulong count, IoctlData data, bool for_recording) { long transferred = 0; -#if G_BYTE_ORDER != G_LITTLE_ENDIAN - // This only works on little endian or 64bit. - assert(sizeof(void*) == sizeof(uint64)); -#endif - + // This only works on 64bit machines for (long i = 0; i < count; i++) { unowned IoctlData tx = null, rx = null; Ioctl.spi_ioc_transfer *transfer = &((Ioctl.spi_ioc_transfer[]) data.data)[i]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/src/umockdev.vala new/umockdev-0.17.5/src/umockdev.vala --- old/umockdev-0.17.1/src/umockdev.vala 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/src/umockdev.vala 2022-01-18 11:19:51.460499300 +0100 @@ -754,7 +754,15 @@ assert(this.ev_sender != null); } debug("umockdev_testbed_uevent: sending uevent %s for device %s", action, devpath); - this.ev_sender.send(devpath, action); + + var uevent_path = Path.build_filename(this.root_dir, devpath, "uevent"); + var properties = ""; + try { + FileUtils.get_contents(uevent_path, out properties); + } catch (FileError e) { + debug("uevent: devpath %s has no uevent file: %s", devpath, e.message); + } + this.ev_sender.send(devpath, action, properties); } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/tests/run-dnf new/umockdev-0.17.5/tests/run-dnf --- old/umockdev-0.17.1/tests/run-dnf 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/tests/run-dnf 2022-01-18 11:19:51.460499300 +0100 @@ -38,7 +38,8 @@ su -s /bin/sh - guest << EOG set -eux cd /source -CFLAGS="-fanalyzer" meson setup /tmp/dbg --buildtype debug --prefix /usr -Dgtk_doc=\${gtk_doc} -Db_coverage=\$coverage --werror + +CFLAGS="\$(grep -q rawhide /etc/os-release && echo -fanalyzer)" meson setup /tmp/dbg --buildtype debug --prefix /usr -Dgtk_doc=\${gtk_doc} -Db_coverage=\$coverage --werror cd /tmp/dbg DESTDIR=/tmp/inst meson install meson test -v --num-processes=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/tests/run-nix new/umockdev-0.17.5/tests/run-nix --- old/umockdev-0.17.1/tests/run-nix 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/tests/run-nix 2022-01-18 11:19:51.460499300 +0100 @@ -12,7 +12,10 @@ # avoid meson exit code 125; https://github.com/containers/podman/issues/11540 trap '[ \$? -eq 0 ] || exit 1' EXIT -sed -i '/sandbox/ s/false/true/' /etc/nix/nix.conf +set -eu + +CONF="\$(cat /etc/nix/nix.conf)" +echo "\${CONF/sandbox = false/sandbox = true}" > /etc/nix/nix.conf cat <<EOG > /tmp/default.nix let pkgs = (import (builtins.fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/master.tar.gz"; }) {}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/tests/test-umockdev-vala.vala new/umockdev-0.17.5/tests/test-umockdev-vala.vala --- old/umockdev-0.17.1/tests/test-umockdev-vala.vala 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/tests/test-umockdev-vala.vala 2022-01-18 11:19:51.460499300 +0100 @@ -705,8 +705,8 @@ int i = 0; assert_cmpint (Posix.ioctl (fd, Ioctl.HIDIOCGRDESCSIZE, ref i), CompareOperator.EQ, 0); assert_cmpint (Posix.errno, CompareOperator.EQ, 0); - // HACK: This actually works fine on real s390x (big endian), but fails in emulated QEMU (such as COPR) - if (Environment.get_variable ("RPM_ARCH") != "s390x") + // HACK: This is broken on big-endian machines like s390x and ppc64, it is 0x22000000 there + if (BYTE_ORDER == ByteOrder.LITTLE_ENDIAN) assert_cmpint (i, CompareOperator.EQ, 34); Ioctl.hidraw_report_descriptor desc = { 34, }; assert_cmpint (Posix.ioctl (fd, Ioctl.HIDIOCGRDESC, ref desc), CompareOperator.EQ, 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/tests/test-umockdev.c new/umockdev-0.17.5/tests/test-umockdev.c --- old/umockdev-0.17.1/tests/test-umockdev.c 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/tests/test-umockdev.c 2022-01-18 11:19:51.460499300 +0100 @@ -48,6 +48,12 @@ #define UNUSED __attribute__ ((unused)) #define UNUSED_DATA UNUSED gconstpointer data +/* avoid leak reports inside assertions; leaking stuff on assertion failures does not matter in tests */ +#if !defined(__clang__) +#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" +#pragma GCC diagnostic ignored "-Wanalyzer-file-leak" +#endif + static gboolean has_real_sysfs; static int slow_testbed_factor = 1; @@ -118,7 +124,7 @@ enumerate = udev_enumerate_new(udev); g_assert(enumerate); - + // NB: using libudev here instead of GUdev so that we can check the return // value of udev_enumerate_scan_devices(). // https://github.com/martinpitt/umockdev/issues/144 @@ -571,40 +577,6 @@ g_object_unref(device); } -struct event_counter { - unsigned add; - unsigned remove; - unsigned change; - gchar last_device[1024]; -}; - -static void -on_uevent(UNUSED GUdevClient *client, const gchar *action, GUdevDevice *device, gpointer user_data) -{ - struct event_counter *counter = (struct event_counter *)user_data; - - g_debug("on_uevent action %s device %s", action, g_udev_device_get_sysfs_path(device)); - - if (strcmp(action, "add") == 0) - counter->add++; - else if (strcmp(action, "remove") == 0) - counter->remove++; - else if (strcmp(action, "change") == 0) - counter->change++; - else - g_assert_not_reached(); - - strncpy(counter->last_device, g_udev_device_get_sysfs_path(device), sizeof(counter->last_device) - 1); -} - -static gboolean -on_timeout(gpointer user_data) -{ - GMainLoop *mainloop = (GMainLoop *) user_data; - g_main_loop_quit(mainloop); - return FALSE; -} - static void t_testbed_uevent_libudev(UMockdevTestbedFixture * fixture, UNUSED_DATA) { @@ -642,12 +614,16 @@ g_assert(device != NULL); g_assert_cmpstr(udev_device_get_syspath(device), ==, syspath); g_assert_cmpstr(udev_device_get_action(device), ==, "add"); + g_assert_cmpstr(udev_device_get_sysattr_value(device, "idVendor"), ==, "0815"); + g_assert_cmpstr(udev_device_get_property_value(device, "ID_INPUT"), ==, "1"); udev_device_unref(device); device = udev_monitor_receive_device(kernel_mon); g_assert(device != NULL); g_assert_cmpstr(udev_device_get_syspath(device), ==, syspath); g_assert_cmpstr(udev_device_get_action(device), ==, "add"); + g_assert_cmpstr(udev_device_get_sysattr_value(device, "idVendor"), ==, "0815"); + g_assert_cmpstr(udev_device_get_property_value(device, "ID_INPUT"), ==, "1"); udev_device_unref(device); udev_monitor_unref(udev_mon); @@ -714,6 +690,41 @@ udev_unref(udev); } +struct event_counter { + unsigned add; + unsigned remove; + unsigned change; + gchar last_device[1024]; +}; + +static void +on_uevent(UNUSED GUdevClient *client, const gchar *action, GUdevDevice *device, gpointer user_data) +{ + struct event_counter *counter = (struct event_counter *)user_data; + + g_debug("on_uevent action %s device %s", action, g_udev_device_get_sysfs_path(device)); + + if (strcmp(action, "add") == 0) + counter->add++; + else if (strcmp(action, "remove") == 0) + counter->remove++; + else if (strcmp(action, "change") == 0) + counter->change++; + else + g_assert_not_reached(); + + strncpy(counter->last_device, g_udev_device_get_sysfs_path(device), sizeof(counter->last_device) - 1); +} + +static gboolean +on_timeout(gpointer user_data) +{ + GMainLoop *mainloop = (GMainLoop *) user_data; + g_main_loop_quit(mainloop); + return FALSE; +} + + static void t_testbed_uevent_gudev(UMockdevTestbedFixture * fixture, UNUSED_DATA) { @@ -1031,6 +1042,8 @@ char *path; char pathbuf[PATH_MAX]; int dirfd, fd; + struct stat st; + uid_t uid = getuid(); /* start with adding one device */ success = umockdev_testbed_add_from_string(fixture->testbed, @@ -1111,6 +1124,51 @@ g_assert_cmpint(openat(AT_FDCWD, "sys/devices", O_RDONLY), <, 0); g_assert_cmpint(errno, ==, ENOENT); g_assert_cmpint(openat64(AT_FDCWD, "sys/devices", O_RDONLY), <, 0); + + /* stat */ + g_assert_cmpint(stat ("/sys/bus/pci/devices", &st), ==, 0); + g_assert_cmpint(st.st_nlink, >=, 1); + g_assert_cmpint(st.st_nlink, <=, 2); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISDIR(st.st_mode)); + + g_assert_cmpint(lstat ("/sys/bus/pci/devices/dev1", &st), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISLNK(st.st_mode)); + + g_assert_cmpint(stat ("/sys/bus/pci/devices/dev1", &st), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISDIR(st.st_mode)); + + g_assert_cmpint(fstatat (AT_FDCWD, "/sys/bus/pci/devices", &st, 0), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISDIR(st.st_mode)); + + g_assert_cmpint(fstatat (AT_FDCWD, "/sys/bus/pci/devices/dev1", &st, AT_SYMLINK_NOFOLLOW), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISLNK(st.st_mode)); + + g_assert_cmpint(fstatat (AT_FDCWD, "/sys/bus/pci/devices/dev1", &st, 0), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISDIR(st.st_mode)); + +#ifdef __GLIBC__ + /* statx */ + struct statx stx; + g_assert_cmpint(statx (AT_FDCWD, "/sys/bus/pci/devices", 0, STATX_TYPE|STATX_NLINK|STATX_UID, &stx), ==, 0); + g_assert_cmpint(stx.stx_nlink, >=, 1); + g_assert_cmpint(stx.stx_nlink, <=, 2); + g_assert_cmpuint(stx.stx_uid, ==, uid); + g_assert(S_ISDIR(stx.stx_mode)); + + g_assert_cmpint(statx (AT_FDCWD, "/sys/bus/pci/devices/dev1", AT_SYMLINK_NOFOLLOW, STATX_TYPE|STATX_NLINK|STATX_UID, &stx), ==, 0); + g_assert_cmpuint(stx.stx_uid, ==, uid); + g_assert(S_ISLNK(stx.stx_mode)); + + g_assert_cmpint(statx (AT_FDCWD, "/sys/bus/pci/devices/dev1", 0, STATX_TYPE|STATX_NLINK|STATX_UID, &stx), ==, 0); + g_assert_cmpuint(stx.stx_uid, ==, uid); + g_assert(S_ISDIR(stx.stx_mode)); +#endif } static void @@ -1172,6 +1230,7 @@ int fd; FILE* f; char buf[100]; + uid_t uid = getuid(); /* no mocked devices */ g_assert_cmpint(g_open("/dev/wishyouwerehere", O_RDONLY, 0), ==, -1); @@ -1198,8 +1257,23 @@ g_assert_cmpint(g_open("/dev/wishyouwerehere", O_RDONLY, 0), ==, -1); g_assert_cmpint(errno, ==, ENOENT); g_assert_cmpint(g_stat("/dev/zero", &st), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); + g_assert(S_ISCHR(st.st_mode)); + g_assert_cmpint(st.st_rdev, ==, 0); /* we did not set anything */ + + memset(&st, 42, sizeof st); + g_assert_cmpint(fstatat(AT_FDCWD, "/dev/zero", &st, 0), ==, 0); + g_assert_cmpuint(st.st_uid, ==, uid); g_assert(S_ISCHR(st.st_mode)); g_assert_cmpint(st.st_rdev, ==, 0); /* we did not set anything */ + +#ifdef __GLIBC__ + struct statx stx; + g_assert_cmpint(statx (AT_FDCWD, "/dev/zero", 0, STATX_TYPE|STATX_UID, &stx), ==, 0); + g_assert_cmpuint(stx.stx_uid, ==, uid); + g_assert(S_ISCHR(stx.stx_mode)); +#endif + fd = g_open("/dev/zero", O_RDONLY, 0); g_assert_cmpint(fd, >, 0); g_assert(!isatty(fd)); @@ -1352,6 +1426,18 @@ g_assert_cmpint(g_stat("/dev/empty", &st), ==, 0); g_assert(S_ISBLK(st.st_mode)); + memset(&st, 42, sizeof st); + g_assert_cmpint(fstatat(AT_FDCWD, "/dev/empty", &st, 0), ==, 0); + g_assert_cmpuint(st.st_uid, ==, getuid()); + g_assert(S_ISBLK(st.st_mode)); + +#ifdef __GLIBC__ + struct statx stx; + g_assert_cmpint(statx (AT_FDCWD, "/dev/empty", 0, STATX_TYPE|STATX_UID, &stx), ==, 0); + g_assert_cmpuint(stx.stx_uid, ==, getuid()); + g_assert(S_ISBLK(stx.stx_mode)); +#endif + /* N: with value should set that contents */ g_assert(umockdev_testbed_add_from_string(fixture->testbed, "P: /devices/block/filled\n" @@ -1366,6 +1452,12 @@ g_free(contents); g_assert_cmpint(g_stat("/dev/sdf", &st), ==, 0); g_assert(S_ISBLK(st.st_mode)); + +#ifdef __GLIBC__ + g_assert_cmpint(statx (AT_FDCWD, "/dev/sdf", 0, STATX_TYPE|STATX_UID, &stx), ==, 0); + g_assert_cmpuint(stx.stx_uid, ==, getuid()); + g_assert(S_ISBLK(stx.stx_mode)); +#endif } static void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/umockdev-0.17.1/tests/test-umockdev.py new/umockdev-0.17.5/tests/test-umockdev.py --- old/umockdev-0.17.1/tests/test-umockdev.py 2021-12-14 07:27:23.400868000 +0100 +++ new/umockdev-0.17.5/tests/test-umockdev.py 2022-01-18 11:19:51.460499300 +0100 @@ -129,7 +129,7 @@ def test_uevent(self): '''testbed uevent()''' - counter = [0, 0, 0, None] # add, remove, change, last device + counter = [0, 0, 0, None, None, None] # add, remove, change, last device, idVendor, ID_INPUT def on_uevent(client, action, device, counters): if action == 'add': @@ -138,9 +138,13 @@ counters[1] += 1 else: assert action == 'change' + self.assertEqual(device.get_sysfs_attr('idVendor'), '0815') + self.assertEqual(device.get_property('ID_INPUT'), '1') counters[2] += 1 counters[3] = device.get_sysfs_path() + counters[4] = device.get_sysfs_attr('idVendor') + counters[5] = device.get_property('ID_INPUT') syspath = self.testbed.add_device('pci', 'mydev', None, ['idVendor', '0815'], ['ID_INPUT', '1']) self.assertNotEqual(syspath, None) @@ -155,14 +159,17 @@ self.testbed.uevent(syspath, 'add') GLib.timeout_add(500, mainloop.quit) mainloop.run() - self.assertEqual(counter, [1, 0, 0, syspath]) + self.assertEqual(counter, [1, 0, 0, syspath, '0815', '1']) counter[0] = 0 counter[3] = None + counter[4] = None + counter[5] = None + self.testbed.uevent(syspath, 'change') GLib.timeout_add(500, mainloop.quit) mainloop.run() - self.assertEqual(counter, [0, 0, 1, syspath]) + self.assertEqual(counter, [0, 0, 1, syspath, '0815', '1']) def test_add_from_string(self): self.assertTrue(self.testbed.add_from_string ('''P: /devices/dev1