]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: add varlink_many_*() helpers that send messages to a set of connections...
authorLennart Poettering <lennart@poettering.net>
Wed, 29 May 2024 07:33:27 +0000 (09:33 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 25 Jun 2024 07:49:26 +0000 (09:49 +0200)
If we have a Varlink interface that allows man subscribers to the same
source of events we typically want to notify all of them at once with
the same message.

Let's add some helpers for this purpose: varlink_many_*() can be used to
send messages, similar to the corresponding varlink_*() calls, but they
take a Set of Varlink objects and we issue the operation on every
connection once.

This ports over one existing case where this is beneficial, but the main
user for this is supposed to be importd later.

src/resolve/resolved-manager.c
src/shared/varlink.c
src/shared/varlink.h

index 2eee418adf2dca6f2afa10b224a3ccb85da4700e..9bbdc648fc4fca4dffe22a96c8985676afdf7bb8 100644 (file)
@@ -1165,7 +1165,6 @@ static int dns_question_to_json(DnsQuestion *q, sd_json_variant **ret) {
 int manager_monitor_send(Manager *m, DnsQuery *q) {
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *jquestion = NULL, *jcollected_questions = NULL, *janswer = NULL;
         _cleanup_(dns_question_unrefp) DnsQuestion *merged = NULL;
-        Varlink *connection;
         DnsAnswerItem *rri;
         int r;
 
@@ -1220,34 +1219,32 @@ int manager_monitor_send(Manager *m, DnsQuery *q) {
                         return log_debug_errno(r, "Failed to append notification entry to array: %m");
         }
 
-        SET_FOREACH(connection, m->varlink_subscription) {
-                r = varlink_notifybo(
-                                connection,
-                                SD_JSON_BUILD_PAIR("state", SD_JSON_BUILD_STRING(dns_transaction_state_to_string(q->state))),
-                                SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_DNSSEC_FAILED,
-                                                             "result", SD_JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result))),
-                                SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_RCODE_FAILURE,
-                                                             "rcode", SD_JSON_BUILD_INTEGER(q->answer_rcode)),
-                                SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_ERRNO,
-                                                             "errno", SD_JSON_BUILD_INTEGER(q->answer_errno)),
-                                SD_JSON_BUILD_PAIR_CONDITION(IN_SET(q->state,
-                                                                    DNS_TRANSACTION_DNSSEC_FAILED,
-                                                                    DNS_TRANSACTION_RCODE_FAILURE) &&
-                                                             q->answer_ede_rcode >= 0,
-                                                             "extendedDNSErrorCode", SD_JSON_BUILD_INTEGER(q->answer_ede_rcode)),
-                                SD_JSON_BUILD_PAIR_CONDITION(IN_SET(q->state,
-                                                                    DNS_TRANSACTION_DNSSEC_FAILED,
-                                                                    DNS_TRANSACTION_RCODE_FAILURE) &&
-                                                             q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg),
-                                                             "extendedDNSErrorMessage", SD_JSON_BUILD_STRING(q->answer_ede_msg)),
-                                SD_JSON_BUILD_PAIR("question", SD_JSON_BUILD_VARIANT(jquestion)),
-                                SD_JSON_BUILD_PAIR_CONDITION(!!jcollected_questions,
-                                                             "collectedQuestions", SD_JSON_BUILD_VARIANT(jcollected_questions)),
-                                SD_JSON_BUILD_PAIR_CONDITION(!!janswer,
+        r = varlink_many_notifybo(
+                        m->varlink_subscription,
+                        SD_JSON_BUILD_PAIR("state", SD_JSON_BUILD_STRING(dns_transaction_state_to_string(q->state))),
+                        SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_DNSSEC_FAILED,
+                                                     "result", SD_JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result))),
+                        SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_RCODE_FAILURE,
+                                                     "rcode", SD_JSON_BUILD_INTEGER(q->answer_rcode)),
+                        SD_JSON_BUILD_PAIR_CONDITION(q->state == DNS_TRANSACTION_ERRNO,
+                                                     "errno", SD_JSON_BUILD_INTEGER(q->answer_errno)),
+                        SD_JSON_BUILD_PAIR_CONDITION(IN_SET(q->state,
+                                                            DNS_TRANSACTION_DNSSEC_FAILED,
+                                                            DNS_TRANSACTION_RCODE_FAILURE) &&
+                                                     q->answer_ede_rcode >= 0,
+                                                     "extendedDNSErrorCode", SD_JSON_BUILD_INTEGER(q->answer_ede_rcode)),
+                        SD_JSON_BUILD_PAIR_CONDITION(IN_SET(q->state,
+                                                            DNS_TRANSACTION_DNSSEC_FAILED,
+                                                            DNS_TRANSACTION_RCODE_FAILURE) &&
+                                                     q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg),
+                                                     "extendedDNSErrorMessage", SD_JSON_BUILD_STRING(q->answer_ede_msg)),
+                        SD_JSON_BUILD_PAIR("question", SD_JSON_BUILD_VARIANT(jquestion)),
+                        SD_JSON_BUILD_PAIR_CONDITION(!!jcollected_questions,
+                                                     "collectedQuestions", SD_JSON_BUILD_VARIANT(jcollected_questions)),
+                        SD_JSON_BUILD_PAIR_CONDITION(!!janswer,
                                                              "answer", SD_JSON_BUILD_VARIANT(janswer)));
