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];
64 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
69 static char *check_log_file(struct slave_node *slave)
72 const char *pattern = "liblive-";
76 char filename[BUFSIZ];
78 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
79 fp = fopen(filename, "rt");
81 ErrPrint("No log file found [%s]\n", strerror(errno));
85 ptr = fgets(pkgname, sizeof(pkgname), fp);
87 ErrPrint("fclose: %s\n", strerror(errno));
89 ErrPrint("Invalid log\n");
93 for (i = 0; pattern[i] && (pattern[i] == pkgname[i]); i++); /*!< Check pattern of filename */
94 if (strlen(pattern) != i) {
95 ErrPrint("Pattern is not matched: %d\n", i);
100 i = strlen(ptr) - 3; /* Skip the ".so" */
101 if (i <= 0 || strcmp(ptr + i, ".so")) {
102 ErrPrint("Extension is not matched\n");
106 ptr[i] = '\0'; /*!< Truncate tailer ".so" */
107 if (unlink(filename) < 0)
108 ErrPrint("Failed to unlink %s\n", filename);
113 HAPI void fault_unicast_info(struct client_node *client, const char *pkgname, const char *filename, const char *func)
115 struct packet *packet;
117 if (!client || !pkgname || !filename || !func)
120 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
124 client_rpc_async_request(client, packet);
125 DbgPrint("Fault package: %s\n", pkgname);
128 HAPI void fault_broadcast_info(const char *pkgname, const char *filename, const char *func)
130 struct packet *packet;
132 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
134 ErrPrint("Failed to create a param\n");
138 client_broadcast(NULL, packet);
139 DbgPrint("Fault package: %s\n", pkgname);
142 static inline void dump_fault_info(const char *name, pid_t pid, const char *pkgname, const char *filename, const char *funcname)
144 CRITICAL_LOG("Slavename: %s[%d]\n" \
147 "Funcname: %s\n", name, pid, pkgname, filename, funcname);
150 HAPI int fault_info_set(struct slave_node *slave, const char *pkgname, const char *id, const char *func)
152 struct pkg_info *pkg;
155 pkg = package_find(pkgname);
157 return LB_STATUS_ERROR_NOT_EXIST;
159 ret = package_set_fault_info(pkg, util_timestamp(), id, func);
161 return LB_STATUS_ERROR_FAULT;
163 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, id, func);
164 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
165 fault_broadcast_info(pkgname, id, func);
171 s_info.fault_mark_count++;
172 return LB_STATUS_SUCCESS;
175 HAPI int fault_check_pkgs(struct slave_node *slave)
177 struct fault_info *info;
178 struct pkg_info *pkg;
189 pkgname = (const char *)check_log_file(slave);
191 pkg = package_find(pkgname);
194 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
195 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
196 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
197 fault_broadcast_info(pkgname, "", "");
198 DbgFree((char *)pkgname);
200 s_info.fault_mark_count = 0;
201 clear_log_file(slave);
202 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
203 if (info->slave != slave)
206 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
208 DbgFree(info->pkgname);
209 DbgFree(info->filename);
215 DbgFree((char *)pkgname);
221 * Is it secured slave?
223 pkgname = package_find_by_secured_slave(slave);
225 pkg = package_find(pkgname);
228 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
229 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
230 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
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)
239 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
241 DbgFree(info->pkgname);
242 DbgFree(info->filename);
252 * At last, check the pair of function call and return mark
255 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
256 if (info->slave == slave) {
257 const char *filename;
260 pkg = package_find(info->pkgname);
262 ErrPrint("Failed to find a package %s\n", info->pkgname);
266 filename = info->filename ? info->filename : "";
267 func = info->func ? info->func : "";
271 ret = package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
272 fault_broadcast_info(info->pkgname, info->filename, info->func);
273 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
275 DbgPrint("Treated as a false log\n");
277 slave_name(info->slave), slave_pid(info->slave), info->pkgname, filename, func);
280 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
282 DbgFree(info->pkgname);
283 DbgFree(info->filename);
290 s_info.fault_mark_count = 0;
291 clear_log_file(slave);
295 HAPI int fault_func_call(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
297 struct fault_info *info;
299 info = malloc(sizeof(*info));
301 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)
343 if (strcmp(info->pkgname, pkgname))
346 if (strcmp(info->filename, filename))
349 if (strcmp(info->func, func))
352 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
353 DbgFree(info->filename);
354 DbgFree(info->pkgname);
358 s_info.fault_mark_count--;
362 return LB_STATUS_ERROR_NOT_EXIST;