blktrace: inclusive terminology
[blktrace.git] / blktrace.c
index f7d35dd1a62e4c687575314e77a6a6a75fcdcc83..82a6aad25b85f0291f0e028eb46e3940c5a438b6 100644 (file)
@@ -112,6 +112,7 @@ struct devpath {
        struct cl_host *ch;
        u32 cl_id;
        time_t cl_connect_time;
+       int setup_done; /* ioctl BLKTRACESETUP done */
        struct io_info *ios;
 };
 
@@ -306,7 +307,7 @@ static pthread_mutex_t dp_mutex = PTHREAD_MUTEX_INITIALIZER;
 static volatile int dp_entries;
 
 /*
- * These synchronize master / thread interactions.
+ * These synchronize main / thread interactions.
  */
 static pthread_cond_t mt_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t mt_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1066,9 +1067,10 @@ static void close_client_connections(void)
        }
 }
 
-static void setup_buts(void)
+static int setup_buts(void)
 {
        struct list_head *p;
+       int ret = 0;
 
        __list_for_each(p, &devpaths) {
                struct blk_user_trace_setup buts;
@@ -1082,14 +1084,19 @@ static void setup_buts(void)
                if (ioctl(dpp->fd, BLKTRACESETUP, &buts) >= 0) {
                        dpp->ncpus = max_cpus;
                        dpp->buts_name = strdup(buts.name);
+                       dpp->setup_done = 1;
                        if (dpp->stats)
                                free(dpp->stats);
                        dpp->stats = calloc(dpp->ncpus, sizeof(*dpp->stats));
                        memset(dpp->stats, 0, dpp->ncpus * sizeof(*dpp->stats));
-               } else
+               } else {
                        fprintf(stderr, "BLKTRACESETUP(2) %s failed: %d/%s\n",
                                dpp->path, errno, strerror(errno));
+                       ret++;
+               }
        }
+
+       return ret;
 }
 
 static void start_buts(void)
@@ -1280,7 +1287,8 @@ static void rel_devpaths(void)
                struct devpath *dpp = list_entry(p, struct devpath, head);
 
                list_del(&dpp->head);
-               __stop_trace(dpp->fd);
+               if (dpp->setup_done)
+                       __stop_trace(dpp->fd);
                close(dpp->fd);
 
                if (dpp->heads)
@@ -1502,30 +1510,25 @@ static inline int net_sendfile_data(struct tracer *tp, struct io_info *iop)
        return net_sendfile(iop);
 }
 
-static int fill_ofname(struct io_info *iop, int cpu)
+static int fill_ofname(char *dst, int dstlen, char *subdir, char *buts_name,
+                      int cpu)
 {
        int len;
        struct stat sb;
-       char *dst = iop->ofn;
 
        if (output_dir)
-               len = snprintf(iop->ofn, sizeof(iop->ofn), "%s/", output_dir);
+               len = snprintf(dst, dstlen, "%s/", output_dir);
        else
-               len = snprintf(iop->ofn, sizeof(iop->ofn), "./");
+               len = snprintf(dst, dstlen, "./");
 
-       if (net_mode == Net_server) {
-               struct cl_conn *nc = iop->nc;
-
-               len += sprintf(dst + len, "%s-", nc->ch->hostname);
-               len += strftime(dst + len, 64, "%F-%T/",
-                               gmtime(&iop->dpp->cl_connect_time));
-       }
+       if (subdir)
+               len += snprintf(dst + len, dstlen - len, "%s", subdir);
 
-       if (stat(iop->ofn, &sb) < 0) {
+       if (stat(dst, &sb) < 0) {
                if (errno != ENOENT) {
                        fprintf(stderr,
                                "Destination dir %s stat failed: %d/%s\n",
-                               iop->ofn, errno, strerror(errno));
+                               dst, errno, strerror(errno));
                        return 1;
                }
                /*
@@ -1533,20 +1536,20 @@ static int fill_ofname(struct io_info *iop, int cpu)
                 * trying to create the directory at once.  It's harmless
                 * to let them try, so just detect the problem and move on.
                 */
-               if (mkdir(iop->ofn, 0755) < 0 && errno != EEXIST) {
+               if (mkdir(dst, 0755) < 0 && errno != EEXIST) {
                        fprintf(stderr,
                                "Destination dir %s can't be made: %d/%s\n",
-                               iop->ofn, errno, strerror(errno));
+                               dst, errno, strerror(errno));
                        return 1;
                }
        }
 
        if (output_name)
-               snprintf(iop->ofn + len, sizeof(iop->ofn), "%s.blktrace.%d",
+               snprintf(dst + len, dstlen - len, "%s.blktrace.%d",
                         output_name, cpu);
        else
-               snprintf(iop->ofn + len, sizeof(iop->ofn), "%s.blktrace.%d",
-                        iop->dpp->buts_name, cpu);
+               snprintf(dst + len, dstlen - len, "%s.blktrace.%d",
+                        buts_name, cpu);
 
        return 0;
 }
@@ -1567,8 +1570,23 @@ static int set_vbuf(struct io_info *iop, int mode, size_t size)
 
 static int iop_open(struct io_info *iop, int cpu)
 {
+       char hostdir[MAXPATHLEN + 64];
+
        iop->ofd = -1;
-       if (fill_ofname(iop, cpu))
+       if (net_mode == Net_server) {
+               struct cl_conn *nc = iop->nc;
+               int len;
+
+               len = snprintf(hostdir, sizeof(hostdir), "%s-",
+                              nc->ch->hostname);
+               len += strftime(hostdir + len, sizeof(hostdir) - len, "%F-%T/",
+                               gmtime(&iop->dpp->cl_connect_time));
+       } else {
+               hostdir[0] = 0;
+       }
+
+       if (fill_ofname(iop->ofn, sizeof(iop->ofn), hostdir,
+                       iop->dpp->buts_name, cpu))
                return 1;
 
        iop->ofp = my_fopen(iop->ofn, "w+");
@@ -1883,6 +1901,26 @@ static int start_tracer(int cpu)
        return 0;
 }
 
+static int create_output_files(int cpu)
+{
+       char fname[MAXPATHLEN + 64];
+       struct list_head *p;
+       FILE *f;
+
+       __list_for_each(p, &devpaths) {
+               struct devpath *dpp = list_entry(p, struct devpath, head);
+
+               if (fill_ofname(fname, sizeof(fname), NULL, dpp->buts_name,
+                               cpu))
+                       return 1;
+               f = my_fopen(fname, "w+");
+               if (!f)
+                       return 1;
+               fclose(f);
+       }
+       return 0;
+}
+
 static void start_tracers(void)
 {
        int cpu, started = 0;
@@ -1890,8 +1928,16 @@ static void start_tracers(void)
        size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
 
        for (cpu = 0; cpu < max_cpus; cpu++) {
-               if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+               if (!CPU_ISSET_S(cpu, alloc_size, online_cpus)) {
+                       /*
+                        * Create fake empty output files so that other tools
+                        * like blkparse don't have to bother with sparse CPU
+                        * number space.
+                        */
+                       if (create_output_files(cpu))
+                               break;
                        continue;
+               }
                if (start_tracer(cpu))
                        break;
                started++;
@@ -2638,7 +2684,8 @@ static int run_tracers(void)
        if (net_mode == Net_client)
                printf("blktrace: connecting to %s\n", hostname);
 
-       setup_buts();
+       if (setup_buts())
+               return 1;
 
        if (use_tracer_devpaths()) {
                if (setup_tracer_devpaths())