Change service to on-demand by Systemd socket activation 65/141765/7
authorSungbae Yoo <sungbae.yoo@samsung.com>
Mon, 28 Aug 2017 11:47:57 +0000 (20:47 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Fri, 1 Sep 2017 07:56:03 +0000 (16:56 +0900)
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
Change-Id: I0a0b8ca9cad833623e8460398368fc7842e59d69

lib/client.cpp
packaging/ode.spec
server/CMakeLists.txt
server/external-encryption.cpp
server/internal-encryption.cpp
server/server.cpp
server/server.h
server/systemd/ode.socket [new file with mode: 0644]

index 25d8cb2..1f5b432 100644 (file)
@@ -22,7 +22,7 @@ const std::string SUBSCRIBER_REGISTER = "Server::registerNotificationSubscriber"
 const std::string SUBSCRIBER_UNREGISTER = "Server::unregisterNotificationSubscriber";
 
 
-const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
+const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.socket";
 
 } // namespace
 
index 3b441cd..9f9fbe8 100755 (executable)
@@ -29,6 +29,8 @@ The ode package provides a daemon which is responsible for encrypting/decryption
 %defattr(644,root,root,755)
 %attr(755,root,root) %{_bindir}/oded
 %attr(700,root,root) %{_sbindir}/ode-mount-external.sh
+%{_unitdir}/ode.socket
+%{_unitdir}/sockets.target.wants/ode.socket
 %{_unitdir}/ode.service
 %{_unitdir}/multi-user.target.wants/ode.service
 %{_unitdir}/ode-mount-external.path
@@ -66,12 +68,12 @@ make %{?jobs:-j%jobs}
 
 %install
 %make_install
-mkdir -p %{buildroot}/%{_unitdir}/multi-user.target.wants
-ln -s ../ode.service %{buildroot}/%{_unitdir}/multi-user.target.wants/ode.service
-ln -s ../ode-mount-external.path %{buildroot}/%{_unitdir}/multi-user.target.wants/ode-mount-external.path
-ln -s ../ode-umount-internal.path %{buildroot}/%{_unitdir}/multi-user.target.wants/ode-umount-internal.path
-ln -s ../ode-progress-internal@Decrypting.path %{buildroot}/%{_unitdir}/multi-user.target.wants/ode-progress-internal@Decrypting.path
-ln -s ../ode-progress-internal@Encrypting.path %{buildroot}/%{_unitdir}/multi-user.target.wants/ode-progress-internal@Encrypting.path
+%install_service sockets.target.wants ode.socket
+%install_service multi-user.target.wants ode.service
+%install_service multi-user.target.wants ode-mount-external.path
+%install_service multi-user.target.wants ode-umount-internal.path
+%install_service multi-user.target.wants ode-progress-internal@Decrypting.path
+%install_service multi-user.target.wants ode-progress-internal@Encrypting.path
 
 %find_lang secure-erase
 %find_lang ode
@@ -82,10 +84,20 @@ rm -rf %{buildroot}
 systemctl daemon-reload
 if [ $1 = 1 ]; then
     # installation
-    systemctl start ode.service
+    systemctl start ode.socket \
+                                       ode.service \
+                                       ode-mount-external.path \
+                                       ode-umount-internal.path \
+                                       ode-progress-internal@Decrypting.path \
+                                       ode-progress-internal@Encrypting.path
 elif [ $1 = 2 ]; then
     # update
-    systemctl restart ode.service
+    systemctl restart ode.socket \
+                                               ode.service \
+                                               ode-mount-external.path \
+                                               ode-umount-internal.path\
+                                               ode-progress-internal@Decrypting.path \
+                                               ode-progress-internal@Encrypting.path
 fi
 
 %preun
index 8015b94..c8342c5 100644 (file)
@@ -72,6 +72,7 @@ CONFIGURE_FILE(systemd/${PROJECT_NAME}-umount-internal.service.in systemd/${PROJ
 CONFIGURE_FILE(systemd/${PROJECT_NAME}-progress-internal@.service.in systemd/${PROJECT_NAME}-progress-internal@.service)
 
 INSTALL(TARGETS ${SERVER_NAME} DESTINATION ${BIN_DIR})
+INSTALL(FILES systemd/${PROJECT_NAME}.socket DESTINATION ${SYSTEMD_UNIT_DIR})
 INSTALL(FILES systemd/${PROJECT_NAME}.service DESTINATION ${SYSTEMD_UNIT_DIR})
 INSTALL(FILES systemd/${PROJECT_NAME}-mount-external.path DESTINATION ${SYSTEMD_UNIT_DIR})
 INSTALL(FILES systemd/${PROJECT_NAME}-mount-external.service DESTINATION ${SYSTEMD_UNIT_DIR})
index ffaf61b..b144cb4 100644 (file)
@@ -233,6 +233,10 @@ ExternalEncryption::ExternalEncryption(ODEControlContext &ctx) :
        ));
 
        externalAddEventReceiver();
