server: attempt to handle client ctrl-c
authorJens Axboe <axboe@kernel.dk>
Mon, 3 Oct 2011 18:53:32 +0000 (20:53 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 3 Oct 2011 18:53:32 +0000 (20:53 +0200)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
client.c
fio.c
fio.h
server.c
server.h

index d81f755a03a9276bf0cb51ec26d5fabeb80b0b0a..e6b51d3516639d06e0230c8fc585a0262fa99c89 100644 (file)
--- a/client.c
+++ b/client.c
@@ -118,12 +118,46 @@ static int fio_client_connect(struct fio_client *client)
        return 0;
 }
 
        return 0;
 }
 
+void fio_clients_terminate(void)
+{
+       struct flist_head *entry;
+       struct fio_client *client;
+
+       flist_for_each(entry, &client_list) {
+               client = flist_entry(entry, struct fio_client, list);
+
+               fio_net_send_simple_cmd(client->fd, FIO_NET_CMD_QUIT, 0);
+       }
+}
+
+static void sig_int(int sig)
+{
+       fio_clients_terminate();
+}
+
+static void client_signal_handler(void)
+{
+       struct sigaction act;
+
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sig_int;
+       act.sa_flags = SA_RESTART;
+       sigaction(SIGINT, &act, NULL);
+
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sig_int;
+       act.sa_flags = SA_RESTART;
+       sigaction(SIGTERM, &act, NULL);
+}
+
 int fio_clients_connect(void)
 {
        struct fio_client *client;
        struct flist_head *entry, *tmp;
        int ret;
 
 int fio_clients_connect(void)
 {
        struct fio_client *client;
        struct flist_head *entry, *tmp;
        int ret;
 
+       client_signal_handler();
+
        flist_for_each_safe(entry, tmp, &client_list) {
                client = flist_entry(entry, struct fio_client, list);
 
        flist_for_each_safe(entry, tmp, &client_list) {
                client = flist_entry(entry, struct fio_client, list);
 
diff --git a/fio.c b/fio.c
index 10746062927f32b0c6956c0770ec88ba416f8747..d1faacae860deaf97c90e9a8e8142aabb899f205 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -75,7 +75,6 @@ unsigned long arch_flags = 0;
 
 struct io_log *agg_io_log[2];
 
 
 struct io_log *agg_io_log[2];
 
-#define TERMINATE_ALL          (-1)
 #define JOB_START_TIMEOUT      (5 * 1000)
 
 void td_set_runstate(struct thread_data *td, int runstate)
 #define JOB_START_TIMEOUT      (5 * 1000)
 
 void td_set_runstate(struct thread_data *td, int runstate)
@@ -88,7 +87,7 @@ void td_set_runstate(struct thread_data *td, int runstate)
        td->runstate = runstate;
 }
 
        td->runstate = runstate;
 }
 
-static void terminate_threads(int group_id)
+void fio_terminate_threads(int group_id)
 {
        struct thread_data *td;
        int i;
 {
        struct thread_data *td;
        int i;
@@ -126,7 +125,7 @@ static void sig_int(int sig)
                exit_backend = 1;
                fflush(stdout);
                exit_value = 128;
                exit_backend = 1;
                fflush(stdout);
                exit_value = 128;
-               terminate_threads(TERMINATE_ALL);
+               fio_terminate_threads(TERMINATE_ALL);
        }
 }
 
        }
 }
 
@@ -184,6 +183,13 @@ static void set_sig_handlers(void)
        act.sa_handler = sig_int;
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
        act.sa_handler = sig_int;
        act.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &act, NULL);
