From: Yu Watanabe Date: Thu, 20 Mar 2025 08:28:28 +0000 (+0900) Subject: udev: split out error code assignment and move them to udev-error.c X-Git-Tag: v258-rc1~948^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aac642ddc1b53966b2e1f1e21406e6b865fe17bd;p=thirdparty%2Fsystemd.git udev: split out error code assignment and move them to udev-error.c No functional change, just refactoring and preparation for later change. --- diff --git a/src/udev/meson.build b/src/udev/meson.build index c77609543bc..00bc581a7dc 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -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 index 00000000000..fea14e3ffe7 --- /dev/null +++ b/src/udev/udev-error.c @@ -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 index 00000000000..c55b443d43b --- /dev/null +++ b/src/udev/udev-error.h @@ -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); diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index 77853298f99..7da211241d4 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -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) { diff --git a/src/udev/udev-worker.c b/src/udev/udev-worker.c index b26bf3b980d..8f54bf9281f 100644 --- a/src/udev/udev-worker.c +++ b/src/udev/udev-worker.c @@ -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 */ diff --git a/src/udev/udev-worker.h b/src/udev/udev-worker.h index d9dd88d4727..8e66e2f6b5e 100644 --- a/src/udev/udev-worker.h +++ b/src/udev/udev-worker.h @@ -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);