activation_dm: Support signal re-emmision 48/212048/6
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Tue, 13 Aug 2019 17:39:31 +0000 (19:39 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Thu, 22 Aug 2019 14:51:48 +0000 (16:51 +0200)
This commit introduces ability for signal re-emmision.  Basic
procedure is as follows:

 - dbus_listener receives signals from system bus - signals to be forwarded
   need to be listed here

 - activationd_dm received "ForwardDBusSignal" `action` which needs to be
   specified, while `destination` specifies target dbus name to which
   signal has to be delivered

 - forward_signal acton is added which re-transmits the signal to specified
   destination

This commit does not yet support passing original signal parameters.

Change-Id: I72346c2dbb326f78252f6f0bdc24acceebbc4ae0

Makefile.am
include/action.h
modules.conf.d/activation_eh.conf.d/99-acceptance-test.conf
modules.conf.d/dbus_listener.conf.d/99-acceptance-test.conf
packaging/activationd.spec
src/action/forward_signal.c [new file with mode: 0644]
src/core/action.c
src/decision_makers/activation_dm.c

index 8f5af34c629fb98977854da899f66b64515ad998..1fdb0034d5f3ec7296ba285a770f5ab103ca3f98 100644 (file)
@@ -114,7 +114,8 @@ actd_SOURCES = \
 # This variable is parsed by Autoconf
 EXTRA_actd_SOURCES = \
     src/action/service_restart.c \
-    src/action/unit_start.c
+    src/action/unit_start.c \
+    src/action/forward_signal.c
 
 actd_CFLAGS = $(AM_CFLAGS)
 actd_LDFLAGS = -ldl -pie
@@ -127,6 +128,7 @@ modulesdir = ${libdir}/actd/available-modules
 modules_LTLIBRARIES = \
                  service_restart_action.la \
                  unit_start_action.la \
+                 forward_signal_action.la \
                  vconf_key_changed_event.la \
                  dbus_signal_event.la \
                  unit_control_event.la \
@@ -139,6 +141,7 @@ modules_LTLIBRARIES = \
 
 service_restart_action_la_SOURCES = src/action/service_restart.c
 unit_start_action_la_SOURCES = src/action/unit_start.c
+forward_signal_action_la_SOURCES = src/action/forward_signal.c
 vconf_key_changed_event_la_SOURCES = src/event_types/vconf_key_changed_event.c
 dbus_signal_event_la_SOURCES = src/event_types/dbus_signal_event.c
 unit_control_event_la_SOURCES = src/event_types/unit_control_event.c
index 74ce09eba35880d942cf40e9087b70b36b27776b..7c0a3fdf6dc91a92da2db8c6d0969872c26b976f 100644 (file)
@@ -26,6 +26,7 @@
 #define EPC_ACTION_REBOOT_ID "org.tizen.epc.action.REBOOT"
 #define EPC_ACTION_RECOVERY_REBOOT_ID "org.tizen.epc.action.RECOVERY_REBOOT"
 #define EPC_ACTION_UNIT_START_ID "org.tizen.epc.action.UNIT_START"
+#define EPC_ACTION_DBUS_SIGNAL_FORWARD_ID "org.tizen.epc.action.DBUS_SIGNAL_FORWARD"
 
 #define EPC_DEFAULT_ACTION_IMPL "default"
 
 #define EPC_AD_CLEANUP_UNIT "RecoveryUnit"
 #define EPC_AD_UNIT_NAME "UnitName"
 #define EPC_AD_UNIT_ACTION "UnitAction"
+#define EPC_AD_SIGNAL_ACTION "SignalAction"
+#define EPC_AD_SIGNAL_DEST "SignalDestination"
+#define EPC_AD_SIGNAL_PATH "SignalPath"
+#define EPC_AD_SIGNAL_INTERFACE "SignalInterface"
+#define EPC_AD_SIGNAL_MEMBER "SignalMember"
+#define EPC_AD_SIGNAL_PARAMS "SignalParams"
 
 int epc_fill_for_srv_restart(struct epc_object *obj, const char *service_path);
 
@@ -41,6 +48,10 @@ int epc_fill_for_srv_recover(struct epc_object *obj, const char *service_path, c
 int epc_fill_for_unit_start(struct epc_object *obj, const char *unit_path);
 int epc_fill_for_unit_action(struct epc_object *obj, const char *action);
 
+int epc_fill_for_signal_forward(struct epc_object *obj, const char *dest,
+                               const char *objpath, const char *interface,
+                               const char *member, struct epc_object *params);
+
 #define epc_fill_for_reboot(o)                                 \
        epc_object_fill_empty(o)
 
index f294df42f9b7c4c5bcb7d6235f03b36352ce977e..b8ffdf9a79e0feb69f3b93a56fd46f05055cabe7 100644 (file)
        },
        {"event":"dbus_signal", "id":"test_bn", "action":"StopUnit", "target":"activationd-acceptance-test-b-n.service", "match":
                {"arg1":false, "arg2":true}
-       }
-
-
+       },
 
