From 302a0d3ed721e4c30c6a2a37f64c60b50ffd33b9 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 21 Dec 2011 12:37:22 +0530 Subject: [PATCH 1/4] hw/9pfs: replace iovec manipulation with QEMUIOVector The v9fs_read() and v9fs_write() functions rely on iovec[] manipulation code should be replaced with QEMUIOVector to avoid duplicating code. In the future it may be possible to make the code even more concise by using QEMUIOVector consistently across virtio and 9pfs. The "v" format specifier for pdu_marshal() and pdu_unmarshal() is dropped since it does not actually pack/unpack anything. The specifier was also not implemented to update the offset variable and could only be used at the end of a format string, another sign that this shouldn't really be a format specifier. Instead, see the new v9fs_init_qiov_from_pdu() function. This change avoids a possible iovec[] buffer overflow when indirect vrings are used since the number of vectors is now limited by the underlying VirtQueueElement and cannot be out-of-bounds. Signed-off-by: Stefan Hajnoczi Signed-off-by: Aneesh Kumar K.V --- hw/9pfs/virtio-9p.c | 162 ++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 102 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 36a862f1f1..46dc9f7340 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -674,40 +674,6 @@ static size_t pdu_pack(V9fsPDU *pdu, size_t offset, const void *src, offset, size, 1); } -static int pdu_copy_sg(V9fsPDU *pdu, size_t offset, int rx, struct iovec *sg) -{ - size_t pos = 0; - int i, j; - struct iovec *src_sg; - unsigned int num; - - if (rx) { - src_sg = pdu->elem.in_sg; - num = pdu->elem.in_num; - } else { - src_sg = pdu->elem.out_sg; - num = pdu->elem.out_num; - } - - j = 0; - for (i = 0; i < num; i++) { - if (offset <= pos) { - sg[j].iov_base = src_sg[i].iov_base; - sg[j].iov_len = src_sg[i].iov_len; - j++; - } else if (offset < (src_sg[i].iov_len + pos)) { - sg[j].iov_base = src_sg[i].iov_base; - sg[j].iov_len = src_sg[i].iov_len; - sg[j].iov_base += (offset - pos); - sg[j].iov_len -= (offset - pos); - j++; - } - pos += src_sg[i].iov_len; - } - - return j; -} - static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...) { size_t old_offset = offset; @@ -743,12 +709,6 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...) *valp = le64_to_cpu(val); break; } - case 'v': { - struct iovec *iov = va_arg(ap, struct iovec *); - int *iovcnt = va_arg(ap, int *); - *iovcnt = pdu_copy_sg(pdu, offset, 0, iov); - break; - } case 's': { V9fsString *str = va_arg(ap, V9fsString *); offset += pdu_unmarshal(pdu, offset, "w", &str->size); @@ -827,12 +787,6 @@ static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...) offset += pdu_pack(pdu, offset, &val, sizeof(val)); break; } - case 'v': { - struct iovec *iov = va_arg(ap, struct iovec *); - int *iovcnt = va_arg(ap, int *); - *iovcnt = pdu_copy_sg(pdu, offset, 1, iov); - break; - } case 's': { V9fsString *str = va_arg(ap, V9fsString *); offset += pdu_marshal(pdu, offset, "w", str->size); @@ -1143,42 +1097,6 @@ static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf, stat_to_qid(stbuf, &v9lstat->qid); } -static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt) -{ - while (len && *iovcnt) { - if (len < sg->iov_len) { - sg->iov_len -= len; - sg->iov_base += len; - len = 0; - } else { - len -= sg->iov_len; - sg++; - *iovcnt -= 1; - } - } - - return sg; -} - -static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt) -{ - int i; - int total = 0; - - for (i = 0; i < *cnt; i++) { - if ((total + sg[i].iov_len) > cap) { - sg[i].iov_len -= ((total + sg[i].iov_len) - cap); - i++; - break; - } - total += sg[i].iov_len; - } - - *cnt = i; - - return sg; -} - static void print_sg(struct iovec *sg, int cnt) { int i; @@ -1861,6 +1779,38 @@ out: return count; } +/* + * Create a QEMUIOVector for a sub-region of PDU iovecs + * + * @qiov: uninitialized QEMUIOVector + * @skip: number of bytes to skip from beginning of PDU + * @size: number of bytes to include + * @is_write: true - write, false - read + * + * The resulting QEMUIOVector has heap-allocated iovecs and must be cleaned up + * with qemu_iovec_destroy(). + */ +static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu, + uint64_t skip, size_t size, + bool is_write) +{ + QEMUIOVector elem; + struct iovec *iov; + unsigned int niov; + + if (is_write) { + iov = pdu->elem.out_sg; + niov = pdu->elem.out_num; + } else { + iov = pdu->elem.in_sg; + niov = pdu->elem.in_num; + } + + qemu_iovec_init_external(&elem, iov, niov); + qemu_iovec_init(qiov, niov); + qemu_iovec_copy(qiov, &elem, skip, size); +} + static void v9fs_read(void *opaque) { int32_t fid; @@ -1895,21 +1845,21 @@ static void v9fs_read(void *opaque) err += pdu_marshal(pdu, offset, "d", count); err += count; } else if (fidp->fid_type == P9_FID_FILE) { - int32_t cnt; + QEMUIOVector qiov_full; + QEMUIOVector qiov; int32_t len; - struct iovec *sg; - struct iovec iov[128]; /* FIXME: bad, bad, bad */ - sg = iov; - pdu_marshal(pdu, offset + 4, "v", sg, &cnt); - sg = cap_sg(sg, max_count, &cnt); + v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, max_count, false); + qemu_iovec_init(&qiov, qiov_full.niov); do { + qemu_iovec_reset(&qiov); + qemu_iovec_copy(&qiov, &qiov_full, count, qiov_full.size - count); if (0) { - print_sg(sg, cnt); + print_sg(qiov.iov, qiov.niov); } /* Loop in case of EINTR */ do { - len = v9fs_co_preadv(pdu, fidp, sg, cnt, off); + len = v9fs_co_preadv(pdu, fidp, qiov.iov, qiov.niov, off); if (len >= 0) { off += len; count += len; @@ -1920,11 +1870,12 @@ static void v9fs_read(void *opaque) err = len; goto out; } - sg = adjust_sg(sg, len, &cnt); } while (count < max_count && len > 0); err = offset; err += pdu_marshal(pdu, offset, "d", count); err += count; + qemu_iovec_destroy(&qiov); + qemu_iovec_destroy(&qiov_full); } else if (fidp->fid_type == P9_FID_XATTR) { err = v9fs_xattr_read(s, pdu, fidp, off, max_count); } else { @@ -2095,7 +2046,6 @@ out: static void v9fs_write(void *opaque) { - int cnt; ssize_t err; int32_t fid; int64_t off; @@ -2104,13 +2054,14 @@ static void v9fs_write(void *opaque) int32_t total = 0; size_t offset = 7; V9fsFidState *fidp; - struct iovec iov[128]; /* FIXME: bad, bad, bad */ - struct iovec *sg = iov; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; + QEMUIOVector qiov_full; + QEMUIOVector qiov; - pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt); - trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, cnt); + offset += pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count); + v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true); + trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, qiov_full.niov); fidp = get_fid(pdu, fid); if (fidp == NULL) { @@ -2126,20 +2077,23 @@ static void v9fs_write(void *opaque) /* * setxattr operation */ - err = v9fs_xattr_write(s, pdu, fidp, off, count, sg, cnt); + err = v9fs_xattr_write(s, pdu, fidp, off, count, + qiov_full.iov, qiov_full.niov); goto out; } else { err = -EINVAL; goto out; } - sg = cap_sg(sg, count, &cnt); + qemu_iovec_init(&qiov, qiov_full.niov); do { + qemu_iovec_reset(&qiov); + qemu_iovec_copy(&qiov, &qiov_full, total, qiov_full.size - total); if (0) { - print_sg(sg, cnt); + print_sg(qiov.iov, qiov.niov); } /* Loop in case of EINTR */ do { - len = v9fs_co_pwritev(pdu, fidp, sg, cnt, off); + len = v9fs_co_pwritev(pdu, fidp, qiov.iov, qiov.niov, off); if (len >= 0) { off += len; total += len; @@ -2148,16 +2102,20 @@ static void v9fs_write(void *opaque) if (len < 0) { /* IO error return the error */ err = len; - goto out; + goto out_qiov; } - sg = adjust_sg(sg, len, &cnt); } while (total < count && len > 0); + + offset = 7; offset += pdu_marshal(pdu, offset, "d", total); err = offset; trace_v9fs_write_return(pdu->tag, pdu->id, total, err); +out_qiov: + qemu_iovec_destroy(&qiov); out: put_fid(pdu, fidp); out_nofid: + qemu_iovec_destroy(&qiov_full); complete_pdu(s, pdu, err); } From 2f008a8c97e2549da7337c98c53eae2d31f0d548 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 21 Dec 2011 12:37:23 +0530 Subject: [PATCH 2/4] hw/9pfs: Use the correct signed type for different variables Signed-off-by: Aneesh Kumar K.V --- fsdev/file-op-9p.h | 2 +- hw/9pfs/virtio-9p.c | 21 +++++++++++---------- hw/9pfs/virtio-9p.h | 2 +- trace-events | 8 ++++---- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index a85ecd30b0..c823fe0aee 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -74,7 +74,7 @@ typedef struct FsContext } FsContext; typedef struct V9fsPath { - int16_t size; + uint16_t size; char *data; } V9fsPath; diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 46dc9f7340..7f1301b856 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1694,8 +1694,8 @@ out_nofid: complete_pdu(s, pdu, err); } -static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, - V9fsFidState *fidp, int64_t off, int32_t max_count) +static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp, + uint64_t off, uint32_t max_count) { size_t offset = 7; int read_count; @@ -1719,7 +1719,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, } static int v9fs_do_readdir_with_stat(V9fsPDU *pdu, - V9fsFidState *fidp, int32_t max_count) + V9fsFidState *fidp, uint32_t max_count) { V9fsPath path; V9fsStat v9stat; @@ -1814,11 +1814,11 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu, static void v9fs_read(void *opaque) { int32_t fid; - int64_t off; + uint64_t off; ssize_t err = 0; int32_t count = 0; size_t offset = 7; - int32_t max_count; + uint32_t max_count; V9fsFidState *fidp; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; @@ -1962,8 +1962,9 @@ static void v9fs_readdir(void *opaque) V9fsFidState *fidp; ssize_t retval = 0; size_t offset = 7; - int64_t initial_offset; - int32_t count, max_count; + uint64_t initial_offset; + int32_t count; + uint32_t max_count; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; @@ -2001,7 +2002,7 @@ out_nofid: } static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp, - int64_t off, int32_t count, + uint64_t off, uint32_t count, struct iovec *sg, int cnt) { int i, to_copy; @@ -2048,8 +2049,8 @@ static void v9fs_write(void *opaque) { ssize_t err; int32_t fid; - int64_t off; - int32_t count; + uint64_t off; + uint32_t count; int32_t len = 0; int32_t total = 0; size_t offset = 7; diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 8b612da529..19a797b727 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -156,7 +156,7 @@ typedef struct V9fsFidState V9fsFidState; typedef struct V9fsString { - int16_t size; + uint16_t size; char *data; } V9fsString; diff --git a/trace-events b/trace-events index 514849aed8..2918398ff4 100644 --- a/trace-events +++ b/trace-events @@ -578,11 +578,11 @@ v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d" v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d" v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d" -v9fs_read(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t max_count) "tag %d id %d fid %d off %"PRId64" max_count %d" +v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u" v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd" -v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, int64_t offset, int32_t max_count) "tag %d id %d fid %d offset %"PRId64" max_count %d" -v9fs_readdir_return(uint16_t tag, uint8_t id, int32_t count, ssize_t retval) "tag %d id %d count %d retval %zd" -v9fs_write(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t count, int cnt) "tag %d id %d fid %d off %"PRId64" count %d cnt %d" +v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u" +v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd" +v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d" v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd" v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d" v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d" From e4027caf9373c5797b7769f5120c249e31ab5487 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 21 Dec 2011 12:37:23 +0530 Subject: [PATCH 3/4] hw/9pfs: iattr_valid flags are kernel internal flags map them to 9p values. Kernel internal values can change, add protocol values for these constant and use them. Signed-off-by: Aneesh Kumar K.V --- hw/9pfs/virtio-9p.c | 47 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 7f1301b856..df0a8e731b 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1293,17 +1293,18 @@ out_nofid: complete_pdu(s, pdu, retval); } -/* From Linux kernel code */ -#define ATTR_MODE (1 << 0) -#define ATTR_UID (1 << 1) -#define ATTR_GID (1 << 2) -#define ATTR_SIZE (1 << 3) -#define ATTR_ATIME (1 << 4) -#define ATTR_MTIME (1 << 5) -#define ATTR_CTIME (1 << 6) -#define ATTR_MASK 127 -#define ATTR_ATIME_SET (1 << 7) -#define ATTR_MTIME_SET (1 << 8) +/* Attribute flags */ +#define P9_ATTR_MODE (1 << 0) +#define P9_ATTR_UID (1 << 1) +#define P9_ATTR_GID (1 << 2) +#define P9_ATTR_SIZE (1 << 3) +#define P9_ATTR_ATIME (1 << 4) +#define P9_ATTR_MTIME (1 << 5) +#define P9_ATTR_CTIME (1 << 6) +#define P9_ATTR_ATIME_SET (1 << 7) +#define P9_ATTR_MTIME_SET (1 << 8) + +#define P9_ATTR_MASK 127 static void v9fs_setattr(void *opaque) { @@ -1322,16 +1323,16 @@ static void v9fs_setattr(void *opaque) err = -EINVAL; goto out_nofid; } - if (v9iattr.valid & ATTR_MODE) { + if (v9iattr.valid & P9_ATTR_MODE) { err = v9fs_co_chmod(pdu, &fidp->path, v9iattr.mode); if (err < 0) { goto out; } } - if (v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) { + if (v9iattr.valid & (P9_ATTR_ATIME | P9_ATTR_MTIME)) { struct timespec times[2]; - if (v9iattr.valid & ATTR_ATIME) { - if (v9iattr.valid & ATTR_ATIME_SET) { + if (v9iattr.valid & P9_ATTR_ATIME) { + if (v9iattr.valid & P9_ATTR_ATIME_SET) { times[0].tv_sec = v9iattr.atime_sec; times[0].tv_nsec = v9iattr.atime_nsec; } else { @@ -1340,8 +1341,8 @@ static void v9fs_setattr(void *opaque) } else { times[0].tv_nsec = UTIME_OMIT; } - if (v9iattr.valid & ATTR_MTIME) { - if (v9iattr.valid & ATTR_MTIME_SET) { + if (v9iattr.valid & P9_ATTR_MTIME) { + if (v9iattr.valid & P9_ATTR_MTIME_SET) { times[1].tv_sec = v9iattr.mtime_sec; times[1].tv_nsec = v9iattr.mtime_nsec; } else { @@ -1359,13 +1360,13 @@ static void v9fs_setattr(void *opaque) * If the only valid entry in iattr is ctime we can call * chown(-1,-1) to update the ctime of the file */ - if ((v9iattr.valid & (ATTR_UID | ATTR_GID)) || - ((v9iattr.valid & ATTR_CTIME) - && !((v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) { - if (!(v9iattr.valid & ATTR_UID)) { + if ((v9iattr.valid & (P9_ATTR_UID | P9_ATTR_GID)) || + ((v9iattr.valid & P9_ATTR_CTIME) + && !((v9iattr.valid & P9_ATTR_MASK) & ~P9_ATTR_CTIME))) { + if (!(v9iattr.valid & P9_ATTR_UID)) { v9iattr.uid = -1; } - if (!(v9iattr.valid & ATTR_GID)) { + if (!(v9iattr.valid & P9_ATTR_GID)) { v9iattr.gid = -1; } err = v9fs_co_chown(pdu, &fidp->path, v9iattr.uid, @@ -1374,7 +1375,7 @@ static void v9fs_setattr(void *opaque) goto out; } } - if (v9iattr.valid & (ATTR_SIZE)) { + if (v9iattr.valid & (P9_ATTR_SIZE)) { err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size); if (err < 0) { goto out; From 058a96ed506d77714bcce3d69b351e364078c080 Mon Sep 17 00:00:00 2001 From: Harsh Prateek Bora Date: Wed, 21 Dec 2011 12:37:23 +0530 Subject: [PATCH 4/4] scripts/analyse-9p-simpletrace.py: Add symbolic names for 9p operations. Currently, we just print the numerical value of 9p operation identifier in case of RERROR which is less meaningful for readability. Mapping 9p operation ids to symbolic names provides a better tracelog: RERROR (tag = 1 , id = TWALK , err = " No such file or directory ") RERROR (tag = 1 , id = TUNLINKAT , err = " Directory not empty ") This patch provides a dictionary of all possible 9p operation symbols mapped to their numerical identifiers which are likely to be used in future at various places in this script. Signed-off-by: Harsh Prateek Bora Signed-off-by: Aneesh Kumar K.V --- scripts/analyse-9p-simpletrace.py | 75 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/scripts/analyse-9p-simpletrace.py b/scripts/analyse-9p-simpletrace.py index b6d58fde96..3c3dee4337 100755 --- a/scripts/analyse-9p-simpletrace.py +++ b/scripts/analyse-9p-simpletrace.py @@ -3,15 +3,86 @@ # Usage: ./analyse-9p-simpletrace # # Author: Harsh Prateek Bora - +import os import simpletrace +symbol_9p = { + 6 : 'TLERROR', + 7 : 'RLERROR', + 8 : 'TSTATFS', + 9 : 'RSTATFS', + 12 : 'TLOPEN', + 13 : 'RLOPEN', + 14 : 'TLCREATE', + 15 : 'RLCREATE', + 16 : 'TSYMLINK', + 17 : 'RSYMLINK', + 18 : 'TMKNOD', + 19 : 'RMKNOD', + 20 : 'TRENAME', + 21 : 'RRENAME', + 22 : 'TREADLINK', + 23 : 'RREADLINK', + 24 : 'TGETATTR', + 25 : 'RGETATTR', + 26 : 'TSETATTR', + 27 : 'RSETATTR', + 30 : 'TXATTRWALK', + 31 : 'RXATTRWALK', + 32 : 'TXATTRCREATE', + 33 : 'RXATTRCREATE', + 40 : 'TREADDIR', + 41 : 'RREADDIR', + 50 : 'TFSYNC', + 51 : 'RFSYNC', + 52 : 'TLOCK', + 53 : 'RLOCK', + 54 : 'TGETLOCK', + 55 : 'RGETLOCK', + 70 : 'TLINK', + 71 : 'RLINK', + 72 : 'TMKDIR', + 73 : 'RMKDIR', + 74 : 'TRENAMEAT', + 75 : 'RRENAMEAT', + 76 : 'TUNLINKAT', + 77 : 'RUNLINKAT', + 100 : 'TVERSION', + 101 : 'RVERSION', + 102 : 'TAUTH', + 103 : 'RAUTH', + 104 : 'TATTACH', + 105 : 'RATTACH', + 106 : 'TERROR', + 107 : 'RERROR', + 108 : 'TFLUSH', + 109 : 'RFLUSH', + 110 : 'TWALK', + 111 : 'RWALK', + 112 : 'TOPEN', + 113 : 'ROPEN', + 114 : 'TCREATE', + 115 : 'RCREATE', + 116 : 'TREAD', + 117 : 'RREAD', + 118 : 'TWRITE', + 119 : 'RWRITE', + 120 : 'TCLUNK', + 121 : 'RCLUNK', + 122 : 'TREMOVE', + 123 : 'RREMOVE', + 124 : 'TSTAT', + 125 : 'RSTAT', + 126 : 'TWSTAT', + 127 : 'RWSTAT' +} + class VirtFSRequestTracker(simpletrace.Analyzer): def begin(self): print "Pretty printing 9p simpletrace log ..." def v9fs_rerror(self, tag, id, err): - print "RERROR (tag =", tag, ", id =", id, ",err =", err, ")" + print "RERROR (tag =", tag, ", id =", symbol_9p[id], ", err = \"", os.strerror(err), "\")" def v9fs_version(self, tag, id, msize, version): print "TVERSION (tag =", tag, ", msize =", msize, ", version =", version, ")"