log_dump: triggered by dbus method call 14/96014/2 accepted/tizen/common/20161108.131657 accepted/tizen/ivi/20161109.002238 accepted/tizen/mobile/20161109.002140 accepted/tizen/tv/20161109.002159 accepted/tizen/wearable/20161109.002218 submit/tizen/20161108.022628
authorSunmin Lee <sunm.lee@samsung.com>
Mon, 7 Nov 2016 09:02:57 +0000 (18:02 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Mon, 7 Nov 2016 10:31:20 +0000 (19:31 +0900)
Add dbus activation feature to log_dump.
It handles two method: normal_dump, short_dump.
Each method corresponds to the options of log_dump.

Change-Id: I3384954f70c55fb7990fe9c5e14405ba63673a63
Signed-off-by: Sunmin Lee <sunm.lee@samsung.com>
packaging/crash-worker.spec
src/log_dump/CMakeLists.txt
src/log_dump/dbus-handler.c [new file with mode: 0644]
src/log_dump/dbus-handler.h [new file with mode: 0644]
src/log_dump/log_dump.c
src/log_dump/log_dump.h [new file with mode: 0644]
src/log_dump/org.tizen.system.crash.service [new file with mode: 0644]

index 4e1233734fe8bf6a939e6e298aa11cc024d36cbd..3fa121296bf00f17892546f578ec0d6747f28a60 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:      crash-worker
 Summary:    Crash-manager
-Version:    0.2.0
+Version:    0.3.0
 Release:    1
 Group:      Framework/system
 License:    Apache-2.0 and PD
@@ -11,6 +11,7 @@ Source1001:    crash-worker.manifest
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  cmake
 %if "%{?sys_assert}" == "on"
 BuildRequires:  pkgconfig(libunwind)
@@ -118,8 +119,6 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload
 
 %endif
 
-
-
 %files
 %license LICENSE
 %manifest crash-worker.manifest
@@ -133,6 +132,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload
 %attr(0755,system,system) %{_bindir}/crash-manager.sh
 %attr(0755,system,system) %{_bindir}/log_dump
 %{_prefix}/lib/sysctl.d/99-crash-manager.conf
+%{_datadir}/dbus-1/system-services/org.tizen.system.crash.service
 
 %if "%{?sys_assert}" == "on"
 %{_libdir}/libsys-assert.so
index 892055966e27cbf2cac8607633247ac9c43c7ec4..12bab7ec6dad96608bff01b7b025f71d375522e5 100644 (file)
@@ -4,6 +4,7 @@ PROJECT(log_dump C)
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
 SET(LOG_DUMP_SRCS
        log_dump.c
+       dbus-handler.c
        ${CMAKE_SOURCE_DIR}/src/shared/util.c
    )
 
@@ -12,6 +13,8 @@ pkg_check_modules(log_dump_pkgs REQUIRED
        dlog
        capi-system-info
        libtzplatform-config
+       glib-2.0
+       gio-2.0
        )
 
 FOREACH(flag ${log_dump_pkgs_CFLAGS})
@@ -23,6 +26,8 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 ADD_EXECUTABLE(${PROJECT_NAME} ${LOG_DUMP_SRCS})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${log_dump_pkgs_LDFLAGS})
 
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.system.crash.service
+       DESTINATION /usr/share/dbus-1/system-services)
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin
                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
