simulatordaemon: Integrate with systemd 58/149458/2
authorLukasz Kostyra <l.kostyra@samsung.com>
Mon, 11 Sep 2017 16:59:54 +0000 (18:59 +0200)
committerLukasz Kostyra <l.kostyra@samsung.com>
Tue, 12 Sep 2017 09:22:08 +0000 (11:22 +0200)
Change-Id: Ie613205772ad7dd1fa66d7b75925a2fdd8ea0fef

CMakeLists.txt
packaging/tef-simulator.spec
simulatordaemon/CMakeLists.txt
simulatordaemon/inc/SimulatorDaemonServer.h
simulatordaemon/src/SimulatorDaemon.cpp
simulatordaemon/src/SimulatorDaemonServer.cpp
systemd/CMakeLists.txt [new file with mode: 0644]
systemd/tef-simulator.service.in [new file with mode: 0644]
systemd/tef-simulator.socket [new file with mode: 0644]
systemd/tef-simulator.target [new file with mode: 0644]

index 6d43b079e29163d7175b44b859ad3c8b1404af96..8444fd092822ad602bad2f9f7dddb390d2732e69 100644 (file)
@@ -110,5 +110,6 @@ ADD_SUBDIRECTORY(PackageMaker)
 ADD_SUBDIRECTORY(pkgconfig)
 ADD_SUBDIRECTORY(simulatordaemon)
 ADD_SUBDIRECTORY(ssflib)
+ADD_SUBDIRECTORY(systemd)
 ADD_SUBDIRECTORY(TEECLib)
 ADD_SUBDIRECTORY(TEEStub)
index 9cf378c2c5b75e1bfefb7160746b69c4c63be900..d2e8b61f2cc9bb6dc5a73c93f26dd23191813fb2 100644 (file)
@@ -13,6 +13,9 @@ BuildRequires: pkgconfig(cynara-client)
 BuildRequires: pkgconfig(cynara-creds-socket)
 BuildRequires: pkgconfig(libtzplatform-config)
 BuildRequires: pkgconfig(security-manager)
+BuildRequires: pkgconfig(libsystemd-daemon)
+
+%{?systemd_requires}
 
 %define bin_dir %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:%_bindir}
 %define sbin_dir %{?TZ_SYS_SBIN:%TZ_SYS_SBIN}%{!?TZ_SYS_SBIN:%_sbindir}
@@ -27,6 +30,9 @@ BuildRequires: pkgconfig(security-manager)
 %define build_data_dir %{buildroot}%{data_dir}
 %define build_include_dir %{buildroot}%{include_dir}
 %define build_tastore_dir %{buildroot}%{tastore_dir}
+%define build_unit_dir %{buildroot}%{_unitdir}
+
+%define smack_domain_name System
 
 %description
 TEF Simulator provides a TrustZone simulated environment
@@ -82,9 +88,12 @@ cmake . \
         -DDATA_DIR=%{build_data_dir} \
         -DINCLUDE_DIR=%{build_include_dir} \
         -DTASTORE_DIR=%{build_tastore_dir} \
+        -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \
+        -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \
         -DPKGCFG_LIB_DIR=%{lib_dir} \
         -DPKGCFG_PREFIX=/usr \
-        -DPKGCFG_VERSION=%{version}
+        -DPKGCFG_VERSION=%{version} \
+        -DSMACK_DOMAIN_NAME=%{smack_domain_name}
 make %{?jobs:-j%jobs}
 
 %install
@@ -102,6 +111,9 @@ make install
 %{bin_dir}/tef-simulator-daemon
 %{lib_dir}/libtef-simulator-ssflib.so
 %{sbin_dir}/tef-simulator-update-uuid-list.sh
+%{_unitdir}/tef-simulator.service
+%{_unitdir}/tef-simulator.socket
+%{_unitdir}/tef-simulator.target
 
 %files -n %{name}-client
 %{lib_dir}/libteec.so
