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);
197 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
198 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
199 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
200 fault_broadcast_info(pkgname, "", "");
201 DbgFree((char *)pkgname);
203 s_info.fault_mark_count = 0;
204 clear_log_file(slave);
205 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
206 if (info->slave != slave) {
210 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
212 DbgFree(info->pkgname);
213 DbgFree(info->filename);
219 DbgFree((char *)pkgname);
225 * Is it secured slave?
227 pkgname = package_find_by_secured_slave(slave);
229 pkg = package_find(pkgname);
232 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
233 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
234 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
235 fault_broadcast_info(pkgname, "", "");
237 s_info.fault_mark_count = 0;
238 clear_log_file(slave);
239 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
240 if (info->slave != slave) {
244 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
246 DbgFree(info->pkgname);
247 DbgFree(info->filename);
257 * At last, check the pair of function call and return mark
260 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
261 if (info->slave == slave) {
262 const char *filename;
265 pkg = package_find(info->pkgname);
267 ErrPrint("Failed to find a package %s\n", info->pkgname);
271 filename = info->filename ? info->filename : "";
272 func = info->func ? info->func : "";
276 ret = package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
277 fault_broadcast_info(info->pkgname, info->filename, info->func);
278 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
280 DbgPrint("Treated as a false log\n");
282 slave_name(info->slave), slave_pid(info->slave), info->pkgname, filename, func);
285 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
287 DbgFree(info->pkgname);
288 DbgFree(info->filename);
295 s_info.fault_mark_count = 0;
296 clear_log_file(slave);
300 HAPI int fault_func_call(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
302 struct fault_info *info;
304 info = malloc(sizeof(*info));
306 return LB_STATUS_ERROR_MEMORY;
311 info->pkgname = strdup(pkgname);
312 if (!info->pkgname) {
314 return LB_STATUS_ERROR_MEMORY;
317 info->filename = strdup(filename);
318 if (!info->filename) {
319 DbgFree(info->pkgname);
321 return LB_STATUS_ERROR_MEMORY;
324 info->func = strdup(func);
326 DbgFree(info->filename);
327 DbgFree(info->pkgname);
329 return LB_STATUS_ERROR_MEMORY;
332 info->timestamp = util_timestamp();
334 s_info.call_list = eina_list_append(s_info.call_list, info);
336 s_info.fault_mark_count++;
337 return LB_STATUS_SUCCESS;
340 HAPI int fault_func_ret(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
342 struct fault_info *info;
345 EINA_LIST_FOREACH(s_info.call_list, l, info) {
346 if (info->slave != slave) {
350 if (strcmp(info->pkgname, pkgname)) {
354 if (strcmp(info->filename, filename)) {
358 if (strcmp(info->func, func)) {
362 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
363 DbgFree(info->filename);
364 DbgFree(info->pkgname);
368 s_info.fault_mark_count--;
372 return LB_STATUS_ERROR_NOT_EXIST;