Split crash-popup-launch from crash manager 78/204678/3
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Thu, 25 Apr 2019 08:39:09 +0000 (10:39 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Thu, 25 Apr 2019 13:22:14 +0000 (15:22 +0200)
Crash manager should not have any dbus depenency to increase its reliability.

Change-Id: I576d3730f47e6562dea71b9399c08cddf3280521

packaging/crash-worker.spec
src/crash-manager/CMakeLists.txt
src/crash-manager/crash-manager.c
src/crash-manager/crash-popup-launch.c [new file with mode: 0644]
src/crash-manager/dbus-util.h [new file with mode: 0644]

index aa9acee..5b6cea8 100644 (file)
@@ -182,6 +182,7 @@ sed -i "/${pattern}/D" %{_sysconfdir}/ld.so.preload
 %attr(0750,system_fw,system_fw) %{_bindir}/crash-manager
 %attr(0750,system_fw,system_fw) %{_bindir}/dump_systemstate
 %{_libexecdir}/crash-stack
+%{_libexecdir}/crash-popup-launch
 
 %if %{with logdump}
 %dir %{crash_all_log}
index b06e32a..01c2a97 100644 (file)
@@ -30,6 +30,11 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
 ADD_EXECUTABLE(${PROJECT_NAME} ${CRASH_MANAGER_SRCS})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${crash-manager_pkgs_LDFLAGS} -pie -lrt)
 
+set(CRASH_POPUP crash-popup-launch)
+ADD_EXECUTABLE(${CRASH_POPUP} ${CRASH_POPUP}.c)
+TARGET_LINK_LIBRARIES(crash-popup-launch ${crash-manager_pkgs_LDFLAGS} -pie -lrt)
+install(TARGETS ${CRASH_POPUP} DESTINATION libexec)
+
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin
                PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
index f82ab25..10c3cd6 100644 (file)
 
 /* Parsing */
 #define KEY_MAX              255
-
-/* Crash-popup dbus */
-#define POPUP_BUS_NAME       "org.tizen.system.popup"
-#define POPUP_OBJECT_PATH    "/Org/Tizen/System/Popup/Crash"
-#define POPUP_INTERFACE_NAME POPUP_BUS_NAME".Crash"
-#define POPUP_METHOD         "PopupLaunch"
-
 #define APPID_MAX                   128
 #define PKGNAME_MAX                 128
 
@@ -456,55 +449,14 @@ static int get_sysassert_cs(struct crash_info *cinfo)
 
 static void launch_crash_popup(struct crash_info *cinfo)
 {
-       GDBusConnection *conn;
-       GVariantBuilder *builder;
-       GVariant *parameters = NULL;
-       GVariant *reply = NULL;
-       GError *error = NULL;
-       int ret;
-
-       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
-       if (error) {
-               _E("Failed to get dbus: %s", error->message);
-               g_error_free(error);
-               return;
-       }
+       assert(cinfo);
 
-       builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
-       g_variant_builder_add(builder, "{ss}", "_SYSPOPUP_CONTENT_", "crash");
-       g_variant_builder_add(builder, "{ss}", "_PROCESS_NAME_",
-                       basename(cinfo->cmd_line));
-       g_variant_builder_add(builder, "{ss}", "_EXEPATH_", cinfo->cmd_path);
-       parameters = g_variant_new("(a{ss})", builder);
-       g_variant_builder_unref(builder);
-
-       reply = g_dbus_connection_call_sync(conn,
-                                           POPUP_BUS_NAME,
-                                           POPUP_OBJECT_PATH,
-                                           POPUP_INTERFACE_NAME,
-                                           POPUP_METHOD,
-                                           parameters,
-                                           G_VARIANT_TYPE("(i)"),
-                                           G_DBUS_CALL_FLAGS_NONE,
-                                           120000,
-                                           NULL,
-                                           &error);
-       if (error) {
-               _E("Failed to get reply: %s", error->message);
-               g_error_free(error);
-               goto exit;
-       }
-
-       g_variant_get(reply, "(i)", &ret);
-       _I("Crash_popup is launched: (%d)", ret);
-
-exit:
-       if (reply)
-               g_variant_unref(reply);
-       if (parameters)
-               g_variant_unref(parameters);
+       char *av[] = { "/usr/libexec/crash-popup-launch",
+                       "--cmdline", cinfo->cmd_line,
+                       "--cmdpath", cinfo->cmd_path,
+                       NULL };
 
-       g_object_unref(conn);
+       spawn(av, NULL, spawn_nullstdfds, NULL, NULL, NULL);
 }
 
 static bool dump_system_state(const struct crash_info *cinfo, pid_t *pid)
