15
15
#include <errno.h>
16
16
#include <pthread.h>
17
17
#include <string.h>
18
+ #include <signal.h>
18
19
19
20
#include "acrntrace.h"
20
21
21
22
/* default minimal amount free space (in MB) left on the disk */
22
23
static uint64_t disk_reserved = 512 ;
24
+
25
+ #define TIMER_ID (128)
26
+ static uint32_t timeout = 0 ;
27
+
23
28
static int exiting = 0 ;
24
29
25
30
/* for opt */
26
31
static uint64_t period = 10000 ;
27
- static const char optString [] = "i:hcr:" ;
32
+ static const char optString [] = "i:hcr:t: " ;
28
33
static const char dev_name [] = "/dev/acrn_trace" ;
29
34
30
35
static uint32_t flags ;
@@ -42,9 +47,50 @@ static void display_usage(void)
42
47
"\t-r: minimal amount (in MB) of free space kept on the disk\n"
43
48
"\t before acrntrace stops\n"
44
49
"\t-i: period_in_ms: specify polling interval [1-999]\n"
50
+ "\t-t: max time to capture trace data (in second)\n"
45
51
"\t-c: clear the buffered old data\n" );
46
52
}
47
53
54
+ static void timer_handler (union sigval sv )
55
+ {
56
+ exiting = 1 ;
57
+ exit (0 );
58
+ }
59
+
60
+ static int init_timer (int timeout )
61
+ {
62
+ struct sigevent event ;
63
+ struct itimerspec it ;
64
+ timer_t tm_id ;
65
+ int err ;
66
+
67
+ memset (& event , 0 , sizeof (struct sigevent ));
68
+
69
+ event .sigev_value .sival_int = TIMER_ID ;
70
+ event .sigev_notify = SIGEV_THREAD ;
71
+ event .sigev_notify_function = timer_handler ;
72
+
73
+ err = timer_create (CLOCK_MONOTONIC , & event , & tm_id );
74
+ if (err < 0 ) {
75
+ pr_err ("Error to create timer, errno(%d)\n" , err );
76
+ return err ;
77
+ }
78
+
79
+ it .it_interval .tv_sec = timeout ;
80
+ it .it_interval .tv_nsec = 0 ;
81
+ it .it_value .tv_sec = timeout ;
82
+ it .it_value .tv_nsec = 0 ;
83
+
84
+ err = timer_settime (tm_id , 0 , & it , NULL );
85
+ if (err < 0 ) {
86
+ pr_err ("Error to set timer, errno(%d)\n" , err );
87
+ return err ;
88
+ }
89
+
90
+ pr_info ("Capture trace data for about %ds and exit\n" , timeout );
91
+ return 0 ;
92
+ }
93
+
48
94
static int parse_opt (int argc , char * argv [])
49
95
{
50
96
int opt , ret ;
@@ -69,6 +115,15 @@ static int parse_opt(int argc, char *argv[])
69
115
disk_reserved = ret ;
70
116
pr_dbg ("Keeping %dMB of space on the disk\n" , ret );
71
117
break ;
118
+ case 't' :
119
+ ret = atoi (optarg );
120
+ if (ret <= 0 ) {
121
+ pr_err ("'-t' require integer greater than 0\n" );
122
+ return - EINVAL ;
123
+ }
124
+ timeout = ret ;
125
+ pr_dbg ("Capture trace data for at most %ds\n" , ret );
126
+ break ;
72
127
case 'c' :
73
128
flags |= FLAG_CLEAR_BUF ;
74
129
break ;
@@ -331,6 +386,7 @@ static void signal_exit_handler(int sig)
331
386
int main (int argc , char * argv [])
332
387
{
333
388
uint32_t cpu = 0 ;
389
+ int err ;
334
390
335
391
/* parse options */
336
392
if (parse_opt (argc , argv ))
@@ -350,6 +406,15 @@ int main(int argc, char *argv[])
350
406
exit (EXIT_FAILURE );
351
407
}
352
408
409
+ /* Set timer if timeout configured */
410
+ if (timeout ) {
411
+ err = init_timer (timeout );
412
+ if (err < 0 ) {
413
+ pr_err ("Failed to set timer\n" );
414
+ exit (EXIT_FAILURE );
415
+ }
416
+ }
417
+
353
418
atexit (handle_on_exit );
354
419
355
420
/* acquair res for each trace dev */
0 commit comments