+
+       if (is_backend) {
+               memset(&act, 0, sizeof(act));
+               act.sa_handler = sig_int;
+               act.sa_flags = SA_RESTART;
+               sigaction(SIGPIPE, &act, NULL);
+       }
 }
 
 /*
 }
 
 /*
@@ -750,7 +756,7 @@ sync_done:
                if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
                        if (check_min_rate(td, &comp_time, bytes_done)) {
                                if (exitall_on_terminate)
                if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
                        if (check_min_rate(td, &comp_time, bytes_done)) {
                                if (exitall_on_terminate)
-                                       terminate_threads(td->groupid);
+                                       fio_terminate_threads(td->groupid);
                                td_verror(td, EIO, "check_min_rate");
                                break;
                        }
                                td_verror(td, EIO, "check_min_rate");
                                break;
                        }
@@ -1265,7 +1271,7 @@ static void *thread_main(void *data)
                exec_string(td->o.exec_postrun);
 
        if (exitall_on_terminate)
                exec_string(td->o.exec_postrun);
 
        if (exitall_on_terminate)
-               terminate_threads(td->groupid);
+               fio_terminate_threads(td->groupid);
 
 err:
        if (td->error)
 
 err:
        if (td->error)
@@ -1419,7 +1425,7 @@ reaped:
        }
 
        if (*nr_running == cputhreads && !pending && realthreads)
        }
 
        if (*nr_running == cputhreads && !pending && realthreads)
-               terminate_threads(TERMINATE_ALL);
+               fio_terminate_threads(TERMINATE_ALL);
 }
 
 static void *gtod_thread_main(void *data)
 }
 
 static void *gtod_thread_main(void *data)
@@ -1481,6 +1487,8 @@ static void run_threads(void)
        if (fio_gtod_offload && fio_start_gtod_thread())
                return;
 
        if (fio_gtod_offload && fio_start_gtod_thread())
                return;
 
+       set_sig_handlers();
+
        if (!terse_output) {
                log_info("Starting ");
                if (nr_thread)
        if (!terse_output) {
                log_info("Starting ");
                if (nr_thread)
@@ -1496,8 +1504,6 @@ static void run_threads(void)
                fflush(stdout);
        }
 
                fflush(stdout);
        }
 
-       set_sig_handlers();
-
        todo = thread_number;
        nr_running = 0;
        nr_started = 0;
        todo = thread_number;
        nr_running = 0;
        nr_started = 0;
@@ -1613,7 +1619,7 @@ static void run_threads(void)
                        dprint(FD_MUTEX, "wait on startup_mutex\n");
                        if (fio_mutex_down_timeout(startup_mutex, 10)) {
                                log_err("fio: job startup hung? exiting.\n");
                        dprint(FD_MUTEX, "wait on startup_mutex\n");
                        if (fio_mutex_down_timeout(startup_mutex, 10)) {
                                log_err("fio: job startup hung? exiting.\n");
-                               terminate_threads(TERMINATE_ALL);
+                               fio_terminate_threads(TERMINATE_ALL);
                                fio_abort = 1;
                                nr_started--;
                                break;
                                fio_abort = 1;
                                nr_started--;
                                break;
@@ -1687,6 +1693,10 @@ static void run_threads(void)
 
        while (nr_running) {
                reap_threads(&nr_running, &t_rate, &m_rate);
 
        while (nr_running) {
                reap_threads(&nr_running, &t_rate, &m_rate);
+
+               if (is_backend)
+                       fio_server_idle_loop();
+
                usleep(10000);
        }
 
                usleep(10000);
        }
 
diff --git a/fio.h b/fio.h
index fdc2c7e04b178175bd1882c1534430b6f347cee0..a74fb108c7f6f79827ea793d9cc099b28ea2777b 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -575,6 +575,8 @@ enum {
 };
 
 extern void td_set_runstate(struct thread_data *, int);
 };
 
 extern void td_set_runstate(struct thread_data *, int);
+#define TERMINATE_ALL          (-1)
+extern void fio_terminate_threads(int);
 
 /*
  * Memory helpers
 
 /*
  * Memory helpers
index 93f5d8ebbb46250718357ceb8396c9ccdc1ec45d..d0ff25a31a898b243aa3a043ccc64264929331ee 100644 (file)
--- a/server.c
+++ b/server.c
@@ -120,6 +120,30 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
        void *pdu = NULL;
 
        do {
        void *pdu = NULL;
 
        do {
+               struct pollfd pfd;
+
+               pfd.fd = sk;
+               pfd.events = POLLIN;
+               ret = 0;
+               do {
+                       ret = poll(&pfd, 1, 100);
+                       if (ret < 0) {
+                               log_err("fio: poll: %s\n", strerror(errno));
+                               break;
+                       } else if (!ret)
+                               continue;
+
+                       if (pfd.revents & POLLIN)
+                               break;
+                       if (pfd.revents & (POLLERR|POLLHUP)) {
+                               ret = 1;
+                               break;
+                       }
+               } while (ret >= 0);
+
+               if (ret < 0)
+                       break;
+
                ret = fio_recv_data(sk, &cmd, sizeof(cmd));
                if (ret)
                        break;
                ret = fio_recv_data(sk, &cmd, sizeof(cmd));
                if (ret)
                        break;
@@ -168,9 +192,7 @@ struct fio_net_cmd *fio_net_recv_cmd(int sk)
        if (ret) {
                free(cmdret);
                cmdret = NULL;
        if (ret) {
                free(cmdret);
                cmdret = NULL;
-       }
-
-       if (cmdret)
+       } else if (cmdret)
                cmdret->flags &= ~FIO_NET_CMD_F_MORE;
 
        return cmdret;
                cmdret->flags &= ~FIO_NET_CMD_F_MORE;
 
        return cmdret;
@@ -216,7 +238,7 @@ int fio_net_send_cmd(int fd, uint16_t opcode, const void *buf, off_t size)
        return ret;
 }
 
        return ret;
 }
 
-static int send_simple_command(int sk, uint16_t opcode, uint64_t serial)
+int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial)
 {
        struct fio_net_cmd cmd = {
                .version        = __cpu_to_le16(FIO_SERVER_VER1),
 {
        struct fio_net_cmd cmd = {
                .version        = __cpu_to_le16(FIO_SERVER_VER1),
@@ -229,29 +251,10 @@ static int send_simple_command(int sk, uint16_t opcode, uint64_t serial)
        return fio_send_data(sk, &cmd, sizeof(cmd));
 }
 
        return fio_send_data(sk, &cmd, sizeof(cmd));
 }
 
-/*
- * Send an ack for this command
- */
-static int ack_command(int sk, struct fio_net_cmd *cmd)
-{
-#if 0
-       return send_simple_command(sk, FIO_NET_CMD_ACK, cmd->serial);
-#else
-       return 0;
-#endif
-}
-
-#if 0
-static int nak_command(int sk, struct fio_net_cmd *cmd)
-{
-       return send_simple_command(sk, FIO_NET_CMD_NAK, cmd->serial);
-}
-#endif
-
 static int send_quit_command(void)
 {
        dprint(FD_NET, "server: sending quit\n");
 static int send_quit_command(void)
 {
        dprint(FD_NET, "server: sending quit\n");
-       return send_simple_command(server_fd, FIO_NET_CMD_QUIT, 0);
+       return fio_net_send_simple_cmd(server_fd, FIO_NET_CMD_QUIT, 0);
 }
 
 static int handle_cur_job(struct fio_net_cmd *cmd)
 }
 
 static int handle_cur_job(struct fio_net_cmd *cmd)