diff --git a/src/crash-manager/crash-popup-launch.c b/src/crash-manager/crash-popup-launch.c
new file mode 100644 (file)
index 0000000..1f24915
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * crash-popup: request showing crash-popup via d-bus
+ * This utility is separate exececutable to limit crash-manager dependencies.
+ *
+ * Copyright (c) 2019 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.
+ */
+
+#define LOG_TAG "CRASH_MANAGER"
+#include "shared/log.h"
+#include "dbus-util.h"
+
+#include <assert.h>
+#include <getopt.h>
+#include <gio/gio.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define POPUP_BUS_NAME       "org.tizen.system.popup"
+#define POPUP_OBJECT_PATH    "/Org/Tizen/System/Popup/Crash"
+#define POPUP_INTERFACE_NAME POPUP_BUS_NAME".Crash"
+#define POPUP_METHOD         "PopupLaunch"
+
+bool launch_crash_popup(GDBusConnection *conn, const char *const cmdline, const char *const cmdpath)
+{
+       assert(conn);
+       assert(cmdline);
+       assert(cmdpath);
+
+       GVariantBuilder *builder;
+       GVariant *parameters = NULL;
+       GVariant *reply = NULL;
+       GError *error = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
+       g_variant_builder_add(builder, "{ss}", "_SYSPOPUP_CONTENT_", "crash");
+       g_variant_builder_add(builder, "{ss}", "_PROCESS_NAME_", basename(cmdline));
+       g_variant_builder_add(builder, "{ss}", "_EXEPATH_", cmdpath);
+       parameters = g_variant_new("(a{ss})", builder);
+       g_variant_builder_unref(builder);
+
+       reply = g_dbus_connection_call_sync(conn,
+                                           POPUP_BUS_NAME,
+                                           POPUP_OBJECT_PATH,
+                                           POPUP_INTERFACE_NAME,
+                                           POPUP_METHOD,
+                                           parameters,
+                                           G_VARIANT_TYPE("(i)"),
+                                           G_DBUS_CALL_FLAGS_NONE,
+                                           120000,
+                                           NULL,
+                                           &error);
+       bool ret = false;
+       if (error) {
+               _E("Failed to get reply from popup service: %s", error->message);
+               g_error_free(error);
+               goto out;
+       }
+
+       int reply_code;
+       g_variant_get(reply, "(i)", &reply_code);
+       _I("Crash popup launched: (%d)", reply_code);
+
+       ret = true;
+out:
+       if (reply)
+               g_variant_unref(reply);
+       if (parameters)
+               g_variant_unref(parameters);
+
+       return ret;
+}
+
+bool parse_cmdline(int ac, char *av[], char **cmdline, char **cmdpath)
+{
+       assert(av);
+       assert(cmdline);
+       assert(cmdpath);
+
+       enum {
+               FLAG_CMDLINE = 1,
+               FLAG_CMDPATH,
+       };
+       static const struct option options[] = {
+               { .name = "cmdline", .has_arg = required_argument, .flag = NULL, .val = FLAG_CMDLINE },
+               { .name = "cmdpath", .has_arg = required_argument, .flag = NULL, .val = FLAG_CMDPATH },
+               { NULL },
+       };
+
+       int val;
+       do {
+               val = getopt_long_only(ac, av, "", options, NULL);
+
+               if (FLAG_CMDLINE == val)
+                       *cmdline = optarg;
+               else if (FLAG_CMDPATH == val)
+                       *cmdpath = optarg;
+       } while (val != -1);
+
+       return *cmdline && *cmdpath;
+}
+
+void usage(const char *const progname)
+{
+       assert(progname);
+
+       printf("%s --cmdline CMDLINE --cmdpath CMDPATH\n", progname);
+}
+
+int main(int ac, char *av[])
+{
+       char *cmdline = NULL, *cmdpath = NULL;
+
+       if (!parse_cmdline(ac, av, &cmdline, &cmdpath)) {
+               usage(av[0]);
+               return EXIT_FAILURE;
+       }
+
+       GDBusConnection *conn = NULL;
+       if (!bus_get(&conn))
+               return EXIT_FAILURE;
+
+       launch_crash_popup(conn, cmdline, cmdpath);
+       bus_put(conn);
+
+       return EXIT_SUCCESS;
+}
diff --git a/src/crash-manager/dbus-util.h b/src/crash-manager/dbus-util.h
new file mode 100644 (file)
index 0000000..14d953c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#pragma once
+
+#include "shared/log.h"
+
+#include <assert.h>
+#include <gio/gio.h>
+#include <stdbool.h>
+
+bool bus_get(GDBusConnection **connection)
+{
+       assert(connection);
+
+       GError *error = NULL;
+       GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (error) {
+               _E("Failed to get D-Bus system bus: %s", error->message);
+               g_error_free(error);
+               return false;
+       }
+
+       *connection = conn;
+       return true;
+}
+
+void bus_put(GDBusConnection *connection)
+{
+       assert(connection);
+
+       g_object_unref(connection);
+}
+