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>
30 #include "slave_life.h"
31 #include "slave_rpc.h"
32 #include "client_life.h"
34 #include "client_rpc.h"
37 #include "critical_log.h"
44 .fault_mark_count = 0,
48 struct slave_node *slave;
55 HAPI int const fault_is_occured(void)
57 return s_info.fault_mark_count;
60 static void clear_log_file(struct slave_node *slave)
62 char filename[BUFSIZ];
65 ret = snprintf(filename, sizeof(filename) - 1, "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
66 if (ret == sizeof(filename) - 1) {
67 filename[sizeof(filename) - 1] = '\0';
68 ErrPrint("filename buffer is overflowed\n");
71 if (unlink(filename) < 0) {
72 ErrPrint("unlink: %s\n", strerror(errno));
76 static char *check_log_file(struct slave_node *slave)
79 const char *pattern = "liblive-";
83 char filename[BUFSIZ];
85 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
86 fp = fopen(filename, "rt");
88 ErrPrint("No log file found [%s]\n", strerror(errno));
92 ptr = fgets(pkgname, sizeof(pkgname), fp);
93 if (fclose(fp) != 0) {
94 ErrPrint("fclose: %s\n", strerror(errno));
98 ErrPrint("Invalid log\n");
102 for (i = 0; pattern[i] && (pattern[i] == pkgname[i]); i++); /*!< Check pattern of filename */
103 if (strlen(pattern) != i) {
104 ErrPrint("Pattern is not matched: %d\n", i);
109 i = strlen(ptr) - 3; /* Skip the ".so" */
110 if (i <= 0 || strcmp(ptr + i, ".so")) {
111 ErrPrint("Extension is not matched\n");
115 ptr[i] = '\0'; /*!< Truncate tailer ".so" */
116 if (unlink(filename) < 0) {
117 ErrPrint("Failed to unlink %s\n", filename);
123 HAPI void fault_unicast_info(struct client_node *client, const char *pkgname, const char *filename, const char *func)
125 struct packet *packet;
127 if (!client || !pkgname || !filename || !func) {
131 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
136 client_rpc_async_request(client, packet);
139 HAPI void fault_broadcast_info(const char *pkgname, const char *filename, const char *func)
141 struct packet *packet;
143 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
145 ErrPrint("Failed to create a param\n");
149 client_broadcast(NULL, packet);
152 static inline void dump_fault_info(const char *name, pid_t pid, const char *pkgname, const char *filename, const char *funcname)
154 CRITICAL_LOG("Slavename: %s[%d]\n" \
157 "Funcname: %s\n", name, pid, pkgname, filename, funcname);
160 HAPI int fault_info_set(struct slave_node *slave, const char *pkgname, const char *id, const char *func)
162 struct pkg_info *pkg;
165 pkg = package_find(pkgname);
167 return LB_STATUS_ERROR_NOT_EXIST;
170 ret = package_set_fault_info(pkg, util_timestamp(), id, func);
172 return LB_STATUS_ERROR_FAULT;
175 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, id, func);
176 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
177 fault_broadcast_info(pkgname, id, func);
183 s_info.fault_mark_count++;
184 return LB_STATUS_SUCCESS;
187 HAPI int fault_check_pkgs(struct slave_node *slave)
189 struct fault_info *info;
190 struct pkg_info *pkg;
201 pkgname = (const char *)check_log_file(slave);
203 pkg = package_find(pkgname);
206 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
207 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
208 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
209 fault_broadcast_info(pkgname, "", "");
210 DbgFree((char *)pkgname);
212 s_info.fault_mark_count = 0;
213 clear_log_file(slave);
214 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
215 if (info->slave != slave) {
219 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
221 DbgFree(info->pkgname);
222 DbgFree(info->filename);
228 DbgFree((char *)pkgname);
234 * Is it secured slave?
236 pkgname = package_find_by_secured_slave(slave);
238 pkg = package_find(pkgname);
241 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
242 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
243 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
244 fault_broadcast_info(pkgname, "", "");
246 s_info.fault_mark_count = 0;
247 clear_log_file(slave);
248 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
249 if (info->slave != slave) {
253 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
255 DbgFree(info->pkgname);
256 DbgFree(info->filename);
266 * At last, check the pair of function call and return mark
269 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
270 if (info->slave == slave) {
271 const char *filename;
274 pkg = package_find(info->pkgname);
276 ErrPrint("Failed to find a package %s\n", info->pkgname);
280 filename = info->filename ? info->filename : "";
281 func = info->func ? info->func : "";
285 ret = package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
286 fault_broadcast_info(info->pkgname, info->filename, info->func);
287 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
289 DbgPrint("Treated as a false log\n");
291 slave_name(info->slave), slave_pid(info->slave), info->pkgname, filename, func);
294 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
296 DbgFree(info->pkgname);
297 DbgFree(info->filename);
304 s_info.fault_mark_count = 0;
305 clear_log_file(slave);
309 HAPI int fault_func_call(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
311 struct fault_info *info;
313 info = malloc(sizeof(*info));
315 return LB_STATUS_ERROR_MEMORY;
320 info->pkgname = strdup(pkgname);
321 if (!info->pkgname) {
323 return LB_STATUS_ERROR_MEMORY;
326 info->filename = strdup(filename);
327 if (!info->filename) {
328 DbgFree(info->pkgname);
330 return LB_STATUS_ERROR_MEMORY;
333 info->func = strdup(func);
335 DbgFree(info->filename);
336 DbgFree(info->pkgname);
338 return LB_STATUS_ERROR_MEMORY;
341 info->timestamp = util_timestamp();
343 s_info.call_list = eina_list_append(s_info.call_list, info);
345 s_info.fault_mark_count++;
346 return LB_STATUS_SUCCESS;
349 HAPI int fault_func_ret(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
351 struct fault_info *info;
354 EINA_LIST_FOREACH(s_info.call_list, l, info) {
355 if (info->slave != slave) {
359 if (strcmp(info->pkgname, pkgname)) {
363 if (strcmp(info->filename, filename)) {
367 if (strcmp(info->func, func)) {
371 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
372 DbgFree(info->filename);
373 DbgFree(info->pkgname);
377 s_info.fault_mark_count--;
381 return LB_STATUS_ERROR_NOT_EXIST;