Add method for getting service's pid 24/30724/2
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Mon, 24 Nov 2014 05:18:35 +0000 (06:18 +0100)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Mon, 24 Nov 2014 17:12:41 +0000 (18:12 +0100)
Systemd that is responsible for launching service provide information
about it's pid with dbus properties mechanism.

Change-Id: Ia56094ad776a758596b4344172a6109b3648365e

tests/common/dbus_access.cpp
tests/common/dbus_access.h

index 9990d02..e83ed52 100644 (file)
@@ -41,6 +41,8 @@ DBusAccess::DBusAccess(const char *service_name)
   , m_dbus_systemd_destination("org.freedesktop.systemd1")
   , m_dbus_systemd_path("/org/freedesktop/systemd1")
   , m_dbus_systemd_manager_interface("org.freedesktop.systemd1.Manager")
+  , m_dbus_systemd_properties_interface("org.freedesktop.DBus.Properties")
+  , m_dbus_systemd_service_interface("org.freedesktop.systemd1.Service")
 {
     dbus_error_init(&m_err);
     connectToDBus();
@@ -80,6 +82,14 @@ void DBusAccess::requestName() {
         "Error in dbus_bus_request_name: " << m_err.message);
 }
 
+void DBusAccess::getUnitPath() {
+    newMethodCall("GetUnit");
+    appendToMsg(m_service_name.c_str());
+    sendMsgWithReply();
+    getMsgReply();
+    m_unitPath = handleObjectPathMsgReply();
+}
+
 void DBusAccess::newMethodCall(const char *method) {
     m_msg = dbus_message_new_method_call(m_dbus_systemd_destination.c_str(),
                                          m_dbus_systemd_path.c_str(),
@@ -135,6 +145,27 @@ std::string DBusAccess::handleObjectPathMsgReply() {
     return ret;
 }
 
+uint32_t DBusAccess::handleVariantUIntMsgReply() {
+    DBusMessageIter iter, iter2;
+
+    RUNNER_ASSERT_MSG(dbus_message_iter_init(m_msg, &iter) != 0,
+        "Message has no arguments");
+    if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&iter)) {
+        RUNNER_FAIL_MSG("Variant type expected");
+    }
+
+    dbus_message_iter_recurse(&iter, &iter2);
+    if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&iter2)) {
+        RUNNER_FAIL_MSG("uint32 type expected");
+    }
+
+    uint32_t ret;
+    dbus_message_iter_get_basic(&iter2, &ret);
+
+    finalizeMsgReply();
+    return ret;
+}
+
 void DBusAccess::finalizeMsgReply() {
     dbus_message_unref(m_msg);
     dbus_pending_call_unref(m_pending);
@@ -153,6 +184,7 @@ void DBusAccess::connectToDBus() {
                                [](void*)->void {});
     subscribeSignals();
     requestName();
+    getUnitPath();
 }
 
 void DBusAccess::sendToService(const char *method) {
@@ -164,6 +196,20 @@ void DBusAccess::sendToService(const char *method) {
     m_runningJobs.insert(handleObjectPathMsgReply());
 }
 
+uint32_t DBusAccess::getUIntProperty(const char *interface, const char *property)
+{
+    m_msg = dbus_message_new_method_call(m_dbus_systemd_destination.c_str(),
+                                         m_unitPath.c_str(),
+                                         m_dbus_systemd_properties_interface.c_str(),
+                                         "Get");
+
+    appendToMsg(interface);
+    appendToMsg(property);
+    sendMsgWithReply();
+    getMsgReply();
+    return handleVariantUIntMsgReply();
+}
+
 void DBusAccess::sendResetFailedToService() {
     newMethodCall("ResetFailedUnit");
     appendToMsg(m_service_name.c_str());
@@ -283,6 +329,10 @@ void DBusAccess::restartService() {
     sendResetFailedToService();
 }
 
+pid_t DBusAccess::getServicePid() {
+    return static_cast<pid_t>(getUIntProperty(m_dbus_systemd_service_interface.c_str(), "MainPID"));
+}
+
 DBusAccess::~DBusAccess() {
     dbus_connection_close(m_conn);
     if (m_conn)
index d59339f..597dc76 100644 (file)
@@ -40,6 +40,7 @@ public:
     void startService();
     void stopService();
     void restartService();
+    pid_t getServicePid();
 
     virtual ~DBusAccess();
 private:
@@ -47,15 +48,18 @@ private:
     void addBusMatch(const char *member);
     void subscribeSignals();
     void requestName();
+    void getUnitPath();
     void newMethodCall(const char *method);
     void appendToMsg(const char *argument);
     void sendMsgWithReply();
     void getMsgReply();
     std::string handleObjectPathMsgReply();
+    uint32_t handleVariantUIntMsgReply();
     void finalizeMsgReply();
 
     void connectToDBus();
     void sendToService(const char *method);
+    uint32_t getUIntProperty(const char *interface, const char *property);
     void sendResetFailedToService();
 
     static DBusHandlerResult messageHandler(DBusConnection *conn, DBusMessage *msg, void *t);
@@ -71,10 +75,13 @@ private:
 
     const std::string m_dbus_client_name;
     const std::string m_service_name;
+    std::string m_unitPath;
 
     const std::string m_dbus_systemd_destination;
     const std::string m_dbus_systemd_path;
     const std::string m_dbus_systemd_manager_interface;
+    const std::string m_dbus_systemd_properties_interface;
+    const std::string m_dbus_systemd_service_interface;
 
     std::set<std::string> m_runningJobs;
 };