diff --git a/src/log_dump/dbus-handler.c b/src/log_dump/dbus-handler.c
new file mode 100644 (file)
index 0000000..adfe7ac
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * log_dump
+ *
+ * Copyright (c) 2016 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 <stdbool.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include "log_dump.h"
+#include "dbus-handler.h"
+
+#define CRASH_BUS_NAME "org.tizen.system.crash"
+#define CRASH_BUS_PATH "/Org/Tizen/System/Crash"
+
+#define TIMEOUT_INTERVAL 30
+
+static GMainLoop *loop;
+static GMutex timeout_mutex;
+static guint timeout_id;
+static GDBusNodeInfo *introspection_data;
+static const gchar introspection_xml[] =
+"<node>"
+" <interface name='org.tizen.system.crash'>"
+"  <method name='normal_dump'>"
+"   <arg type='i' name='response' direction='out'/>"
+"  </method>"
+"  <method name='short_dump'>"
+"   <arg type='i' name='response' direction='out'/>"
+"  </method>"
+" </interface>"
+"</node>";
+
+static int timeout_cb(gpointer data)
+{
+       LOGI("Time out!");
+       g_main_loop_quit((GMainLoop *)data);
+
+       return 0;
+}
+
+static void add_timeout(void)
+{
+       g_mutex_lock(&timeout_mutex);
+
+       if (timeout_id)
+               g_source_remove(timeout_id);
+       timeout_id = g_timeout_add_seconds(TIMEOUT_INTERVAL, timeout_cb, loop);
+
+       g_mutex_unlock(&timeout_mutex);
+       LOGI("Add loop timeout (%d)", TIMEOUT_INTERVAL);
+}
+
+static void remove_timeout(void)
+{
+       g_mutex_lock(&timeout_mutex);
+
+       if (timeout_id) {
+               g_source_remove(timeout_id);
+               timeout_id = 0;
+       }
+
+       g_mutex_unlock(&timeout_mutex);
+       LOGI("Remove loop timeout");
+}
+
+static void method_call_handler(GDBusConnection *conn,
+                               const gchar *sender,
+                               const gchar *object_path,
+                               const gchar *iface_name,
+                               const gchar *method_name,
+                               GVariant *parameters,
+                               GDBusMethodInvocation *invocation,
+                               gpointer user_data)
+{
+       int ret = -1;
+       int option = -1;
+
+       remove_timeout();
+
+       if (g_strcmp0(method_name, "normal_dump") == 0)
+               option = OPT_NORMAL;
+       else if (g_strcmp0(method_name, "short_dump") == 0)
+               option = OPT_SHORT;
+
+       if (option >= 0)
+               ret = log_dump(option);
+       g_dbus_method_invocation_return_value(invocation,
+                       g_variant_new("(i)", ret));
+
+       add_timeout();
+}
+
+static const GDBusInterfaceVTable interface_vtable = {
+       method_call_handler,
+       NULL,
+       NULL
+};
+
+static void on_bus_acquired(GDBusConnection *conn,
+                           const gchar *name,
+                           gpointer user_data)
+{
+       guint registration_id;
+
+       registration_id = g_dbus_connection_register_object(conn,
+                       CRASH_BUS_PATH, introspection_data->interfaces[0],
+                       &interface_vtable, NULL, NULL, NULL);
+       if (registration_id == 0)
+               LOGE("Failed to g_dbus_connection_register_object");
+}
+
+static void on_name_acquired(GDBusConnection *conn,
+                            const gchar *name,
+                            gpointer user_data)
+{
+       LOGD("Acquired the name %s on the system bus", name);
+}
+
+static void on_name_lost(GDBusConnection *conn,
+                        const gchar *name,
+                        gpointer user_data)
+{
+       LOGD("Lost the name %s on the system bus", name);
+}
+
+static void dbus_init(void)
+{
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+
+       introspection_data =
+               g_dbus_node_info_new_for_xml(introspection_xml, NULL);
+       if (introspection_data == NULL) {
+               LOGE("Failed to init g_dbus_info_new_for_xml");
+               return;
+       }
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (!conn) {
+               LOGE("Failed to get dbus");
+               return;
+       }
+
+       if (error) {
+               LOGE("Failed to get dbus");
+               g_error_free(error);
+               return;
+       }
+
+       g_bus_own_name(G_BUS_TYPE_SYSTEM, CRASH_BUS_NAME,
+                       G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired,
+                       on_name_acquired, on_name_lost, NULL, NULL);
+}
+
+int log_dump_dbus(void)
+{
+       loop = g_main_loop_new(NULL, false);
+
+       dbus_init();
+
+       g_mutex_init(&timeout_mutex);
+       add_timeout();
+
+       LOGI("log_dump_dbus activated");
+       g_main_loop_run(loop);
+
+       if (introspection_data)
+               g_dbus_node_info_unref(introspection_data);
+       g_mutex_clear(&timeout_mutex);
+       g_main_loop_unref(loop);
+
+       return 0;
+}
diff --git a/src/log_dump/dbus-handler.h b/src/log_dump/dbus-handler.h
new file mode 100644 (file)
index 0000000..0d3d5d9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * log_dump
+ *
+ * Copyright (c) 2016 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 __LOGDUMP_DBUS_H__
+#define __LOGDUMP_DBUS_H__
+
+int log_dump_dbus(void);
+
+#endif
index 38180f5b61ebfed5f628d4e7a30d69fdb4ee28d6..cdfa7f048be8bc0ca31e23f1d25a3bc855215ec6 100644 (file)
@@ -1,4 +1,5 @@
-/* log_dump: dump current system states
+/*
+ * log_dump: dump current system states
  *
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
 #include <time.h>
 #include <unistd.h>
 #include <dirent.h>
-#include <dlog.h>
 #include <system_info.h>
 #include <tzplatform_config.h>
 #include "shared/util.h"
+#include "log_dump.h"
+#include "dbus-handler.h"
 
 #undef LOG_TAG
 #define LOG_TAG          "LOG_DUMP"
 #define DUMP_SCRIPTS_DIR tzplatform_getenv(TZ_SYS_DUMPGEN)
 #define SYSTEM_INFO_KEY_BUILD_STRING "http://tizen.org/system/build.string"
 
-enum {
-       OPT_NORMAL,
-       OPT_SHORT,
-};
-
 static const struct option opts[] = {
        { "normal", no_argument, 0, OPT_NORMAL },
        { "short",  no_argument, 0, OPT_SHORT  },
+       { "dbus",   no_argument, 0, OPT_DBUS   },
        { 0, 0, 0, 0 }
 };
 
@@ -53,6 +51,8 @@ static inline void usage(void)
                        "dump all logs", DUMP_SCRIPTS_DIR);
        printf("  %-10s %s\n", "--short",
                        "dump systemstate only");
+       printf("  %-10s %s\n", "--dbus",
+                       "activate dbus interface");
 }
 
 static int dump_scripts(const char *path)
@@ -85,10 +85,9 @@ static int dump_scripts(const char *path)
        return 0;
 }
 
-int main(int argc, char *argv[])
+int log_dump(int option)
 {
-       int c, ret;
-       int opt_normal, opt_short;
+       int ret;
        char *version_str = NULL;
        char timestr[80];
        char command[PATH_MAX];
@@ -96,40 +95,16 @@ int main(int argc, char *argv[])
        time_t cur_time;
        struct tm loc_tm;
 
-       if (argc < 2) {
-               usage();
-               exit(EXIT_SUCCESS);
-       }
-
-       opt_normal = opt_short = 0;
-       while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) {
-               switch (c) {
-               case OPT_NORMAL:
-                       opt_normal = 1;
-                       break;
-               case OPT_SHORT:
-                       opt_short = 1;
-                       break;
-               default:
-                       usage();
-                       exit(EXIT_SUCCESS);
-                       break;
-               }
-       }
-
-       if (opt_normal & opt_short) {
-               usage();
-               exit(EXIT_SUCCESS);
-       }
-
        /* Make debug directory */