+       {"event":"dbus_signal", "id":"test_unicast_signal_001", "action":"ForwardDBusSignal", "target":"org.tizen.activationd.testsuite.UnicastSignalReceiver001" },
+       {"event":"dbus_signal", "id":"test_unicast_signal_002", "action":"ForwardDBusSignal", "target":"org.tizen.activationd.testsuite.UnicastSignalReceiver002" }
 
        ]
 }
index 5e43ef1458deada8b0736e2f8ad739c52dea72cf..044bdb36b233622ce332d36ddbc801a7fc8d131f 100644 (file)
@@ -7,6 +7,9 @@
                {"id":"test_dp", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestDP", "path_namespace":"/org/freedesktop"},
                {"id":"test_dn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestDN", "path_namespace":"/org/freedesktop"},
                {"id":"test_bp", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBP", "path_namespace":"/org/freedesktop"},
-               {"id":"test_bn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBN", "path_namespace":"/org/freedesktop"}
+               {"id":"test_bn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBN", "path_namespace":"/org/freedesktop"},
+
+               {"id":"test_unicast_signal_001", "interface":"org.tizen.activationd.eventtest", "member":"Test001", "path_namespace":"/"},
+               {"id":"test_unicast_signal_002", "interface":"org.tizen.activationd.eventtest", "member":"Test002", "path_namespace":"/"}
        ]
 }
index 91c2f648f22fabe8036fbf98a0a196418491891b..7428bd4bb0ca75b0a719dc62d0558a7db2f602cd 100644 (file)
@@ -149,6 +149,7 @@ mkdir -p %{buildroot}/%{enabled_moduledir}
 
 %install_module service_restart_action extra
 %install_module unit_start_action extra
+%install_module forward_signal_action extra
 %install_module vconf_key_changed_event vconf
 %install_module vconf_listener vconf
 %install_module dbus_signal_event dbus
diff --git a/src/action/forward_signal.c b/src/action/forward_signal.c
new file mode 100644 (file)
index 0000000..65a895d
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * This file is part of activationd.
+ *
+ * Copyright © 2019 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "action.h"
+#include "action_executor.h"
+#include "decision_made_event.h"
+#include "unit_control_event.h"
+#include "log.h"
+#include "systemd_dbus.h"
+#include "common.h"
+
+#include <libsyscommon/dbus-system.h>
+
+static int forward_signal(struct epc_action *action,
+               struct action_executed_event *exe_info)
+{
+       struct epc_event *ev = pop_epc_event(&action->execution_queue);
+       struct decision_made_event *dm_ev = to_decision_made_event(ev);
+       char *signal_action = NULL;
+       char *signal_dest = NULL;
+       char *signal_path = NULL;
+       char *signal_interface = NULL;
+       char *signal_member = NULL;
+       //FIXME: we need to pass both signature or original signal and their parameters
+       //       while passing GVariant* directly seems ok, we already have serialized
+       //       form in module that generates the event, so might try to pass it here
+       //       as epc_object (look for ->params in decision_makers/activation_dm)
+       //FIXME: signal_params = NULL;
+
+       epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_ACTION, &signal_action);
+       epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_DEST, &signal_dest);
+       epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_PATH, &signal_path);
+       epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_INTERFACE, &signal_interface);
+       epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_MEMBER, &signal_member);
+       log_debug("forward_signal: action %s, dest %s, path %s, interface %s, member %s",
+                 signal_action, signal_dest, signal_path, signal_interface, signal_member);
+       //FIXME: epc_object_get_object(dm_ev->action_data, EPC_AD_SIGNAL_PARAMS, &signal_params);
+       if (!signal_dest || !signal_path || !signal_interface || !signal_member)
+               goto err;
+
+       dbus_handle_broadcast_dbus_signal(signal_dest, signal_path, signal_interface, signal_member, NULL);
+
+
+       //FIXME: shortly after this function exits actd gets segfault.  I assume something
+       //       more needs to be done in terms of cleanup here.  Unfortunatelly, I have
+       //       no idea what.
+       exe_info->result = 0;
+       return 0;
+
+err:
+       epc_object_append_string(exe_info->action_log, "error", "Invalid parameters given for forward_signal");
+       exe_info->result = -EINVAL;
+       log_error("Invalid parameters given for forward_signal");
+
+       return 0;
+}
+
+static struct epc_action forward_signal_action = {
+       .action_id = EPC_ACTION_DBUS_SIGNAL_FORWARD_ID,
+       .impl_name = EPC_DEFAULT_ACTION_IMPL,
+       .execute = forward_signal,
+       .node = LIST_HEAD_INIT(forward_signal_action.node),
+};
+
+EPC_ACTION_REGISTER_SIMPLE(forward_signal_action);
index 47f6d66fbf05068e5a3b77fddea29167583df408..4b1eed0f99b7ac0ac0eb0b27d136106c09197fe9 100644 (file)
@@ -86,3 +86,29 @@ int epc_fill_for_unit_action(struct epc_object *obj, const char *unit_action)
 
        return 0;
 }
