diff options
Diffstat (limited to 'tools/virtio/virtio-trace/trace-agent-ctl.c')
-rw-r--r-- | tools/virtio/virtio-trace/trace-agent-ctl.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/virtio/virtio-trace/trace-agent-ctl.c b/tools/virtio/virtio-trace/trace-agent-ctl.c new file mode 100644 index 000000000000..a2d0403c4f94 --- /dev/null +++ b/tools/virtio/virtio-trace/trace-agent-ctl.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * Controller of read/write threads for virtio-trace | ||
3 | * | ||
4 | * Copyright (C) 2012 Hitachi, Ltd. | ||
5 | * Created by Yoshihiro Yunomae <yoshihiro.yunomae.ez@hitachi.com> | ||
6 | * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | ||
7 | * | ||
8 | * Licensed under GPL version 2 only. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #define _GNU_SOURCE | ||
13 | #include <fcntl.h> | ||
14 | #include <poll.h> | ||
15 | #include <signal.h> | ||
16 | #include <stdio.h> | ||
17 | #include <stdlib.h> | ||
18 | #include <unistd.h> | ||
19 | #include "trace-agent.h" | ||
20 | |||
21 | #define HOST_MSG_SIZE 256 | ||
22 | #define EVENT_WAIT_MSEC 100 | ||
23 | |||
24 | static volatile sig_atomic_t global_signal_val; | ||
25 | bool global_sig_receive; /* default false */ | ||
26 | bool global_run_operation; /* default false*/ | ||
27 | |||
28 | /* Handle SIGTERM/SIGINT/SIGQUIT to exit */ | ||
29 | static void signal_handler(int sig) | ||
30 | { | ||
31 | global_signal_val = sig; | ||
32 | } | ||
33 | |||
34 | int rw_ctl_init(const char *ctl_path) | ||
35 | { | ||
36 | int ctl_fd; | ||
37 | |||
38 | ctl_fd = open(ctl_path, O_RDONLY); | ||
39 | if (ctl_fd == -1) { | ||
40 | pr_err("Cannot open ctl_fd\n"); | ||
41 | goto error; | ||
42 | } | ||
43 | |||
44 | return ctl_fd; | ||
45 | |||
46 | error: | ||
47 | exit(EXIT_FAILURE); | ||
48 | } | ||
49 | |||
50 | static int wait_order(int ctl_fd) | ||
51 | { | ||
52 | struct pollfd poll_fd; | ||
53 | int ret = 0; | ||
54 | |||
55 | while (!global_sig_receive) { | ||
56 | poll_fd.fd = ctl_fd; | ||
57 | poll_fd.events = POLLIN; | ||
58 | |||
59 | ret = poll(&poll_fd, 1, EVENT_WAIT_MSEC); | ||
60 | |||
61 | if (global_signal_val) { | ||
62 | global_sig_receive = true; | ||
63 | pr_info("Receive interrupt %d\n", global_signal_val); | ||
64 | |||
65 | /* Wakes rw-threads when they are sleeping */ | ||
66 | if (!global_run_operation) | ||
67 | pthread_cond_broadcast(&cond_wakeup); | ||
68 | |||
69 | ret = -1; | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | if (ret < 0) { | ||
74 | pr_err("Polling error\n"); | ||
75 | goto error; | ||
76 | } | ||
77 | |||
78 | if (ret) | ||
79 | break; | ||
80 | }; | ||
81 | |||
82 | return ret; | ||
83 | |||
84 | error: | ||
85 | exit(EXIT_FAILURE); | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * contol read/write threads by handling global_run_operation | ||
90 | */ | ||
91 | void *rw_ctl_loop(int ctl_fd) | ||
92 | { | ||
93 | ssize_t rlen; | ||
94 | char buf[HOST_MSG_SIZE]; | ||
95 | int ret; | ||
96 | |||
97 | /* Setup signal handlers */ | ||
98 | signal(SIGTERM, signal_handler); | ||
99 | signal(SIGINT, signal_handler); | ||
100 | signal(SIGQUIT, signal_handler); | ||
101 | |||
102 | while (!global_sig_receive) { | ||
103 | |||
104 | ret = wait_order(ctl_fd); | ||
105 | if (ret < 0) | ||
106 | break; | ||
107 | |||
108 | rlen = read(ctl_fd, buf, sizeof(buf)); | ||
109 | if (rlen < 0) { | ||
110 | pr_err("read data error in ctl thread\n"); | ||
111 | goto error; | ||
112 | } | ||
113 | |||
114 | if (rlen == 2 && buf[0] == '1') { | ||
115 | /* | ||
116 | * If host writes '1' to a control path, | ||
117 | * this controller wakes all read/write threads. | ||
118 | */ | ||
119 | global_run_operation = true; | ||
120 | pthread_cond_broadcast(&cond_wakeup); | ||
121 | pr_debug("Wake up all read/write threads\n"); | ||
122 | } else if (rlen == 2 && buf[0] == '0') { | ||
123 | /* | ||
124 | * If host writes '0' to a control path, read/write | ||
125 | * threads will wait for notification from Host. | ||
126 | */ | ||
127 | global_run_operation = false; | ||
128 | pr_debug("Stop all read/write threads\n"); | ||
129 | } else | ||
130 | pr_info("Invalid host notification: %s\n", buf); | ||
131 | } | ||
132 | |||
133 | return NULL; | ||
134 | |||
135 | error: | ||
136 | exit(EXIT_FAILURE); | ||
137 | } | ||