index 658ce48b395d4e32714f67023a2fe483137db182..e79bf6a6735a1afe37a678d8c7152ebe2fdd7168 100644 (file)
@@ -21,6 +21,7 @@ PKG_CHECK_MODULES(DAEMON_DEPS REQUIRED
                   cynara-client
                   cynara-creds-socket
                   security-manager
+                  libsystemd-daemon
                   )
 
 FIND_PACKAGE(Threads REQUIRED)
index b0a8ec5e455f239ce9a904fe7e2eea3d95187ce6..5d7942b99d8a4b3d4922a1864eb2a0ed2dcf2799 100644 (file)
  *-----------------------------------------------------------------------------*/
 class SimulatorDaemonServer {
 public:
-       SimulatorDaemonServer(boost::asio::io_service& io_service,
-           const std::string& file);
+       // create a server and a socket
+       SimulatorDaemonServer(boost::asio::io_service& io_service, const std::string& file);
+
+       // create a server based on an existing socket fd
+       SimulatorDaemonServer(boost::asio::io_service& io_service, int sockfd);
+
 private:
-       void startAccept(void);
-       void handleAccept(ConnectionSession::session_ptr new_session,
-           const boost::system::error_code& error);
+       void startAccept();
+       void handleAccept(ConnectionSession::session_ptr session,
+               const boost::system::error_code& error);
        boost::asio::io_service& mem_io_service;
        stream_protocol::acceptor acceptor;
 };
index 560721c6110fb9fa39ddf8d64e5af8e5e07a6d08..25feff6b28f48f84aca5081b9283612f684188a3 100644 (file)
@@ -22,6 +22,8 @@
 #include "path.h"
 #include "SimulatorDaemonServer.h"
 
+#include <systemd/sd-daemon.h>
+
 /*-----------------------------------------------------------------------------
  *  Local functions
  *-----------------------------------------------------------------------------*/
@@ -61,6 +63,38 @@ void stopServer(boost::asio::io_service& io_service) {
        io_service.stop();
 }
 
+/**
+ * Acquire systemd emulator socket
+ */
+int getSystemdSocket(const std::string& path) {
+       int n = sd_listen_fds(0);
+
+       if (n < 0) {
+               LOGE(SIM_DAEMON, "Error while getting sockets from systemd: %d", n);
+               return n;
+       }
+
+       if (n == 0) {
+               LOGE(SIM_DAEMON, "No usable systemd socket found");
+               return 0;
+       }
+
+       if (n > 1) {
+               LOGI(SIM_DAEMON, "Received %d sockets. Only first one will be used.", n);
+       }
+
+       int fd = SD_LISTEN_FDS_START;
+       int ret = sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0);
+       if (ret > 0) {
+               LOGI(SIM_DAEMON, "Acquired systemd socket %d", fd);
+               sd_notify(0, "READY=1");
+               return fd;
+       }
+
+       LOGE(SIM_DAEMON, "Found systemd socket is not an UNIX socket.");
+       return 0;
+}
+
 /**
  * main function for Simulator Daemon
  * @return
@@ -69,12 +103,19 @@ int main() {
        LOGD(SIM_DAEMON, "Entry");
        uint32_t result = 0;
        try {
-               ::unlink(SIMDAEMON_PATH);
+               int sockFD = getSystemdSocket(SIMDAEMON_PATH);
+
                //initializeShm();
-               SimulatorDaemonServer s(ioService::getInstance(), SIMDAEMON_PATH);
-               // Once the server is started, it exits only after the
-               // connection is lost or gracefully disconnected.
-               startServer(ioService::getInstance());
+               if (sockFD > 0) {
+                       LOGI(SIM_DAEMON, "Using existing systemd socket %d", sockFD);
+                       SimulatorDaemonServer s(ioService::getInstance(), sockFD);
+                       startServer(ioService::getInstance());
+               } else {
+                       LOGI(SIM_DAEMON, "No systemd socket available - creating own one");
+                       SimulatorDaemonServer s(ioService::getInstance(), SIMDAEMON_PATH);
+                       startServer(ioService::getInstance());
+               }
+
                syslog(LOG_INFO | LOG_USER, "Daemon stopped");
        } catch (std::exception& e) {
                syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what());
index 6d9e746749b37a6ff7ce0b83e7b7fe43273168c3..e9f04f79af289534a6998d230d76aed2f6d26a46 100644 (file)
  * @param io_service provides OS abstraction for async communication
  * @param file path to Unix Domain Socket represented by a local file
  */
