Merge branch 'for-upstream' of https://github.com/andyprice/blktrace
[blktrace.git] / blktrace.c
index 4cccb7c635f720c89bd3b13696c1e339af31b1bf..3c8fb4c43885c48b2c73d113ce282df5bb007ce4 100644 (file)
@@ -93,7 +93,7 @@ struct devpath {
        char *path;                     /* path to device special file */
        char *buts_name;                /* name returned from bt kernel code */
        struct pdc_stats *stats;
-       int fd, idx, ncpus;
+       int fd, ncpus;
        unsigned long long drops;
 
        /*
@@ -460,8 +460,8 @@ static char usage_str[] = "\n\n" \
        "\t-w Stop after defined time, in seconds\n" \
        "\t-a Only trace specified actions. See documentation\n" \
        "\t-A Give trace mask as a single value. See documentation\n" \
-       "\t-b Sub buffer size in KiB\n" \
-       "\t-n Number of sub buffers\n" \
+       "\t-b Sub buffer size in KiB (default 512)\n" \
+       "\t-n Number of sub buffers (default 4)\n" \
        "\t-l Run in network listen mode (blktrace server)\n" \
        "\t-h Run in network client mode, connecting to the given host\n" \
        "\t-p Network port to use (default 8462)\n" \
@@ -621,13 +621,19 @@ static void dpp_free(struct devpath *dpp)
 
 static int lock_on_cpu(int cpu)
 {
-       cpu_set_t cpu_mask;
+       cpu_set_t * cpu_mask;
+       size_t size;
+       cpu_mask = CPU_ALLOC(ncpus);
+       size = CPU_ALLOC_SIZE(ncpus);
 
-       CPU_ZERO(&cpu_mask);
-       CPU_SET(cpu, &cpu_mask);
-       if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) < 0)
+       CPU_ZERO_S(size, cpu_mask);
+       CPU_SET_S(cpu, size, cpu_mask);
+       if (sched_setaffinity(0, size, cpu_mask) < 0) {
+               CPU_FREE(cpu_mask);             
                return errno;
+       }
 
+       CPU_FREE(cpu_mask);             
        return 0;
 }
 
@@ -721,18 +727,24 @@ static void *my_mmap(void *addr, size_t length, int prot, int flags, int fd,
        return new;
 }
 
-static int my_mlock(const void *addr, size_t len)
+static int my_mlock(struct tracer *tp,
+                   const void *addr, size_t len)
 {
-       int ret;
+       int ret, retry = 0;
 
        do {
                ret = mlock(addr, len);
+               if ((retry >= 10) && tp && tp->is_done)
+                       break;
+               retry++;
        } while (ret < 0 && handle_mem_failure(len));
 
        return ret;
 }
 
-static int setup_mmap(int fd, unsigned int maxlen, struct mmap_info *mip)
+static int setup_mmap(int fd, unsigned int maxlen,
+                     struct mmap_info *mip,
+                     struct tracer *tp)
 {
        if (mip->fs_off + maxlen > mip->fs_buf_len) {
                unsigned long nr = max(16, mip->buf_nr);
@@ -759,7 +771,10 @@ static int setup_mmap(int fd, unsigned int maxlen, struct mmap_info *mip)
                        perror("setup_mmap: mmap");
                        return 1;
                }
-               my_mlock(mip->fs_buf, mip->fs_buf_len);
+               if (my_mlock(tp, mip->fs_buf, mip->fs_buf_len) < 0) {
+                       perror("setup_mlock: mlock");
+                       return 1;
+               }
        }
 
        return 0;
@@ -863,8 +878,9 @@ static int net_send_header(int fd, int cpu, char *buts_name, int len)
        memset(&hdr, 0, sizeof(hdr));
 
        hdr.magic = BLK_IO_TRACE_MAGIC;
+       memset(hdr.buts_name, 0, sizeof(hdr.buts_name));
        strncpy(hdr.buts_name, buts_name, sizeof(hdr.buts_name));
-       hdr.buts_name[sizeof(hdr.buts_name)-1] = '\0';
+       hdr.buts_name[sizeof(hdr.buts_name) - 1] = '\0';
        hdr.cpu = cpu;
        hdr.max_cpus = ncpus;
        hdr.len = len;
@@ -972,7 +988,9 @@ retry:
                }
 
                memcpy(&addr->sin_addr, hent->h_addr, 4);
-               strcpy(hostname, hent->h_name);
+               memset(hostname, 0, sizeof(hostname));
+               strncpy(hostname, hent->h_name, sizeof(hostname));
+               hostname[sizeof(hostname) - 1] = '\0';
        }
 
        return 0;
@@ -1239,7 +1257,7 @@ static int add_devpath(char *path)
        memset(dpp, 0, sizeof(*dpp));
        dpp->path = strdup(path);
        dpp->fd = fd;
-       dpp->idx = ndevs++;
+       ndevs++;
        list_add_tail(&dpp->head, &devpaths);
 
        return 0;
@@ -1321,7 +1339,7 @@ static struct trace_buf *tb_combine(struct trace_buf *prev,
                 * the whole structures, as the other fields
                 * are "static".
                 */
-               prev = realloc(prev->buf, sizeof(*prev) + tot_len);
+               prev = realloc(prev, sizeof(*prev) + tot_len);
                prev->buf = (void *)(prev + 1);
        }
 
