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 <stdlib.h> /* free */
26 #include <livebox-errno.h>
27 #include <livebox-service.h>
31 #include "slave_life.h"
32 #include "slave_rpc.h"
33 #include "client_life.h"
35 #include "client_rpc.h"
38 #include "critical_log.h"
45 .fault_mark_count = 0,
49 struct slave_node *slave;
56 HAPI int const fault_is_occured(void)
58 return s_info.fault_mark_count;
61 static void clear_log_file(struct slave_node *slave)
63 char filename[BUFSIZ];
66 ret = snprintf(filename, sizeof(filename) - 1, "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
67 if (ret == sizeof(filename) - 1) {
68 filename[sizeof(filename) - 1] = '\0';
69 ErrPrint("filename buffer is overflowed\n");
72 if (unlink(filename) < 0) {
73 ErrPrint("unlink: %s\n", strerror(errno));
77 static char *check_log_file(struct slave_node *slave)
82 char filename[BUFSIZ];
84 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
85 fp = fopen(filename, "rt");
87 ErrPrint("No log file found [%s]\n", strerror(errno));
91 ptr = fgets(libexec, sizeof(libexec), fp);
92 if (fclose(fp) != 0) {
93 ErrPrint("fclose: %s\n", strerror(errno));
97 ErrPrint("Invalid log\n");
101 if (unlink(filename) < 0) {
102 ErrPrint("Failed to unlink %s\n", filename);
105 ptr = livebox_service_pkgname_by_libexec(libexec);
107 ErrPrint("Failed to find the faulted package\n");
110 DbgPrint("Faulted package: %s\n", ptr);
114 HAPI void fault_unicast_info(struct client_node *client, const char *pkgname, const char *filename, const char *func)
116 struct packet *packet;
118 if (!client || !pkgname || !filename || !func) {
122 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
127 client_rpc_async_request(client, packet);
130 HAPI void fault_broadcast_info(const char *pkgname, const char *filename, const char *func)
132 struct packet *packet;
134 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
136 ErrPrint("Failed to create a param\n");
140 client_broadcast(NULL, packet);
143 static inline void dump_fault_info(const char *name, pid_t pid, const char *pkgname, const char *filename, const char *funcname)
145 CRITICAL_LOG("Slavename: %s[%d]\n" \
148 "Funcname: %s\n", name, pid, pkgname, filename, funcname);
151 HAPI int fault_info_set(struct slave_node *slave, const char *pkgname, const char *id, const char *func)
153 struct pkg_info *pkg;
156 pkg = package_find(pkgname);
158 return LB_STATUS_ERROR_NOT_EXIST;
161 ret = package_set_fault_info(pkg, util_timestamp(), id, func);
163 return LB_STATUS_ERROR_FAULT;
166 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, id, func);
167 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
168 fault_broadcast_info(pkgname, id, func);
174 s_info.fault_mark_count++;
175 return LB_STATUS_SUCCESS;
178 HAPI int fault_check_pkgs(struct slave_node *slave)
180 struct fault_info *info;
181 struct pkg_info *pkg;
192 pkgname = (const char *)check_log_file(slave);
194 pkg = package_find(pkgname);
196 (void)package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
197 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
198 fault_broadcast_info(pkgname, "", "");
199 DbgFree((char *)pkgname);
201 s_info.fault_mark_count = 0;
202 clear_log_file(slave);
203 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
204 if (info->slave != slave) {
208 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
210 DbgFree(info->pkgname);
211 DbgFree(info->filename);
217 DbgFree((char *)pkgname);
223 * Is it secured slave?
225 pkgname = package_find_by_secured_slave(slave);
227 pkg = package_find(pkgname);
229 (void)package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
230 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
231 fault_broadcast_info(pkgname, "", "");
233 s_info.fault_mark_count = 0;
234 clear_log_file(slave);
235 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
236 if (info->slave != slave) {
240 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
242 DbgFree(info->pkgname);
243 DbgFree(info->filename);
253 * At last, check the pair of function call and return mark
256 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
257 if (info->slave == slave) {
258 const char *filename;
261 pkg = package_find(info->pkgname);
263 ErrPrint("Failed to find a package %s\n", info->pkgname);
267 filename = info->filename ? info->filename : "";
268 func = info->func ? info->func : "";
271 (void)package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
272 fault_broadcast_info(info->pkgname, info->filename, info->func);
274 DbgPrint("Treated as a false log\n");
276 slave_name(info->slave), slave_pid(info->slave), info->pkgname, filename, func);
279 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
281 DbgFree(info->pkgname);
282 DbgFree(info->filename);
289 s_info.fault_mark_count = 0;
290 clear_log_file(slave);
294 HAPI int fault_func_call(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
296 struct fault_info *info;
298 info = malloc(sizeof(*info));
300 return LB_STATUS_ERROR_MEMORY;
305 info->pkgname = strdup(pkgname);
306 if (!info->pkgname) {
308 return LB_STATUS_ERROR_MEMORY;
311 info->filename = strdup(filename);
312 if (!info->filename) {
313 DbgFree(info->pkgname);
315 return LB_STATUS_ERROR_MEMORY;
318 info->func = strdup(func);
320 DbgFree(info->filename);
321 DbgFree(info->pkgname);
323 return LB_STATUS_ERROR_MEMORY;
326 info->timestamp = util_timestamp();
328 s_info.call_list = eina_list_append(s_info.call_list, info);
330 s_info.fault_mark_count++;
331 return LB_STATUS_SUCCESS;
334 HAPI int fault_func_ret(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
336 struct fault_info *info;
339 EINA_LIST_FOREACH(s_info.call_list, l, info) {
340 if (info->slave != slave) {
344 if (strcmp(info->pkgname, pkgname)) {
348 if (strcmp(info->filename, filename)) {
352 if (strcmp(info->func, func)) {
356 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
357 DbgFree(info->filename);
358 DbgFree(info->pkgname);
362 s_info.fault_mark_count--;
366 return LB_STATUS_ERROR_NOT_EXIST;