udevadm-trigger: do not return immediately on EACCES
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 20 Feb 2021 07:30:23 +0000 (16:30 +0900)
committerLuca Boccassi <bluca@debian.org>
Sun, 18 Jun 2023 14:55:54 +0000 (15:55 +0100)
Prompted by https://github.com/systemd/systemd/pull/18559.

(cherry picked from commit 0e789e6d48046d43c50dd949a71ac56f1127bb96)

Gbp-Pq: Name udevadm-trigger-do-not-return-immediately-on-EACCES.patch

src/udev/udevadm-trigger.c

index 5c74184c33620785dfe8883eaf75acf681098725..da9b89aa11e1e7cad698fec7fc03c085a4a59af7 100644 (file)
@@ -45,13 +45,39 @@ static int exec_list(sd_device_enumerator *e, const char *action, Set **settle_s
 
                 r = write_string_file(filename, action, WRITE_STRING_FILE_DISABLE_BUFFER);
                 if (r < 0) {
+                        /* ENOENT may be returned when a device does not have /uevent or is already
+                         * removed. Hence, this is logged at debug level and ignored.
+                         *
+                         * ENODEV may be returned by some buggy device drivers e.g. /sys/devices/vio.
+                         * See,
+                         * https://github.com/systemd/systemd/issues/13652#issuecomment-535129791 and
+                         * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1845319.
+                         * So, this error is ignored, but logged at warning level to encourage people to
+                         * fix the driver.
+                         *
+                         * EROFS is returned when /sys is read only. In that case, all subsequent
+                         * writes will also fail, hence return immediately.
+                         *
+                         * EACCES or EPERM may be returned when this is invoked by non-priviledged user.
+                         * We do NOT return immediately, but continue operation and propagate the error.
+                         * Why? Some device can be owned by a user, e.g., network devices configured in
+                         * a network namespace. See, https://github.com/systemd/systemd/pull/18559 and
+                         * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ebb4a4bf76f164457184a3f43ebc1552416bc823
+                         *
+                         * All other errors are logged at error level, but let's continue the operation,
+                         * and propagate the error.
+                         */
+
                         bool ignore = IN_SET(r, -ENOENT, -ENODEV);
+                        int level =
+                                r == -ENOENT ? LOG_DEBUG :
+                                r == -ENODEV ? LOG_WARNING : LOG_ERR;
 
-                        log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
+                        log_full_errno(level, r,
                                        "Failed to write '%s' to '%s'%s: %m",
                                        action, filename, ignore ? ", ignoring" : "");
-                        if (IN_SET(r, -EACCES, -EROFS))
-                                /* Inovoked by unpriviledged user, or read only filesystem. Return earlier. */
+
+                        if (r == -EROFS)
                                 return r;
                         if (ret == 0 && !ignore)
                                 ret = r;