Update SMACK, Fix a crash of terminating sequence, etc, ...
authorSung-jae Park <nicesj.park@samsung.com>
Thu, 13 Jun 2013 00:57:24 +0000 (09:57 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 13 Jun 2013 01:18:10 +0000 (10:18 +0900)
[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

33 files changed:
CMakeLists.txt
include/client_life.h
include/debug.h
include/instance.h
include/package.h
include/service_common.h
include/slave_life.h
packaging/data-provider-master.spec
pkgmgr_livebox/src/service_register.c
src/badge_service.c
src/buffer_handler.c
src/client_life.c
src/conf.c
src/critical_log.c
src/dead_monitor.c
src/fault_manager.c
src/fb.c
src/instance.c
src/io.c
src/liveinfo.c
src/main.c
src/notification_service.c
src/package.c
src/parser.c
src/script_handler.c
src/server.c
src/service_common.c
src/setting.c
src/shortcut_service.c
src/slave_life.c
src/slave_rpc.c
src/utility_service.c
src/xmonitor.c

index a907636..b7764ee 100644 (file)
@@ -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})
index 446b952..66caf9a 100644 (file)
@@ -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);
 
index fb7c780..0929bf0 100644 (file)
  * 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("[\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
-#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
+#define DbgPrint(format, arg...)       SECURE_LOGD("[\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...)       SECURE_LOGE("[\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
 #else
 extern FILE *__file_log_fp;
 #define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
index c21e58c..54ba80a 100644 (file)
@@ -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));
index 488f465..330628f 100644 (file)
@@ -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 */
index eb6e385..eaa06ea 100644 (file)
@@ -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 */
index dea9f27..d294520 100644 (file)
@@ -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 */
index ba1be6a..0b806f2 100644 (file)
@@ -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
 
index 78bc0d6..dd725cb 100644 (file)
 
 #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("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
-#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define DbgPrint(format, arg...)       SECURE_LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...)       SECURE_LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
 #endif
 /* End of a file */
 
  * 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);
index 2001bc0..96050f3 100644 (file)
@@ -22,6 +22,8 @@
 #include <livebox-errno.h>
 #include <packet.h>
 
+#include <sys/smack.h>
+
 #include <badge.h>
 #include <badge_db.h>
 
@@ -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;
 }
index 79d3c83..79e5c20 100644 (file)
@@ -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;
        }
 
index d30417a..dd0e49c 100644 (file)
@@ -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)
index 4c7bd7f..1c05206 100644 (file)
@@ -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;
 }
 
index 7469013..75a9796 100644 (file)
@@ -23,6 +23,7 @@
 #include <libgen.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <pthread.h>
 
 #include <dlog.h>
 #include <Eina.h>
@@ -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;
        }
 }
index a768f39..adea7d3 100644 (file)
@@ -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;
        }
 
index 86b61c0..7e44685 100644 (file)
@@ -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;
index 0907537..e3f4f0d 100644 (file)
--- 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;
         }
 
index 25a0a11..8bf38f9 100644 (file)
@@ -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)
index fee17f2..e4ad05c 100644 (file)
--- 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;
index 3f76531..c81a3e9 100644 (file)
@@ -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);
 }
 
index a235299..b8441bf 100644 (file)
@@ -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();
 
index 12da940..fec5fa4 100644 (file)
@@ -21,6 +21,8 @@
 #include <livebox-errno.h>
 #include <packet.h>
 
+#include <sys/smack.h>
+
 #include <notification_ipc.h>
 #include <notification_noti.h>
 #include <notification_error.h>
 #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;
 }
index 188c170..017488e 100644 (file)
@@ -25,7 +25,9 @@
 
 #include <packet.h>
 #include <livebox-errno.h>
+#include <ail.h>
 
+#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 */
index 948aec8..987772c 100644 (file)
@@ -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;
index ff554bc..9811312 100644 (file)
@@ -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);
        }
 
index 517a4da..07aad34 100644 (file)
 #include <Ecore_Evas.h> /* fb.h */
 #include <aul.h>
 #include <Ecore.h>
+#include <ail.h>
 
 #include <packet.h>
 #include <com-core_packet.h>
 #include <livebox-errno.h>
 #include <livebox-service.h>
 
+#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);
                }
        }
index 8b5405f..d6d4007 100644 (file)
@@ -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 */
index e7e5379..47c41c8 100644 (file)
@@ -30,6 +30,8 @@
 #include <Ecore.h>
 #include <Eina.h>
 
+#include <livebox-service.h>
+
 #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;
 }
 
index a2f74af..690c08b 100644 (file)
 #include <packet.h>
 
 #include <Eina.h>
+#include <sys/smack.h>
+
+#include <security-server.h>
 
 #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;
 }
index fba87fc..8d36a27 100644 (file)
@@ -33,6 +33,7 @@
 #include <packet.h>
 #include <livebox-errno.h>
 
+#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 */
index faeb94b..0e66261 100644 (file)
@@ -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;
        }
 
index 651e284..0b01608 100644 (file)
 #include <livebox-errno.h>
 #include <packet.h>
 
+#include <sys/smack.h>
+
+#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;
 }
index e687959..b56966e 100644 (file)
@@ -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)