Add API for controling systemd units 19/181419/4
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Wed, 30 May 2018 12:31:47 +0000 (14:31 +0200)
committerPaweł Szewczyk <p.szewczyk@samsung.com>
Tue, 26 Jun 2018 13:40:14 +0000 (15:40 +0200)
Change-Id: Ic13a69fbf0008ce37c0774b857e718335c0cf921
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
CMakeLists.txt
hw/systemd.c [new file with mode: 0644]
hw/systemd.h [new file with mode: 0644]
packaging/libdevice-node.spec

index 0c4e82d..bdba1d1 100644 (file)
@@ -12,7 +12,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/${INC_DIR})
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(rpkgs REQUIRED dlog vconf glib-2.0)
+pkg_check_modules(rpkgs REQUIRED dlog vconf glib-2.0 libsystemd)
 
 FOREACH(flag ${rpkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -40,7 +40,7 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS} "-ldl")
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION})
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
 
-ADD_LIBRARY(hwcommon SHARED hw/common.c)
+ADD_LIBRARY(hwcommon SHARED hw/common.c hw/systemd.c)
 TARGET_LINK_LIBRARIES(hwcommon ${rpkgs_LDFLAGS} "-ldl")
 SET_TARGET_PROPERTIES(hwcommon PROPERTIES SOVERSION ${VERSION})
 INSTALL(TARGETS hwcommon DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/hw/systemd.c b/hw/systemd.c
new file mode 100644 (file)
index 0000000..97d32ce
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * libdevice-node
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <hw/systemd.h>
+#include <systemd/sd-bus.h>
+
+#define SYSTEMD_DBUS_SERVICE "org.freedesktop.systemd1"
+#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1"
+#define SYSTEMD_DBUS_MANAGER_IFACE "org.freedesktop.systemd1.Manager"
+
+#define SYSTEMD_SOCKET_SUFFIX ".socket"
+#define MAX_SOCKET_NAME 1024
+
+#define SYSTEMD_SERVICE_SUFFIX ".service"
+#define MAX_SERVICE_NAME 1024
+
+#ifndef EXPORT
+#define EXPORT __attribute__ ((visibility("default")))
+#endif
+
+struct bus_ctx {
+       const char *unit;
+       sd_event *loop;
+};
+
+static int socket_started(sd_bus_message *m, void *userdata,
+                         sd_bus_error *ret_error)
+{
+       struct bus_ctx *ctx = userdata;
+       char *signal_unit;
+       int ret;
+
+       ret = sd_bus_message_read(m, "uoss", NULL, NULL, &signal_unit, NULL);
+       if (ret < 0) {
+               sd_event_exit(ctx->loop, ret);
+               return 0;
+       }
+
+       if (!strcmp(signal_unit, ctx->unit))
+               sd_event_exit(ctx->loop, 0);
+
+       return 0;
+}
+
+static int systemd_unit_interface_sync(const char *method, const char *unit,
+                                      bool wait)
+{
+       sd_bus *bus = NULL;
+       sd_event *loop = NULL;
+       struct bus_ctx ctx;
+       int ret;
+
+       ret = sd_bus_open_system(&bus);
+       if (ret < 0)
+               return ret;
+
+       if (wait) {
+               ret = sd_event_new(&loop);
+               if (ret < 0)
+                       goto unref_bus;
+
+               ctx.loop = loop;
+               ctx.unit = unit;
+
+               ret = sd_bus_attach_event(bus, loop, SD_EVENT_PRIORITY_NORMAL);
+               if (ret < 0)
+                       goto unref_loop;
+
+               ret = sd_bus_add_match(bus, NULL,
+                                      "type='signal',"
+                                      "sender='" SYSTEMD_DBUS_SERVICE "',"
+                                      "interface='" SYSTEMD_DBUS_MANAGER_IFACE "',"
+                                      "member='JobRemoved',"
+                                      "path_namespace='" SYSTEMD_DBUS_PATH "'",
+                                      socket_started,
+                                      &ctx);
+               if (ret < 0)
+                       goto unref_loop;
+       }
+
+
+       ret = sd_bus_call_method(bus,
+                       SYSTEMD_DBUS_SERVICE,
+                       SYSTEMD_DBUS_PATH,
+                       SYSTEMD_DBUS_MANAGER_IFACE,
+                       method,
+                       NULL,
+                       NULL,
+                       "ss",
+                       unit,
+                       "replace");
+       if (ret < 0)
+               goto unref_loop;
+
+       if (wait)
+               ret = sd_event_loop(loop);
+
+unref_loop:
+       if (wait)
+               sd_event_unref(loop);
+unref_bus:
+       sd_bus_unref(bus);
+       return ret;
+}
+
+EXPORT int systemd_start_service(const char *service_name)
+{
+       char unit[MAX_SERVICE_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+                      service_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+       return systemd_unit_interface_sync("StartUnit", unit, true);
+}
+
+EXPORT int systemd_stop_service(const char *service_name)
+{
+       char unit[MAX_SERVICE_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+                      service_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+       return systemd_unit_interface_sync("StopUnit", unit, false);
+}
+
+EXPORT int systemd_start_socket(const char *socket_name)
+{
+       char unit[MAX_SOCKET_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX,
+                      socket_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+
+       return systemd_unit_interface_sync("StartUnit", unit, true);
+}
+
+EXPORT int systemd_stop_socket(const char *socket_name)
+{
+       char unit[MAX_SOCKET_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SOCKET_SUFFIX,
+                      socket_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+       return systemd_unit_interface_sync("StopUnit", unit, false);
+}
diff --git a/hw/systemd.h b/hw/systemd.h
new file mode 100644 (file)
index 0000000..28ce944
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * libdevice-node
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+
+#ifndef __HW_SYSTEMD_H__
+#define __HW_SYSTEMD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int systemd_start_service(const char *service_name);
+int systemd_stop_service(const char *service_name);
+int systemd_start_socket(const char *socket_name);
+int systemd_stop_socket(const char *socket_name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __HW_SYSTEMD_H__ */
+
index 0aef2a2..bdfd0de 100755 (executable)
@@ -13,6 +13,7 @@ BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(gmock)
 BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(libsystemd)
 
 %description
 development package of library to control OAL APIs