@@ -274,6 +277,7 @@ static int handle_command(struct fio_net_cmd *cmd)
 
        switch (cmd->opcode) {
        case FIO_NET_CMD_QUIT:
 
        switch (cmd->opcode) {
        case FIO_NET_CMD_QUIT:
+               fio_terminate_threads(TERMINATE_ALL);
                return 1;
        case FIO_NET_CMD_EXIT:
                exit_backend = 1;
                return 1;
        case FIO_NET_CMD_EXIT:
                exit_backend = 1;
@@ -306,10 +310,6 @@ static int handle_connection(int sk)
                        break;
                }
 
                        break;
                }
 
-               ret = ack_command(sk, cmd);
-               if (ret)
-                       break;
-
                ret = handle_command(cmd);
                if (ret)
                        break;
                ret = handle_command(cmd);
                if (ret)
                        break;
@@ -324,6 +324,12 @@ static int handle_connection(int sk)
        return ret;
 }
 
        return ret;
 }
 
+void fio_server_idle_loop(void)
+{
+       if (server_fd != -1)
+               handle_connection(server_fd);
+}
+
 static int accept_loop(int listen_sk)
 {
        struct sockaddr addr;
 static int accept_loop(int listen_sk)
 {
        struct sockaddr addr;
@@ -364,8 +370,12 @@ again:
 
        server_fd = sk;
 
 
        server_fd = sk;
 
+       printf("handle\n");
+
        exitval = handle_connection(sk);
 
        exitval = handle_connection(sk);
 
+       printf("out, exit %d\n", exitval);
+
        server_fd = -1;
        close(sk);
 
        server_fd = -1;
        close(sk);
 
index 431ae9e7155bf48a1009a5271802eecff7b7db69..61b61f35d4df1f9b4153ac6bb53829916206d7d8 100644 (file)
--- a/server.h
+++ b/server.h
@@ -57,12 +57,14 @@ extern int fio_start_server(int);
 extern int fio_server_text_output(const char *, unsigned int len);
 extern int fio_server_log(const char *format, ...);
 extern int fio_net_send_cmd(int, uint16_t, const void *, off_t);
 extern int fio_server_text_output(const char *, unsigned int len);
 extern int fio_server_log(const char *format, ...);
 extern int fio_net_send_cmd(int, uint16_t, const void *, off_t);
+extern int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t serial);
 
 struct thread_stat;
 struct group_run_stats;
 extern void fio_server_send_ts(struct thread_stat *, struct group_run_stats *);
 extern void fio_server_send_gs(struct group_run_stats *);
 extern void fio_server_send_status(void);
 
 struct thread_stat;
 struct group_run_stats;
 extern void fio_server_send_ts(struct thread_stat *, struct group_run_stats *);
 extern void fio_server_send_gs(struct group_run_stats *);
 extern void fio_server_send_status(void);
+extern void fio_server_idle_loop(void);
 
 extern int fio_clients_connect(void);
 extern int fio_clients_send_ini(const char *);
 
 extern int fio_clients_connect(void);
 extern int fio_clients_send_ini(const char *);