Path: blob/master/tools/virtio/virtio-trace/trace-agent-ctl.c
26282 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Controller of read/write threads for virtio-trace3*4* Copyright (C) 2012 Hitachi, Ltd.5* Created by Yoshihiro Yunomae <[email protected]>6* Masami Hiramatsu <[email protected]>7*/89#define _GNU_SOURCE10#include <fcntl.h>11#include <poll.h>12#include <signal.h>13#include <stdio.h>14#include <stdlib.h>15#include <unistd.h>16#include "trace-agent.h"1718#define HOST_MSG_SIZE 25619#define EVENT_WAIT_MSEC 1002021static volatile sig_atomic_t global_signal_val;22bool global_sig_receive; /* default false */23bool global_run_operation; /* default false*/2425/* Handle SIGTERM/SIGINT/SIGQUIT to exit */26static void signal_handler(int sig)27{28global_signal_val = sig;29}3031int rw_ctl_init(const char *ctl_path)32{33int ctl_fd;3435ctl_fd = open(ctl_path, O_RDONLY);36if (ctl_fd == -1) {37pr_err("Cannot open ctl_fd\n");38goto error;39}4041return ctl_fd;4243error:44exit(EXIT_FAILURE);45}4647static int wait_order(int ctl_fd)48{49struct pollfd poll_fd;50int ret = 0;5152while (!global_sig_receive) {53poll_fd.fd = ctl_fd;54poll_fd.events = POLLIN;5556ret = poll(&poll_fd, 1, EVENT_WAIT_MSEC);5758if (global_signal_val) {59global_sig_receive = true;60pr_info("Receive interrupt %d\n", global_signal_val);6162/* Wakes rw-threads when they are sleeping */63if (!global_run_operation)64pthread_cond_broadcast(&cond_wakeup);6566ret = -1;67break;68}6970if (ret < 0) {71pr_err("Polling error\n");72goto error;73}7475if (ret)76break;77}7879return ret;8081error:82exit(EXIT_FAILURE);83}8485/*86* contol read/write threads by handling global_run_operation87*/88void *rw_ctl_loop(int ctl_fd)89{90ssize_t rlen;91char buf[HOST_MSG_SIZE];92int ret;9394/* Setup signal handlers */95signal(SIGTERM, signal_handler);96signal(SIGINT, signal_handler);97signal(SIGQUIT, signal_handler);9899while (!global_sig_receive) {100101ret = wait_order(ctl_fd);102if (ret < 0)103break;104105rlen = read(ctl_fd, buf, sizeof(buf));106if (rlen < 0) {107pr_err("read data error in ctl thread\n");108goto error;109}110111if (rlen == 2 && buf[0] == '1') {112/*113* If host writes '1' to a control path,114* this controller wakes all read/write threads.115*/116global_run_operation = true;117pthread_cond_broadcast(&cond_wakeup);118pr_debug("Wake up all read/write threads\n");119} else if (rlen == 2 && buf[0] == '0') {120/*121* If host writes '0' to a control path, read/write122* threads will wait for notification from Host.123*/124global_run_operation = false;125pr_debug("Stop all read/write threads\n");126} else127pr_info("Invalid host notification: %s\n", buf);128}129130return NULL;131132error:133exit(EXIT_FAILURE);134}135136137