@@ -1683,7 +1701,7 @@ static int handle_pfds_file(struct tracer *tp, int nevs, int force_read)
                if (pfd->revents & POLLIN || force_read) {
                        mip = &iop->mmap_info;
 
-                       ret = setup_mmap(iop->ofd, buf_size, mip);
+                       ret = setup_mmap(iop->ofd, buf_size, mip, tp);
                        if (ret < 0) {
                                pfd->events = 0;
                                break;
@@ -1719,11 +1737,10 @@ static int handle_pfds_netclient(struct tracer *tp, int nevs, int force_read)
 {
        struct stat sb;
        int i, nentries = 0;
-       struct pdc_stats *sp;
        struct pollfd *pfd = tp->pfds;
        struct io_info *iop = tp->ios;
 
-       for (i = 0; i < ndevs; i++, pfd++, iop++, sp++) {
+       for (i = 0; i < ndevs; i++, pfd++, iop++) {
                if (pfd->revents & POLLIN || force_read) {
                        if (fstat(iop->ifd, &sb) < 0) {
                                perror(iop->ifn);
@@ -1896,6 +1913,7 @@ static void stop_tracers(void)
                struct tracer *tp = list_entry(p, struct tracer, head);
                tp->is_done = 1;
        }
+       pthread_cond_broadcast(&mt_cond);
 }
 
 static void del_tracers(void)
@@ -2067,9 +2085,13 @@ static int handle_args(int argc, char *argv[])
                                return 1;
                        }
 
-                       while (fscanf(ifp, "%s\n", dev_line) == 1)
-                               if (add_devpath(dev_line) != 0)
+                       while (fscanf(ifp, "%s\n", dev_line) == 1) {
+                               if (add_devpath(dev_line) != 0) {
+                                       fclose(ifp);
                                        return 1;
+                               }
+                       }
+                       fclose(ifp);
                        break;
                }
 
@@ -2119,7 +2141,9 @@ static int handle_args(int argc, char *argv[])
                        break;
                case 'h':
                        net_mode = Net_client;
-                       strcpy(hostname, optarg);
+                       memset(hostname, 0, sizeof(hostname));
+                       strncpy(hostname, optarg, sizeof(hostname));
+                       hostname[sizeof(hostname) - 1] = '\0';
                        break;
                case 'l':
                        net_mode = Net_server;
@@ -2146,12 +2170,17 @@ static int handle_args(int argc, char *argv[])
                return 1;
        }
 
-       if (statfs(debugfs_path, &st) < 0 || st.f_type != (long)DEBUGFS_TYPE) {
+       if (statfs(debugfs_path, &st) < 0) {
                fprintf(stderr, "Invalid debug path %s: %d/%s\n",
                        debugfs_path, errno, strerror(errno));
                return 1;
        }
 
+       if (st.f_type != (long)DEBUGFS_TYPE) {
+               fprintf(stderr, "Debugfs is not mounted at %s\n", debugfs_path);
+               return 1;
+       }
+
        if (act_mask_tmp != 0)
                act_mask = act_mask_tmp;
 
@@ -2169,7 +2198,10 @@ static int handle_args(int argc, char *argv[])
                piped_output = 1;
                handle_pfds = handle_pfds_entries;
                pfp = stdout;
-               setvbuf(pfp, NULL, _IONBF, 0);
+               if (setvbuf(pfp, NULL, _IONBF, 0)) {
+                       perror("setvbuf stdout");
+                       return 1;
+               }
        } else
                handle_pfds = handle_pfds_file;
        return 0;
@@ -2381,7 +2413,7 @@ static void net_client_read_data(struct cl_conn *nc, struct devpath *dpp,
        struct io_info *iop = &dpp->ios[bnh->cpu];
        struct mmap_info *mip = &iop->mmap_info;
 
-       if (setup_mmap(iop->ofd, bnh->len, &iop->mmap_info)) {
+       if (setup_mmap(iop->ofd, bnh->len, &iop->mmap_info, NULL)) {
                fprintf(stderr, "ncd(%s:%d): mmap failed\n",
                        nc->ch->hostname, nc->fd);
                exit(1);
@@ -2631,9 +2663,9 @@ int main(int argc, char *argv[])
 
        setlocale(LC_NUMERIC, "en_US");
        pagesize = getpagesize();
-       ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+       ncpus = sysconf(_SC_NPROCESSORS_CONF);
        if (ncpus < 0) {
-               fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed %d/%s\n",
+               fprintf(stderr, "sysconf(_SC_NPROCESSORS_CONF) failed %d/%s\n",
                        errno, strerror(errno));
                ret = 1;
                goto out;