Natively parse 'struct blk_io_trace2' from a blktrace binary.

Signed-off-by: Johannes Thumshirn <[email protected]>
---
 blkparse.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 blktrace.h |  18 +++++++++
 2 files changed, 130 insertions(+)

diff --git a/blkparse.c b/blkparse.c
index 7100009..2eec3a9 100644
--- a/blkparse.c
+++ b/blkparse.c
@@ -2471,6 +2471,37 @@ static int read_one_bit(int fd, struct blk_io_trace2 
**bit2, int block,
        return 0;
 }
 
+static int read_one_bit2(int fd, struct blk_io_trace2 **bit2, int block,
+                        int *fdblock)
+{
+       struct blk_io_trace2 *new = *bit2;
+       int ret;
+       int pdu_len;
+       void *p;
+
+       p = (void *) ((u8 *)new + sizeof(__u32));
+
+       ret = read_data(fd, p, sizeof(*new) - sizeof(__u32), block, fdblock);
+       if (ret)
+               return ret;
+
+       pdu_len = get_pdulen(new->pdu_len);
+       if (pdu_len) {
+               void *ptr = realloc(new, sizeof(*new) + pdu_len);
+
+               ret = read_data(fd, ptr + sizeof(*new), pdu_len, 1, fdblock);
+               if (ret) {
+                       free(ptr);
+                       return ret;
+               }
+               new = ptr;
+       }
+
+       bit2_trace_to_cpu(new);
+       *bit2 = new;
+
+       return 0;
+}
 static int read_events(int fd, int always_block, int *fdblock)
 {
        struct per_dev_info *pdi = NULL;
@@ -2538,6 +2569,44 @@ static int read_events(int fd, int always_block, int 
*fdblock)
                        t->next = trace_list;
                        trace_list = t;
 
+                       if (!pdi || pdi->dev != bit->device)
+                               pdi = get_dev_info(bit->device);
+
+                       if (bit->time > pdi->last_read_time)
+                               pdi->last_read_time = bit->time;
+               } else if (version == SUPPORTED_VERSION2) {
+                       struct blk_io_trace2 *bit;
+                       bit = bit_alloc();
+                       bit->magic = magic;
+
+                       ret = read_one_bit2(fd, &bit, 1, fdblock);
+                       if (ret)
+                               break;
+
+                       /*
+                        * not a real trace, so grab and handle it here
+                        */
+                       if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) &&
+                           (bit->action & ~__BLK_TN_CGROUP) != BLK_TN_MESSAGE) 
{
+                               handle_notify(bit);
+                               output_binary(bit, sizeof(*bit) + bit->pdu_len);
+                               continue;
+                       }
+
+                       if (verify_trace(bit->magic)) {
+                               bit_free(bit);
+                               bit = NULL;
+                               continue;
+                       }
+
+                       t = t_alloc();
+                       memset(t, 0, sizeof(*t));
+                       t->bit = bit;
+                       t->read_sequence = read_sequence;
+
+                       t->next = trace_list;
+                       trace_list = t;
+
                        if (!pdi || pdi->dev != bit->device)
                                pdi = get_dev_info(bit->device);
 
@@ -2698,6 +2767,49 @@ static int ms_prime(struct ms_stream *msp)
                                msp->last->next = t;
                                msp->last = t;
                        }
+               } else if (version == SUPPORTED_VERSION2) {
+                       bit = bit_alloc();
+                       bit->magic = magic;
+
+                       ret = read_one_bit2(pci->fd, &bit, 1, &pci->fdblock);
+                       if (ret)
+                               goto err;
+
+                       if (verify_trace(bit->magic))
+                               goto err;
+
+                       if (bit->cpu != pci->cpu) {
+                               fprintf(stderr,
+                                       "cpu %d trace info has error cpu %d\n",
+                                       pci->cpu, bit->cpu);
+                               continue;
+                       }
+
+                       if (bit->action & BLK_TC_ACT(BLK_TC_NOTIFY) &&
+                           (bit->action & ~__BLK_TN_CGROUP) != BLK_TN_MESSAGE) 
{
+                               handle_notify(bit);
+                               output_binary(bit, sizeof(*bit) + bit->pdu_len);
+                               bit_free(bit);
+                               bit = NULL;
+
+                               i -= 1;
+                               continue;
+                       }
+
+                       if (bit->time > pdi->last_read_time)
+                               pdi->last_read_time = bit->time;
+
+                       t = t_alloc();
+                       memset(t, 0, sizeof(*t));
+                       t->bit = bit;
+
+                       if (msp->first == NULL)
+                               msp->first = msp->last = t;
+                       else {
+                               msp->last->next = t;
+                               msp->last = t;
+                       }
+
                } else {
                        fprintf(stderr, "unsupported version %d\n", version);
                        continue;
diff --git a/blktrace.h b/blktrace.h
index 196b3c9..ba06237 100644
--- a/blktrace.h
+++ b/blktrace.h
@@ -129,6 +129,24 @@ static inline void bit_to_bit2(struct blk_io_trace *old,
                       old->pdu_len);
 }
 
+static inline void bit2_trace_to_cpu(struct blk_io_trace2 *t)
+{
+       if (data_is_native)
+               return;
+
+       t->magic        = be32_to_cpu(t->magic);
+       t->sequence     = be32_to_cpu(t->sequence);
+       t->time         = be64_to_cpu(t->time);
+       t->sector       = be64_to_cpu(t->sector);
+       t->bytes        = be32_to_cpu(t->bytes);
+       t->action       = be64_to_cpu(t->action);
+       t->pid          = be32_to_cpu(t->pid);
+       t->device       = be32_to_cpu(t->device);
+       t->cpu          = be32_to_cpu(t->cpu);
+       t->error        = be16_to_cpu(t->error);
+       t->pdu_len      = be16_to_cpu(t->pdu_len);
+}
+
 static inline void bit_trace_to_cpu(struct blk_io_trace *t)
 {
        if (data_is_native)
-- 
2.51.0


Reply via email to