+
+int epc_fill_for_signal_forward(struct epc_object *obj, const char *dest,
+                               const char *path, const char *interface,
+                               const char *member, struct epc_object *params)
+{
+       assert(dest);
+       assert(path);
+       assert(interface);
+       assert(member);
+
+       int ret;
+
+       ret = epc_object_append_string(obj, EPC_AD_SIGNAL_DEST, dest);
+       ret += epc_object_append_string(obj, EPC_AD_SIGNAL_PATH, path);
+       ret += epc_object_append_string(obj, EPC_AD_SIGNAL_INTERFACE, interface);
+       ret += epc_object_append_string(obj, EPC_AD_SIGNAL_MEMBER, member);
+       if (params)
+               ret += epc_object_append_object(obj, EPC_AD_SIGNAL_PARAMS, params);
+
+       if (ret != 0) {
+               log_error("Unable to append parameters for forward_signal");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
index bf1a935025a3314e344f49eb54b01aaa01a59eb7..713657bf56222509c4d3af64bcfb89bc5dcebd16 100644 (file)
@@ -151,6 +151,35 @@ static int dbus_rule_match(struct rule *r, struct epc_event *event)
        return 1;
 }
 
+static int execute_rule_uc(struct rule *r, struct epc_event *ev, struct dm_event_data *ev_data)
+{
+       ev_data->action = EPC_ACTION_UNIT_START_ID;
+
+       if (epc_fill_for_unit_start(ev_data->action_data, r->target)) {
+               log_error("Unable to create event data");
+               return -1;
+       }
+       epc_fill_for_unit_action(ev_data->action_data, r->action);
+
+       return 0;
+}
+
+static int execute_rule_signal(struct rule *r, struct epc_event *ev, struct dm_event_data *ev_data)
+{
+       struct dbus_signal_event *dev = to_dbus_signal_event(ev);
+
+       ev_data->action = EPC_ACTION_DBUS_SIGNAL_FORWARD_ID;
+
+       if (epc_fill_for_signal_forward(ev_data->action_data, r->target,
+                       dev->path, dev->interface, dev->member,
+                       NULL /* FIXME not supported yet (dev->params) */)) {
+               // FIXME note that dev->params already has parameters that need to be passed as epc_object
+               log_error("Unable to create event data");
+               return -1;
+       }
+
+       return 0;
+}
 
 static int execute_rule(struct rule *r, struct epc_event *ev)
 {
@@ -161,19 +190,23 @@ static int execute_rule(struct rule *r, struct epc_event *ev)
        struct epc_event *new_ev;
        int ret;
 
-       ev_data.action = EPC_ACTION_UNIT_START_ID;
        ret = epc_object_new(&ev_data.action_data);
        if (ret < 0) {
                log_error("Could not create data object for action");
                goto out;
        }
 
-       ret = epc_fill_for_unit_start(ev_data.action_data, r->target);
-       if (ret) {
-               log_error("Unable to create event data");
+       bool is_uc = !strcmp(r->action, "StartUnit") ||
+                       !strcmp(r->action, "StopUnit") ||
+                       !strcmp(r->action, "RestartUnit");
+       bool is_sig = !strcmp(r->action, "ForwardDBusSignal");
+
+       ret = is_uc ? execute_rule_uc(r, ev, &ev_data) :
+               (is_sig ? execute_rule_signal(r, ev, &ev_data) : -1);
+       if (ret < 0) {
+               log_debug("Unsupported action");
                goto out;
        }
-       epc_fill_for_unit_action(ev_data.action_data, r->action);
 
        ret = epc_event_create(DECISION_MADE_EVENT_ID, &ev_data, &new_ev);
        if (ret) {