libactd: Call systemd directly if on session bus 48/208048/1
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Mon, 17 Jun 2019 15:06:00 +0000 (17:06 +0200)
committerPaweł Szewczyk <p.szewczyk@samsung.com>
Mon, 17 Jun 2019 15:06:52 +0000 (17:06 +0200)
Change-Id: I6508537d0289d0d4723a8f52317d48887b1150ce
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
src/libactd/unit_control.c

index d41e8c7a1b04a19b74263a69c4e89cea726282d0..4156faf227b4fdbde35f44dcae99c7e564a58ab9 100644 (file)
 #define UNIT_CONTROL_INTERFACE "org.tizen.Activationd"
 #define UNIT_CONTROL_OBJ_PATH "/org/tizen/activationd"
 
+#define SYSTEMD_SERVICE "org.freedesktop.systemd1"
+#define SYSTEMD_INTERFACE "org.freedesktop.systemd1.Manager"
+#define SYSTEMD_OBJ_PATH "/org/freedesktop/systemd1"
+
+struct generic_user_data {
+       actd_unit_cb cb;
+       void *user_data;
+};
+
+static void generic_callback(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+       struct generic_user_data *data = user_data;
+       GVariant *var;
+       GError *err = NULL;
+
+       var = g_dbus_connection_call_finish(source_object, res, &err);
+
+       data->cb(var, data->user_data, err);
+
+       if (err)
+               g_error_free(err);
+
+       free(data);
+}
+
+const char *translate_to_systemd(const char *method)
+{
+       if (strcmp(method, "Start") == 0)
+               return "StartUnit";
+       if (strcmp(method, "Stop") == 0)
+               return "StopUnit";
+       if (strcmp(method, "Restart") == 0)
+               return "RestartUnit";
+
+       return NULL;
+}
+
 static int call_uc(GBusType bus_type, const char *method, const char *unit)
 {
        int ret;
@@ -37,50 +74,93 @@ static int call_uc(GBusType bus_type, const char *method, const char *unit)
        if (!bus)
                return -1;
 
-       msg = g_dbus_connection_call_sync(bus,
-                       UNIT_CONTROL_NAME,
-                       UNIT_CONTROL_OBJ_PATH,
-                       UNIT_CONTROL_INTERFACE,
-                       method,
-                       g_variant_new("(s)", unit),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       NULL);
-       if (!msg)
-               return -EBADMSG;
-
-       g_variant_get(msg, "(s)", &result);
-       if (g_strcmp0(result, "ok") == 0)
+       if (bus_type == G_BUS_TYPE_SESSION) {
+               msg = g_dbus_connection_call_sync(bus,
+                               SYSTEMD_SERVICE,
+                               SYSTEMD_OBJ_PATH,
+                               SYSTEMD_INTERFACE,
+                               translate_to_systemd(method),
+                               g_variant_new("(ss)", unit, "replace"),
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
+               if (!msg)
+                       return -EBADMSG;
+
                ret = 0;
-       else
-               ret = -1;
+       } else {
+               /* we assume that activationd runs on system bus and can be used as a proxy */
+               msg = g_dbus_connection_call_sync(bus,
+                               UNIT_CONTROL_NAME,
+                               UNIT_CONTROL_OBJ_PATH,
+                               UNIT_CONTROL_INTERFACE,
+                               method,
+                               g_variant_new("(s)", unit),
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               NULL);
+               if (!msg)
+                       return -EBADMSG;
+
+               g_variant_get(msg, "(s)", &result);
+               if (g_strcmp0(result, "ok") == 0)
+                       ret = 0;
+               else
+                       ret = -1;
+
+               g_free(result);
+       }
 
-       g_free(result);
        return ret;
 }
 
 static int call_uc_async(GBusType bus_type, const char *method, const char *unit, actd_unit_cb cb, void *user_data)
 {
        GDBusConnection *bus;
+       struct generic_user_data *data = user_data;
 
        bus = g_bus_get_sync(bus_type, NULL, NULL);
        if (!bus)
                return -1;
 
-       g_dbus_connection_call(bus,
-                       UNIT_CONTROL_NAME,
-                       UNIT_CONTROL_OBJ_PATH,
-                       UNIT_CONTROL_INTERFACE,
-                       method,
-                       g_variant_new("(s)", unit),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       (GAsyncReadyCallback) cb,
-                       NULL);
+       data = malloc(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+
+       data->user_data = user_data;
+       data->cb = cb;
+
+       if (bus_type == G_BUS_TYPE_SESSION) {
+               g_dbus_connection_call(bus,
+                               SYSTEMD_SERVICE,
+                               SYSTEMD_OBJ_PATH,
+                               SYSTEMD_INTERFACE,
+                               translate_to_systemd(method),
+                               g_variant_new("(ss)", unit, "replace"),
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               (GAsyncReadyCallback) generic_callback,
+                               data);
+       } else {
+               g_dbus_connection_call(bus,
+                               UNIT_CONTROL_NAME,
+                               UNIT_CONTROL_OBJ_PATH,
+                               UNIT_CONTROL_INTERFACE,
+                               method,
+                               g_variant_new("(s)", unit),
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               (GAsyncReadyCallback) generic_callback,
+                               data);
+       }
 
        return 0;
 }