-       ret = snprintf(command, sizeof(command),
-                       "/usr/bin/mkdir -p %s", LOG_DUMP_DIR);
-       if (ret < 0) {
-               LOGE("Failed to mkdir");
-               exit(EXIT_FAILURE);
+       if (access(LOG_DUMP_DIR, F_OK) != 0) {
+               ret = snprintf(command, sizeof(command),
+                               "/usr/bin/mkdir -p %s", LOG_DUMP_DIR);
+               if (ret < 0) {
+                       LOGE("Failed to mkdir");
+                       return -1;
+               }
+               system_command(command);
        }
-       system_command(command);
 
        /* Get timestamp */
        cur_time = time(NULL);
@@ -150,12 +125,12 @@ int main(int argc, char *argv[])
                        "%s/dump_systemstate_%s.log", LOG_DUMP_DIR, timestr);
        if (ret < 0) {
                LOGE("Failed to snprintf for command");
-               exit(EXIT_FAILURE);
+               goto exit;
        }
        system_command(command);
 
        /* Dump all logs */
-       if (opt_normal)
+       if (option == OPT_NORMAL)
                dump_scripts(DUMP_SCRIPTS_DIR);
 
        if (version_str) {
@@ -163,14 +138,14 @@ int main(int argc, char *argv[])
                                "log_dump", version_str);
                if (ret < 0) {
                        LOGE("Failed to snprintf for dump path");
-                       exit(EXIT_FAILURE);
+                       goto exit;
                }
        } else {
                ret = snprintf(dump_filename, sizeof(dump_filename), "%s",
                                "log_dump");
                if (ret < 0) {
                        LOGE("Failed to snprintf for dump path");
-                       exit(EXIT_FAILURE);
+                       return -1;
                }
        }
 
