From 2af8a6ac30d93ddbc70bbf8c0be3cc3c39a3aa61 Mon Sep 17 00:00:00 2001 From: Sung-jae Park Date: Thu, 13 Jun 2013 09:57:24 +0900 Subject: [PATCH] Update SMACK, Fix a crash of terminating sequence, etc, ... [model] Tizen [binary_type] AP [customer] Tizen Developer [issue#] N/A [problem] SMACK label is separated, Crash of terminating sequence [cause] Terminating sequence is not valid when the edje plugin is loaded. SMACK should be separated by each service module. [solution] Update SMACK label. Fix the crash of terminating sequence [team] HomeTF [request] [horizontal_expansion] Change-Id: I8aa7c4773a6548685e63bd3e822d83cbbb01db98 --- CMakeLists.txt | 11 ++ include/client_life.h | 2 +- include/debug.h | 16 +- include/instance.h | 4 +- include/package.h | 3 + include/service_common.h | 2 + include/slave_life.h | 3 + packaging/data-provider-master.spec | 13 +- pkgmgr_livebox/src/service_register.c | 70 +++++++-- src/badge_service.c | 25 ++- src/buffer_handler.c | 12 +- src/client_life.c | 8 +- src/conf.c | 5 +- src/critical_log.c | 22 ++- src/dead_monitor.c | 3 +- src/fault_manager.c | 3 +- src/fb.c | 4 +- src/instance.c | 8 +- src/io.c | 9 +- src/liveinfo.c | 15 +- src/main.c | 55 +++++-- src/notification_service.c | 27 +++- src/package.c | 59 +++++++- src/parser.c | 3 +- src/script_handler.c | 43 ++++-- src/server.c | 276 +++++++++++++++++++++++++++------- src/service_common.c | 94 +++++++++--- src/setting.c | 83 +++++++++- src/shortcut_service.c | 26 +++- src/slave_life.c | 62 +++++++- src/slave_rpc.c | 10 +- src/utility_service.c | 104 ++++++++++--- src/xmonitor.c | 8 +- 33 files changed, 884 insertions(+), 204 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a907636..b7764ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ pkg_check_modules(pkg REQUIRED livebox-service notification badge + libsmack ) SET(PACKAGE "${PROJECT_NAME}") @@ -48,6 +49,16 @@ ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\" ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"") ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/opt/usr/share/live_magazine/.service.socket\"") +ADD_DEFINITIONS("-DBADGE_SOCKET=\"/tmp/.badge.service\"") +ADD_DEFINITIONS("-DSHORTCUT_SOCKET=\"/tmp/.shortcut.service\"") +ADD_DEFINITIONS("-DNOTIFICATION_SOCKET=\"/tmp/.notification.service\"") +ADD_DEFINITIONS("-DUTILITY_SOCKET=\"/tmp/.utility.service\"") + +ADD_DEFINITIONS("-DUTILITY_SMACK_LABEL=\"data-provider-master::utility\"") +ADD_DEFINITIONS("-DSHORTCUT_SMACK_LABEL=\"data-provider-master::shortcut\"") +ADD_DEFINITIONS("-DNOTIFICATION_SMACK_LABEL=\"data-provider-master::notification\"") +ADD_DEFINITIONS("-DBADGE_SMACK_LABEL=\"data-provider-master::badge\"") + ADD_DEFINITIONS("-DNDEBUG") #ADD_DEFINITIONS("-DFLOG") ADD_DEFINITIONS(${pkg_CFLAGS}) diff --git a/include/client_life.h b/include/client_life.h index 446b952..66caf9a 100644 --- a/include/client_life.h +++ b/include/client_life.h @@ -62,7 +62,7 @@ extern int client_count(void); * \note * For dead signal handler */ -extern int client_deactivated_by_fault(struct client_node *client); +extern struct client_node *client_deactivated_by_fault(struct client_node *client); extern void client_reset_fault(struct client_node *client); extern const int const client_is_faulted(const struct client_node *client); diff --git a/include/debug.h b/include/debug.h index fb7c780..0929bf0 100644 --- a/include/debug.h +++ b/include/debug.h @@ -14,9 +14,21 @@ * limitations under the License. */ +#if !defined(SECURE_LOGD) +#define SECURE_LOGD LOGD +#endif + +#if !defined(SECURE_LOGE) +#define SECURE_LOGE LOGE +#endif + +#if !defined(SECURE_LOGW) +#define SECURE_LOGW LOGW +#endif + #if !defined(FLOG) -#define DbgPrint(format, arg...) LOGD("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) -#define ErrPrint(format, arg...) LOGE("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) +#define DbgPrint(format, arg...) SECURE_LOGD("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) +#define ErrPrint(format, arg...) SECURE_LOGE("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) #else extern FILE *__file_log_fp; #define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) diff --git a/include/instance.h b/include/instance.h index c21e58c..54ba80a 100644 --- a/include/instance.h +++ b/include/instance.h @@ -229,8 +229,8 @@ extern int instance_del_client(struct inst_info *inst, struct client_node *clien extern int instance_has_client(struct inst_info *inst, struct client_node *client); extern void *instance_client_list(struct inst_info *inst); -extern void instance_init(void); -extern void instance_fini(void); +extern int instance_init(void); +extern int instance_fini(void); extern int instance_event_callback_add(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data), void *data); extern int instance_event_callback_del(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data)); diff --git a/include/package.h b/include/package.h index 488f465..330628f 100644 --- a/include/package.h +++ b/include/package.h @@ -99,6 +99,7 @@ extern void package_set_pd_height(struct pkg_info *info, int height); extern void package_set_pd_width(struct pkg_info *info, int width); extern int package_set_abi(struct pkg_info *info, const char *abi); extern void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info); +extern void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info); /*! * \brief @@ -124,4 +125,6 @@ extern int const package_fault_count(struct pkg_info *info); extern int package_init(void); extern int package_fini(void); +extern int package_is_enabled(const char *appid); + /* End of a file */ diff --git a/include/service_common.h b/include/service_common.h index eb6e385..eaa06ea 100644 --- a/include/service_common.h +++ b/include/service_common.h @@ -37,4 +37,6 @@ extern int service_common_unicast_packet(struct tcb *tcb, struct packet *packet) extern struct service_event_item *service_common_add_timer(struct service_context *svc_ctx, double timer, int (*timer_cb)(struct service_context *svc_cx, void *data), void *data); extern int service_common_del_timer(struct service_context *svc_ctx, struct service_event_item *item); +extern int service_common_fd(struct service_context *ctx); + /* End of a file */ diff --git a/include/slave_life.h b/include/slave_life.h index dea9f27..d294520 100644 --- a/include/slave_life.h +++ b/include/slave_life.h @@ -193,4 +193,7 @@ extern int slave_need_to_reactivate(struct slave_node *slave); extern int slave_network(const struct slave_node *slave); extern void slave_set_network(struct slave_node *slave, int network); +extern int slave_deactivate_all(int reactivate, int reactivate_instances); +extern int slave_activate_all(void); + /* End of a file */ diff --git a/packaging/data-provider-master.spec b/packaging/data-provider-master.spec index ba1be6a..0b806f2 100644 --- a/packaging/data-provider-master.spec +++ b/packaging/data-provider-master.spec @@ -1,6 +1,6 @@ Name: data-provider-master Summary: Master service provider for liveboxes. -Version: 0.23.5 +Version: 0.24.7 Release: 1 Group: HomeTF/Livebox License: Flora License @@ -14,6 +14,7 @@ BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(ecore-x) BuildRequires: pkgconfig(ecore) @@ -34,6 +35,7 @@ BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(livebox-service) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(badge) +BuildRequires: pkgconfig(security-server) %description Manage the 2nd stage livebox service provider and communicate with the viewer application. @@ -60,7 +62,7 @@ mkdir -p %{buildroot}/%{_sysconfdir}/rc.d/rc3.d mkdir -p %{buildroot}/%{_libdir}/systemd/user/tizen-middleware.target.wants touch %{buildroot}/opt/dbspace/.livebox.db touch %{buildroot}/opt/dbspace/.livebox.db-journal -ln -sf %{_sysconfdir}/rc.d/init.d/data-provider-master %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master +#ln -sf %{_sysconfdir}/rc.d/init.d/data-provider-master %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master ln -sf %{_libdir}/systemd/user/data-provider-master.service %{buildroot}/%{_libdir}/systemd/user/tizen-middleware.target.wants/data-provider-master.service %pre @@ -90,7 +92,7 @@ echo "%{_sysconfdir}/init.d/data-provider-master start" %manifest data-provider-master.manifest %defattr(-,root,root,-) %{_sysconfdir}/rc.d/init.d/data-provider-master -%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master +#%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master %{_bindir}/data-provider-master %{_bindir}/liveinfo %{_prefix}/etc/package-manager/parserlib/* @@ -98,10 +100,7 @@ echo "%{_sysconfdir}/init.d/data-provider-master start" %{_libdir}/systemd/user/data-provider-master.service %{_libdir}/systemd/user/tizen-middleware.target.wants/data-provider-master.service %{_datarootdir}/license/* -/opt/usr/share/live_magazine -/opt/usr/share/live_magazine/log -/opt/usr/share/live_magazine/reader -/opt/usr/share/live_magazine/always +/opt/usr/share/live_magazine/* /opt/dbspace/.livebox.db /opt/dbspace/.livebox.db-journal diff --git a/pkgmgr_livebox/src/service_register.c b/pkgmgr_livebox/src/service_register.c index 78bc0d6..dd725cb 100644 --- a/pkgmgr_livebox/src/service_register.c +++ b/pkgmgr_livebox/src/service_register.c @@ -32,9 +32,21 @@ #include "dlist.h" +#if !defined(SECURE_LOGD) +#define SECURE_LOGD LOGD +#endif + +#if !defined(SECURE_LOGE) +#define SECURE_LOGE LOGE +#endif + +#if !defined(SECURE_LOGW) +#define SECURE_LOGW LOGW +#endif + #if !defined(FLOG) -#define DbgPrint(format, arg...) LOGD("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) -#define ErrPrint(format, arg...) LOGE("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) +#define DbgPrint(format, arg...) SECURE_LOGD("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) +#define ErrPrint(format, arg...) SECURE_LOGE("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) #endif /* End of a file */ @@ -43,12 +55,12 @@ * DB Table schema * * pkgmap - * +-------+-------+---------+ - * | appid | pkgid | prime | - * +-------+-------+---------+ - * | - | - | | - * +-------+-------+---------+ - * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER ) + * +-------+-------+-------+-------+ + * | appid | pkgid | uiapp | prime | + * +-------+-------+-------+-------+ + * | - | - | - | - | + * +-------+-------+-------+-------+ + * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER ) * * * provider @@ -165,6 +177,7 @@ struct livebox { xmlChar *script; /* Script engine */ xmlChar *content; /* Content information */ xmlChar *setup; + xmlChar *uiapp; /* UI App Id */ int pinup; /* Is this support the pinup feature? */ int primary; /* Is this primary livebox? */ @@ -284,7 +297,7 @@ static inline int db_create_pkgmap(void) char *err; static const char *ddl; - ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )"; + ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER )"; if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { ErrPrint("Failed to execute the DDL (%s)\n", err); return -EIO; @@ -296,13 +309,16 @@ static inline int db_create_pkgmap(void) return 0; } -static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int primary) +static inline int db_insert_pkgmap(const char *appid, const char *pkgid, const char *uiappid, int primary) { int ret; static const char *dml; sqlite3_stmt *stmt; - dml = "INSERT INTO pkgmap ( appid, pkgid, prime ) VALUES (? ,?, ?)"; + if (!uiappid) + uiappid = ""; /*!< Could we replace this with Main AppId of this package? */ + + dml = "INSERT INTO pkgmap ( appid, pkgid, uiapp, prime ) VALUES (? ,?, ?, ?)"; ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL); if (ret != SQLITE_OK) { DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle)); @@ -323,7 +339,14 @@ static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int pri goto out; } - ret = sqlite3_bind_int(stmt, 3, primary); + ret = sqlite3_bind_text(stmt, 3, uiappid, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle)); + ret = -EIO; + goto out; + } + + ret = sqlite3_bind_int(stmt, 4, primary); if (ret != SQLITE_OK) { DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle)); ret = -EIO; @@ -1657,6 +1680,22 @@ static inline void update_launch(struct livebox *livebox, xmlNodePtr node) } } +static inline void update_ui_appid(struct livebox *livebox, xmlNodePtr node) +{ + xmlChar *uiapp; + uiapp = xmlNodeGetContent(node); + if (!uiapp) { + DbgPrint("Has no valid ui-appid\n"); + return; + } + + livebox->uiapp = xmlStrdup(uiapp); + if (!livebox->uiapp) { + ErrPrint("Failed to duplicate string: %s\n", (char *)uiapp); + return; + } +} + static inline void update_setup(struct livebox *livebox, xmlNodePtr node) { xmlChar *setup; @@ -2135,7 +2174,7 @@ static inline int db_insert_livebox(struct livebox *livebox, const char *appid) struct option *option; begin_transaction(); - ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, livebox->primary); + ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, (char *)livebox->uiapp, livebox->primary); if (ret < 0) goto errout; @@ -2450,6 +2489,11 @@ static inline int do_install(xmlNodePtr node, const char *appid) update_launch(livebox, node); continue; } + + if (!xmlStrcasecmp(node->name, (const xmlChar *)"ui-appid")) { + update_ui_appid(livebox, node); + continue; + } } return db_insert_livebox(livebox, appid); diff --git a/src/badge_service.c b/src/badge_service.c index 2001bc0..96050f3 100644 --- a/src/badge_service.c +++ b/src/badge_service.c @@ -22,6 +22,8 @@ #include #include +#include + #include #include @@ -30,8 +32,6 @@ #include "util.h" #include "conf.h" -#define BADGE_ADDR "/tmp/.badge.service" - static struct info { Eina_List *context_list; struct service_context *svc_ctx; @@ -367,12 +367,30 @@ HAPI int badge_service_init(void) return LB_STATUS_ERROR_ALREADY; } - s_info.svc_ctx = service_common_create(BADGE_ADDR, service_thread_main, NULL); + s_info.svc_ctx = service_common_create(BADGE_SOCKET, service_thread_main, NULL); if (!s_info.svc_ctx) { ErrPrint("Unable to activate service thread\n"); return LB_STATUS_ERROR_FAULT; } + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + DbgPrint("Successfully initiated\n"); return LB_STATUS_SUCCESS; } @@ -383,6 +401,7 @@ HAPI int badge_service_fini(void) return LB_STATUS_ERROR_INVALID; service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; DbgPrint("Successfully finalized\n"); return LB_STATUS_SUCCESS; } diff --git a/src/buffer_handler.c b/src/buffer_handler.c index 79d3c83..79e5c20 100644 --- a/src/buffer_handler.c +++ b/src/buffer_handler.c @@ -1250,7 +1250,8 @@ HAPI void buffer_handler_flush(struct buffer_info *info) if (write(fd, info->buffer, size) != size) ErrPrint("Write is not completed: %s\n", strerror(errno)); - close(fd); + if (close(fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); } else { DbgPrint("Flush nothing\n"); } @@ -1304,7 +1305,8 @@ HAPI int buffer_handler_init(void) DbgPrint("DRM Magic: 0x%X\n", magic); if (!DRI2Authenticate(ecore_x_display_get(), DefaultRootWindow(ecore_x_display_get()), (unsigned int)magic)) { DbgPrint("Failed to do authenticate for DRI2\n"); - close(s_info.fd); + if (close(s_info.fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); s_info.fd = -1; s_info.evt_base = 0; s_info.err_base = 0; @@ -1314,7 +1316,8 @@ HAPI int buffer_handler_init(void) s_info.slp_bufmgr = tbm_bufmgr_init(s_info.fd); if (!s_info.slp_bufmgr) { DbgPrint("Failed to init bufmgr\n"); - close(s_info.fd); + if (close(s_info.fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); s_info.fd = -1; s_info.evt_base = 0; s_info.err_base = 0; @@ -1327,7 +1330,8 @@ HAPI int buffer_handler_init(void) HAPI int buffer_handler_fini(void) { if (s_info.fd >= 0) { - close(s_info.fd); + if (close(s_info.fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); s_info.fd = -1; } diff --git a/src/client_life.c b/src/client_life.c index d30417a..dd0e49c 100644 --- a/src/client_life.c +++ b/src/client_life.c @@ -370,17 +370,17 @@ HAPI int client_count(void) return eina_list_count(s_info.client_list); } -HAPI int client_deactivated_by_fault(struct client_node *client) +HAPI struct client_node *client_deactivated_by_fault(struct client_node *client) { if (!client || client->faulted) - return 0; + return client; ErrPrint("Client[%p] is faulted(%d), pid(%d)\n", client, client->refcnt, client->pid); client->faulted = 1; client->pid = (pid_t)-1; invoke_deactivated_cb(client); - (void)client_destroy(client); + client = client_destroy(client); /*! * \todo * Who invokes this function has to care the reference counter of a client @@ -388,7 +388,7 @@ HAPI int client_deactivated_by_fault(struct client_node *client) * client->pid = (pid_t)-1; * slave_unref(client) */ - return 0; + return client; } HAPI const int const client_is_faulted(const struct client_node *client) diff --git a/src/conf.c b/src/conf.c index 4c7bd7f..1c05206 100644 --- a/src/conf.c +++ b/src/conf.c @@ -517,7 +517,7 @@ HAPI int conf_loader(void) do { c = getc(fp); if ((c == EOF) && (state == VALUE)) { - LOGD("[%s:%d] VALUE state EOF\n", __func__, __LINE__); + DbgPrint("[%s:%d] VALUE state EOF\n", __func__, __LINE__); state = END; } @@ -662,7 +662,8 @@ HAPI int conf_loader(void) linelen++; } while (c != EOF); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_SUCCESS; } diff --git a/src/critical_log.c b/src/critical_log.c index 7469013..75a9796 100644 --- a/src/critical_log.c +++ b/src/critical_log.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -38,11 +39,13 @@ static struct { int file_id; int nr_of_lines; char *filename; + pthread_mutex_t cri_lock; } s_info = { .fp = NULL, .file_id = 0, .nr_of_lines = 0, .filename = NULL, + .cri_lock = PTHREAD_MUTEX_INITIALIZER, }; @@ -62,8 +65,10 @@ static inline void rotate_log(void) if (filename) { snprintf(filename, namelen, "%s/%d_%s.%d", SLAVE_LOG_PATH, s_info.file_id, s_info.filename, getpid()); - if (s_info.fp) - fclose(s_info.fp); + if (s_info.fp) { + if (fclose(s_info.fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); + } s_info.fp = fopen(filename, "w+"); if (!s_info.fp) @@ -81,10 +86,15 @@ HAPI int critical_log(const char *func, int line, const char *fmt, ...) { va_list ap; int ret; + int status; if (!s_info.fp) return LB_STATUS_ERROR_IO; + status = pthread_mutex_lock(&s_info.cri_lock); + if (status != 0) + ErrPrint("lock: %s\n", strerror(status)); + fprintf(s_info.fp, "%lf [%s:%d] ", util_timestamp(), util_basename((char *)func), line); va_start(ap, fmt); @@ -95,6 +105,11 @@ HAPI int critical_log(const char *func, int line, const char *fmt, ...) s_info.nr_of_lines++; rotate_log(); + + status = pthread_mutex_unlock(&s_info.cri_lock); + if (status != 0) + ErrPrint("unlock: %s\n", strerror(status)); + return ret; } @@ -149,7 +164,8 @@ HAPI void critical_log_fini(void) } if (s_info.fp) { - fclose(s_info.fp); + if (fclose(s_info.fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); s_info.fp = NULL; } } diff --git a/src/dead_monitor.c b/src/dead_monitor.c index a768f39..adea7d3 100644 --- a/src/dead_monitor.c +++ b/src/dead_monitor.c @@ -55,8 +55,9 @@ static int evt_cb(int handle, void *data) client = client_find_by_rpc_handle(handle); if (client) { if (client_pid(client) != (pid_t)-1) - client_deactivated_by_fault(client); + client = client_deactivated_by_fault(client); + DbgPrint("Client pointer: %p (0 means deleted)\n", client); return 0; } diff --git a/src/fault_manager.c b/src/fault_manager.c index 86b61c0..7e44685 100644 --- a/src/fault_manager.c +++ b/src/fault_manager.c @@ -83,7 +83,8 @@ static char *check_log_file(struct slave_node *slave) } ptr = fgets(pkgname, sizeof(pkgname), fp); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); if (ptr != pkgname) { ErrPrint("Invalid log\n"); return NULL; diff --git a/src/fb.c b/src/fb.c index 0907537..e3f4f0d 100644 --- a/src/fb.c +++ b/src/fb.c @@ -115,14 +115,14 @@ static void sw_render_post_cb(void *data, Evas *e, void *event_info) internal_ee = ecore_evas_ecore_evas_get(e); if (!internal_ee) { - LOGD("Failed to get ecore evas\n"); + ErrPrint("Failed to get ecore evas\n"); return; } // Get a pointer of a buffer of the virtual canvas canvas = (void*)ecore_evas_buffer_pixels_get(internal_ee); if (!canvas) { - LOGD("Failed to get pixel canvas\n"); + ErrPrint("Failed to get pixel canvas\n"); return; } diff --git a/src/instance.c b/src/instance.c index 25a0a11..8bf38f9 100644 --- a/src/instance.c +++ b/src/instance.c @@ -3031,16 +3031,20 @@ HAPI void *instance_client_list(struct inst_info *inst) return inst->client_list; } -HAPI void instance_init(void) +HAPI int instance_init(void) { if (!strcasecmp(PROVIDER_METHOD, "shm")) s_info.env_buf_type = BUFFER_TYPE_SHM; else if (!strcasecmp(PROVIDER_METHOD, "pixmap")) s_info.env_buf_type = BUFFER_TYPE_PIXMAP; + /* Default method is BUFFER_TYPE_FILE */ + + return LB_STATUS_SUCCESS; } -HAPI void instance_fini(void) +HAPI int instance_fini(void) { + return LB_STATUS_SUCCESS; } static inline struct tag_item *find_tag_item(struct inst_info *inst, const char *tag) diff --git a/src/io.c b/src/io.c index fee17f2..e4ad05c 100644 --- a/src/io.c +++ b/src/io.c @@ -208,7 +208,8 @@ static inline int load_abi_table(void) } } - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_SUCCESS; } @@ -700,12 +701,14 @@ HAPI int io_crawling_liveboxes(int (*cb)(const char *pkgname, int prime, void *d continue; if (cb(ent->d_name, -1, data) < 0) { - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); return LB_STATUS_ERROR_CANCEL; } } - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); } return LB_STATUS_SUCCESS; diff --git a/src/liveinfo.c b/src/liveinfo.c index 3f76531..c81a3e9 100644 --- a/src/liveinfo.c +++ b/src/liveinfo.c @@ -58,8 +58,10 @@ HAPI void liveinfo_fini(void) struct liveinfo *info; EINA_LIST_FREE(s_info.info_list, info) { - fclose(info->fp); - unlink(info->fifo_name); + if (fclose(info->fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); + if (unlink(info->fifo_name) < 0) + ErrPrint("unlink: %s\n", strerror(errno)); DbgFree(info); } } @@ -105,7 +107,8 @@ HAPI struct liveinfo *liveinfo_create(pid_t pid, int handle) snprintf(info->fifo_name, sizeof(info->fifo_name), "/tmp/.live_info.%lf", util_timestamp()); if (mkfifo(info->fifo_name, 0644) < 0) { ErrPrint("mkfifo: %s\n", strerror(errno)); - unlink(info->fifo_name); + if (unlink(info->fifo_name) < 0) + ErrPrint("unlink: %s\n", strerror(errno)); DbgFree(info); return NULL; } @@ -134,7 +137,8 @@ HAPI int liveinfo_open_fifo(struct liveinfo *info) HAPI void liveinfo_close_fifo(struct liveinfo *info) { if (info->fp) { - fclose(info->fp); + if (fclose(info->fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); info->fp = NULL; } } @@ -143,7 +147,8 @@ HAPI void liveinfo_destroy(struct liveinfo *info) { s_info.info_list = eina_list_remove(s_info.info_list, info); liveinfo_close_fifo(info); - unlink(info->fifo_name); + if (unlink(info->fifo_name) < 0) + ErrPrint("unlink: %s\n", strerror(errno)); DbgFree(info); } diff --git a/src/main.c b/src/main.c index a235299..b8441bf 100644 --- a/src/main.c +++ b/src/main.c @@ -132,8 +132,11 @@ static inline int app_terminate(void) { int ret; - ret = script_fini(); - DbgPrint("script: %d\n", ret); + ret = server_fini(); + DbgPrint("Finalize server: %d\n", ret); + + ret = dead_fini(); + DbgPrint("dead signal handler finalized: %d\n", ret); ret = utility_service_fini(); DbgPrint("utility: %d\n", ret); @@ -153,23 +156,21 @@ static inline int app_terminate(void) ret = setting_fini(); DbgPrint("Finalize setting : %d\n", ret); - ret = buffer_handler_fini(); - DbgPrint("buffer handler: %d\n", ret); - - xmonitor_fini(); - - instance_fini(); + ret = instance_fini(); + DbgPrint("Finalizing instances: %d\n", ret); ret = package_fini(); DbgPrint("Finalize package info: %d\n", ret); - client_fini(); + ret = script_fini(); + DbgPrint("script: %d\n", ret); - ret = server_fini(); - DbgPrint("Finalize dbus: %d\n", ret); + ret = buffer_handler_fini(); + DbgPrint("buffer handler: %d\n", ret); - ret = dead_fini(); - DbgPrint("dead signal handler finalized: %d\n", ret); + xmonitor_fini(); + + client_fini(); ret = io_fini(); DbgPrint("IO finalized: %d\n", ret); @@ -209,8 +210,22 @@ static Eina_Bool signal_cb(void *data, Ecore_Fd_Handler *handler) ErrPrint("stop.provider: %s\n", strerror(errno)); vconf_set_bool(VCONFKEY_MASTER_STARTED, 0); - exit(0); - //ecore_main_loop_quit(); + //exit(0); + ecore_main_loop_quit(); + } else if (fdsi.ssi_signo == SIGUSR1) { + /*! + * Turn off auto-reactivation + * Terminate all slaves + */ + CRITICAL_LOG("USRS1, Deactivate ALL\n"); + slave_deactivate_all(0, 1); + } else if (fdsi.ssi_signo == SIGUSR2) { + /*! + * Turn on auto-reactivation + * Launch all slaves again + */ + CRITICAL_LOG("USR2, Activate ALL\n"); + slave_activate_all(); } else { CRITICAL_LOG("Unknown SIG[%d] received\n", fdsi.ssi_signo); } @@ -259,6 +274,14 @@ int main(int argc, char *argv[]) if (ret < 0) CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno)); + ret = sigaddset(&mask, SIGUSR1); + if (ret < 0) + CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno)); + + ret = sigaddset(&mask, SIGUSR2); + if (ret < 0) + CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno)); + ret = sigprocmask(SIG_BLOCK, &mask, NULL); if (ret < 0) CRITICAL_LOG("Failed to mask the SIGTERM: %s\n", strerror(errno)); @@ -309,8 +332,8 @@ int main(int argc, char *argv[]) app_terminate(); - ecore_evas_shutdown(); evas_shutdown(); + ecore_evas_shutdown(); ecore_x_shutdown(); diff --git a/src/notification_service.c b/src/notification_service.c index 12da940..fec5fa4 100644 --- a/src/notification_service.c +++ b/src/notification_service.c @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -30,10 +32,6 @@ #include "util.h" #include "conf.h" -#ifndef NOTIFICATION_ADDR -#define NOTIFICATION_ADDR "/tmp/.notification.service" -#endif - #ifndef NOTIFICATION_DEL_PACKET_UNIT #define NOTIFICATION_DEL_PACKET_UNIT 10 #endif @@ -438,12 +436,30 @@ HAPI int notification_service_init(void) return LB_STATUS_ERROR_ALREADY; } - s_info.svc_ctx = service_common_create(NOTIFICATION_ADDR, service_thread_main, NULL); + s_info.svc_ctx = service_common_create(NOTIFICATION_SOCKET, service_thread_main, NULL); if (!s_info.svc_ctx) { ErrPrint("Unable to activate service thread\n"); return LB_STATUS_ERROR_FAULT; } + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + DbgPrint("Successfully initiated\n"); return LB_STATUS_SUCCESS; } @@ -454,6 +470,7 @@ HAPI int notification_service_fini(void) return LB_STATUS_ERROR_INVALID; service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; DbgPrint("Successfully Finalized\n"); return LB_STATUS_SUCCESS; } diff --git a/src/package.c b/src/package.c index 188c170..017488e 100644 --- a/src/package.c +++ b/src/package.c @@ -25,7 +25,9 @@ #include #include +#include +#include "critical_log.h" #include "debug.h" #include "util.h" #include "parser.h" @@ -279,6 +281,11 @@ static int slave_resumed_cb(struct slave_node *slave, void *data) static inline void destroy_package(struct pkg_info *info) { + struct context_info *ctx_info; + EINA_LIST_FREE(info->ctx_list, ctx_info) { + /* This items will be deleted from group_del_livebox */ + } + group_del_livebox(info->pkgname); package_clear_fault(info); @@ -541,6 +548,11 @@ HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *in pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info); } +HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info) +{ + pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info); +} + HAPI char *package_lb_pkgname(const char *pkgname) { char *lb_pkgname; @@ -633,11 +645,11 @@ HAPI int package_dump_fault_info(struct pkg_info *info) if (!info->fault_info) return LB_STATUS_ERROR_NOT_EXIST; - ErrPrint("=============\n"); - ErrPrint("faulted at %lf\n", info->fault_info->timestamp); - ErrPrint("Package: %s\n", info->pkgname); - ErrPrint("Function: %s\n", info->fault_info->function); - ErrPrint("InstanceID: %s\n", info->fault_info->filename); + CRITICAL_LOG("=============\n"); + CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp); + CRITICAL_LOG("Package: %s\n", info->pkgname); + CRITICAL_LOG("Function: %s\n", info->fault_info->function); + CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename); return LB_STATUS_SUCCESS; } @@ -1361,11 +1373,28 @@ HAPI int package_init(void) HAPI int package_fini(void) { + Eina_List *p_l; + Eina_List *p_n; + Eina_List *i_l; + Eina_List *i_n; + struct pkg_info *info; + struct inst_info *inst; + pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL); pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL); pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL); pkgmgr_fini(); client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL); + + EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) { + EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) { + instance_state_reset(inst); + instance_destroy(inst); + } + + package_destroy(info); + } + return 0; } @@ -1475,4 +1504,24 @@ HAPI int const package_fault_count(struct pkg_info *info) return info ? info->fault_count : 0; } +HAPI int package_is_enabled(const char *appid) +{ + ail_appinfo_h ai; + bool enabled; + int ret; + + ret = ail_get_appinfo(appid, &ai); + if (ret != AIL_ERROR_OK) { + ErrPrint("Unable to get appinfo: %d\n", ret); + return 0; + } + + if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK) + enabled = false; + + ail_destroy_appinfo(ai); + + return enabled == true; +} + /* End of a file */ diff --git a/src/parser.c b/src/parser.c index 948aec8..987772c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -820,7 +820,8 @@ HAPI struct parser *parser_load(const char *pkgname) linelen++; } while (c != EOF); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); s_list = eina_list_append(s_list, item); return item; diff --git a/src/script_handler.c b/src/script_handler.c index ff554bc..9811312 100644 --- a/src/script_handler.c +++ b/src/script_handler.c @@ -396,6 +396,8 @@ HAPI struct script_info *script_handler_create(struct inst_info *inst, const cha HAPI int script_handler_destroy(struct script_info *info) { struct block *block; + int ret; + if (!info || !info->port) { ErrPrint("port is not valid\n"); return LB_STATUS_ERROR_INVALID; @@ -406,8 +408,9 @@ HAPI int script_handler_destroy(struct script_info *info) return LB_STATUS_ERROR_INVALID; } - if (info->port->destroy(info->port_data) < 0) - ErrPrint("Failed to destroy port, but go ahead\n"); + ret = info->port->destroy(info->port_data); + if (ret < 0) + ErrPrint("Failed to destroy port, but go ahead: %d\n", ret); fb_destroy(info->fb); @@ -863,7 +866,7 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch return LB_STATUS_ERROR_IO; } - DbgPrint("Parsing %s\n", descfile); + DbgPrint("Start parsing %s\n", descfile); state = UNKNOWN; field_idx = 0; @@ -884,7 +887,8 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch if (!isspace(ch) && ch != EOF) { ErrPrint("%d: Syntax error: Desc is not started with '{' or space - (%c = 0x%x)\n", lineno, ch, ch); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_ERROR_INVALID; } break; @@ -901,7 +905,8 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch block = calloc(1, sizeof(*block)); if (!block) { ErrPrint("Heap: %s\n", strerror(errno)); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_ERROR_MEMORY; } @@ -1209,14 +1214,16 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch goto errout; } - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_SUCCESS; errout: ErrPrint("Parse error at %d file %s\n", lineno, util_basename(descfile)); if (block) delete_block(block); - fclose(fp); + if (fclose(fp) != 0) + ErrPrint("fclose: %s\n", strerror(errno)); return LB_STATUS_ERROR_INVALID; } @@ -1247,7 +1254,8 @@ HAPI int script_init(void) path = malloc(pathlen); if (!path) { ErrPrint("Heap: %s %d\n", strerror(errno), pathlen); - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); return LB_STATUS_ERROR_MEMORY; } @@ -1257,7 +1265,8 @@ HAPI int script_init(void) if (!item) { ErrPrint("Heap: %s\n", strerror(errno)); DbgFree(path); - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); return LB_STATUS_ERROR_MEMORY; } @@ -1267,7 +1276,8 @@ HAPI int script_init(void) if (!item->handle) { ErrPrint("Error: %s\n", dlerror()); DbgFree(item); - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); return LB_STATUS_ERROR_FAULT; } @@ -1349,14 +1359,18 @@ HAPI int script_init(void) s_info.script_port_list = eina_list_append(s_info.script_port_list, item); } - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); + return LB_STATUS_SUCCESS; errout: ErrPrint("Error: %s\n", dlerror()); - dlclose(item->handle); + if (dlclose(item->handle) != 0) + ErrPrint("dlclose: %s\n", strerror(errno)); DbgFree(item); - closedir(dir); + if (closedir(dir) < 0) + ErrPrint("closedir: %s\n", strerror(errno)); return LB_STATUS_ERROR_FAULT; } @@ -1368,7 +1382,8 @@ HAPI int script_fini(void) */ EINA_LIST_FREE(s_info.script_port_list, item) { item->fini(); - dlclose(item->handle); + if (dlclose(item->handle) != 0) + ErrPrint("dlclose: %s\n", strerror(errno)); DbgFree(item); } diff --git a/src/server.c b/src/server.c index 517a4da..07aad34 100644 --- a/src/server.c +++ b/src/server.c @@ -23,12 +23,14 @@ #include /* fb.h */ #include #include +#include #include #include #include #include +#include "critical_log.h" #include "conf.h" #include "debug.h" #include "server.h" @@ -497,6 +499,40 @@ static Eina_Bool lazy_delete_cb(void *data) return ECORE_CALLBACK_CANCEL; } +/* +static inline void clear_pd_monitor(struct inst_info *inst) +{ + Ecore_Timer *pd_monitor; + + pd_monitor = instance_del_data(inst, "pd,open,monitor"); + if (pd_monitor) { + DbgPrint("Clear pd,open,monitor\n"); + (void)instance_client_pd_created(inst, LB_STATUS_SUCCESS); + ecore_timer_del(pd_monitor); + (void)instance_unref(inst); + return; + } + + pd_monitor = instance_del_data(inst, "pd,close,monitor"); + if (pd_monitor) { + DbgPrint("Clear pd,close,monitor\n"); + (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS); + ecore_timer_del(pd_monitor); + (void)instance_unref(inst); + return; + } + + pd_monitor = instance_del_data(inst, "pd,resize,monitor"); + if (pd_monitor) { + DbgPrint("Clear pd,resize,monitor\n"); + (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS); + ecore_timer_del(pd_monitor); + (void)instance_unref(inst); + return; + } +} +*/ + static struct packet *client_delete(pid_t pid, int handle, const struct packet *packet) /* pid, pkgname, filename, ret */ { struct client_node *client; @@ -549,6 +585,7 @@ static struct packet *client_delete(pid_t pid, int handle, const struct packet * * So We have to make a delay to send a deleted event. */ + DbgPrint("Client has PD\n"); item->client = client_ref(client); item->inst = instance_ref(inst); @@ -563,9 +600,12 @@ static struct packet *client_delete(pid_t pid, int handle, const struct packet * } } } else { + DbgPrint("Client has no permission\n"); ret = LB_STATUS_ERROR_PERMISSION; } } else { + DbgPrint("Ok. destroy instance\n"); + //clear_pd_monitor(inst); ret = instance_destroy(inst); } @@ -641,6 +681,7 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac int width; int height; char *lb_pkgname; + char *mainappid; client = client_find_by_pid(pid); if (!client) { @@ -666,6 +707,15 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac goto out; } + mainappid = livebox_service_mainappid(lb_pkgname); + if (!package_is_enabled(mainappid)) { + DbgFree(mainappid); + DbgFree(lb_pkgname); + ret = LB_STATUS_ERROR_DISABLED; + goto out; + } + DbgFree(mainappid); + info = package_find(lb_pkgname); if (!info) info = package_create(lb_pkgname); @@ -4523,16 +4573,16 @@ out: static Eina_Bool lazy_pd_created_cb(void *data) { - (void)instance_del_data(data, "lazy,pd,open"); - - /*! - * After unref instance first, - * if the instance is not destroyed, try to notify the created PD event to the client. - */ - if (instance_unref(data)) { - int ret; - ret = instance_client_pd_created(data, LB_STATUS_SUCCESS); - DbgPrint("Send PD Create event (%d)\n", ret); + if (!!instance_del_data(data, "lazy,pd,open")) { + /*! + * After unref instance first, + * if the instance is not destroyed, try to notify the created PD event to the client. + */ + if (instance_unref(data)) { + int ret; + ret = instance_client_pd_created(data, LB_STATUS_SUCCESS); + DbgPrint("Send PD Create event (%d)\n", ret); + } } return ECORE_CALLBACK_CANCEL; @@ -4540,11 +4590,12 @@ static Eina_Bool lazy_pd_created_cb(void *data) static Eina_Bool lazy_pd_destroyed_cb(void *data) { - (void)instance_del_data(data, "lazy,pd,close"); - - if (instance_unref(data)) { - DbgPrint("Send PD Destroy event\n"); - instance_client_pd_destroyed(data, LB_STATUS_SUCCESS); + if (!!instance_del_data(data, "lazy,pd,close")) { + if (instance_unref(data)) { + int ret; + ret = instance_client_pd_destroyed(data, LB_STATUS_SUCCESS); + DbgPrint("Send PD Destroy event (%d)\n", ret); + } } return ECORE_CALLBACK_CANCEL; @@ -4616,7 +4667,18 @@ static Eina_Bool pd_close_monitor_cb(void *data) ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT); (void)instance_del_data(data, "pd,close,monitor"); (void)instance_unref(data); - ErrPrint("PD Close request it not processed in %lf seconds\n", PD_REQUEST_TIMEOUT); + ErrPrint("PD Close request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret); + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool pd_resize_monitor_cb(void *data) +{ + int ret; + + ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT); + (void)instance_del_data(data, "pd,resize,monitor"); + (void)instance_unref(data); + ErrPrint("PD Resize request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret); return ECORE_CALLBACK_CANCEL; } @@ -4649,9 +4711,29 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe if (ret != LB_STATUS_SUCCESS) goto out; - if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) + if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) { ret = LB_STATUS_ERROR_NO_SPACE; - else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) { + } else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) { + lazy_pd_destroyed_cb(inst); + + if (instance_get_data(inst, "pd,open,monitor")) { + DbgPrint("PD Open request is already processed\n"); + ret = LB_STATUS_ERROR_ALREADY; + goto out; + } + + if (instance_get_data(inst, "pd,close,monitor")) { + DbgPrint("PD Close request is already in process\n"); + ret = LB_STATUS_ERROR_BUSY; + goto out; + } + + if (instance_get_data(inst, "pd,resize,monitor")) { + DbgPrint("PD resize request is already in process\n"); + ret = LB_STATUS_ERROR_BUSY; + goto out; + } + instance_slave_set_pd_pos(inst, x, y); /*! * \note @@ -4692,6 +4774,9 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe } else if (package_pd_type(instance_package(inst)) == PD_TYPE_SCRIPT) { int ix; int iy; + + lazy_pd_destroyed_cb(inst); + /*! * \note * ret value should be cared but in this case, @@ -4717,6 +4802,7 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe */ if (ret == LB_STATUS_SUCCESS) { Ecore_Timer *timer; + /*! * \note * But the created event has to be send afte return @@ -4784,6 +4870,7 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack int ret; struct inst_info *inst; const struct pkg_info *pkg; + Ecore_Timer *pd_monitor; client = client_find_by_pid(pid); if (!client) { @@ -4804,7 +4891,7 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack goto out; if (package_pd_type(pkg) == PD_TYPE_BUFFER) { - Ecore_Timer *pd_monitor; + int resize_aborted = 0; pd_monitor = instance_del_data(inst, "pd,open,monitor"); if (pd_monitor) { @@ -4819,13 +4906,39 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack * Because they understand that the destroy request is successfully processed. */ ret = LB_STATUS_ERROR_CANCEL; + ret = instance_client_pd_created(inst, ret); + if (ret < 0) + ErrPrint("PD client create event: %d\n", ret); + + ret = instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS); + if (ret < 0) + ErrPrint("PD client destroy event: %d\n", ret); + + ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); + if (ret < 0) + ErrPrint("PD close signal emit failed: %d\n", ret); + + ret = instance_slave_close_pd(inst, client); + if (ret < 0) + ErrPrint("PD close request failed: %d\n", ret); - (void)instance_client_pd_created(inst, ret); ecore_timer_del(pd_monitor); (void)instance_unref(inst); goto out; } + pd_monitor = instance_del_data(inst, "pd,resize,monitor"); + if (pd_monitor) { + ErrPrint("PD Resize request is found. clear it [%s]\n", pkgname); + ecore_timer_del(pd_monitor); + + inst = instance_unref(inst); + if (!inst) + goto out; + + resize_aborted = 1; + } + ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0); if (ret < 0) ErrPrint("PD close signal emit failed: %d\n", ret); @@ -4834,12 +4947,22 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack if (ret < 0) { ErrPrint("PD close request failed: %d\n", ret); } else { - pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst)); - if (!pd_monitor) { - (void)instance_unref(inst); - ErrPrint("Failed to add pd close monitor\n"); + if (resize_aborted) { + pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst)); + if (!pd_monitor) { + ErrPrint("Failed to create a timer: %s\n", pkgname); + (void)instance_unref(inst); + } else { + (void)instance_set_data(inst, "lazy,pd,close", pd_monitor); + } } else { - (void)instance_set_data(inst, "pd,close,monitor", pd_monitor); + pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst)); + if (!pd_monitor) { + (void)instance_unref(inst); + ErrPrint("Failed to add pd close monitor\n"); + } else { + (void)instance_set_data(inst, "pd,close,monitor", pd_monitor); + } } } /*! @@ -4850,6 +4973,8 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack * instance_client_pd_destroyed(inst); */ } else if (package_pd_type(pkg) == PD_TYPE_SCRIPT) { + lazy_pd_created_cb(inst); + ret = script_handler_unload(instance_pd_script(inst), 1); if (ret < 0) ErrPrint("Unable to unload the script: %s, %d\n", pkgname, ret); @@ -4868,10 +4993,6 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack * Send the destroyed PD event to the client */ if (ret == LB_STATUS_SUCCESS) { - Ecore_Timer *timer; - - inst = instance_ref(inst); - /*! * \note * 13-05-28 @@ -4879,16 +5000,12 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack * But I just add it to the tagged-data of the instance. * Just reserve for future-use. */ - timer = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, inst); - if (!timer) { + pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst)); + if (!pd_monitor) { ErrPrint("Failed to create a timer: %s\n", pkgname); (void)instance_unref(inst); - /*! - * How can we handle this? - */ - ret = LB_STATUS_ERROR_FAULT; } else { - (void)instance_set_data(inst, "lazy,pd,close", timer); + (void)instance_set_data(inst, "lazy,pd,close", pd_monitor); } } } else { @@ -5258,7 +5375,11 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa DbgPrint("New slave[%s](%d) is arrived\n", slavename, pid); - slave = slave_find_by_pid(pid); + slave = slave_find_by_name(slavename); + + if (!slave) /* Try again to find a slave using pid */ + slave = slave_find_by_pid(pid); + if (!slave) { if (DEBUG_MODE) { char pkgname[pathconf("/", _PC_PATH_MAX)]; @@ -5294,9 +5415,22 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa slave_set_pid(slave, pid); DbgPrint("Provider is forcely activated, pkgname(%s), abi(%s), slavename(%s)\n", pkgname, abi, slavename); } else { - ErrPrint("Slave[%d] is not exists\n", pid); + ErrPrint("Slave[%d, %s] is not exists\n", pid, slavename); goto out; } + } else { + if (slave_pid(slave) != pid) { + if (slave_pid(slave) > 0) { + CRITICAL_LOG("Slave(%s) is already assigned to %d\n", slave_name(slave), slave_pid(slave)); + if (pid > 0) { + ret = aul_terminate_pid(pid); + CRITICAL_LOG("Terminate %d (ret: %d)\n", pid, ret); + } + goto out; + } + CRITICAL_LOG("PID of slave(%s) is updated (%d -> %d)\n", slave_name(slave), slave_pid(slave), pid); + slave_set_pid(slave, pid); + } } /*! @@ -5362,6 +5496,7 @@ static struct packet *slave_faulted(pid_t pid, int handle, const struct packet * } else if (instance_state(inst) == INST_DESTROYED) { ErrPrint("Instance(%s) is already destroyed\n", id); } else { + //clear_pd_monitor(inst); ret = instance_destroy(inst); } @@ -5792,8 +5927,10 @@ static struct packet *slave_deleted(pid_t pid, int handle, const struct packet * } ret = validate_request(pkgname, id, &inst, NULL); - if (ret == LB_STATUS_SUCCESS) + if (ret == LB_STATUS_SUCCESS) { + //clear_pd_monitor(inst); ret = instance_destroyed(inst); + } out: return NULL; @@ -5833,7 +5970,7 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p } if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) { - DbgPrint("No space\n"); + ErrPrint("Not enough space\n"); ret = LB_STATUS_ERROR_NO_SPACE; id = ""; goto out; @@ -5886,10 +6023,16 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p } else if (target == TYPE_PD && package_pd_type(pkg) == PD_TYPE_BUFFER) { struct buffer_info *info; Ecore_Timer *pd_monitor; + int is_resize; + is_resize = 0; pd_monitor = instance_del_data(inst, "pd,open,monitor"); - if (!pd_monitor) - goto out; + if (!pd_monitor) { + pd_monitor = instance_del_data(inst, "pd,resize,monitor"); + is_resize = !!pd_monitor; + if (!is_resize) + goto out; + } ecore_timer_del(pd_monitor); inst = instance_unref(inst); @@ -5931,7 +6074,8 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p /*! * Send the PD created event to the client */ - instance_client_pd_created(inst, ret); + if (!is_resize) + instance_client_pd_created(inst, ret); } out: @@ -6092,6 +6236,32 @@ static struct packet *slave_release_buffer(pid_t pid, int handle, const struct p * by pd.need_to_send_close_event flag. * which will be checked by instance_client_pd_destroyed function. */ + + /*! + * \note + * provider can try to resize the buffer size. + * in that case, it will release the buffer first. + * Then even though the client doesn't request to close the PD, + * the provider can release it. + * If we send the close event to the client, + * The client will not able to allocate PD again. + * In this case, add the pd,monitor again. from here. + * to wait the re-allocate buffer. + * If the client doesn't request buffer reallocation, + * Treat it as a fault. and close the PD. + */ + info = instance_pd_buffer(inst); + ret = buffer_handler_unload(info); + + if (ret == LB_STATUS_SUCCESS) { + pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_resize_monitor_cb, instance_ref(inst)); + if (!pd_monitor) { + (void)instance_unref(inst); + ErrPrint("Failed to create a timer for PD Open monitor\n"); + } else { + (void)instance_set_data(inst, "pd,resize,monitor", pd_monitor); + } + } } else { ecore_timer_del(pd_monitor); inst = instance_unref(inst); @@ -6100,16 +6270,17 @@ static struct packet *slave_release_buffer(pid_t pid, int handle, const struct p ret = LB_STATUS_ERROR_FAULT; goto out; } - } - info = instance_pd_buffer(inst); - ret = buffer_handler_unload(info); + info = instance_pd_buffer(inst); + ret = buffer_handler_unload(info); + + /*! + * \note + * Send the PD destroyed event to the client + */ + instance_client_pd_destroyed(inst, ret); + } - /*! - * \note - * Send the PD destroyed event to the client - */ - instance_client_pd_destroyed(inst, ret); } out: @@ -6493,7 +6664,8 @@ static struct packet *liveinfo_pkg_ctrl(pid_t pid, int handle, const struct pack if (!inst) { fprintf(fp, "%d\n", ENOENT); } else { - instance_destroy(inst); + //clear_pd_monitor(inst); + (void)instance_destroy(inst); fprintf(fp, "%d\n", 0); } } diff --git a/src/service_common.c b/src/service_common.c index 8b5405f..d6d4007 100644 --- a/src/service_common.c +++ b/src/service_common.c @@ -90,6 +90,7 @@ struct tcb { /* Thread controll block */ pthread_t thid; /*!< Thread Id */ int fd; /*!< Connection handle */ enum tcb_type type; + int ctrl_pipe[PIPE_MAX]; }; /*! @@ -109,6 +110,7 @@ static void *client_packet_pump_main(void *data) int recv_offset; int pid; int ret; + int fd; char evt_ch = EVT_CH; enum { RECV_INIT, @@ -128,7 +130,9 @@ static void *client_packet_pump_main(void *data) while (ret == 0) { FD_ZERO(&set); FD_SET(tcb->fd, &set); - ret = select(tcb->fd + 1, &set, NULL, NULL, NULL); + FD_SET(tcb->ctrl_pipe[PIPE_READ], &set); + fd = tcb->fd > tcb->ctrl_pipe[PIPE_READ] ? tcb->fd : tcb->ctrl_pipe[PIPE_READ]; + ret = select(fd + 1, &set, NULL, NULL, NULL); if (ret < 0) { ret = -errno; if (errno == EINTR) { @@ -148,6 +152,14 @@ static void *client_packet_pump_main(void *data) break; } + if (FD_ISSET(tcb->ctrl_pipe[PIPE_READ], &set)) { + DbgPrint("Thread is canceled\n"); + ret = -ECANCELED; + free(ptr); + ptr = NULL; + break; + } + if (!FD_ISSET(tcb->fd, &set)) { ErrPrint("Unexpected handler is toggled\n"); ret = -EINVAL; @@ -321,6 +333,12 @@ static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd) return NULL; } + if (pipe2(tcb->ctrl_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { + ErrPrint("pipe2: %s\n", strerror(errno)); + free(tcb); + return NULL; + } + tcb->fd = fd; tcb->svc_ctx = svc_ctx; tcb->type = TCB_CLIENT_TYPE_APP; @@ -329,6 +347,7 @@ static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd) status = pthread_create(&tcb->thid, NULL, client_packet_pump_main, tcb); if (status != 0) { ErrPrint("Unable to create a new thread: %s\n", strerror(status)); + CLOSE_PIPE(tcb->ctrl_pipe); free(tcb); return NULL; } @@ -346,6 +365,7 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx) struct tcb *tcb; void *ret; int status; + char ch = EVT_END_CH; /*! * We don't need to make critical section on here. @@ -356,7 +376,8 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx) /*! * ASSERT(tcb->fd >= 0); */ - secure_socket_destroy_handle(tcb->fd); + if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch)) + ErrPrint("write: %s\n", strerror(errno)); status = pthread_join(tcb->thid, &ret); if (status != 0) @@ -364,6 +385,9 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx) else DbgPrint("Thread returns: %d\n", (int)ret); + secure_socket_destroy_handle(tcb->fd); + + CLOSE_PIPE(tcb->ctrl_pipe); free(tcb); } } @@ -376,13 +400,15 @@ static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb) { void *ret; int status; + char ch = EVT_END_CH; svc_ctx->tcb_list = eina_list_remove(svc_ctx->tcb_list, tcb); /*! * ASSERT(tcb->fd >= 0); * Close the connection, and then collecting the return value of thread */ - secure_socket_destroy_handle(tcb->fd); + if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch)) + ErrPrint("write: %s\n", strerror(errno)); status = pthread_join(tcb->thid, &ret); if (status != 0) @@ -390,6 +416,9 @@ static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb) else DbgPrint("Thread returns: %d\n", (int)ret); + secure_socket_destroy_handle(tcb->fd); + + CLOSE_PIPE(tcb->ctrl_pipe); free(tcb); } @@ -478,6 +507,7 @@ static void *server_main(void *data) { struct service_context *svc_ctx = data; fd_set set; + fd_set except_set; int ret; int client_fd; struct tcb *tcb; @@ -488,8 +518,9 @@ static void *server_main(void *data) DbgPrint("Server thread is activated\n"); while (1) { fd = update_fdset(svc_ctx, &set); + memcpy(&except_set, &set, sizeof(set)); - ret = select(fd, &set, NULL, NULL, NULL); + ret = select(fd, &set, NULL, &except_set, NULL); if (ret < 0) { ret = -errno; if (errno == EINTR) { @@ -526,6 +557,12 @@ static void *server_main(void *data) break; } + if (!tcb) { + ErrPrint("Terminate service thread\n"); + ret = -ECANCELED; + break; + } + /*! * \note * Invoke the service thread main, to notify the termination of a TCB @@ -551,17 +588,19 @@ static void *server_main(void *data) svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info); CRITICAL_SECTION_END(&svc_ctx->packet_list_lock); - /*! - * \CRITICAL - * What happens if the client thread is terminated, so the packet_info->tcb is deleted - * while processing svc_ctx->service_thread_main? - */ - ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data); - if (ret < 0) - ErrPrint("Service thread returns: %d\n", ret); - - packet_destroy(packet_info->packet); - free(packet_info); + if (packet_info) { + /*! + * \CRITICAL + * What happens if the client thread is terminated, so the packet_info->tcb is deleted + * while processing svc_ctx->service_thread_main? + */ + ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data); + if (ret < 0) + ErrPrint("Service thread returns: %d\n", ret); + + packet_destroy(packet_info->packet); + free(packet_info); + } } processing_timer_event(svc_ctx, &set); @@ -671,6 +710,13 @@ HAPI struct service_context *service_common_create(const char *addr, int (*servi return NULL; } + /*! + * \note + * To give a chance to run for server thread. + */ + DbgPrint("Yield\n"); + pthread_yield(); + return svc_ctx; } @@ -680,7 +726,7 @@ HAPI struct service_context *service_common_create(const char *addr, int (*servi */ HAPI int service_common_destroy(struct service_context *svc_ctx) { - int status; + int status = 0; void *ret; if (!svc_ctx) @@ -690,7 +736,8 @@ HAPI int service_common_destroy(struct service_context *svc_ctx) * \note * Terminate server thread */ - secure_socket_destroy_handle(svc_ctx->fd); + if (write(svc_ctx->tcb_pipe[PIPE_WRITE], &status, sizeof(status)) != sizeof(status)) + ErrPrint("Failed to write: %s\n", strerror(errno)); status = pthread_join(svc_ctx->server_thid, &ret); if (status != 0) @@ -698,6 +745,8 @@ HAPI int service_common_destroy(struct service_context *svc_ctx) else DbgPrint("Thread returns: %d\n", (int)ret); + secure_socket_destroy_handle(svc_ctx->fd); + status = pthread_mutex_destroy(&svc_ctx->packet_list_lock); if (status != 0) ErrPrint("Unable to destroy a mutex: %s\n", strerror(status)); @@ -839,7 +888,8 @@ HAPI struct service_event_item *service_common_add_timer(struct service_context if (timerfd_settime(item->info.timer.fd, 0, &spec, NULL) < 0) { ErrPrint("Error: %s\n", strerror(errno)); - close(item->info.timer.fd); + if (close(item->info.timer.fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); free(item); return NULL; } @@ -864,9 +914,15 @@ HAPI int service_common_del_timer(struct service_context *svc_ctx, struct servic svc_ctx->event_list = eina_list_remove(svc_ctx->event_list, item); - close(item->info.timer.fd); + if (close(item->info.timer.fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); free(item); return 0; } +HAPI int service_common_fd(struct service_context *ctx) +{ + return ctx->fd; +} + /* End of a file */ diff --git a/src/setting.c b/src/setting.c index e7e5379..47c41c8 100644 --- a/src/setting.c +++ b/src/setting.c @@ -30,6 +30,8 @@ #include #include +#include + #include "client_life.h" #include "setting.h" #include "util.h" @@ -38,6 +40,8 @@ #include "critical_log.h" #include "xmonitor.h" #include "conf.h" +#include "package.h" +#include "instance.h" int errno; @@ -80,8 +84,8 @@ static void power_off_cb(keynode_t *node, void *user_data) ErrPrint("stop.provider [%s]\n", strerror(errno)); vconf_set_bool(VCONFKEY_MASTER_STARTED, 0); - exit(0); - //ecore_main_loop_quit(); + //exit(0); + ecore_main_loop_quit(); } else { ErrPrint("Unknown power state: %d\n", val); } @@ -112,7 +116,7 @@ static void region_changed_cb(keynode_t *node, void *user_data) if (r == NULL) ErrPrint("Failed to change region\n"); - free(region); + DbgFree(region); } static void lang_changed_cb(keynode_t *node, void *user_data) @@ -132,7 +136,70 @@ static void lang_changed_cb(keynode_t *node, void *user_data) ErrPrint("Failed to change locale\n"); DbgPrint("Locale: %s\n", setlocale(LC_ALL, NULL)); - free(lang); + DbgFree(lang); +} + +static void ail_info_cb(keynode_t *node, void *user_data) +{ + Eina_List *inst_list; + Eina_List *pkg_list; + struct inst_info *inst; + Eina_List *l; + Eina_List *n; + Eina_List *j; + struct pkg_info *info; + char *event; + char *appid; + char *pkgname; + int len; + int enabled; + + event = vconf_get_str(VCONFKEY_AIL_INFO_STATE); + if (!event) + return; + + len = strlen("update:"); + if (!strncasecmp(event, "update:", len)) + goto out; + + appid = event + len; + DbgPrint("AppId: [%s]\n", appid); + + enabled = package_is_enabled(appid); + + DbgPrint("AppId: %s, %d\n", appid, enabled); + if (enabled != 0) { + /* + * \note + * reload? + */ + goto out; + } + + len = strlen(appid); + + pkg_list = (Eina_List *)package_list(); + EINA_LIST_FOREACH(pkg_list, l, info) { + inst_list = NULL; + pkgname = livebox_service_mainappid(package_name(info)); + if (!pkgname) + continue; + + if (strcmp(appid, pkgname)) { + DbgFree(pkgname); + continue; + } + DbgPrint("Package disabled: %s (%s)\n", pkgname, appid); + DbgFree(pkgname); + + inst_list = package_instance_list(info); + EINA_LIST_FOREACH_SAFE(inst_list, j, n, inst) { + instance_destroy(inst); + } + } + +out: + DbgFree(event); } HAPI int setting_init(void) @@ -155,6 +222,10 @@ HAPI int setting_init(void) if (ret < 0) ErrPrint("Failed to add vconf for region change: %d\n", ret); + ret = vconf_notify_key_changed(VCONFKEY_AIL_INFO_STATE, ail_info_cb, NULL); + if (ret < 0) + ErrPrint("Failed to add vconf for ail info state: %d\n", ret); + lang_changed_cb(NULL, NULL); region_changed_cb(NULL, NULL); return ret; @@ -180,6 +251,10 @@ HAPI int setting_fini(void) if (ret < 0) ErrPrint("Failed to ignore vconf key (%d)\n", ret); + ret = vconf_ignore_key_changed(VCONFKEY_AIL_INFO_STATE, ail_info_cb); + if (ret < 0) + ErrPrint("Failed to ignore vconf key (%d)\n", ret); + return ret; } diff --git a/src/shortcut_service.c b/src/shortcut_service.c index a2f74af..690c08b 100644 --- a/src/shortcut_service.c +++ b/src/shortcut_service.c @@ -22,14 +22,15 @@ #include #include +#include + +#include #include "service_common.h" #include "debug.h" #include "util.h" #include "conf.h" -#define SHORTCUT_ADDR "/tmp/.shortcut.service" - static struct info { Eina_List *context_list; struct service_context *svc_ctx; @@ -162,12 +163,30 @@ HAPI int shortcut_service_init(void) return LB_STATUS_ERROR_ALREADY; } - s_info.svc_ctx = service_common_create(SHORTCUT_ADDR, service_thread_main, NULL); + s_info.svc_ctx = service_common_create(SHORTCUT_SOCKET, service_thread_main, NULL); if (!s_info.svc_ctx) { ErrPrint("Unable to activate service thread\n"); return LB_STATUS_ERROR_FAULT; } + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + DbgPrint("Successfully initiated\n"); return LB_STATUS_SUCCESS; } @@ -178,6 +197,7 @@ HAPI int shortcut_service_fini(void) return LB_STATUS_ERROR_INVALID; service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; DbgPrint("Successfully Finalized\n"); return LB_STATUS_SUCCESS; } diff --git a/src/slave_life.c b/src/slave_life.c index fba87fc..8d36a27 100644 --- a/src/slave_life.c +++ b/src/slave_life.c @@ -33,6 +33,7 @@ #include #include +#include "critical_log.h" #include "slave_life.h" #include "slave_rpc.h" #include "client_life.h" @@ -390,31 +391,36 @@ static Eina_Bool activate_timer_cb(void *data) ErrPrint("Terminate failed, pid %d (reason: %d)\n", slave_pid(slave), ret); } - ErrPrint("Slave is not activated in %lf sec (slave: %s)\n", SLAVE_ACTIVATE_TIME, slave_name(slave)); + CRITICAL_LOG("Slave is not activated in %lf sec (slave: %s)\n", SLAVE_ACTIVATE_TIME, slave_name(slave)); slave = slave_deactivated(slave); - DbgPrint("Slave: %p\n", slave); return ECORE_CALLBACK_CANCEL; } HAPI int slave_activate(struct slave_node *slave) { - /*! * \note - * This check code can replace the slave->state check code + * This check code can be replaced with the slave->state check code * If the slave data has the PID, it means, it is activated * Even if it is in the termiating sequence, it will have the PID * before terminated at last. * So we can use this simple code for checking the slave's last state. * about it is alive? or not. */ - if (slave_pid(slave) != (pid_t)-1) + if (slave_pid(slave) != (pid_t)-1) { + if (slave_state(slave) == SLAVE_REQUEST_TO_TERMINATE) + slave_set_reactivation(slave, 1); return LB_STATUS_ERROR_ALREADY; + } else if (slave_state(slave) == SLAVE_REQUEST_TO_LAUNCH) { + DbgPrint("Slave is already launched: but the AUL is timed out\n"); + return LB_STATUS_ERROR_ALREADY; + } if (DEBUG_MODE) { DbgPrint("Debug Mode enabled. name[%s] secured[%d] abi[%s]\n", slave_name(slave), slave->secured, slave->abi); } else { bundle *param; + param = bundle_create(); if (!param) { ErrPrint("Failed to create a bundle\n"); @@ -430,9 +436,15 @@ HAPI int slave_activate(struct slave_node *slave) bundle_free(param); if (slave->pid < 0) { - ErrPrint("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid); - slave->pid = (pid_t)-1; - return LB_STATUS_ERROR_FAULT; + CRITICAL_LOG("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid); + if (slave->pid != AUL_R_ETIMEOUT && slave->pid != AUL_R_ECOMM) { + ErrPrint("failed, because of %d\n", slave->pid); + slave->pid = (pid_t)-1; + return LB_STATUS_ERROR_FAULT; + } else { + ErrPrint("But waiting \"hello\"\n"); + slave->pid = (pid_t)-1; + } } DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave)); @@ -1302,4 +1314,38 @@ HAPI void slave_set_network(struct slave_node *slave, int network) slave->network = network; } +HAPI int slave_deactivate_all(int reactivate, int reactivate_instances) +{ + Eina_List *l; + Eina_List *n; + struct slave_node *slave; + int cnt = 0; + + EINA_LIST_FOREACH_SAFE(s_info.slave_list, l, n, slave) { + slave_set_reactivate_instances(slave, reactivate_instances); + slave_set_reactivation(slave, reactivate); + + if (!slave_deactivate(slave)) + s_info.slave_list = eina_list_remove(s_info.slave_list, slave); + + cnt++; + } + + return cnt; +} + +HAPI int slave_activate_all(void) +{ + Eina_List *l; + struct slave_node *slave; + int cnt = 0; + + EINA_LIST_FOREACH(s_info.slave_list, l, slave) { + slave_activate(slave); + cnt++; + } + + return cnt; +} + /* End of a file */ diff --git a/src/slave_rpc.c b/src/slave_rpc.c index faeb94b..0e66261 100644 --- a/src/slave_rpc.c +++ b/src/slave_rpc.c @@ -123,7 +123,7 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo struct command *command = data; if (!command) { - ErrPrint("Packet is NIL\n"); + ErrPrint("Command is NIL\n"); return LB_STATUS_SUCCESS; } @@ -135,7 +135,6 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo ErrPrint("Slave is not activated (accidently dead)\n"); if (command->ret_cb) command->ret_cb(command->slave, packet, command->cbdata); - goto out; } @@ -144,7 +143,14 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo if (command->ret_cb) command->ret_cb(command->slave, packet, command->cbdata); + /* + * \NOTE + * Slave will be deactivated from dead monitor if it lost its connections. + * So we don't need to care it again from here. + command->slave = slave_deactivated_by_fault(command->slave); + + */ goto out; } diff --git a/src/utility_service.c b/src/utility_service.c index 651e284..0b01608 100644 --- a/src/utility_service.c +++ b/src/utility_service.c @@ -23,15 +23,22 @@ #include #include +#include + +#include "critical_log.h" #include "service_common.h" #include "utility_service.h" #include "debug.h" #include "util.h" #include "conf.h" -#define UTILITY_ADDR "/tmp/.utility.service" +#ifndef SVC_PKG #define SVC_PKG "org.tizen.data-provider-slave.icon" +#endif + +#ifndef LAUNCH_TIMEOUT #define LAUNCH_TIMEOUT 10.0f +#endif static struct info { Eina_List *pending_list; @@ -39,18 +46,20 @@ static struct info { struct service_context *svc_ctx; struct tcb *svc_daemon; - pid_t svc_pid; + int svc_daemon_is_launched; struct service_event_item *launch_timer; + struct service_event_item *delay_launcher; } s_info = { .pending_list = NULL, .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */ .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */ .svc_daemon = NULL, - .svc_pid = -1, + .svc_daemon_is_launched = 0, .launch_timer = NULL, + .delay_launcher = NULL, }; struct pending_item { @@ -63,6 +72,8 @@ struct context { double seq; }; +static int lazy_launcher_cb(struct service_context *svc_ctx, void *data); + static inline int put_reply_tcb(struct tcb *tcb, double seq) { struct context *ctx; @@ -172,9 +183,51 @@ static int launch_timeout_cb(struct service_context *svc_ctx, void *data) } s_info.launch_timer = NULL; + s_info.svc_daemon_is_launched = 0; return -ECANCELED; /* Delete this timer */ } +static inline int launch_svc(struct service_context *svc_ctx) +{ + pid_t pid; + int ret = LB_STATUS_SUCCESS; + + pid = aul_launch_app(SVC_PKG, NULL); + if (pid > 0) { + s_info.svc_daemon_is_launched = 1; + s_info.launch_timer = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, launch_timeout_cb, NULL); + if (!s_info.launch_timer) + ErrPrint("Unable to create launch timer\n"); + } else if (pid == AUL_R_ETIMEOUT || pid == AUL_R_ECOMM) { + s_info.svc_daemon_is_launched = 1; + CRITICAL_LOG("SVC launch failed with timeout(%d), But waiting response\n", pid); + s_info.launch_timer = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, launch_timeout_cb, NULL); + if (!s_info.launch_timer) + ErrPrint("Unable to create launch timer\n"); + } else if (pid == AUL_R_ETERMINATING) { + /* Need time to launch app again */ + ErrPrint("Terminating now, try to launch this after few sec later\n"); + s_info.svc_daemon_is_launched = 1; + s_info.delay_launcher = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, lazy_launcher_cb, NULL); + if (!s_info.delay_launcher) { + ErrPrint("Unable to add delay launcher\n"); + ret = LB_STATUS_ERROR_FAULT; + } + } else { + ErrPrint("Failed to launch an app: %s(%d)\n", SVC_PKG, pid); + ret = LB_STATUS_ERROR_FAULT; + } + + return ret; +} + +static int lazy_launcher_cb(struct service_context *svc_ctx, void *data) +{ + s_info.svc_daemon_is_launched = launch_svc(svc_ctx) == LB_STATUS_SUCCESS; + s_info.delay_launcher = NULL; + return -ECANCELED; +} + static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data) { struct packet *reply; @@ -186,7 +239,7 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat if (tcb == s_info.svc_daemon) { s_info.svc_daemon = NULL; - s_info.svc_pid = -1; + s_info.svc_daemon_is_launched = 0; } return 0; @@ -200,20 +253,13 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat switch (packet_type(packet)) { case PACKET_REQ: - if (s_info.svc_pid < 0) { - s_info.svc_pid = aul_launch_app(SVC_PKG, NULL); - if (s_info.svc_pid > 0) { - s_info.launch_timer = service_common_add_timer(tcb_svc_ctx(tcb), LAUNCH_TIMEOUT, launch_timeout_cb, NULL); - if (!s_info.launch_timer) - ErrPrint("Unable to create launch timer\n"); - } + if (!s_info.svc_daemon_is_launched) { + ret = launch_svc(tcb_svc_ctx(tcb)); + if (ret != LB_STATUS_SUCCESS) + goto reply_out; } - if (s_info.svc_pid < 0) { - ErrPrint("Failed to launch an app: %s(%d)\n", SVC_PKG, s_info.svc_pid); - ret = LB_STATUS_ERROR_FAULT; - goto reply_out; - } else if (!s_info.svc_daemon) { + if (!s_info.svc_daemon) { ret = put_pended_request(tcb, packet); if (ret < 0) goto reply_out; @@ -228,6 +274,11 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat break; case PACKET_REQ_NOACK: if (!strcmp(cmd, "service_register")) { + if (!s_info.svc_daemon_is_launched) { + ErrPrint("Service daemon is not launched. but something tries to register a service\n"); + return LB_STATUS_ERROR_INVALID; + } + if (s_info.svc_daemon) { ErrPrint("Service daemon is already prepared\n"); return LB_STATUS_ERROR_INVALID; @@ -275,12 +326,30 @@ int utility_service_init(void) return LB_STATUS_ERROR_ALREADY; } - s_info.svc_ctx = service_common_create(UTILITY_ADDR, service_thread_main, NULL); + s_info.svc_ctx = service_common_create(UTILITY_SOCKET, service_thread_main, NULL); if (!s_info.svc_ctx) { ErrPrint("Unable to activate service thread\n"); return LB_STATUS_ERROR_FAULT; } + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), UTILITY_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + + if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), UTILITY_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) { + if (errno != EOPNOTSUPP) { + ErrPrint("Unable to set SMACK label(%d)\n", errno); + service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; + return LB_STATUS_ERROR_FAULT; + } + } + DbgPrint("Successfully initiated\n"); return LB_STATUS_SUCCESS; } @@ -291,6 +360,7 @@ int utility_service_fini(void) return LB_STATUS_ERROR_INVALID; service_common_destroy(s_info.svc_ctx); + s_info.svc_ctx = NULL; DbgPrint("Successfully Finalized\n"); return LB_STATUS_SUCCESS; } diff --git a/src/xmonitor.c b/src/xmonitor.c index e687959..b56966e 100644 --- a/src/xmonitor.c +++ b/src/xmonitor.c @@ -74,10 +74,12 @@ static inline void touch_paused_file(void) { int fd; fd = creat(PAUSED_FILE, 0644); - if (fd >= 0) - close(fd); - else + if (fd >= 0) { + if (close(fd) < 0) + ErrPrint("close: %s\n", strerror(errno)); + } else { ErrPrint("Create .live.paused: %s\n", strerror(errno)); + } } static inline void remove_paused_file(void) -- 2.7.4