0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define _GNU_SOURCE
0011 #include <fcntl.h>
0012 #include <poll.h>
0013 #include <signal.h>
0014 #include <stdio.h>
0015 #include <stdlib.h>
0016 #include <unistd.h>
0017 #include "trace-agent.h"
0018
0019 #define HOST_MSG_SIZE 256
0020 #define EVENT_WAIT_MSEC 100
0021
0022 static volatile sig_atomic_t global_signal_val;
0023 bool global_sig_receive;
0024 bool global_run_operation;
0025
0026
0027 static void signal_handler(int sig)
0028 {
0029 global_signal_val = sig;
0030 }
0031
0032 int rw_ctl_init(const char *ctl_path)
0033 {
0034 int ctl_fd;
0035
0036 ctl_fd = open(ctl_path, O_RDONLY);
0037 if (ctl_fd == -1) {
0038 pr_err("Cannot open ctl_fd\n");
0039 goto error;
0040 }
0041
0042 return ctl_fd;
0043
0044 error:
0045 exit(EXIT_FAILURE);
0046 }
0047
0048 static int wait_order(int ctl_fd)
0049 {
0050 struct pollfd poll_fd;
0051 int ret = 0;
0052
0053 while (!global_sig_receive) {
0054 poll_fd.fd = ctl_fd;
0055 poll_fd.events = POLLIN;
0056
0057 ret = poll(&poll_fd, 1, EVENT_WAIT_MSEC);
0058
0059 if (global_signal_val) {
0060 global_sig_receive = true;
0061 pr_info("Receive interrupt %d\n", global_signal_val);
0062
0063
0064 if (!global_run_operation)
0065 pthread_cond_broadcast(&cond_wakeup);
0066
0067 ret = -1;
0068 break;
0069 }
0070
0071 if (ret < 0) {
0072 pr_err("Polling error\n");
0073 goto error;
0074 }
0075
0076 if (ret)
0077 break;
0078 };
0079
0080 return ret;
0081
0082 error:
0083 exit(EXIT_FAILURE);
0084 }
0085
0086
0087
0088
0089 void *rw_ctl_loop(int ctl_fd)
0090 {
0091 ssize_t rlen;
0092 char buf[HOST_MSG_SIZE];
0093 int ret;
0094
0095
0096 signal(SIGTERM, signal_handler);
0097 signal(SIGINT, signal_handler);
0098 signal(SIGQUIT, signal_handler);
0099
0100 while (!global_sig_receive) {
0101
0102 ret = wait_order(ctl_fd);
0103 if (ret < 0)
0104 break;
0105
0106 rlen = read(ctl_fd, buf, sizeof(buf));
0107 if (rlen < 0) {
0108 pr_err("read data error in ctl thread\n");
0109 goto error;
0110 }
0111
0112 if (rlen == 2 && buf[0] == '1') {
0113
0114
0115
0116
0117 global_run_operation = true;
0118 pthread_cond_broadcast(&cond_wakeup);
0119 pr_debug("Wake up all read/write threads\n");
0120 } else if (rlen == 2 && buf[0] == '0') {
0121
0122
0123
0124
0125 global_run_operation = false;
0126 pr_debug("Stop all read/write threads\n");
0127 } else
0128 pr_info("Invalid host notification: %s\n", buf);
0129 }
0130
0131 return NULL;
0132
0133 error:
0134 exit(EXIT_FAILURE);
0135 }