2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <string.h> /* strcmp */
20 #include <stdlib.h> /* free */
24 #include <Ecore_Evas.h>
27 #include <livebox-errno.h>
33 #include "slave_life.h"
34 #include "slave_rpc.h"
35 #include "client_life.h"
37 #include "fault_manager.h"
39 #include "script_handler.h"
55 * pkg_info describes the loaded package.
71 /*!< Reserved for future use */
75 /*!< Reserved for future use */
79 /*!< Reserved for future use */
83 unsigned int size_list;
101 /*!< Reserved for future use */
105 /*!< Reserved for future use */
115 char *script; /* script type: edje, ... */
119 struct fault_info *fault_info;
121 struct slave_node *slave;
124 Eina_List *inst_list;
136 static int slave_activated_cb(struct slave_node *slave, void *data)
138 struct pkg_info *info = data;
139 struct inst_info *inst;
145 if (!slave_need_to_reactivate_instances(slave)) {
146 DbgPrint("Do not need to reactivate instances\n");
151 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
152 ret = instance_recover_state(inst);
156 instance_thaw_updator(inst);
160 DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
164 static int slave_fault_cb(struct slave_node *slave, void *data)
168 struct inst_info *inst;
169 struct pkg_info *info = (struct pkg_info *)data;
171 if (package_is_fault(info)) {
172 ErrPrint("Already faulted package: %s\n", package_name(info));
176 (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
177 fault_broadcast_info(package_name(info), slave_name(slave), __func__);
179 DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
180 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
181 DbgPrint("Destroy instance %p\n", inst);
182 instance_destroyed(inst);
188 static int slave_deactivated_cb(struct slave_node *slave, void *data)
190 struct pkg_info *info = data;
191 struct inst_info *inst;
196 if (info->fault_info) {
197 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
198 instance_destroyed(inst);
201 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
202 cnt += instance_need_slave(inst);
204 * instance_deactivated will call the slave_unload_instance.
205 * if the loaded instance counter meets 0,
206 * the slave will be deactivated.
207 * so we should not call the instance activate function
210 * activate slave when the slave is reactivated
215 return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
218 static int xmonitor_paused_cb(void *data)
220 struct pkg_info *info = (struct pkg_info *)data;
221 struct inst_info *inst;
224 if (slave_state(info->slave) != SLAVE_TERMINATED) {
225 DbgPrint("Skip this\n");
229 EINA_LIST_FOREACH(info->inst_list, l, inst) {
230 instance_freeze_updator(inst);
236 static int xmonitor_resumed_cb(void *data)
238 struct pkg_info *info = data;
239 struct inst_info *inst;
242 if (slave_state(info->slave) != SLAVE_TERMINATED) {
243 DbgPrint("Skip this\n");
247 EINA_LIST_FOREACH(info->inst_list, l, inst) {
248 instance_thaw_updator(inst);
254 static int slave_paused_cb(struct slave_node *slave, void *data)
256 struct pkg_info *info = (struct pkg_info *)data;
257 struct inst_info *inst;
260 EINA_LIST_FOREACH(info->inst_list, l, inst) {
261 instance_freeze_updator(inst);
267 static int slave_resumed_cb(struct slave_node *slave, void *data)
269 struct pkg_info *info = (struct pkg_info *)data;
270 struct inst_info *inst;
273 EINA_LIST_FOREACH(info->inst_list, l, inst) {
274 instance_thaw_updator(inst);
280 static inline void destroy_package(struct pkg_info *info)
282 group_del_livebox(info->pkgname);
283 package_clear_fault(info);
285 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
287 if (info->lb.type == LB_TYPE_SCRIPT) {
288 DbgFree(info->lb.info.script.path);
289 DbgFree(info->lb.info.script.group);
292 if (info->pd.type == PD_TYPE_SCRIPT) {
293 DbgFree(info->pd.info.script.path);
294 DbgFree(info->pd.info.script.group);
297 DbgFree(info->script);
299 DbgFree(info->pkgname);
300 DbgFree(info->lb.libexec);
301 DbgFree(info->lb.auto_launch);
306 static inline int load_conf(struct pkg_info *info)
308 struct parser *parser;
312 parser = parser_load(info->pkgname);
314 info->lb.size_list = 0x01; /* Default */
316 info->script = strdup(DEFAULT_SCRIPT);
318 ErrPrint("Heap: %s\n", strerror(errno));
319 return LB_STATUS_ERROR_MEMORY;
322 info->abi = strdup(DEFAULT_ABI);
324 ErrPrint("Heap: %s\n", strerror(errno));
325 DbgFree(info->script);
327 return LB_STATUS_ERROR_MEMORY;
330 info->pd.width = g_conf.width;
331 info->pd.height = g_conf.height >> 2;
333 return LB_STATUS_SUCCESS;
336 info->lb.type = LB_TYPE_FILE;
337 if (parser_text_lb(parser)) {
338 info->lb.type = LB_TYPE_TEXT;
339 } else if (parser_buffer_lb(parser)) {
340 info->lb.type = LB_TYPE_BUFFER;
342 str = parser_lb_path(parser);
344 info->lb.type = LB_TYPE_SCRIPT;
346 info->lb.info.script.path = strdup(str);
347 if (!info->lb.info.script.path) {
348 ErrPrint("Heap: %s\n", strerror(errno));
349 parser_unload(parser);
350 return LB_STATUS_ERROR_MEMORY;
353 str = parser_lb_group(parser);
355 info->lb.info.script.group = strdup(str);
356 if (!info->lb.info.script.group) {
357 ErrPrint("Heap: %s\n", strerror(errno));
358 DbgFree(info->lb.info.script.path);
359 parser_unload(parser);
360 return LB_STATUS_ERROR_MEMORY;
366 if (parser_text_pd(parser)) {
367 info->pd.type = PD_TYPE_TEXT;
368 } else if (parser_buffer_pd(parser)) {
369 info->pd.type = PD_TYPE_BUFFER;
371 str = parser_pd_path(parser);
373 info->pd.type = PD_TYPE_SCRIPT;
374 info->pd.info.script.path = strdup(str);
375 if (!info->pd.info.script.path) {
376 ErrPrint("Heap: %s\n", strerror(errno));
377 if (info->lb.type == LB_TYPE_SCRIPT) {
378 DbgFree(info->lb.info.script.path);
379 DbgFree(info->lb.info.script.group);
381 parser_unload(parser);
382 return LB_STATUS_ERROR_MEMORY;
385 str = parser_pd_group(parser);
387 info->pd.info.script.group = strdup(str);
388 if (!info->pd.info.script.group) {
389 ErrPrint("Heap: %s\n", strerror(errno));
390 DbgFree(info->pd.info.script.path);
391 if (info->lb.type == LB_TYPE_SCRIPT) {
392 DbgFree(info->lb.info.script.path);
393 DbgFree(info->lb.info.script.group);
395 parser_unload(parser);
396 return LB_STATUS_ERROR_MEMORY;
402 str = parser_script(parser);
403 str = str ? str : DEFAULT_SCRIPT;
404 info->script = strdup(str);
406 ErrPrint("Heap: %s\n", strerror(errno));
407 if (info->pd.type == PD_TYPE_SCRIPT) {
408 DbgFree(info->pd.info.script.path);
409 DbgFree(info->pd.info.script.group);
412 if (info->lb.type == LB_TYPE_SCRIPT) {
413 DbgFree(info->lb.info.script.path);
414 DbgFree(info->lb.info.script.group);
417 parser_unload(parser);
418 return LB_STATUS_ERROR_MEMORY;
421 str = parser_abi(parser);
422 str = str ? str : DEFAULT_ABI;
423 info->abi = strdup(str);
425 ErrPrint("Heap: %s\n", strerror(errno));
426 DbgFree(info->script);
427 if (info->pd.type == PD_TYPE_SCRIPT) {
428 DbgFree(info->pd.info.script.path);
429 DbgFree(info->pd.info.script.group);
432 if (info->lb.type == LB_TYPE_SCRIPT) {
433 DbgFree(info->lb.info.script.path);
434 DbgFree(info->lb.info.script.group);
436 parser_unload(parser);
437 return LB_STATUS_ERROR_MEMORY;
440 info->lb.timeout = parser_timeout(parser);
441 info->network = parser_network(parser);
443 info->lb.period = parser_period(parser);
444 if (info->lb.period < 0.0f)
445 info->lb.period = 0.0f;
446 else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD)
447 info->lb.period = MINIMUM_PERIOD;
449 info->lb.size_list = parser_size(parser);
451 str = parser_auto_launch(parser);
452 str = str ? str : "";
453 info->lb.auto_launch = strdup(str);
454 if (!info->lb.auto_launch) {
455 ErrPrint("Heap: %s\n", strerror(errno));
457 DbgFree(info->script);
458 if (info->pd.type == PD_TYPE_SCRIPT) {
459 DbgFree(info->pd.info.script.path);
460 DbgFree(info->pd.info.script.group);
463 if (info->lb.type == LB_TYPE_SCRIPT) {
464 DbgFree(info->lb.info.script.path);
465 DbgFree(info->lb.info.script.group);
467 parser_unload(parser);
468 return LB_STATUS_ERROR_MEMORY;
471 info->secured = parser_secured(parser);
472 info->lb.pinup = parser_pinup(parser);
474 parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
476 group = parser_group_str(parser);
477 if (group && group_add_livebox(group, info->pkgname) < 0)
478 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->pkgname, group);
480 parser_unload(parser);
481 return LB_STATUS_SUCCESS;
484 HAPI struct pkg_info *package_create(const char *pkgname)
486 struct pkg_info *pkginfo;
488 pkginfo = calloc(1, sizeof(*pkginfo));
490 ErrPrint("Heap: %s\n", strerror(errno));
494 pkginfo->pkgname = io_livebox_pkgname(pkgname);
495 if (!pkginfo->pkgname) {
496 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
497 if (util_validate_livebox_package(pkgname) < 0) {
498 ErrPrint("Invalid package name: %s\n", pkgname);
503 pkginfo->pkgname = strdup(pkgname);
504 if (!pkginfo->pkgname) {
505 ErrPrint("Heap: %s\n", strerror(errno));
511 if (io_load_package_db(pkginfo) < 0) {
512 ErrPrint("Failed to load DB, fall back to conf file loader\n");
513 if (load_conf(pkginfo) < 0) {
514 ErrPrint("Failed to initiate the conf file loader\n");
515 DbgFree(pkginfo->pkgname);
521 package_ref(pkginfo);
523 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
528 HAPI int package_destroy(struct pkg_info *info)
531 return LB_STATUS_SUCCESS;
534 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
536 return pkginfo->ctx_list;
539 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
541 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
544 HAPI char *package_lb_pkgname(const char *pkgname)
548 lb_pkgname = io_livebox_pkgname(pkgname);
550 if (util_validate_livebox_package(pkgname) < 0)
553 lb_pkgname = strdup(pkgname);
555 ErrPrint("Heap: %s\n", strerror(errno));
563 HAPI int package_is_lb_pkgname(const char *pkgname)
568 lb_pkgname = package_lb_pkgname(pkgname);
575 HAPI struct pkg_info *package_find(const char *pkgname)
578 struct pkg_info *info;
583 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
584 if (!strcmp(info->pkgname, pkgname))
591 HAPI struct inst_info *package_find_instance_by_id(const char *pkgname, const char *id)
594 struct inst_info *inst;
595 struct pkg_info *info;
597 info = package_find(pkgname);
599 ErrPrint("Package %s is not exists\n", pkgname);
603 EINA_LIST_FOREACH(info->inst_list, l, inst) {
604 if (!strcmp(instance_id(inst), id))
611 HAPI struct inst_info *package_find_instance_by_timestamp(const char *pkgname, double timestamp)
614 struct inst_info *inst;
615 struct pkg_info *info;
617 info = package_find(pkgname);
619 ErrPrint("Package %s is not exists\n", pkgname);
623 EINA_LIST_FOREACH(info->inst_list, l, inst) {
624 if (instance_timestamp(inst) == timestamp)
631 HAPI int package_dump_fault_info(struct pkg_info *info)
633 if (!info->fault_info)
634 return LB_STATUS_ERROR_NOT_EXIST;
636 ErrPrint("=============\n");
637 ErrPrint("faulted at %lf\n", info->fault_info->timestamp);
638 ErrPrint("Package: %s\n", info->pkgname);
639 ErrPrint("Function: %s\n", info->fault_info->function);
640 ErrPrint("InstanceID: %s\n", info->fault_info->filename);
641 return LB_STATUS_SUCCESS;
644 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
646 if (!info->fault_info)
647 return LB_STATUS_ERROR_NOT_EXIST;
649 *timestamp = info->fault_info->timestamp;
650 *filename = info->fault_info->filename;
651 *function = info->fault_info->function;
652 return LB_STATUS_SUCCESS;
655 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
657 struct fault_info *fault;
659 package_clear_fault(info);
661 fault = calloc(1, sizeof(*fault));
663 ErrPrint("Heap: %s\n", strerror(errno));
664 return LB_STATUS_ERROR_MEMORY;
667 fault->timestamp = timestamp;
669 filename = "unknown";
671 function = "unknown";
673 fault->filename = strdup(filename);
674 if (!fault->filename) {
675 ErrPrint("Heap: %s\n", strerror(errno));
677 return LB_STATUS_ERROR_MEMORY;
680 fault->function = strdup(function);
681 if (!fault->function) {
682 ErrPrint("Heap: %s\n", strerror(errno));
683 DbgFree(fault->filename);
685 return LB_STATUS_ERROR_MEMORY;
688 info->fault_info = fault;
690 return LB_STATUS_SUCCESS;
693 HAPI int package_clear_fault(struct pkg_info *info)
695 if (!info->fault_info)
696 return LB_STATUS_ERROR_INVALID;
698 package_dump_fault_info(info);
700 DbgFree(info->fault_info->function);
701 DbgFree(info->fault_info->filename);
702 DbgFree(info->fault_info);
703 info->fault_info = NULL;
704 return LB_STATUS_SUCCESS;
707 HAPI const int const package_is_fault(const struct pkg_info *info)
709 return !!info->fault_info;
712 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
717 HAPI const int const package_timeout(const struct pkg_info *info)
719 return info->lb.timeout;
722 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
724 info->lb.timeout = timeout;
727 HAPI const double const package_period(const struct pkg_info *info)
729 return info->lb.period;
732 HAPI void package_set_period(struct pkg_info *info, double period)
734 info->lb.period = period;
737 HAPI const int const package_secured(const struct pkg_info *info)
739 return info->secured;
742 HAPI void package_set_secured(struct pkg_info *info, int secured)
744 info->secured = secured;
747 HAPI const char * const package_script(const struct pkg_info *info)
752 HAPI int package_set_script(struct pkg_info *info, const char *script)
756 tmp = strdup(script);
758 ErrPrint("Heap: %s\n", strerror(errno));
759 return LB_STATUS_ERROR_MEMORY;
762 DbgFree(info->script);
764 return LB_STATUS_SUCCESS;
767 HAPI const char * const package_abi(const struct pkg_info *info)
772 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
777 ErrPrint("Heap: %s\n", strerror(errno));
778 return LB_STATUS_ERROR_MEMORY;
783 return LB_STATUS_SUCCESS;
786 HAPI const char * const package_lb_path(const struct pkg_info *info)
788 if (info->lb.type != LB_TYPE_SCRIPT)
791 return info->lb.info.script.path;
794 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
798 if (info->lb.type != LB_TYPE_SCRIPT)
799 return LB_STATUS_ERROR_INVALID;
803 ErrPrint("Heap: %s\n", strerror(errno));
804 return LB_STATUS_ERROR_MEMORY;
807 DbgFree(info->lb.info.script.path);
808 info->lb.info.script.path = tmp;
809 return LB_STATUS_SUCCESS;
812 HAPI const char * const package_lb_group(const struct pkg_info *info)
814 if (info->lb.type != LB_TYPE_SCRIPT)
817 return info->lb.info.script.group;
820 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
824 if (info->lb.type != LB_TYPE_SCRIPT)
825 return LB_STATUS_ERROR_INVALID;
829 ErrPrint("Heap: %s\n", strerror(errno));
830 return LB_STATUS_ERROR_MEMORY;
833 DbgFree(info->lb.info.script.group);
834 info->lb.info.script.group = tmp;
835 return LB_STATUS_SUCCESS;
838 HAPI const char * const package_pd_path(const struct pkg_info *info)
840 if (info->pd.type != PD_TYPE_SCRIPT)
843 return info->pd.info.script.path;
846 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
850 if (info->pd.type != PD_TYPE_SCRIPT)
851 return LB_STATUS_ERROR_INVALID;
855 ErrPrint("Heap: %s\n", strerror(errno));
856 return LB_STATUS_ERROR_MEMORY;
859 DbgFree(info->pd.info.script.path);
860 info->pd.info.script.path = tmp;
861 return LB_STATUS_SUCCESS;
864 HAPI const char * const package_pd_group(const struct pkg_info *info)
866 if (info->pd.type != PD_TYPE_SCRIPT)
869 return info->pd.info.script.group;
872 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
876 if (info->pd.type != PD_TYPE_SCRIPT)
877 return LB_STATUS_ERROR_INVALID;
881 ErrPrint("Heap: %s\n", strerror(errno));
882 return LB_STATUS_ERROR_MEMORY;
885 DbgFree(info->pd.info.script.group);
886 info->pd.info.script.group = tmp;
887 return LB_STATUS_SUCCESS;
890 HAPI const int const package_pinup(const struct pkg_info *info)
892 return info->lb.pinup;
895 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
897 info->lb.pinup = pinup;
900 HAPI const char * const package_auto_launch(const struct pkg_info *info)
902 return info->lb.auto_launch;
905 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
910 info->lb.auto_launch = strdup(auto_launch);
911 if (!info->lb.auto_launch) {
912 ErrPrint("Heap: %s\n", strerror(errno));
917 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
919 return info->lb.size_list;
922 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
924 info->lb.size_list = size_list;
927 HAPI const int const package_pd_width(const struct pkg_info *info)
929 return info->pd.width;
932 HAPI void package_set_pd_width(struct pkg_info *info, int width)
934 info->pd.width = width;
937 HAPI const int const package_pd_height(const struct pkg_info *info)
939 return info->pd.height;
942 HAPI void package_set_pd_height(struct pkg_info *info, int height)
944 info->pd.height = height;
947 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
953 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
955 if (info->refcnt == 0) {
956 ErrPrint("Invalid request\n");
961 if (info->refcnt == 0) {
962 destroy_package(info);
969 HAPI const int const package_refcnt(const struct pkg_info *info)
974 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
976 return info->lb.type;
979 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
981 info->lb.type = type;
984 HAPI const char * const package_libexec(struct pkg_info *info)
986 return info->lb.libexec;
989 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
993 tmp = strdup(libexec);
995 ErrPrint("Heap: %s\n", strerror(errno));
996 return LB_STATUS_ERROR_MEMORY;
999 DbgFree(info->lb.libexec);
1000 info->lb.libexec = tmp;
1001 return LB_STATUS_SUCCESS;
1004 HAPI int package_network(struct pkg_info *info)
1006 return info->network;
1009 HAPI void package_set_network(struct pkg_info *info, int network)
1011 info->network = network;
1014 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1016 return info->pd.type;
1019 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1021 info->pd.type = type;
1026 * Add the instance to the package info.
1027 * If a package has no slave, assign a new slave.
1029 static inline int assign_new_slave(struct pkg_info *info)
1035 s_name = util_slavename();
1037 ErrPrint("Failed to get a new slave name\n");
1038 return LB_STATUS_ERROR_FAULT;
1041 tmp = abi_find_slave(info->abi);
1044 ErrPrint("Failed to find a proper pkgname of a slave\n");
1045 return LB_STATUS_ERROR_INVALID;
1048 DbgPrint("Slave package: \"%s\" (abi: %s)\n", tmp, info->abi);
1049 s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->pkgname);
1051 DbgPrint("Failed to get replaced string\n");
1052 s_pkgname = strdup(tmp);
1054 ErrPrint("Heap: %s\n", strerror(errno));
1056 return LB_STATUS_ERROR_MEMORY;
1060 DbgPrint("New slave name is %s, it is assigned for livebox %s (using %s)\n", s_name, info->pkgname, s_pkgname);
1061 info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1069 * package_destroy will try to remove "info" from the pkg_list.
1070 * but we didn't add this to it yet.
1071 * If the list method couldn't find an "info" from the list,
1072 * it just do nothing so I'll leave this.
1074 return LB_STATUS_ERROR_FAULT;
1078 * Slave is not activated yet.
1080 return LB_STATUS_SUCCESS;
1083 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1085 if (!info->inst_list) {
1086 info->slave = slave_find_available(info->abi, info->secured, info->network);
1091 ret = assign_new_slave(info);
1095 DbgPrint("Slave %s is assigned for %s\n", slave_name(info->slave), info->pkgname);
1098 slave_ref(info->slave);
1099 slave_load_package(info->slave);
1100 slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1101 slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1102 slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1104 if (info->secured) {
1105 slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1106 slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1110 * In case of the slave is terminated because of expired TTL timer,
1111 * Master should freeze the all update time.
1112 * But the callback should check the slave's state to prevent from duplicated freezing.
1114 * This callback will freeze the timer only if a slave doesn't running.
1116 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1117 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1121 info->inst_list = eina_list_append(info->inst_list, inst);
1122 return LB_STATUS_SUCCESS;
1125 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1127 info->inst_list = eina_list_remove(info->inst_list, inst);
1129 if (info->inst_list)
1130 return LB_STATUS_SUCCESS;
1133 slave_unload_package(info->slave);
1135 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1136 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1137 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1139 if (info->secured) {
1140 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1141 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1143 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1144 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1147 slave_unref(info->slave);
1151 if (info->is_uninstalled)
1152 package_destroy(info);
1154 return LB_STATUS_SUCCESS;
1157 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1159 return info->inst_list;
1162 static int client_created_cb(struct client_node *client, void *data)
1164 struct pkg_info *info;
1167 struct inst_info *inst;
1170 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1171 if (info->fault_info) {
1172 fault_unicast_info(client, info->pkgname, info->fault_info->filename, info->fault_info->function);
1176 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1177 switch (instance_state(inst)) {
1179 /* Will be send a created event after the instance gets created event */
1181 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1182 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1183 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1184 if (instance_client(inst) == client) {
1185 instance_unicast_created_event(inst, client);
1186 } else if (instance_client(inst) == NULL) {
1189 * Instances are lives in the system cluster/sub-cluster
1191 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1192 instance_unicast_created_event(inst, client);
1193 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1199 DbgPrint("%s(%s) is not activated (%d)\n",
1200 package_name(info), instance_id(inst), instance_state(inst));
1209 static int io_uninstall_cb(const char *pkgname, int prime, void *data)
1211 struct pkg_info *info;
1214 struct inst_info *inst;
1216 DbgPrint("Livebox package %s is uninstalled\n", pkgname);
1217 info = package_find(pkgname);
1219 DbgPrint("%s is not yet loaded\n", pkgname);
1223 info->is_uninstalled = 1;
1227 * Don't delete an item from the inst_list.
1228 * destroy callback will use this list again.
1229 * So, Don't touch it from here.
1231 if (info->inst_list) {
1232 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1233 instance_destroy(inst);
1236 package_destroy(info);
1242 static inline void reload_package_info(struct pkg_info *info)
1246 struct inst_info *inst;
1248 DbgPrint("Already exists, try to update it\n");
1251 * Without "is_uninstalled", the package will be kept
1253 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1254 instance_destroy(inst);
1257 group_del_livebox(info->pkgname);
1258 package_clear_fault(info);
1264 io_load_package_db(info);
1267 static int io_install_cb(const char *pkgname, int prime, void *data)
1269 struct pkg_info *info;
1271 DbgPrint("Livebox package %s is installed\n", pkgname);
1272 info = package_find(pkgname);
1274 reload_package_info(info);
1276 info = package_create(pkgname);
1277 DbgPrint("Package %s is%sbuilt\n", pkgname, info ? " " : " not ");
1283 static int install_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1287 if (status != PKGMGR_STATUS_END)
1290 ret = io_update_livebox_package(pkgname, io_install_cb, NULL);
1291 DbgPrint("Processed %d packages\n", ret);
1295 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1299 if (status == PKGMGR_STATUS_START) {
1300 ret = io_update_livebox_package(pkgname, io_uninstall_cb, NULL);
1301 DbgPrint("Processed %d packages\n", ret);
1303 /*! for keeping the old style */
1304 (void)io_uninstall_cb(pkgname, -1, NULL);
1311 static int io_update_cb(const char *pkgname, int prime, void *data)
1313 struct pkg_info *info;
1315 DbgPrint("Livebox package %s is updated\n", pkgname);
1316 info = package_find(pkgname);
1320 reload_package_info(info);
1324 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1327 if (status != PKGMGR_STATUS_END)
1330 ret = io_update_livebox_package(pkgname, io_update_cb, NULL);
1331 DbgPrint("Processed %d packages\n", ret);
1335 static int crawling_liveboxes(const char *pkgname, int prime, void *data)
1337 if (package_find(pkgname)) {
1338 ErrPrint("Information of %s is already built\n", pkgname);
1340 struct pkg_info *info;
1341 info = package_create(pkgname);
1343 DbgPrint("[%s] information is built prime(%d)\n", pkgname, prime);
1349 HAPI int package_init(void)
1351 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1354 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1355 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1356 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1358 io_crawling_liveboxes(crawling_liveboxes, NULL);
1362 HAPI int package_fini(void)
1364 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
1365 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1366 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1368 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1372 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1375 struct pkg_info *info;
1377 if (!slave_is_secured(slave))
1380 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1381 if (info->slave == slave)
1382 return info->pkgname;
1388 HAPI const char * const package_name(const struct pkg_info *info)
1390 return info->pkgname;
1394 * del_or_creat : 1 == create, 0 == delete
1396 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1398 struct pkg_info *info;
1401 struct inst_info *inst;
1404 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1405 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1406 if (instance_client(inst))
1409 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst)))
1412 switch (instance_state(inst)) {
1414 case INST_REQUEST_TO_ACTIVATE:
1415 /* Will be send a created event after the instance gets created event */
1418 if (!instance_has_client(inst, client)) {
1419 instance_add_client(inst, client);
1423 if (instance_has_client(inst, client)) {
1424 instance_del_client(inst, client);
1431 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1432 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1433 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1436 * Instances are lives in the system cluster/sub-cluster
1440 if (!instance_has_client(inst, client)) {
1441 instance_unicast_created_event(inst, client);
1442 instance_add_client(inst, client);
1443 DbgPrint("(Subscribed) Created package: %s\n", info->pkgname);
1447 if (instance_has_client(inst, client)) {
1448 instance_unicast_deleted_event(inst, client);
1449 instance_del_client(inst, client);
1458 DbgPrint("%s(%s) is not activated (%d)\n",
1459 package_name(info), instance_id(inst), instance_state(inst));
1468 HAPI const Eina_List *package_list(void)
1470 return s_info.pkg_list;
1473 HAPI int const package_fault_count(struct pkg_info *info)
1475 return info ? info->fault_count : 0;