-SimulatorDaemonServer::SimulatorDaemonServer(
-    boost::asio::io_service& io_service, const std::string& file) :
-               mem_io_service(io_service),
-                   acceptor(io_service, stream_protocol::endpoint(file)) {
+SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, const std::string& file)
+       : mem_io_service(io_service)
+       , acceptor(io_service, stream_protocol::endpoint(file))
+{
        startAccept();
 }
 
 /**
- * Method to start accepting a new connection
- * @param none
+ * Creates a server based on already opened socket FD
+ * @param io_service provides OS abstraction for async communication
+ * @param sock opened socket file descriptor (ex. provided by systemd)
  */
-void SimulatorDaemonServer::startAccept() {
-       LOGD(SIM_DAEMON, "Entry");
-       ConnectionSession::session_ptr new_session = ConnectionSession::create(
-           acceptor.get_io_service());
+SimulatorDaemonServer::SimulatorDaemonServer(boost::asio::io_service& io_service, int sockfd)
+       : mem_io_service(io_service)
+       , acceptor(io_service)
+{
+       acceptor.assign(stream_protocol(), sockfd);
+       startAccept();
+}
+
+void SimulatorDaemonServer::startAccept()
+{
+       ConnectionSession::session_ptr newSession = ConnectionSession::create(acceptor.get_io_service());
 
-       acceptor.async_accept(new_session->socket(),
-           boost::bind(&SimulatorDaemonServer::handleAccept, this, new_session,
-               boost::asio::placeholders::error));
+       acceptor.async_accept(newSession->socket(),
+               boost::bind(&SimulatorDaemonServer::handleAccept, this, newSession,
+                       boost::asio::placeholders::error));
 }
 
 /**
@@ -56,9 +64,9 @@ void SimulatorDaemonServer::startAccept() {
  * @param error error code if any occurred
  */
 void SimulatorDaemonServer::handleAccept(
-       ConnectionSession::session_ptr new_session,
-       const boost::system::error_code& error) {
-
+       ConnectionSession::session_ptr session,
+       const boost::system::error_code& error)
+{
        const string privelege("http://tizen.org/privilege/account.read");
        LOGD(SIM_DAEMON, "Entry");
        // TODO reenable after refactor
@@ -68,7 +76,7 @@ void SimulatorDaemonServer::handleAccept(
        }*/
 
        if (!error) {
-               new_session->start();
+               session->start();
        }
        startAccept();
 }
diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8cb8ad1
--- /dev/null
@@ -0,0 +1,11 @@
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service.in
+               ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service @ONLY)
+
+INSTALL(FILES
+    ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.service
+    ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.target
+    ${CMAKE_SOURCE_DIR}/systemd/tef-simulator.socket
+    DESTINATION
+    ${SYSTEMD_UNIT_DIR}
+)
+
diff --git a/systemd/tef-simulator.service.in b/systemd/tef-simulator.service.in
new file mode 100644 (file)
index 0000000..4c55561
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=TEF Simulator Daemon
+DefaultDependencies=no
+
+[Service]
+User=root
+Group=root
+SmackProcessLabel=@SMACK_DOMAIN_NAME@
+ExecStart=@SYSTEMD_CFG_BIN_DIR@/tef-simulator-daemon
+Sockets=tef-simulator.socket
+RuntimeDirectory=@SERVICE_NAME@
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/tef-simulator.socket b/systemd/tef-simulator.socket
new file mode 100644 (file)
index 0000000..0551f60
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/tmp/simdaemon
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=tef-simulator.service
+
+[Unit]
+Wants=tef-simulator.target
+Before=tef-simulator.target
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/tef-simulator.target b/systemd/tef-simulator.target
new file mode 100644 (file)
index 0000000..e7be849
--- /dev/null
@@ -0,0 +1,4 @@
+[Unit]
+Description=TEF Simulator socket
+DefaultDependencies=true
+