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"
43 .fault_mark_count = 0,
47 struct slave_node *slave;
54 HAPI int const fault_is_occured(void)
56 return s_info.fault_mark_count;
59 static void clear_log_file(struct slave_node *slave)
61 char filename[BUFSIZ];
63 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
68 static char *check_log_file(struct slave_node *slave)
71 const char *pattern = "liblive-";
75 char filename[BUFSIZ];
77 snprintf(filename, sizeof(filename), "%s/slave.%d", SLAVE_LOG_PATH, slave_pid(slave));
78 fp = fopen(filename, "rt");
80 ErrPrint("No log file found [%s]\n", strerror(errno));
84 ptr = fgets(pkgname, sizeof(pkgname), fp);
87 ErrPrint("Invalid log\n");
91 for (i = 0; pattern[i] && (pattern[i] == pkgname[i]); i++); /*!< Check pattern of filename */
92 if (strlen(pattern) != i) {
93 ErrPrint("Pattern is not matched: %d\n", i);
98 i = strlen(ptr) - 3; /* Skip the ".so" */
99 if (i <= 0 || strcmp(ptr + i, ".so")) {
100 ErrPrint("Extension is not matched\n");
104 ptr[i] = '\0'; /*!< Truncate tailer ".so" */
105 if (unlink(filename) < 0)
106 ErrPrint("Failed to unlink %s\n", filename);
111 HAPI void fault_unicast_info(struct client_node *client, const char *pkgname, const char *filename, const char *func)
113 struct packet *packet;
115 if (!client || !pkgname || !filename || !func)
118 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
122 client_rpc_async_request(client, packet);
123 DbgPrint("Fault package: %s\n", pkgname);
126 HAPI void fault_broadcast_info(const char *pkgname, const char *filename, const char *func)
128 struct packet *packet;
130 packet = packet_create_noack("fault_package", "sss", pkgname, filename, func);
132 ErrPrint("Failed to create a param\n");
136 client_broadcast(NULL, packet);
137 DbgPrint("Fault package: %s\n", pkgname);
140 static inline void dump_fault_info(const char *name, pid_t pid, const char *pkgname, const char *filename, const char *funcname)
142 ErrPrint("Fault processing ====\n");
143 ErrPrint("Slavename: %s[%d]\n", name, pid);
144 ErrPrint("Package: %s\n", pkgname);
145 ErrPrint("Filename: %s\n", filename);
146 ErrPrint("Funcname: %s\n", funcname);
149 HAPI int fault_info_set(struct slave_node *slave, const char *pkgname, const char *id, const char *func)
151 struct pkg_info *pkg;
154 pkg = package_find(pkgname);
156 return LB_STATUS_ERROR_NOT_EXIST;
158 ret = package_set_fault_info(pkg, util_timestamp(), id, func);
160 return LB_STATUS_ERROR_FAULT;
162 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, id, func);
163 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
164 fault_broadcast_info(pkgname, id, func);
170 s_info.fault_mark_count++;
171 return LB_STATUS_SUCCESS;
174 HAPI int fault_check_pkgs(struct slave_node *slave)
176 struct fault_info *info;
177 struct pkg_info *pkg;
188 pkgname = (const char *)check_log_file(slave);
190 pkg = package_find(pkgname);
193 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
194 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
195 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
196 fault_broadcast_info(pkgname, "", "");
197 DbgFree((char *)pkgname);
199 s_info.fault_mark_count = 0;
200 clear_log_file(slave);
201 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
202 if (info->slave != slave)
205 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
207 DbgFree(info->pkgname);
208 DbgFree(info->filename);
214 DbgFree((char *)pkgname);
220 * Is it secured slave?
222 pkgname = package_find_by_secured_slave(slave);
224 pkg = package_find(pkgname);
227 ret = package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
228 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
229 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
230 fault_broadcast_info(pkgname, "", "");
232 s_info.fault_mark_count = 0;
233 clear_log_file(slave);
234 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
235 if (info->slave != slave)
238 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
240 DbgFree(info->pkgname);
241 DbgFree(info->filename);
251 * At last, check the pair of function call and return mark
254 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
255 if (info->slave == slave) {
256 const char *filename;
259 pkg = package_find(info->pkgname);
261 ErrPrint("Failed to find a package %s\n", info->pkgname);
265 filename = info->filename ? info->filename : "";
266 func = info->func ? info->func : "";
270 ret = package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
271 fault_broadcast_info(info->pkgname, info->filename, info->func);
272 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
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;
304 info->pkgname = strdup(pkgname);
305 if (!info->pkgname) {
307 return LB_STATUS_ERROR_MEMORY;
310 info->filename = strdup(filename);
311 if (!info->filename) {
312 DbgFree(info->pkgname);
314 return LB_STATUS_ERROR_MEMORY;
317 info->func = strdup(func);
319 DbgFree(info->filename);
320 DbgFree(info->pkgname);
322 return LB_STATUS_ERROR_MEMORY;
325 info->timestamp = util_timestamp();
327 s_info.call_list = eina_list_append(s_info.call_list, info);
329 s_info.fault_mark_count++;
330 return LB_STATUS_SUCCESS;
333 HAPI int fault_func_ret(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
335 struct fault_info *info;
338 EINA_LIST_FOREACH(s_info.call_list, l, info) {
339 if (info->slave != slave)
342 if (strcmp(info->pkgname, pkgname))
345 if (strcmp(info->filename, filename))
348 if (strcmp(info->func, func))
351 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
352 DbgFree(info->filename);
353 DbgFree(info->pkgname);
357 s_info.fault_mark_count--;
361 return LB_STATUS_ERROR_NOT_EXIST;