From: Sangyoon Jang Date: Mon, 8 Aug 2016 10:35:51 +0000 (+0900) Subject: Implement pkgmgr-installer-signal-agent X-Git-Tag: submit/tizen/20160822.060113~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4cc051a98bbb842e8541d07eac9323b6196642d1;p=platform%2Fcore%2Fappfw%2Fslp-pkgmgr.git Implement pkgmgr-installer-signal-agent pkgmgr-installer-signal-agent receives signal information from backend installer, and emits into user-session bus. backend installer running as system user cannot use user session bus, so this agent will cover for it. Change-Id: I834782358cf37a151b44737a7592bf40c3fbeba1 Signed-off-by: Sangyoon Jang --- diff --git a/installer/CMakeLists.txt b/installer/CMakeLists.txt index 379aa14..48bafce 100644 --- a/installer/CMakeLists.txt +++ b/installer/CMakeLists.txt @@ -30,6 +30,11 @@ foreach(flag ${installer_pkgs_CFLAGS}) set(installer_pkgs_CFLAGS_str "${installer_pkgs_CFLAGS_str} ${flag}") endforeach() +PKG_CHECK_MODULES(AGENT_DEPS REQUIRED glib-2.0 gio-2.0 dlog libsystemd-daemon) +FOREACH(FLAG ${AGENT_DEPS_CFLAGS}) + SET(AGENT_CFLAGS "${AGENT_CFLAGS} ${FLAG}") +ENDFOREACH() + ### Build modules ## pkgmgr_installer object (by youmin.ha) @@ -48,3 +53,10 @@ INSTALL(TARGETS pkgmgr_installer DESTINATION ${LIB_INSTALL_DIR} COMPONENT Runtim INSTALL(FILES pkgmgr_installer.h DESTINATION include/pkgmgr) INSTALL(FILES pkgmgr_installer_info.h DESTINATION include/pkgmgr) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +## pkgmgr_installer_signal_agent +ADD_EXECUTABLE(pkgmgr-installer-signal-agent pkgmgr_installer_signal_agent.c) +SET_TARGET_PROPERTIES(pkgmgr-installer-signal-agent PROPERTIES COMPILE_FLAGS "${AGENT_CFLAGS}") +TARGET_LINK_LIBRARIES(pkgmgr-installer-signal-agent ${AGENT_DEPS_LDFLAGS}) + +INSTALL(TARGETS pkgmgr-installer-signal-agent DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/installer/pkgmgr_installer_signal_agent.c b/installer/pkgmgr_installer_signal_agent.c new file mode 100644 index 0000000..e96f963 --- /dev/null +++ b/installer/pkgmgr_installer_signal_agent.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../client/include/comm_config.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "PKGMGR_INSTALLER_SIGNAL_AGENT" + +#define BUFMAX 4096 + +static int server_fd; +static GMainLoop *loop; +static guint sid; +static guint tid; +static GDBusConnection *conn; + +static int __create_server_socket(const char *path) +{ + int r; + int fd; + struct sockaddr_un sa; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + LOGE("socket create failed: %d", errno); + return -1; + } + + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", path); + + r = unlink(sa.sun_path); + if (r == -1 && errno != ENOENT) { + LOGE("unlink(%s) failed: %d", sa.sun_path, errno); + close(fd); + return -1; + } + + r = bind(fd, (struct sockaddr *)&sa, sizeof(sa)); + if (r == -1) { + LOGE("bind(%s) failed: %d", sa.sun_path, errno); + close(fd); + return -1; + } + + r = chmod(sa.sun_path, 0666); + if (r == -1) + LOGW("chmod(%s) failed: %d", sa.sun_path, errno); + + r = listen(fd, SOMAXCONN); + if (r == -1) { + LOGE("listen(%s) failed: %d", sa.sun_path, errno); + close(fd); + return -1; + } + + return fd; +} + +static int __get_server_socket(const char *path) +{ + int i; + int n; + int r; + int fd = -1; + + n = sd_listen_fds(0); + if (n < 0) { + LOGE("sd_listen_fds: %d", n); + return -1; + } else if (n == 0) { + return __create_server_socket(path); + } + + for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + n; i++) { + r = sd_is_socket_unix(i, SOCK_STREAM, -1, path, 0); + if (r > 0) { + fd = i; + break; + } + } + + if (fd == -1) { + LOGE("socket is not passed, create server socket"); + return __create_server_socket(path); + } + + return fd; +} + +static void __emit_signal(const char *name, GVariant *gv) +{ + GError *err = NULL; + + if (g_dbus_connection_emit_signal(conn, NULL, + COMM_STATUS_BROADCAST_OBJECT_PATH, + COMM_STATUS_BROADCAST_INTERFACE, + name, gv, &err) != TRUE) { + LOGE("g_dbus_connection_emit_signal failed: %s", err->message); + g_error_free(err); + } +} + +static gboolean __quit(gpointer user_data) +{ + g_main_loop_quit(loop); + return FALSE; +} + +/** + * packet format: + * +----------------+-------------+-----------+-------------------+ + * |signal name size|GVariant size|signal name|serialized GVariant| + * +----------------+-------------+-----------+-------------------+ + */ +static gboolean __handle_signal(gint fd, GIOCondition cond, gpointer user_data) +{ + int r; + unsigned char buf[BUFMAX]; + int clifd; + struct sockaddr_un sa; + socklen_t s = sizeof(sa); + size_t type_len; + char *type_name; + gsize data_len; + gpointer data; + GVariant *gv; + + clifd = accept(fd, (struct sockaddr *)&sa, &s); + if (clifd == -1) { + LOGE("accept failed: %d", errno); + return FALSE; + } + + r = recv(clifd, buf, sizeof(size_t) + sizeof(gsize), 0); + if (r < 0) { + LOGE("recv failed: %d", errno); + close(clifd); + return FALSE; + } else if (r == 0) { + LOGE("client fd already closed"); + close(clifd); + return FALSE; + } + + memcpy(&type_len, buf, sizeof(size_t)); + memcpy(&data_len, buf + sizeof(int), sizeof(gsize)); + + r = recv(clifd, buf, type_len + data_len, 0); + if (r < 0) { + LOGE("recv failed: %d", errno); + close(clifd); + return FALSE; + } else if (r == 0) { + LOGE("client fd already closed"); + close(clifd); + return FALSE; + } + + /* get signal name (including terminating null byte) */ + type_name = malloc(type_len); + memcpy(type_name, buf, type_len); + + /* get data */ + data = malloc(data_len); + memcpy(data, buf + type_len, data_len); + + gv = g_variant_new_from_data(G_VARIANT_TYPE("(ussssss)"), data, + data_len, TRUE, NULL, NULL); + __emit_signal(type_name, gv); + + g_variant_unref(gv); + free(data); + free(type_name); + close(clifd); + + /* renew timeout */ + g_source_remove(tid); + tid = g_timeout_add_seconds(10, __quit, NULL); + + return TRUE; +} + +static int __init(void) +{ + char path[PATH_MAX]; + GError *err = NULL; + + snprintf(path, sizeof(path), "/run/pkgmgr/agent/%d", getuid()); + server_fd = __get_server_socket(path); + if (server_fd < 0) { + LOGE("server init failed"); + return -1; + } + + conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + if (conn == NULL) { + LOGE("g_bus_get_sync failed: %s", err->message); + g_error_free(err); + close(server_fd); + return -1; + } + + loop = g_main_loop_new(NULL, FALSE); + sid = g_unix_fd_add(server_fd, G_IO_IN, __handle_signal, NULL); + tid = g_timeout_add_seconds(10, __quit, NULL); + + return 0; +} + +static void __fini(void) +{ + g_source_remove(sid); + g_main_loop_unref(loop); + g_object_unref(conn); + close(server_fd); +} + +int main(int argc, char *argv[]) +{ + int r; + + r = __init(); + if (r < 0) + return -1; + + g_main_loop_run(loop); + + __fini(); + + return 0; +} diff --git a/packaging/pkgmgr-installer-signal-agent.service b/packaging/pkgmgr-installer-signal-agent.service new file mode 100644 index 0000000..545ff4a --- /dev/null +++ b/packaging/pkgmgr-installer-signal-agent.service @@ -0,0 +1,6 @@ +[Unit] +Description=Package Manager Installer Signal Agent on User Session + +[Service] +Type=oneshot +ExecStart=/usr/bin/pkgmgr-installer-signal-agent diff --git a/packaging/pkgmgr-installer-signal-agent.socket b/packaging/pkgmgr-installer-signal-agent.socket new file mode 100644 index 0000000..92caf14 --- /dev/null +++ b/packaging/pkgmgr-installer-signal-agent.socket @@ -0,0 +1,7 @@ +[Socket] +ListenStream=/run/pkgmgr/agent/%U +DirectoryMode=0777 +ExecStartPost=/usr/bin/chmod 0777 /run/pkgmgr/agent/%U + +[Install] +WantedBy=sockets.target diff --git a/packaging/pkgmgr.conf b/packaging/pkgmgr.conf index 129544b..c92c823 100644 --- a/packaging/pkgmgr.conf +++ b/packaging/pkgmgr.conf @@ -1,3 +1,4 @@ d /tmp/pkgmgr 1777 root users t /tmp/pkgmgr - - - - security.SMACK64="User::App::Shared" t /tmp/pkgmgr - - - - security.SMACK64TRANSMUTE="TRUE" +d /run/pkgmgr/agent 0777 root users - diff --git a/packaging/pkgmgr.spec b/packaging/pkgmgr.spec index 3dfcbb7..326702d 100644 --- a/packaging/pkgmgr.spec +++ b/packaging/pkgmgr.spec @@ -14,6 +14,8 @@ Source1004: %{name}-installer.manifest Source1005: %{name}-installer-devel.manifest Source1006: %{name}-types-devel.manifest Source1007: %{name}.conf +Source1008: %{name}-installer-signal-agent.service +Source1009: %{name}-installer-signal-agent.socket Requires(post): /usr/sbin/useradd BuildRequires: cmake @@ -31,6 +33,7 @@ BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(xdgmime) BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgmgr-info-parser-devel BuildRequires: pkgmgr-info-parser BuildRequires: fdupes @@ -99,6 +102,11 @@ rm -f %{buildroot}%{_libdir}/libpkgmgr_parser_lib_sample.so mkdir -p %{buildroot}%{_tmpfilesdir}/ install -m 0644 %{SOURCE1007} %{buildroot}%{_tmpfilesdir}/pkgmgr.conf +mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants +install -m 0644 %{SOURCE1008} %{buildroot}%{_unitdir_user}/pkgmgr-installer-signal-agent.service +install -m 0644 %{SOURCE1009} %{buildroot}%{_unitdir_user}/pkgmgr-installer-signal-agent.socket +ln -sf ../alarm_session_agent.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/pkgmgr-installer-signal-agent.socket + mkdir -p %{buildroot}%{_sysconfdir}/package-manager/backend mkdir -p %{buildroot}%{_sysconfdir}/package-manager/backendlib mkdir -p %{buildroot}%{_sysconfdir}/opt/upgrade @@ -160,6 +168,10 @@ HOME="$saveHOME" %manifest %{name}-installer.manifest %defattr(-,root,root,-) %{_libdir}/libpkgmgr_installer.so.* +%{_bindir}/pkgmgr-installer-signal-agent +%{_unitdir_user}/pkgmgr-installer-signal-agent.service +%{_unitdir_user}/pkgmgr-installer-signal-agent.socket +%{_unitdir_user}/sockets.target.wants/pkgmgr-installer-signal-agent.socket %files installer-devel %manifest %{name}-installer-devel.manifest