-                if (r < 0)
-                        log_debug_errno(r, "Failed to send monitor event, ignoring: %m");
-        }
+        if (r < 0)
+                log_debug_errno(r, "Failed to send monitor event, ignoring: %m");
 
         return 0;
 }
index 8329f39021ee9e7ed646a672c3a45e3d0a0516d7..d0a86157a284ca223b9191f29917f6d5c1faebd4 100644 (file)
@@ -4162,3 +4162,51 @@ int varlink_error_to_errno(const char *error, sd_json_variant *parameters) {
 
         return -EBADR; /* Catch-all */
 }
+
+int varlink_many_notifyb(Set *s, ...) {
+        int r;
+
+        /* Equivalent to varlink_notifyb(), but does this for each entry of the supplied set of Varlink connections */
+
+        if (set_isempty(s))
+                return 0;
+
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL;
+        va_list ap;
+        va_start(ap, s);
+        r = sd_json_buildv(&parameters, ap);
+        va_end(ap);
+        if (r < 0)
+                return r;
+
+        int ret = 1;
+        Varlink *link;
+        SET_FOREACH(link, s)
+                RET_GATHER(ret, varlink_notify(link, parameters));
+
+        return ret;
+}
+
+int varlink_many_reply(Set *s, sd_json_variant *parameters) {
+        if (set_isempty(s))
+                return 0;
+
+        int ret = 1;
+        Varlink *link;
+        SET_FOREACH(link, s)
+                RET_GATHER(ret, varlink_reply(link, parameters));
+
+        return ret;
+}
+
+int varlink_many_error(Set *s, const char *error_id, sd_json_variant *parameters) {
+        if (set_isempty(s))
+                return 0;
+
+        int ret = 1;
+        Varlink *link;
+        SET_FOREACH(link, s)
+                RET_GATHER(ret, varlink_error(link, error_id, parameters));
+
+        return ret;
+}
index 739786b975f1e4ac21e500ef0e73b2c6e0929c2b..40a8fd086f61672b170463dc71407d51a8c233da 100644 (file)
@@ -2,9 +2,10 @@
 #pragma once
 
 #include "sd-event.h"
-
 #include "sd-json.h"
+
 #include "pidref.h"
+#include "set.h"
 #include "time-util.h"
 #include "varlink-idl.h"
 
@@ -264,6 +265,12 @@ int varlink_invocation(VarlinkInvocationFlags flags);
 
 int varlink_error_to_errno(const char *error, sd_json_variant *parameters);
 
+int varlink_many_notifyb(Set *s, ...);
+#define varlink_many_notifybo(s, ...)                           \
+        varlink_many_notifyb((s), SD_JSON_BUILD_OBJECT(__VA_ARGS__))
+int varlink_many_reply(Set *s, sd_json_variant *parameters);
+int varlink_many_error(Set *s, const char *error_id, sd_json_variant *parameters);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_close_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_flush_close_unref);