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 <dynamicbox_errno.h>
27 #include <dynamicbox_service.h>
28 #include <dynamicbox_conf.h>
29 #include <dynamicbox_cmd_list.h>
33 #include "slave_life.h"
34 #include "slave_rpc.h"
35 #include "client_life.h"
37 #include "client_rpc.h"
40 #include "critical_log.h"
47 .fault_mark_count = 0,
51 struct slave_node *slave;
58 HAPI int const fault_is_occured(void)
60 return s_info.fault_mark_count;
63 static void clear_log_file(struct slave_node *slave)
65 char filename[BUFSIZ];
68 ret = snprintf(filename, sizeof(filename) - 1, "%s/slave.%d", DYNAMICBOX_CONF_LOG_PATH, slave_pid(slave));
69 if (ret == sizeof(filename) - 1) {
70 filename[sizeof(filename) - 1] = '\0';
71 ErrPrint("filename buffer is overflowed\n");
74 if (unlink(filename) < 0) {
75 ErrPrint("unlink: %s\n", strerror(errno));
79 static char *check_log_file(struct slave_node *slave)
84 char filename[BUFSIZ];
86 snprintf(filename, sizeof(filename), "%s/slave.%d", DYNAMICBOX_CONF_LOG_PATH, slave_pid(slave));
87 fp = fopen(filename, "rt");
89 ErrPrint("No log file found [%s]\n", strerror(errno));
93 ptr = fgets(libexec, sizeof(libexec), fp);
94 if (fclose(fp) != 0) {
95 ErrPrint("fclose: %s\n", strerror(errno));
99 ErrPrint("Invalid log\n");
103 if (unlink(filename) < 0) {
104 ErrPrint("Failed to unlink %s\n", filename);
107 ptr = dynamicbox_service_dbox_id_by_libexec(libexec);
109 ErrPrint("Failed to find the faulted package\n");
112 DbgPrint("Faulted package: %s\n", ptr);
116 HAPI void fault_unicast_info(struct client_node *client, const char *pkgname, const char *filename, const char *func)
118 struct packet *packet;
119 unsigned int cmd = CMD_FAULT_PACKAGE;
121 if (!client || !pkgname || !filename || !func) {
125 packet = packet_create_noack((const char *)&cmd, "sss", pkgname, filename, func);
130 client_rpc_async_request(client, packet);
133 HAPI void fault_broadcast_info(const char *pkgname, const char *filename, const char *func)
135 struct packet *packet;
136 unsigned int cmd = CMD_FAULT_PACKAGE;
138 packet = packet_create_noack((const char *)&cmd, "sss", pkgname, filename, func);
140 ErrPrint("Failed to create a param\n");
144 client_broadcast(NULL, packet);
147 static inline void dump_fault_info(const char *name, pid_t pid, const char *pkgname, const char *filename, const char *funcname)
149 CRITICAL_LOG("Slavename: %s[%d]\n" \
152 "Funcname: %s\n", name, pid, pkgname, filename, funcname);
155 HAPI int fault_info_set(struct slave_node *slave, const char *pkgname, const char *id, const char *func)
157 struct pkg_info *pkg;
160 pkg = package_find(pkgname);
162 return DBOX_STATUS_ERROR_NOT_EXIST;
165 ret = package_set_fault_info(pkg, util_timestamp(), id, func);
167 return DBOX_STATUS_ERROR_FAULT;
170 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, id, func);
171 ErrPrint("Set fault %s(%d)\n", !ret ? "Success" : "Failed", ret);
172 fault_broadcast_info(pkgname, id, func);
178 s_info.fault_mark_count++;
179 return DBOX_STATUS_ERROR_NONE;
182 HAPI int fault_check_pkgs(struct slave_node *slave)
184 struct fault_info *info;
185 struct pkg_info *pkg;
196 pkgname = (const char *)check_log_file(slave);
198 pkg = package_find(pkgname);
200 (void)package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
201 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
202 fault_broadcast_info(pkgname, "", "");
203 DbgFree((char *)pkgname);
205 s_info.fault_mark_count = 0;
206 clear_log_file(slave);
207 EINA_LIST_REVERSE_FOREACH_SAFE(s_info.call_list, l, n, info) {
208 if (info->slave != slave) {
212 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
214 DbgFree(info->pkgname);
215 DbgFree(info->filename);
221 DbgFree((char *)pkgname);
227 * Is it secured slave?
229 pkgname = package_find_by_secured_slave(slave);
231 pkg = package_find(pkgname);
233 (void)package_set_fault_info(pkg, util_timestamp(), NULL, NULL);
234 dump_fault_info(slave_name(slave), slave_pid(slave), pkgname, "", "");
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 : "";
275 (void)package_set_fault_info(pkg, info->timestamp, info->filename, info->func);
276 fault_broadcast_info(info->pkgname, info->filename, info->func);
278 DbgPrint("Treated as a false log\n");
280 slave_name(info->slave), slave_pid(info->slave), info->pkgname, filename, func);
283 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
285 DbgFree(info->pkgname);
286 DbgFree(info->filename);
293 s_info.fault_mark_count = 0;
294 clear_log_file(slave);
298 HAPI int fault_func_call(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
300 struct fault_info *info;
302 info = malloc(sizeof(*info));
304 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
309 info->pkgname = strdup(pkgname);
310 if (!info->pkgname) {
312 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
315 info->filename = strdup(filename);
316 if (!info->filename) {
317 DbgFree(info->pkgname);
319 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
322 info->func = strdup(func);
324 DbgFree(info->filename);
325 DbgFree(info->pkgname);
327 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
330 info->timestamp = util_timestamp();
332 s_info.call_list = eina_list_append(s_info.call_list, info);
334 s_info.fault_mark_count++;
335 return DBOX_STATUS_ERROR_NONE;
338 HAPI int fault_func_ret(struct slave_node *slave, const char *pkgname, const char *filename, const char *func)
340 struct fault_info *info;
343 EINA_LIST_FOREACH(s_info.call_list, l, info) {
344 if (info->slave != slave) {
348 if (strcmp(info->pkgname, pkgname)) {
352 if (strcmp(info->filename, filename)) {
356 if (strcmp(info->func, func)) {
360 s_info.call_list = eina_list_remove_list(s_info.call_list, l);
361 DbgFree(info->filename);
362 DbgFree(info->pkgname);
366 s_info.fault_mark_count--;
370 return DBOX_STATUS_ERROR_NOT_EXIST;