[PATCH] blktrace: remove padding logic, it's not needed with the new sendfile()
[blktrace.git] / blktrace.c
index ad18fd3b11ec93c1d6e5792fd1b4e9778ca1731d..89f0ce6b56ff70d97225e5c3a7eea4e27af4a7cf 100644 (file)
@@ -160,7 +160,6 @@ struct tip_subbuf {
        void *buf;
        unsigned int len;
        unsigned int max_len;
-       off_t offset;
 };
 
 #define FIFO_SIZE      (1024)  /* should be plenty big! */
@@ -180,9 +179,6 @@ struct thread_information {
        void *fd_buf;
        char fn[MAXPATHLEN + 64];
 
-       int pfd;
-       size_t *pfd_buf;
-
        struct in_addr cl_in_addr;
 
        FILE *ofile;
@@ -190,6 +186,7 @@ struct thread_information {
        off_t ofile_offset;
        int ofile_stdout;
        int ofile_mmap;
+       volatile int sendfile_pending;
 
        int (*get_subbuf)(struct thread_information *, unsigned int);
        int (*flush_subbuf)(struct thread_information *, struct tip_subbuf *);
@@ -197,6 +194,7 @@ struct thread_information {
 
        unsigned long events_processed;
        unsigned long long data_read;
+       unsigned long long data_queued;
        struct device_information *device;
 
        int exited;
@@ -344,21 +342,6 @@ static int get_dropped_count(const char *buts_name)
        return atoi(tmp);
 }
 
-static size_t get_subbuf_padding(struct thread_information *tip,
-                                unsigned subbuf)
-{
-       size_t padding_size = buf_nr * sizeof(size_t);
-       size_t ret;
-
-       if (read(tip->pfd, tip->pfd_buf, padding_size) < 0) {
-               perror("tip pad read");
-               ret = -1;
-       } else
-               ret = tip->pfd_buf[subbuf];
-
-       return ret;
-}
-
 static int start_trace(struct device_information *dip)
 {
        struct blk_user_trace_setup buts;
@@ -594,7 +577,7 @@ static int get_subbuf_sendfile(struct thread_information *tip,
 {
        struct tip_subbuf *ts;
        struct stat sb;
-       unsigned int ready, this_size, total;
+       unsigned int ready;
 
        wait_for_data(tip);
 
@@ -604,62 +587,44 @@ static int get_subbuf_sendfile(struct thread_information *tip,
        if (is_done())
                return get_subbuf(tip, maxlen);
 
+       if (tip->sendfile_pending) {
+               usleep(100);
+               return 0;
+       }
+
        if (fstat(tip->fd, &sb) < 0) {
                perror("trace stat");
                return -1;
        }
-
-       ready = sb.st_size - tip->ofile_offset;
-       if (!ready) {
-               /*
-                * delay a little, since poll() will return data available
-                * until sendfile() is run
-                */
-               usleep(100);
+       ready = sb.st_size - tip->data_queued;
+       if (!ready)
                return 0;
-       }
 
-       this_size = buf_size;
-       total = ready;
-       while (ready) {
-               if (this_size > ready)
-                       this_size = ready;
+       ts = malloc(sizeof(*ts));
+       ts->buf = NULL;
+       ts->max_len = 0;
+       ts->len = ready;
+       tip->data_queued += ready;
 
-               ts = malloc(sizeof(*ts));
-
-               ts->buf = NULL;
-               ts->max_len = 0;
-
-               ts->len = this_size;
-               ts->offset = tip->ofile_offset;
-               tip->ofile_offset += ts->len;
-
-               if (subbuf_fifo_queue(tip, ts))
-                       return -1;
-
-               ready -= this_size;
-       }
+       if (subbuf_fifo_queue(tip, ts))
+               return -1;
 
-       return total;
+       tip->sendfile_pending++;
+       return ready;
 }
 
 static void close_thread(struct thread_information *tip)
 {
        if (tip->fd != -1)
                close(tip->fd);
-       if (tip->pfd != -1)
-               close(tip->pfd);
        if (tip->ofile)
                fclose(tip->ofile);
        if (tip->ofile_buffer)
                free(tip->ofile_buffer);
        if (tip->fd_buf)
                free(tip->fd_buf);
-       if (tip->pfd_buf)
-               free(tip->pfd_buf);
 
        tip->fd = -1;
-       tip->pfd = -1;
        tip->ofile = NULL;
        tip->ofile_buffer = NULL;
        tip->fd_buf = NULL;
@@ -704,21 +669,6 @@ static void *thread_main(void *arg)
                exit_trace(1);
        }
 
-       if (net_mode == Net_client && net_use_sendfile) {
-               char tmp[MAXPATHLEN + 64];
-
-               snprintf(tmp, sizeof(tmp), "%s/block/%s/trace%d.padding",
-                        relay_path, tip->device->buts_name, tip->cpu);
-
-               tip->pfd = open(tmp, O_RDONLY);
-               if (tip->pfd < 0) {
-                       fprintf(stderr, "Couldn't open padding file %s\n", tmp);
-                       exit_trace(1);
-               }
-
-               tip->pfd_buf = malloc(buf_nr * sizeof(size_t));
-       }
-
        while (!is_done()) {
                if (tip->get_subbuf(tip, buf_size) < 0)
                        break;
@@ -797,31 +747,23 @@ static int flush_subbuf_net(struct thread_information *tip,
 
 static int net_sendfile(struct thread_information *tip, struct tip_subbuf *ts)
 {
-       unsigned int bytes_left = ts->len;
-       int ret;
+       int ret = sendfile(net_out_fd, tip->fd, NULL, ts->len);
 
-       while (bytes_left && !is_done()) {
-               ret = sendfile(net_out_fd, tip->fd, &ts->offset, bytes_left);
-               if (ret < 0) {
-                       perror("sendfile");
-                       break;
-               } else if (!ret) {
-                       usleep(100);
-                       continue;
-               }
-
-               ts->offset += ret;
-               bytes_left -= ret;
+       if (ret < 0) {
+               perror("sendfile");
+               return 1;
+       } else if (ret < (int) ts->len) {
+               fprintf(stderr, "short sendfile send (%d of %d)\n", ret, ts->len);
+               return 1;
        }
 
-       return bytes_left;
+       return 0;
 }
 
 static int flush_subbuf_sendfile(struct thread_information *tip,
                                 struct tip_subbuf *ts)
 {
-       size_t padding;
-       unsigned subbuf;
+       int ret = 1;
 
        /*
         * currently we cannot use sendfile() on the last bytes read, as they
@@ -831,18 +773,18 @@ static int flush_subbuf_sendfile(struct thread_information *tip,
        if (ts->buf)
                return flush_subbuf_net(tip, ts);
        
-       subbuf = (ts->offset / buf_size) % buf_nr;
-       padding = get_subbuf_padding(tip, subbuf);
-       ts->len -= padding;
-
        if (net_send_header(tip, ts->len))
-               return 1;
+               goto err;
        if (net_sendfile(tip, ts))
-               return 1;
+               goto err;
 
        tip->data_read += ts->len;
+       tip->ofile_offset += buf_size;
+       ret = 0;
+err:
+       tip->sendfile_pending--;
        free(ts);
-       return 0;
+       return ret;
 }
 
 static int write_data(struct thread_information *tip, void *buf,
@@ -1134,7 +1076,6 @@ static int start_threads(struct device_information *dip)
                tip->device = dip;
                tip->events_processed = 0;
                tip->fd = -1;
-               tip->pfd = -1;
                memset(&tip->fifo, 0, sizeof(tip->fifo));
                tip->leftover_ts = NULL;
 
@@ -1343,7 +1284,6 @@ static struct device_information *net_get_dip(char *buts_name,
                tip->cpu = i;
                tip->device = dip;
                tip->fd = -1;
-               tip->pfd = -1;
                tip->cl_in_addr = *cl_in_addr;
 
                if (tip_open_output(dip, tip))
@@ -1434,6 +1374,31 @@ static int net_server_loop(struct in_addr *cl_in_addr)
        return 0;
 }
 
+static int get_connection(int fd, struct sockaddr_in *addr)
+{
+       struct pollfd pfd = { .fd = fd, .events = POLLIN };
+       socklen_t socklen;
+
+       printf("blktrace: waiting for incoming connection...\n");
+
+       if (poll(&pfd, 1, -1) < 0) {
+               perror("poll for connection");
+               return 1;
+       }
+       if ((pfd.revents & POLLIN) == 0)
+               return 1;
+
+       socklen = sizeof(*addr);
+       net_in_fd = accept(fd, (struct sockaddr *) addr, &socklen);
+       if (net_in_fd < 0) {
+               perror("accept");
+               return 1;
+       }
+
+       printf("blktrace: connection from %s\n", inet_ntoa(addr->sin_addr));
+       return 0;
+}
+
 /*
  * Start here when we are in server mode - just fetch data from the network
  * and dump to files
@@ -1443,7 +1408,6 @@ static int net_server(void)
        struct device_information *dip;
        struct thread_information *tip;
        struct sockaddr_in addr;
-       socklen_t socklen;
        int fd, opt, i, j;
 
        fd = socket(AF_INET, SOCK_STREAM, 0);
@@ -1474,26 +1438,8 @@ static int net_server(void)
        }
 
 repeat:
-       signal(SIGINT, NULL);
-       signal(SIGHUP, NULL);
-       signal(SIGTERM, NULL);
-       signal(SIGALRM, NULL);
-
-       printf("blktrace: waiting for incoming connection...\n");
-
-       socklen = sizeof(addr);
-       net_in_fd = accept(fd, (struct sockaddr *) &addr, &socklen);
-       if (net_in_fd < 0) {
-               perror("accept");
-               return 1;
-       }
-
-       signal(SIGINT, handle_sigint);
-       signal(SIGHUP, handle_sigint);
-       signal(SIGTERM, handle_sigint);
-       signal(SIGALRM, handle_sigint);
-
-       printf("blktrace: connection from %s\n", inet_ntoa(addr.sin_addr));
+       if (get_connection(fd, &addr))
+               return 0;
 
        while (!is_done()) {
                if (net_server_loop(&addr.sin_addr))