Skip to content

Commit 384c195

Browse files
lauxinwlijinxia
authored andcommitted
tools: acrn-crashlog: event handler thread for acrnprobe
Event handler is the thread to handle events detected by channel. It's awakened by a enqueued event. Signed-off-by: Liu Xinwu <xinwu.liu@intel.com> Reviewed-by: Zhang Yanmin <yanmin.zhang@intel.com> Reviewed-by: Liu Chuansheng <chuansheng.liu@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Reviewed-by: Geoffroy Van Cutsem <geoffroy.vancutsem@intel.com> Acked-by: Eddie Dong <Eddie.dong@intel.com>
1 parent 9caa5d7 commit 384c195

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

tools/acrn-crashlog/acrnprobe/event_handler.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,187 @@
33
* SPDX-License-Identifier: BSD-3-Clause
44
*/
55

6+
#include <stdio.h>
7+
#include <signal.h>
8+
#include <string.h>
9+
#include <sys/time.h>
10+
#include <malloc.h>
11+
#include <stdlib.h>
12+
#include "event_queue.h"
13+
#include "load_conf.h"
14+
#include "channels.h"
15+
#include "fsutils.h"
16+
#include "log_sys.h"
617
#include "event_handler.h"
718

19+
/* Watchdog timeout in second*/
20+
#define WDT_TIMEOUT 300
21+
22+
static struct event_t *last_e;
23+
static int event_processing;
24+
25+
/**
26+
* Handle watchdog expire.
27+
*
28+
* @param signal Signal which triggered this function.
29+
*/
30+
static void wdt_timeout(int signal)
31+
{
32+
struct event_t *e;
33+
struct crash_t *crash;
34+
struct info_t *info;
35+
int count;
36+
37+
if (signal == SIGALRM) {
38+
LOGE("haven't received heart beat(%ds) for %ds, killing self\n",
39+
HEART_BEAT, WDT_TIMEOUT);
40+
41+
if (event_processing) {
42+
LOGE("event (%d, %s) processing...\n",
43+
last_e->event_type, last_e->path);
44+
free(last_e);
45+
}
46+
47+
count = events_count();
48+
LOGE("total %d unhandled events :\n", count);
49+
50+
while (count-- && (e = event_dequeue())) {
51+
switch (e->event_type) {
52+
case CRASH:
53+
crash = (struct crash_t *)e->private;
54+
LOGE("CRASH (%s, %s)\n", (char *)crash->name,
55+
e->path);
56+
break;
57+
case INFO:
58+
info = (struct info_t *)e->private;
59+
LOGE("INFO (%s)\n", (char *)info->name);
60+
break;
61+
case UPTIME:
62+
LOGE("UPTIME\n");
63+
break;
64+
case HEART_BEAT:
65+
LOGE("HEART_BEAT\n");
66+
break;
67+
case REBOOT:
68+
LOGE("REBOOT\n");
69+
break;
70+
default:
71+
LOGE("error event type %d\n", e->event_type);
72+
}
73+
free(e);
74+
}
75+
76+
raise(SIGKILL);
77+
}
78+
}
79+
80+
/**
81+
* Fed watchdog.
82+
*
83+
* @param timeout in second When the watchdog expire next time.
84+
*/
85+
static void watchdog_fed(int timeout)
86+
{
87+
struct itimerval new_value;
88+
int ret;
89+
90+
memset(&new_value, 0, sizeof(new_value));
91+
92+
new_value.it_value.tv_sec = timeout;
93+
ret = setitimer(ITIMER_REAL, &new_value, NULL);
94+
if (ret < 0) {
95+
LOGE("setitimer failed, error (%s)\n", strerror(errno));
96+
exit(EXIT_FAILURE);
97+
}
98+
}
99+
100+
/**
101+
* Initialize watchdog. This watchdog is used to monitor event handler.
102+
*
103+
* @param timeout in second When the watchdog expire next time.
104+
*/
105+
static void watchdog_init(int timeout)
106+
{
107+
struct itimerval new_value;
108+
int ret;
109+
sighandler_t ohdlr;
110+
111+
ohdlr = signal(SIGALRM, wdt_timeout);
112+
if (ohdlr == SIG_ERR) {
113+
LOGE("signal failed, error (%s)\n", strerror(errno));
114+
exit(EXIT_FAILURE);
115+
}
116+
117+
memset(&new_value, 0, sizeof(new_value));
118+
119+
new_value.it_value.tv_sec = timeout;
120+
ret = setitimer(ITIMER_REAL, &new_value, NULL);
121+
if (ret < 0) {
122+
LOGE("setitimer failed, error (%s)\n", strerror(errno));
123+
exit(EXIT_FAILURE);
124+
}
125+
}
126+
127+
/**
128+
* Process each event in event queue.
129+
* Note that currently event handler is single threaded.
130+
*/
131+
static void *event_handle(void *unused __attribute__((unused)))
132+
{
133+
int id;
134+
struct sender_t *sender;
135+
struct event_t *e;
136+
137+
while ((e = event_dequeue())) {
138+
/* here we only handle internal event */
139+
if (e->event_type == HEART_BEAT) {
140+
watchdog_fed(WDT_TIMEOUT);
141+
free(e);
142+
continue;
143+
}
144+
145+
/* last_e is allocated for debug purpose, the information
146+
* will be dumped if watchdog expire.
147+
*/
148+
last_e = malloc(sizeof(*e) + e->len);
149+
if (last_e == NULL) {
150+
LOGE("malloc failed, error (%s)\n", strerror(errno));
151+
exit(EXIT_FAILURE);
152+
}
153+
event_processing = 1;
154+
memcpy(last_e, e, sizeof(*e) + e->len);
155+
156+
for_each_sender(id, sender, conf) {
157+
if (!sender)
158+
continue;
159+
160+
sender->send(e);
161+
}
162+
163+
if ((e->dir))
164+
free(e->dir);
165+
free(e);
166+
event_processing = 0;
167+
free(last_e);
168+
}
169+
170+
LOGE("something goes error, %s exit\n", __func__);
171+
return NULL;
172+
}
173+
174+
/**
175+
* Initialize event handler.
176+
*/
8177
int init_event_handler(void)
9178
{
179+
int ret;
180+
pthread_t pid;
181+
182+
watchdog_init(WDT_TIMEOUT);
183+
ret = create_detached_thread(&pid, &event_handle, NULL);
184+
if (ret) {
185+
LOGE("create event handler failed (%s)\n", strerror(errno));
186+
return -1;
187+
}
10188
return 0;
11189
}

0 commit comments

Comments
 (0)