From: Ivan Kruglov Date: Thu, 24 Oct 2024 12:13:51 +0000 (+0200) Subject: machine: operation should not send a response when 'done' callback set X-Git-Tag: v257-rc1~140 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10a48938ef3565c9a0c5ffda35f68d6d2ce8e574;p=thirdparty%2Fsystemd.git machine: operation should not send a response when 'done' callback set --- diff --git a/src/machine/operation.c b/src/machine/operation.c index 4d3939496fb..7d7bfa50627 100644 --- a/src/machine/operation.c +++ b/src/machine/operation.c @@ -8,7 +8,7 @@ #include "operation.h" #include "process-util.h" -static int operation_done_internal(const siginfo_t *si, Operation *o, sd_bus_error *error) { +static int read_operation_errno(const siginfo_t *si, Operation *o) { int r; assert(si); @@ -27,15 +27,6 @@ static int operation_done_internal(const siginfo_t *si, Operation *o, sd_bus_err return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpectedly short message when reading operation's errno"); } - if (o->done) - /* A completion routine is set for this operation, call it. */ - return o->done(o, r, error); - - /* The default operation when done is to simply return an error on failure or an empty success - * message on success. */ - if (r < 0) - log_debug_errno(r, "Operation failed: %m"); - return r; } @@ -51,10 +42,18 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat o->pid = 0; + r = read_operation_errno(si, o); + if (r < 0) + log_debug_errno(r, "Operation failed: %m"); + + /* If a completion routine (o->done) is set for this operation, call it. It sends a response, but can return an error in which case it expect us to reply. + * Otherwise, the default action is to simply return an error on failure or an empty success message on success. */ + if (o->message) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + if (o->done) + r = o->done(o, r, &error); - r = operation_done_internal(si, o, &error); if (r < 0) { if (!sd_bus_error_is_set(&error)) sd_bus_error_set_errno(&error, r); @@ -62,16 +61,20 @@ static int operation_done(sd_event_source *s, const siginfo_t *si, void *userdat r = sd_bus_reply_method_error(o->message, &error); if (r < 0) log_error_errno(r, "Failed to reply to dbus message: %m"); - } else { + } else if (!o->done) { + /* when o->done set it's responsible for sending reply in a happy-path case */ r = sd_bus_reply_method_return(o->message, NULL); if (r < 0) log_error_errno(r, "Failed to reply to dbus message: %m"); } } else if (o->link) { - r = operation_done_internal(si, o, /* error = */ NULL); + if (o->done) + r = o->done(o, r, /* error = */ NULL); + if (r < 0) (void) sd_varlink_error_errno(o->link, r); - else + else if (!o->done) + /* when o->done set it's responsible for sending reply in a happy-path case */ (void) sd_varlink_reply(o->link, NULL); } else assert_not_reached();