]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: split out error code assignment and move them to udev-error.c
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 20 Mar 2025 08:28:28 +0000 (17:28 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 2 Apr 2025 14:24:35 +0000 (23:24 +0900)
No functional change, just refactoring and preparation for later change.

src/udev/meson.build
src/udev/udev-error.c [new file with mode: 0644]
src/udev/udev-error.h [new file with mode: 0644]
src/udev/udev-manager.c
src/udev/udev-worker.c
src/udev/udev-worker.h

index c77609543bcd784fc5b04bba7104d9bd2baa87aa..00bc581a7dcbb37b4ccdffa4e752d1ea6eda003c 100644 (file)
@@ -34,6 +34,7 @@ libudevd_core_sources = files(
         'udev-config.c',
         'udev-ctrl.c',
         'udev-dump.c',
+        'udev-error.c',
         'udev-event.c',
         'udev-format.c',
         'udev-manager.c',
diff --git a/src/udev/udev-error.c b/src/udev/udev-error.c
new file mode 100644 (file)
index 0000000..fea14e3
--- /dev/null
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "device-private.h"
+#include "errno-list.h"
+#include "signal-util.h"
+#include "udev-error.h"
+
+int device_add_errno(sd_device *dev, int error) {
+        int r;
+
+        assert(dev);
+
+        if (error == 0)
+                return 0;
+
+        error = abs(error);
+
+        r = device_add_property(dev, "UDEV_WORKER_FAILED", "1");
+        RET_GATHER(r, device_add_propertyf(dev, "UDEV_WORKER_ERRNO", "%i", error));
+
+        const char *str = errno_to_name(error);
+        if (str)
+                RET_GATHER(r, device_add_property(dev, "UDEV_WORKER_ERRNO_NAME", str));
+
+        return r;
+}
+
+int device_add_exit_status(sd_device *dev, int status) {
+        int r;
+
+        assert(dev);
+
+        if (status == 0)
+                return 0;
+
+        r = device_add_property(dev, "UDEV_WORKER_FAILED", "1");
+        return RET_GATHER(r, device_add_propertyf(dev, "UDEV_WORKER_EXIT_STATUS", "%i", status));
+}
+
+int device_add_signal(sd_device *dev, int signo) {
+        int r;
+
+        assert(dev);
+
+        r = device_add_property(dev, "UDEV_WORKER_FAILED", "1");
+        RET_GATHER(r, device_add_propertyf(dev, "UDEV_WORKER_SIGNAL", "%i", signo));
+
+        const char *str = signal_to_string(signo);
+        if (str)
+                RET_GATHER(r, device_add_property(dev, "UDEV_WORKER_SIGNAL_NAME", str));
+
+        return r;
+}
diff --git a/src/udev/udev-error.h b/src/udev/udev-error.h
new file mode 100644 (file)
index 0000000..c55b443
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
+#include "sd-device.h"
+
+int device_add_errno(sd_device *dev, int error);
+int device_add_exit_status(sd_device *dev, int status);
+int device_add_signal(sd_device *dev, int signo);
index 77853298f99f88dd2831a50623e2979b680277fe..7da211241d49e6eaa5da1d942d321b1c340d2cd1 100644 (file)
@@ -25,6 +25,7 @@
 #include "udev-builtin.h"
 #include "udev-config.h"
 #include "udev-ctrl.h"
+#include "udev-error.h"
 #include "udev-event.h"
 #include "udev-manager.h"
 #include "udev-manager-ctrl.h"
@@ -684,7 +685,11 @@ static void event_requeue(Event *event) {
         return;
 
 fail:
-        udev_broadcast_result(event->manager->monitor, dev, r);
+        (void) device_add_errno(dev, r);
+        r = device_monitor_send(event->manager->monitor, NULL, dev);
+        if (r < 0)
+                log_device_warning_errno(dev, r, "Failed to broadcast event to libudev listeners, ignoring: %m");
+
         event_free(event);
 }
 
@@ -1038,46 +1043,50 @@ static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void
 }
 
 static int on_sigchld(sd_event_source *s, const siginfo_t *si, void *userdata) {
-        Worker *worker = ASSERT_PTR(userdata);
-        Manager *manager = ASSERT_PTR(worker->manager);
+        _cleanup_(worker_freep) Worker *worker = ASSERT_PTR(userdata);
         sd_device *dev = worker->event ? ASSERT_PTR(worker->event->dev) : NULL;
-        EventResult result;
+        int r;
 
         assert(si);
 
         switch (si->si_code) {
         case CLD_EXITED:
-                if (si->si_status == 0)
+                if (si->si_status == 0) {
                         log_device_debug(dev, "Worker ["PID_FMT"] exited.", si->si_pid);
-                else
-                        log_device_warning(dev, "Worker ["PID_FMT"] exited with return code %i.",
-                                           si->si_pid, si->si_status);
-                result = EVENT_RESULT_EXIT_STATUS_BASE + si->si_status;
+                        return 0;
+                }
+
+                log_device_warning(dev, "Worker ["PID_FMT"] exited with return code %i.",
+                                   si->si_pid, si->si_status);
+                if (!dev)
+                        return 0;
+
+                (void) device_add_exit_status(dev, si->si_status);
                 break;
 
         case CLD_KILLED:
         case CLD_DUMPED:
                 log_device_warning(dev, "Worker ["PID_FMT"] terminated by signal %i (%s).",
                                    si->si_pid, si->si_status, signal_to_string(si->si_status));
-                result = EVENT_RESULT_SIGNAL_BASE + si->si_status;
+                if (!dev)
+                        return 0;
+
+                (void) device_add_signal(dev, si->si_status);
                 break;
 
         default:
                 assert_not_reached();
         }
 
-        if (result != EVENT_RESULT_SUCCESS && dev) {
-                /* delete state from disk */
-                device_delete_db(dev);
-                device_tag_index(dev, NULL, false);
-
-                /* Forward kernel event to libudev listeners */
-                udev_broadcast_result(manager->monitor, dev, result);
-        }
+        /* delete state from disk */
+        device_delete_db(dev);
+        device_tag_index(dev, NULL, false);
 
-        worker_free(worker);
+        r = device_monitor_send(worker->manager->monitor, NULL, dev);
+        if (r < 0)
+                log_device_warning_errno(dev, r, "Failed to broadcast event to libudev listeners, ignoring: %m");
 
-        return 1;
+        return 0;
 }
 
 static int on_post(sd_event_source *s, void *userdata) {
index b26bf3b980d85092c05bd4fa9be2b9a30e5d54e2..8f54bf9281f06e2e81b155e304dea1d9b89f3f79 100644 (file)
@@ -17,6 +17,7 @@
 #include "process-util.h"
 #include "signal-util.h"
 #include "string-util.h"
+#include "udev-error.h"
 #include "udev-event.h"
 #include "udev-rules.h"
 #include "udev-spawn.h"
@@ -239,59 +240,6 @@ static int worker_process_device(UdevWorker *worker, sd_device *dev) {
         return 0;
 }
 
-void udev_broadcast_result(sd_device_monitor *monitor, sd_device *dev, EventResult result) {
-        int r;
-
-        assert(dev);
-
-        /* On exit, manager->monitor is already NULL. */
-        if (!monitor)
-                return;
-
-        if (result != EVENT_RESULT_SUCCESS) {
-                (void) device_add_property(dev, "UDEV_WORKER_FAILED", "1");
-
-                switch (result) {
-                case EVENT_RESULT_NERRNO_MIN ... EVENT_RESULT_NERRNO_MAX: {
-                        const char *str;
-
-                        (void) device_add_propertyf(dev, "UDEV_WORKER_ERRNO", "%i", -result);
-
-                        str = errno_to_name(result);
-                        if (str)
-                                (void) device_add_property(dev, "UDEV_WORKER_ERRNO_NAME", str);
-                        break;
-                }
-                case EVENT_RESULT_EXIT_STATUS_BASE ... EVENT_RESULT_EXIT_STATUS_MAX:
-                        assert(result != EVENT_RESULT_EXIT_STATUS_BASE);
-                        (void) device_add_propertyf(dev, "UDEV_WORKER_EXIT_STATUS", "%i", result - EVENT_RESULT_EXIT_STATUS_BASE);
-                        break;
-
-                case EVENT_RESULT_TRY_AGAIN:
-                        assert_not_reached();
-                        break;
-
-                case EVENT_RESULT_SIGNAL_BASE ... EVENT_RESULT_SIGNAL_MAX: {
-                        const char *str;
-
-                        (void) device_add_propertyf(dev, "UDEV_WORKER_SIGNAL", "%i", result - EVENT_RESULT_SIGNAL_BASE);
-
-                        str = signal_to_string(result - EVENT_RESULT_SIGNAL_BASE);
-                        if (str)
-                                (void) device_add_property(dev, "UDEV_WORKER_SIGNAL_NAME", str);
-                        break;
-                }
-                default:
-                        log_device_warning(dev, "Unknown event result \"%i\", ignoring.", result);
-                }
-        }
-
-        r = device_monitor_send(monitor, NULL, dev);
-        if (r < 0)
-                log_device_warning_errno(dev, r,
-                                         "Failed to broadcast event to libudev listeners, ignoring: %m");
-}
-
 static int worker_send_result(UdevWorker *worker, EventResult result) {
         assert(worker);
         assert(worker->pipe_fd >= 0);
@@ -310,11 +258,15 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *
                 /* if we couldn't acquire the flock(), then requeue the event */
                 log_device_debug(dev, "Block device is currently locked, requeueing the event.");
         else {
-                if (r < 0)
+                if (r < 0) {
                         log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
+                        (void) device_add_errno(dev, r);
+                }
 
                 /* send processed event back to libudev listeners */
-                udev_broadcast_result(monitor, dev, r);
+                int k = device_monitor_send(monitor, NULL, dev);
+                if (k < 0)
+                        log_device_warning_errno(dev, k, "Failed to broadcast event to libudev listeners, ignoring: %m");
         }
 
         /* send udevd the result of the event execution */
index d9dd88d4727b1758636c5dba122911274a1a1c2f..8e66e2f6b5e62c4a026f5825fd141ed2cab5fc7f 100644 (file)
@@ -48,5 +48,4 @@ typedef enum EventResult {
 void udev_worker_done(UdevWorker *worker);
 int udev_worker_main(UdevWorker *worker, sd_device *dev);
 
-void udev_broadcast_result(sd_device_monitor *monitor, sd_device *dev, EventResult result);
 int udev_get_whole_disk(sd_device *dev, sd_device **ret_device, const char **ret_devname);