+
+       if (getState() == State::Encrypted) {
+               context.ref();
+       }
 }
 
 ExternalEncryption::~ExternalEncryption()
@@ -313,6 +317,7 @@ int ExternalEncryption::encrypt(const std::string &password, unsigned int option
 
        KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
        auto encryptWorker = [MasterKey, options, this]() {
+               context.ref();
                try {
                        INFO(SINK, "Close all applications using external storage...");
                        killDependedApplications();
@@ -335,6 +340,7 @@ int ExternalEncryption::encrypt(const std::string &password, unsigned int option
                } catch (runtime::Exception &e) {
                        ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
                        ERROR(SINK, "Encryption failed - " + std::string(e.what()));
+                       context.unref();
                }
        };
 
@@ -379,6 +385,7 @@ int ExternalEncryption::decrypt(const std::string &password)
                        sync();
                        INFO(SINK, "Decryption completed");
                        ::vconf_set_str(EXTERNAL_STATE_VCONF_KEY, "unencrypted");
+                       context.unref();
                } catch (runtime::Exception &e) {
                        ERROR(SINK, "Decryption failed - " + std::string(e.what()));
                }
index ae410c5..31bc35f 100644 (file)
@@ -245,6 +245,7 @@ int InternalEncryption::encrypt(const std::string& password, unsigned int option
 
        KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
        auto encryptWorker = [MasterKey, options, this]() {
+               context.ref();
                try {
                        INFO(SINK, "Close all processes that use internal storage...");
                        stopDependedSystemdServices();
@@ -273,6 +274,7 @@ int InternalEncryption::encrypt(const std::string& password, unsigned int option
                        ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
                        ERROR(SINK, "Encryption failed - " + std::string(e.what()));
                }
+               context.unref();
        };
 
        std::thread asyncWork(encryptWorker);
@@ -296,6 +298,7 @@ int InternalEncryption::decrypt(const std::string& password)
 
        KeyManager::data MasterKey = keyManager.getMasterKey(pwData);
        auto decryptWorker = [MasterKey, this]() {
+               context.ref();
                try {
                        INFO(SINK, "Umount internal storage...");
                        stopDependedSystemdServices();
@@ -324,6 +327,7 @@ int InternalEncryption::decrypt(const std::string& password)
                        ::vconf_set_str(INTERNAL_STATE_VCONF_KEY, "error_partially_encrypted");
                        ERROR(SINK, "Decryption failed - " + std::string(e.what()));
                }
+               context.unref();
        };
 
        std::thread asyncWork(decryptWorker);
index c5824b0..7495b37 100644 (file)
@@ -31,7 +31,8 @@ using namespace std::placeholders;
 
 namespace {
 
-const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.sock";
+const int ODE_MANAGER_ONDEMAND_TIMEOUT = 1000;
+const std::string ODE_MANAGER_ADDRESS = "/tmp/.ode.socket";
 
 std::unique_ptr<ode::SecureErase> secureErase;
 std::unique_ptr<ode::InternalEncryption> internalEncryption;
@@ -43,7 +44,8 @@ std::unique_ptr<audit::DlogLogSink> _sink = nullptr;
 
 audit::LogSink *SINK = nullptr;
 
-Server::Server()
+Server::Server() :
+       referenceCount(0)
 {
        _sink.reset(new audit::DlogLogSink("ODE"));
        SINK = dynamic_cast<audit::LogSink*>((_sink).get());
@@ -73,7 +75,10 @@ Server::~Server()
 void Server::run()
 {
        // Prepare execution environment
-       service->start();
+       service->start(true, ODE_MANAGER_ONDEMAND_TIMEOUT);
+       while (referenceCount > 0) {
+               service->mainloop.dispatch(ODE_MANAGER_ONDEMAND_TIMEOUT);
+       }
 }
 
 void Server::terminate()
index d7a439d..28e192a 100644 (file)
@@ -71,8 +71,19 @@ public:
        runtime::FileDescriptor registerNotificationSubscriber(const std::string& name);
        int unregisterNotificationSubscriber(const std::string& name, int id);
 
+       void ref()
+       {
+               referenceCount++;
+       }
+
+       void unref()
+       {
+               referenceCount--;
+       }
+
 private:
        std::string securityLabel;
+       std::atomic<int> referenceCount;
        std::unique_ptr<rmi::Service> service;
 };
 
diff --git a/server/systemd/ode.socket b/server/systemd/ode.socket
new file mode 100644 (file)
index 0000000..0dd7a5b
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=ODE daemon socket
+Wants=ode.service
+Before=ode.service
+
+[Socket]
+ListenStream=/tmp/.ode.socket
+Service=ode.service
+SocketMode=0770
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+[Install]
+WantedBy=sockets.target