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 */
26 #include <livebox-errno.h>
27 #include <livebox-service.h>
30 #include "critical_log.h"
35 #include "slave_life.h"
36 #include "slave_rpc.h"
37 #include "client_life.h"
39 #include "fault_manager.h"
41 #include "script_handler.h"
57 * pkg_info describes the loaded package.
74 /*!< Reserved for future use */
78 /*!< Reserved for future use */
82 /*!< Reserved for future use */
86 unsigned int size_list;
104 /*!< Reserved for future use */
108 /*!< Reserved for future use */
118 char *script; /* script type: edje, ... */
122 struct fault_info *fault_info;
124 struct slave_node *slave;
127 Eina_List *inst_list;
139 static int slave_activated_cb(struct slave_node *slave, void *data)
141 struct pkg_info *info = data;
142 struct inst_info *inst;
148 if (!slave_need_to_reactivate_instances(slave)) {
149 DbgPrint("Do not need to reactivate instances\n");
154 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
155 ret = instance_recover_state(inst);
160 instance_thaw_updator(inst);
164 DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
168 static int slave_fault_cb(struct slave_node *slave, void *data)
172 struct inst_info *inst;
173 struct pkg_info *info = (struct pkg_info *)data;
175 if (package_is_fault(info)) {
176 ErrPrint("Already faulted package: %s\n", package_name(info));
180 (void)package_set_fault_info(info, util_timestamp(), slave_name(slave), __func__);
181 fault_broadcast_info(package_name(info), slave_name(slave), __func__);
183 DbgPrint("Slave critical fault - package: %s (by slave fault %s\n", package_name(info), slave_name(slave));
184 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
185 DbgPrint("Destroy instance %p\n", inst);
186 instance_destroyed(inst, LB_STATUS_ERROR_FAULT);
192 static int slave_deactivated_cb(struct slave_node *slave, void *data)
194 struct pkg_info *info = data;
195 struct inst_info *inst;
200 if (info->fault_info) {
201 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
202 instance_destroyed(inst, LB_STATUS_ERROR_FAULT);
205 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
206 cnt += instance_need_slave(inst);
208 * instance_deactivated will call the slave_unload_instance.
209 * if the loaded instance counter meets 0,
210 * the slave will be deactivated.
211 * so we should not call the instance activate function
214 * activate slave when the slave is reactivated
219 return cnt ? SLAVE_NEED_TO_REACTIVATE : 0;
222 static int xmonitor_paused_cb(void *data)
224 struct pkg_info *info = (struct pkg_info *)data;
225 struct inst_info *inst;
228 if (slave_state(info->slave) != SLAVE_TERMINATED) {
232 EINA_LIST_FOREACH(info->inst_list, l, inst) {
233 instance_freeze_updator(inst);
239 static int xmonitor_resumed_cb(void *data)
241 struct pkg_info *info = data;
242 struct inst_info *inst;
245 if (slave_state(info->slave) != SLAVE_TERMINATED) {
249 EINA_LIST_FOREACH(info->inst_list, l, inst) {
250 instance_thaw_updator(inst);
256 static int slave_paused_cb(struct slave_node *slave, void *data)
258 struct pkg_info *info = (struct pkg_info *)data;
259 struct inst_info *inst;
262 EINA_LIST_FOREACH(info->inst_list, l, inst) {
263 instance_freeze_updator(inst);
269 static int slave_resumed_cb(struct slave_node *slave, void *data)
271 struct pkg_info *info = (struct pkg_info *)data;
272 struct inst_info *inst;
275 EINA_LIST_FOREACH(info->inst_list, l, inst) {
276 instance_thaw_updator(inst);
282 static inline void destroy_package(struct pkg_info *info)
284 eina_list_free(info->ctx_list);
285 /* This items will be deleted from group_del_livebox */
286 info->ctx_list = NULL;
288 group_del_livebox(info->lbid);
289 package_clear_fault(info);
291 s_info.pkg_list = eina_list_remove(s_info.pkg_list, info);
293 if (info->lb.type == LB_TYPE_SCRIPT) {
294 DbgFree(info->lb.info.script.path);
295 DbgFree(info->lb.info.script.group);
298 if (info->pd.type == PD_TYPE_SCRIPT) {
299 DbgFree(info->pd.info.script.path);
300 DbgFree(info->pd.info.script.group);
303 DbgFree(info->script);
306 DbgFree(info->lb.libexec);
307 DbgFree(info->lb.auto_launch);
308 DbgFree(info->pkgid);
313 static inline int load_conf(struct pkg_info *info)
315 struct parser *parser;
319 parser = parser_load(info->lbid);
321 info->lb.size_list = 0x01; /* Default */
323 info->script = strdup(DEFAULT_SCRIPT);
325 ErrPrint("Heap: %s\n", strerror(errno));
326 return LB_STATUS_ERROR_MEMORY;
329 info->abi = strdup(DEFAULT_ABI);
331 ErrPrint("Heap: %s\n", strerror(errno));
332 DbgFree(info->script);
334 return LB_STATUS_ERROR_MEMORY;
337 info->pd.width = g_conf.width;
338 info->pd.height = g_conf.height >> 2;
340 return LB_STATUS_SUCCESS;
343 info->lb.type = LB_TYPE_FILE;
344 if (parser_text_lb(parser)) {
345 info->lb.type = LB_TYPE_TEXT;
346 } else if (parser_buffer_lb(parser)) {
347 info->lb.type = LB_TYPE_BUFFER;
349 str = parser_lb_path(parser);
351 info->lb.type = LB_TYPE_SCRIPT;
353 info->lb.info.script.path = strdup(str);
354 if (!info->lb.info.script.path) {
355 ErrPrint("Heap: %s\n", strerror(errno));
356 parser_unload(parser);
357 return LB_STATUS_ERROR_MEMORY;
360 str = parser_lb_group(parser);
362 info->lb.info.script.group = strdup(str);
363 if (!info->lb.info.script.group) {
364 ErrPrint("Heap: %s\n", strerror(errno));
365 DbgFree(info->lb.info.script.path);
366 parser_unload(parser);
367 return LB_STATUS_ERROR_MEMORY;
373 if (parser_text_pd(parser)) {
374 info->pd.type = PD_TYPE_TEXT;
375 } else if (parser_buffer_pd(parser)) {
376 info->pd.type = PD_TYPE_BUFFER;
378 str = parser_pd_path(parser);
380 info->pd.type = PD_TYPE_SCRIPT;
381 info->pd.info.script.path = strdup(str);
382 if (!info->pd.info.script.path) {
383 ErrPrint("Heap: %s\n", strerror(errno));
384 if (info->lb.type == LB_TYPE_SCRIPT) {
385 DbgFree(info->lb.info.script.path);
386 DbgFree(info->lb.info.script.group);
388 parser_unload(parser);
389 return LB_STATUS_ERROR_MEMORY;
392 str = parser_pd_group(parser);
394 info->pd.info.script.group = strdup(str);
395 if (!info->pd.info.script.group) {
396 ErrPrint("Heap: %s\n", strerror(errno));
397 DbgFree(info->pd.info.script.path);
398 if (info->lb.type == LB_TYPE_SCRIPT) {
399 DbgFree(info->lb.info.script.path);
400 DbgFree(info->lb.info.script.group);
402 parser_unload(parser);
403 return LB_STATUS_ERROR_MEMORY;
409 str = parser_script(parser);
410 str = str ? str : DEFAULT_SCRIPT;
411 info->script = strdup(str);
413 ErrPrint("Heap: %s\n", strerror(errno));
414 if (info->pd.type == PD_TYPE_SCRIPT) {
415 DbgFree(info->pd.info.script.path);
416 DbgFree(info->pd.info.script.group);
419 if (info->lb.type == LB_TYPE_SCRIPT) {
420 DbgFree(info->lb.info.script.path);
421 DbgFree(info->lb.info.script.group);
424 parser_unload(parser);
425 return LB_STATUS_ERROR_MEMORY;
428 str = parser_abi(parser);
429 str = str ? str : DEFAULT_ABI;
430 info->abi = strdup(str);
432 ErrPrint("Heap: %s\n", strerror(errno));
433 DbgFree(info->script);
434 if (info->pd.type == PD_TYPE_SCRIPT) {
435 DbgFree(info->pd.info.script.path);
436 DbgFree(info->pd.info.script.group);
439 if (info->lb.type == LB_TYPE_SCRIPT) {
440 DbgFree(info->lb.info.script.path);
441 DbgFree(info->lb.info.script.group);
443 parser_unload(parser);
444 return LB_STATUS_ERROR_MEMORY;
447 info->lb.timeout = parser_timeout(parser);
448 info->network = parser_network(parser);
450 info->lb.period = parser_period(parser);
451 if (info->lb.period < 0.0f) {
452 info->lb.period = 0.0f;
453 } else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD) {
454 info->lb.period = MINIMUM_PERIOD;
457 info->lb.size_list = parser_size(parser);
459 str = parser_auto_launch(parser);
460 str = str ? str : "";
461 info->lb.auto_launch = strdup(str);
462 if (!info->lb.auto_launch) {
463 ErrPrint("Heap: %s\n", strerror(errno));
465 DbgFree(info->script);
466 if (info->pd.type == PD_TYPE_SCRIPT) {
467 DbgFree(info->pd.info.script.path);
468 DbgFree(info->pd.info.script.group);
471 if (info->lb.type == LB_TYPE_SCRIPT) {
472 DbgFree(info->lb.info.script.path);
473 DbgFree(info->lb.info.script.group);
475 parser_unload(parser);
476 return LB_STATUS_ERROR_MEMORY;
479 info->secured = parser_secured(parser);
480 info->lb.pinup = parser_pinup(parser);
482 parser_get_pdsize(parser, &info->pd.width, &info->pd.height);
484 group = parser_group_str(parser);
485 if (group && group_add_livebox(group, info->lbid) < 0) {
486 ErrPrint("Failed to build cluster tree for %s{%s}\n", info->lbid, group);
489 parser_unload(parser);
490 return LB_STATUS_SUCCESS;
493 HAPI struct pkg_info *package_create(const char *pkgid, const char *lbid)
495 struct pkg_info *pkginfo;
497 pkginfo = calloc(1, sizeof(*pkginfo));
499 ErrPrint("Heap: %s\n", strerror(errno));
503 pkginfo->pkgid = strdup(pkgid);
504 if (!pkginfo->pkgid) {
505 ErrPrint("Heap: %s\n", strerror(errno));
510 pkginfo->lbid = io_livebox_pkgname(lbid);
511 if (!pkginfo->lbid) {
512 ErrPrint("Failed to get pkgname, fallback to fs checker\n");
513 if (util_validate_livebox_package(lbid) < 0) {
514 ErrPrint("Invalid package name: %s\n", lbid);
515 DbgFree(pkginfo->pkgid);
520 pkginfo->lbid = strdup(lbid);
521 if (!pkginfo->lbid) {
522 ErrPrint("Heap: %s\n", strerror(errno));
523 DbgFree(pkginfo->pkgid);
529 if (io_load_package_db(pkginfo) < 0) {
530 ErrPrint("Failed to load DB, fall back to conf file loader\n");
531 if (load_conf(pkginfo) < 0) {
532 ErrPrint("Failed to initiate the conf file loader\n");
533 DbgFree(pkginfo->lbid);
534 DbgFree(pkginfo->pkgid);
540 package_ref(pkginfo);
542 s_info.pkg_list = eina_list_append(s_info.pkg_list, pkginfo);
547 HAPI int package_destroy(struct pkg_info *info)
550 return LB_STATUS_SUCCESS;
553 HAPI Eina_List *package_ctx_info(struct pkg_info *pkginfo)
555 return pkginfo->ctx_list;
558 HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
560 pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
563 HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
565 pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
568 HAPI char *package_lb_pkgname(const char *pkgname)
572 lbid = io_livebox_pkgname(pkgname);
574 if (util_validate_livebox_package(pkgname) < 0) {
578 lbid = strdup(pkgname);
580 ErrPrint("Heap: %s\n", strerror(errno));
588 HAPI int package_is_lb_pkgname(const char *pkgname)
593 lbid = package_lb_pkgname(pkgname);
600 HAPI struct pkg_info *package_find(const char *lbid)
603 struct pkg_info *info;
609 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
610 if (!strcmp(info->lbid, lbid)) {
618 HAPI struct inst_info *package_find_instance_by_id(const char *lbid, const char *id)
621 struct inst_info *inst;
622 struct pkg_info *info;
624 info = package_find(lbid);
626 ErrPrint("Package %s is not exists\n", lbid);
630 EINA_LIST_FOREACH(info->inst_list, l, inst) {
631 if (!strcmp(instance_id(inst), id)) {
639 HAPI struct inst_info *package_find_instance_by_timestamp(const char *lbid, double timestamp)
642 struct inst_info *inst;
643 struct pkg_info *info;
645 info = package_find(lbid);
647 ErrPrint("Package %s is not exists\n", lbid);
651 EINA_LIST_FOREACH(info->inst_list, l, inst) {
652 if (instance_timestamp(inst) == timestamp) {
660 HAPI int package_dump_fault_info(struct pkg_info *info)
662 if (!info->fault_info) {
663 return LB_STATUS_ERROR_NOT_EXIST;
666 CRITICAL_LOG("=============\n");
667 CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
668 CRITICAL_LOG("Package: %s\n", info->lbid);
669 CRITICAL_LOG("Function: %s\n", info->fault_info->function);
670 CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
671 return LB_STATUS_SUCCESS;
674 HAPI int package_get_fault_info(struct pkg_info *info, double *timestamp, const char **filename, const char **function)
676 if (!info->fault_info) {
677 return LB_STATUS_ERROR_NOT_EXIST;
680 *timestamp = info->fault_info->timestamp;
681 *filename = info->fault_info->filename;
682 *function = info->fault_info->function;
683 return LB_STATUS_SUCCESS;
686 HAPI int package_set_fault_info(struct pkg_info *info, double timestamp, const char *filename, const char *function)
688 struct fault_info *fault;
690 package_clear_fault(info);
692 fault = calloc(1, sizeof(*fault));
694 ErrPrint("Heap: %s\n", strerror(errno));
695 return LB_STATUS_ERROR_MEMORY;
698 fault->timestamp = timestamp;
700 filename = "unknown";
703 function = "unknown";
706 fault->filename = strdup(filename);
707 if (!fault->filename) {
708 ErrPrint("Heap: %s\n", strerror(errno));
710 return LB_STATUS_ERROR_MEMORY;
713 fault->function = strdup(function);
714 if (!fault->function) {
715 ErrPrint("Heap: %s\n", strerror(errno));
716 DbgFree(fault->filename);
718 return LB_STATUS_ERROR_MEMORY;
721 info->fault_info = fault;
723 return LB_STATUS_SUCCESS;
726 HAPI int package_clear_fault(struct pkg_info *info)
728 if (!info->fault_info) {
729 return LB_STATUS_ERROR_INVALID;
732 package_dump_fault_info(info);
734 DbgFree(info->fault_info->function);
735 DbgFree(info->fault_info->filename);
736 DbgFree(info->fault_info);
737 info->fault_info = NULL;
738 return LB_STATUS_SUCCESS;
741 HAPI const int const package_is_fault(const struct pkg_info *info)
743 return !!info->fault_info;
746 HAPI struct slave_node * const package_slave(const struct pkg_info *info)
751 HAPI const int const package_timeout(const struct pkg_info *info)
753 return info->lb.timeout;
756 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
758 info->lb.timeout = timeout;
761 HAPI const double const package_period(const struct pkg_info *info)
763 return info->lb.period;
766 HAPI void package_set_period(struct pkg_info *info, double period)
768 info->lb.period = period;
771 HAPI const int const package_secured(const struct pkg_info *info)
773 return info->secured;
776 HAPI void package_set_secured(struct pkg_info *info, int secured)
778 info->secured = secured;
781 HAPI const char * const package_script(const struct pkg_info *info)
786 HAPI int package_set_script(struct pkg_info *info, const char *script)
790 tmp = strdup(script);
792 ErrPrint("Heap: %s\n", strerror(errno));
793 return LB_STATUS_ERROR_MEMORY;
796 DbgFree(info->script);
798 return LB_STATUS_SUCCESS;
801 HAPI const char * const package_abi(const struct pkg_info *info)
806 HAPI int package_set_abi(struct pkg_info *info, const char *abi)
811 ErrPrint("Heap: %s\n", strerror(errno));
812 return LB_STATUS_ERROR_MEMORY;
817 return LB_STATUS_SUCCESS;
820 HAPI const char * const package_lb_path(const struct pkg_info *info)
822 if (info->lb.type != LB_TYPE_SCRIPT) {
826 return info->lb.info.script.path;
829 HAPI int package_set_lb_path(struct pkg_info *info, const char *path)
833 if (info->lb.type != LB_TYPE_SCRIPT) {
834 return LB_STATUS_ERROR_INVALID;
839 ErrPrint("Heap: %s\n", strerror(errno));
840 return LB_STATUS_ERROR_MEMORY;
843 DbgFree(info->lb.info.script.path);
844 info->lb.info.script.path = tmp;
845 return LB_STATUS_SUCCESS;
848 HAPI const char * const package_lb_group(const struct pkg_info *info)
850 if (info->lb.type != LB_TYPE_SCRIPT) {
854 return info->lb.info.script.group;
857 HAPI int package_set_lb_group(struct pkg_info *info, const char *group)
861 if (info->lb.type != LB_TYPE_SCRIPT) {
862 return LB_STATUS_ERROR_INVALID;
867 ErrPrint("Heap: %s\n", strerror(errno));
868 return LB_STATUS_ERROR_MEMORY;
871 DbgFree(info->lb.info.script.group);
872 info->lb.info.script.group = tmp;
873 return LB_STATUS_SUCCESS;
876 HAPI const char * const package_pd_path(const struct pkg_info *info)
878 if (info->pd.type != PD_TYPE_SCRIPT) {
882 return info->pd.info.script.path;
885 HAPI int package_set_pd_path(struct pkg_info *info, const char *path)
889 if (info->pd.type != PD_TYPE_SCRIPT) {
890 return LB_STATUS_ERROR_INVALID;
895 ErrPrint("Heap: %s\n", strerror(errno));
896 return LB_STATUS_ERROR_MEMORY;
899 DbgFree(info->pd.info.script.path);
900 info->pd.info.script.path = tmp;
901 return LB_STATUS_SUCCESS;
904 HAPI const char * const package_pd_group(const struct pkg_info *info)
906 if (info->pd.type != PD_TYPE_SCRIPT) {
910 return info->pd.info.script.group;
913 HAPI int package_set_pd_group(struct pkg_info *info, const char *group)
917 if (info->pd.type != PD_TYPE_SCRIPT) {
918 return LB_STATUS_ERROR_INVALID;
923 ErrPrint("Heap: %s\n", strerror(errno));
924 return LB_STATUS_ERROR_MEMORY;
927 DbgFree(info->pd.info.script.group);
928 info->pd.info.script.group = tmp;
929 return LB_STATUS_SUCCESS;
932 HAPI const int const package_pinup(const struct pkg_info *info)
934 return info->lb.pinup;
937 HAPI void package_set_pinup(struct pkg_info *info, int pinup)
939 info->lb.pinup = pinup;
942 HAPI const char * const package_auto_launch(const struct pkg_info *info)
944 return info->lb.auto_launch;
947 HAPI void package_set_auto_launch(struct pkg_info *info, const char *auto_launch)
953 info->lb.auto_launch = strdup(auto_launch);
954 if (!info->lb.auto_launch) {
955 ErrPrint("Heap: %s\n", strerror(errno));
960 HAPI const unsigned int const package_size_list(const struct pkg_info *info)
962 return info->lb.size_list;
965 HAPI void package_set_size_list(struct pkg_info *info, unsigned int size_list)
967 info->lb.size_list = size_list;
970 HAPI const int const package_pd_width(const struct pkg_info *info)
972 return info->pd.width;
975 HAPI void package_set_pd_width(struct pkg_info *info, int width)
977 info->pd.width = width;
980 HAPI const int const package_pd_height(const struct pkg_info *info)
982 return info->pd.height;
985 HAPI void package_set_pd_height(struct pkg_info *info, int height)
987 info->pd.height = height;
990 HAPI struct pkg_info * const package_ref(struct pkg_info *info)
996 HAPI struct pkg_info * const package_unref(struct pkg_info *info)
998 if (info->refcnt == 0) {
999 ErrPrint("Invalid request\n");
1004 if (info->refcnt == 0) {
1005 destroy_package(info);
1012 HAPI const int const package_refcnt(const struct pkg_info *info)
1014 return info->refcnt;
1017 HAPI const enum lb_type package_lb_type(const struct pkg_info *info)
1019 return info ? info->lb.type : LB_TYPE_NONE;
1022 HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
1024 info->lb.type = type;
1027 HAPI const char * const package_libexec(struct pkg_info *info)
1029 return info->lb.libexec;
1032 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
1036 tmp = strdup(libexec);
1038 ErrPrint("Heap: %s\n", strerror(errno));
1039 return LB_STATUS_ERROR_MEMORY;
1042 DbgFree(info->lb.libexec);
1043 info->lb.libexec = tmp;
1044 return LB_STATUS_SUCCESS;
1047 HAPI int package_network(struct pkg_info *info)
1049 return info->network;
1052 HAPI void package_set_network(struct pkg_info *info, int network)
1054 info->network = network;
1057 HAPI const enum pd_type const package_pd_type(const struct pkg_info *info)
1059 return info ? info->pd.type : PD_TYPE_NONE;
1062 HAPI void package_set_pd_type(struct pkg_info *info, enum pd_type type)
1064 info->pd.type = type;
1069 * Add the instance to the package info.
1070 * If a package has no slave, assign a new slave.
1072 static inline int assign_new_slave(struct pkg_info *info)
1078 s_name = util_slavename();
1080 ErrPrint("Failed to get a new slave name\n");
1081 return LB_STATUS_ERROR_FAULT;
1084 tmp = abi_find_slave(info->abi);
1087 ErrPrint("Failed to find a proper pkgname of a slave\n");
1088 return LB_STATUS_ERROR_INVALID;
1091 s_pkgname = util_replace_string(tmp, REPLACE_TAG_APPID, info->lbid);
1093 DbgPrint("Failed to get replaced string\n");
1094 s_pkgname = strdup(tmp);
1096 ErrPrint("Heap: %s\n", strerror(errno));
1098 return LB_STATUS_ERROR_MEMORY;
1102 DbgPrint("New slave[%s] is assigned for %s (using %s / abi[%s])\n", s_name, info->lbid, s_pkgname, info->abi);
1103 info->slave = slave_create(s_name, info->secured, info->abi, s_pkgname, info->network);
1111 * package_destroy will try to remove "info" from the pkg_list.
1112 * but we didn't add this to it yet.
1113 * If the list method couldn't find an "info" from the list,
1114 * it just do nothing so I'll leave this.
1116 return LB_STATUS_ERROR_FAULT;
1120 * Slave is not activated yet.
1122 return LB_STATUS_SUCCESS;
1125 HAPI int package_add_instance(struct pkg_info *info, struct inst_info *inst)
1127 if (!info->inst_list) {
1128 info->slave = slave_find_available(info->abi, info->secured, info->network);
1133 ret = assign_new_slave(info);
1138 DbgPrint("Slave %s is used for %s\n", slave_name(info->slave), info->lbid);
1141 (void)slave_ref(info->slave);
1142 slave_load_package(info->slave);
1143 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1144 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1145 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1147 if (info->secured) {
1148 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1149 (void)slave_event_callback_add(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1153 * In case of the slave is terminated because of expired TTL timer,
1154 * Master should freeze the all update time.
1155 * But the callback should check the slave's state to prevent from duplicated freezing.
1157 * This callback will freeze the timer only if a slave doesn't running.
1159 (void)xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1160 (void)xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1164 info->inst_list = eina_list_append(info->inst_list, inst);
1165 return LB_STATUS_SUCCESS;
1168 HAPI int package_del_instance(struct pkg_info *info, struct inst_info *inst)
1170 info->inst_list = eina_list_remove(info->inst_list, inst);
1172 if (info->inst_list) {
1173 return LB_STATUS_SUCCESS;
1177 slave_unload_package(info->slave);
1179 slave_event_callback_del(info->slave, SLAVE_EVENT_FAULT, slave_fault_cb, info);
1180 slave_event_callback_del(info->slave, SLAVE_EVENT_DEACTIVATE, slave_deactivated_cb, info);
1181 slave_event_callback_del(info->slave, SLAVE_EVENT_ACTIVATE, slave_activated_cb, info);
1183 if (info->secured) {
1184 slave_event_callback_del(info->slave, SLAVE_EVENT_PAUSE, slave_paused_cb, info);
1185 slave_event_callback_del(info->slave, SLAVE_EVENT_RESUME, slave_resumed_cb, info);
1187 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_paused_cb, info);
1188 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resumed_cb, info);
1191 slave_unref(info->slave);
1195 if (info->is_uninstalled) {
1196 package_destroy(info);
1199 return LB_STATUS_SUCCESS;
1202 HAPI Eina_List *package_instance_list(struct pkg_info *info)
1204 return info->inst_list;
1207 static int client_created_cb(struct client_node *client, void *data)
1209 struct pkg_info *info;
1212 struct inst_info *inst;
1215 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1216 if (info->fault_info) {
1217 fault_unicast_info(client, info->lbid, info->fault_info->filename, info->fault_info->function);
1221 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1222 switch (instance_state(inst)) {
1224 /* Will be send a created event after the instance gets created event */
1226 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1227 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1228 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1229 if (instance_client(inst) == client) {
1230 instance_unicast_created_event(inst, client);
1231 } else if (instance_client(inst) == NULL) {
1234 * Instances are lives in the system cluster/sub-cluster
1236 if (client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1237 instance_unicast_created_event(inst, client);
1238 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1244 DbgPrint("%s(%s) is not activated (%d)\n",
1245 package_name(info), instance_id(inst), instance_state(inst));
1254 static int io_uninstall_cb(const char *pkgid, const char *lbid, int prime, void *data)
1256 struct pkg_info *info;
1259 struct inst_info *inst;
1261 DbgPrint("Package %s is uninstalled\n", lbid);
1262 info = package_find(lbid);
1264 DbgPrint("%s is not yet loaded\n", lbid);
1268 info->is_uninstalled = 1;
1272 * Don't delete an item from the inst_list.
1273 * destroy callback will use this list again.
1274 * So, Don't touch it from here.
1276 if (info->inst_list) {
1277 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1278 instance_destroy(inst, INSTANCE_DESTROY_UNINSTALL);
1281 package_destroy(info);
1287 static inline void reload_package_info(struct pkg_info *info)
1291 struct inst_info *inst;
1292 unsigned int size_type;
1297 DbgPrint("Already exists, try to update it\n");
1299 old_period = info->lb.period;
1301 group_del_livebox(info->lbid);
1302 package_clear_fault(info);
1308 io_load_package_db(info);
1312 * Without "is_uninstalled", the package will be kept
1314 EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
1315 width = instance_lb_width(inst);
1316 height = instance_lb_height(inst);
1317 size_type = livebox_service_size_type(width, height);
1318 if (info->lb.size_list & size_type) {
1319 if (instance_period(inst) == old_period) {
1320 instance_reload_period(inst, package_period(info));
1322 instance_reload(inst, INSTANCE_DESTROY_UPGRADE);
1324 instance_destroy(inst, INSTANCE_DESTROY_UNINSTALL);
1329 static int io_install_cb(const char *pkgid, const char *lbid, int prime, void *data)
1331 struct pkg_info *info;
1333 info = package_find(lbid);
1336 * Already exists. skip to create this.
1341 info = package_create(pkgid, lbid);
1343 ErrPrint("Failed to build an info %s\n", lbid);
1345 DbgPrint("Livebox %s is built\n", lbid);
1351 static int uninstall_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1355 struct pkg_info *info;
1357 if (status != PKGMGR_STATUS_END) {
1361 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1362 if (!strcmp(info->pkgid, pkgname)) {
1363 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1370 static int update_cb(const char *pkgname, enum pkgmgr_status status, double value, void *data)
1374 struct pkg_info *info;
1376 if (status != PKGMGR_STATUS_END) {
1380 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, l, n, info) {
1381 if (!strcmp(info->pkgid, pkgname)) {
1382 DbgPrint("Update lbid: %s\n", info->lbid);
1383 if (io_is_exists(info->lbid) == 1) {
1384 reload_package_info(info);
1386 io_uninstall_cb(pkgname, info->lbid, -1, NULL);
1391 (void)io_update_livebox_package(pkgname, io_install_cb, NULL);
1395 static int crawling_liveboxes(const char *pkgid, const char *lbid, int prime, void *data)
1397 if (package_find(lbid)) {
1398 ErrPrint("Information of %s is already built\n", lbid);
1400 struct pkg_info *info;
1401 info = package_create(pkgid, lbid);
1403 DbgPrint("[%s] information is built prime(%d)\n", lbid, prime);
1410 HAPI int package_init(void)
1412 client_global_event_handler_add(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1415 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1416 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1417 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1419 io_crawling_liveboxes(crawling_liveboxes, NULL);
1423 HAPI int package_fini(void)
1429 struct pkg_info *info;
1430 struct inst_info *inst;
1432 pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, update_cb, NULL);
1433 pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
1434 pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
1436 client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
1438 EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
1439 EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
1440 instance_state_reset(inst);
1441 instance_destroy(inst, INSTANCE_DESTROY_TERMINATE);
1444 package_destroy(info);
1450 HAPI const char *package_find_by_secured_slave(struct slave_node *slave)
1453 struct pkg_info *info;
1455 if (!slave_is_secured(slave)) {
1459 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1460 if (info->slave == slave) {
1468 HAPI const char * const package_name(const struct pkg_info *info)
1474 * del_or_creat : 1 == create, 0 == delete
1476 HAPI int package_alter_instances_to_client(struct client_node *client, enum alter_type alter)
1478 struct pkg_info *info;
1481 struct inst_info *inst;
1484 EINA_LIST_FOREACH(s_info.pkg_list, l, info) {
1485 EINA_LIST_FOREACH(info->inst_list, i_l, inst) {
1486 if (instance_client(inst)) {
1490 if (!client_is_subscribed(client, instance_cluster(inst), instance_category(inst))) {
1494 switch (instance_state(inst)) {
1496 case INST_REQUEST_TO_ACTIVATE:
1497 /* Will be send a created event after the instance gets created event */
1500 if (!instance_has_client(inst, client)) {
1501 instance_add_client(inst, client);
1505 if (instance_has_client(inst, client)) {
1506 instance_del_client(inst, client);
1513 case INST_ACTIVATED: /*!< This instance is actiavted, and used */
1514 case INST_REQUEST_TO_REACTIVATE: /*!< This instance will be reactivated soon */
1515 case INST_REQUEST_TO_DESTROY: /*!< This instance will be destroy soon */
1518 * Instances are lives in the system cluster/sub-cluster
1522 if (!instance_has_client(inst, client)) {
1523 instance_unicast_created_event(inst, client);
1524 instance_add_client(inst, client);
1525 DbgPrint("(Subscribed) Created package: %s\n", info->lbid);
1529 if (instance_has_client(inst, client)) {
1530 instance_unicast_deleted_event(inst, client, LB_STATUS_SUCCESS);
1531 instance_del_client(inst, client);
1540 DbgPrint("%s(%s) is not activated (%d)\n",
1541 package_name(info), instance_id(inst), instance_state(inst));
1550 HAPI const Eina_List *package_list(void)
1552 return s_info.pkg_list;
1555 HAPI int const package_fault_count(struct pkg_info *info)
1557 return info ? info->fault_count : 0;
1560 HAPI int package_is_enabled(const char *appid)
1566 ret = ail_get_appinfo(appid, &ai);
1567 if (ret != AIL_ERROR_OK) {
1568 ErrPrint("Unable to get appinfo: %d\n", ret);
1572 if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK) {
1576 ail_destroy_appinfo(ai);
1578 return enabled == true;
1581 HAPI int package_faulted(struct pkg_info *pkg, int broadcast)
1585 struct slave_node *slave;
1586 struct inst_info *inst;
1588 slave = package_slave(pkg);
1590 ErrPrint("Package has no slave?\n");
1591 return LB_STATUS_ERROR_FAULT;
1594 /* Emulated fault routine */
1595 // (void)package_set_fault_info(pkg, util_timestamp(), slave_name(slave), __func__);
1597 fault_broadcast_info(package_name(pkg), slave_name(slave), __func__);
1600 DbgPrint("package: %s (forucely faulted %s)\n", package_name(pkg), slave_name(slave));
1601 EINA_LIST_FOREACH_SAFE(pkg->inst_list, l, n, inst) {
1602 DbgPrint("Destroy instance %p\n", inst);
1603 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
1606 return LB_STATUS_SUCCESS;