@@ -180,19 +155,75 @@ int main(int argc, char *argv[])
                        LOG_DUMP_ROOT, dump_filename, timestr, LOG_DUMP_ROOT);
        if (ret < 0) {
                LOGE("Failed to snprintf for command");
-               exit(EXIT_FAILURE);
+               goto exit;
        }
        system_command(command);
 
        sync();
 
-       if (remove_dir(LOG_DUMP_DIR, 0) < 0) {
-               ret = -1;
+       ret = remove_dir(LOG_DUMP_DIR, 0);
+       if (ret < 0) {
                LOGE("Failed to delete dump directory");
+               goto exit;
        }
 
+       /* Further operations for log_dump here */
+
+exit:
        if (version_str)
                free(version_str);
 
        return ret;
 }
+
+int main(int argc, char *argv[])
+{
+       int c, ret;
+       int option;
+
+       if (argc < 2) {
+               usage();
+               exit(EXIT_SUCCESS);
+       }
+
+       option = -1;
+       while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) {
+               switch (c) {
+               case OPT_NORMAL:
+                       if (option >= 0) {
+                               usage();
+                               exit(EXIT_SUCCESS);
+                       }
+                       option = OPT_NORMAL;
+                       break;
+               case OPT_SHORT:
+                       if (option >= 0) {
+                               usage();
+                               exit(EXIT_SUCCESS);
+                       }
+                       option = OPT_SHORT;
+                       break;
+               case OPT_DBUS:
+                       if (option >= 0) {
+                               usage();
+                               exit(EXIT_SUCCESS);
+                       }
+                       option = OPT_DBUS;
+                       break;
+               default:
+                       usage();
+                       exit(EXIT_SUCCESS);
+                       break;
+               }
+       }
+
+       if (option == OPT_DBUS)
+               ret = log_dump_dbus();
+       else
+               ret = log_dump(option);
+
+       if (ret < 0)
+               exit(EXIT_FAILURE);
+
+       return 0;
+}
diff --git a/src/log_dump/log_dump.h b/src/log_dump/log_dump.h
new file mode 100644 (file)
index 0000000..9936a08
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * log_dump
+ *
+ * Copyright (c) 2016 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 __LOGDUMP_H__
+#define __LOGDUMP_H__
+
+#include <dlog.h>
+#undef LOG_TAG
+#define LOG_TAG "LOG_DUMP"
+
+enum {
+       OPT_NORMAL,
+       OPT_SHORT,
+       OPT_DBUS,
+};
+
+int log_dump(int option);
+
+#endif
diff --git a/src/log_dump/org.tizen.system.crash.service b/src/log_dump/org.tizen.system.crash.service
new file mode 100644 (file)
index 0000000..1e9a605
--- /dev/null
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=org.tizen.system.crash
+Exec=/usr/bin/log_dump --dbus
+User=root
+Group=root