4 * Copyright IBM, Corp. 2010
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
15 #include "virtio-9p.h"
16 #include "virtio-9p-debug.h"
18 #define BUG_ON(cond) assert(!(cond))
20 static FILE *llogfile
;
22 static struct iovec
*get_sg(V9fsPDU
*pdu
, int rx
)
25 return pdu
->elem
.in_sg
;
27 return pdu
->elem
.out_sg
;
30 static int get_sg_count(V9fsPDU
*pdu
, int rx
)
33 return pdu
->elem
.in_num
;
35 return pdu
->elem
.out_num
;
39 static void pprint_int8(V9fsPDU
*pdu
, int rx
, size_t *offsetp
,
43 int count
= get_sg_count(pdu
, rx
);
44 size_t offset
= *offsetp
;
45 struct iovec
*sg
= get_sg(pdu
, rx
);
48 copied
= do_pdu_unpack(&value
, sg
, count
, offset
, sizeof(value
));
50 BUG_ON(copied
!= sizeof(value
));
51 offset
+= sizeof(value
);
52 fprintf(llogfile
, "%s=0x%x", name
, value
);
56 static void pprint_int16(V9fsPDU
*pdu
, int rx
, size_t *offsetp
,
60 int count
= get_sg_count(pdu
, rx
);
61 struct iovec
*sg
= get_sg(pdu
, rx
);
62 size_t offset
= *offsetp
;
66 copied
= do_pdu_unpack(&value
, sg
, count
, offset
, sizeof(value
));
68 BUG_ON(copied
!= sizeof(value
));
69 offset
+= sizeof(value
);
70 fprintf(llogfile
, "%s=0x%x", name
, value
);
74 static void pprint_int32(V9fsPDU
*pdu
, int rx
, size_t *offsetp
,
78 int count
= get_sg_count(pdu
, rx
);
79 struct iovec
*sg
= get_sg(pdu
, rx
);
80 size_t offset
= *offsetp
;
84 copied
= do_pdu_unpack(&value
, sg
, count
, offset
, sizeof(value
));
86 BUG_ON(copied
!= sizeof(value
));
87 offset
+= sizeof(value
);
88 fprintf(llogfile
, "%s=0x%x", name
, value
);
92 static void pprint_int64(V9fsPDU
*pdu
, int rx
, size_t *offsetp
,
96 int count
= get_sg_count(pdu
, rx
);
97 struct iovec
*sg
= get_sg(pdu
, rx
);
98 size_t offset
= *offsetp
;
102 copied
= do_pdu_unpack(&value
, sg
, count
, offset
, sizeof(value
));
104 BUG_ON(copied
!= sizeof(value
));
105 offset
+= sizeof(value
);
106 fprintf(llogfile
, "%s=0x%" PRIx64
, name
, value
);
110 static void pprint_str(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
112 int sg_count
= get_sg_count(pdu
, rx
);
113 struct iovec
*sg
= get_sg(pdu
, rx
);
114 size_t offset
= *offsetp
;
115 uint16_t tmp_size
, size
;
121 copied
= do_pdu_unpack(&tmp_size
, sg
, sg_count
, offset
, sizeof(tmp_size
));
122 BUG_ON(copied
!= sizeof(tmp_size
));
123 size
= le16_to_cpupu(&tmp_size
);
126 fprintf(llogfile
, "%s=", name
);
127 for (i
= 0; size
&& i
< sg_count
; i
++) {
129 if (offset
>= sg
[i
].iov_len
) {
131 offset
-= sg
[i
].iov_len
;
134 len
= MIN(sg
[i
].iov_len
- offset
, size
);
135 result
= fwrite(sg
[i
].iov_base
+ offset
, 1, len
, llogfile
);
136 BUG_ON(result
!= len
);
148 static void pprint_qid(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
150 fprintf(llogfile
, "%s={", name
);
151 pprint_int8(pdu
, rx
, offsetp
, "type");
152 pprint_int32(pdu
, rx
, offsetp
, ", version");
153 pprint_int64(pdu
, rx
, offsetp
, ", path");
154 fprintf(llogfile
, "}");
157 static void pprint_stat(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
159 fprintf(llogfile
, "%s={", name
);
160 pprint_int16(pdu
, rx
, offsetp
, "size");
161 pprint_int16(pdu
, rx
, offsetp
, ", type");
162 pprint_int32(pdu
, rx
, offsetp
, ", dev");
163 pprint_qid(pdu
, rx
, offsetp
, ", qid");
164 pprint_int32(pdu
, rx
, offsetp
, ", mode");
165 pprint_int32(pdu
, rx
, offsetp
, ", atime");
166 pprint_int32(pdu
, rx
, offsetp
, ", mtime");
167 pprint_int64(pdu
, rx
, offsetp
, ", length");
168 pprint_str(pdu
, rx
, offsetp
, ", name");
169 pprint_str(pdu
, rx
, offsetp
, ", uid");
170 pprint_str(pdu
, rx
, offsetp
, ", gid");
171 pprint_str(pdu
, rx
, offsetp
, ", muid");
172 pprint_str(pdu
, rx
, offsetp
, ", extension");
173 pprint_int32(pdu
, rx
, offsetp
, ", uid");
174 pprint_int32(pdu
, rx
, offsetp
, ", gid");
175 pprint_int32(pdu
, rx
, offsetp
, ", muid");
176 fprintf(llogfile
, "}");
179 static void pprint_stat_dotl(V9fsPDU
*pdu
, int rx
, size_t *offsetp
,
182 fprintf(llogfile
, "%s={", name
);
183 pprint_qid(pdu
, rx
, offsetp
, "qid");
184 pprint_int32(pdu
, rx
, offsetp
, ", st_mode");
185 pprint_int64(pdu
, rx
, offsetp
, ", st_nlink");
186 pprint_int32(pdu
, rx
, offsetp
, ", st_uid");
187 pprint_int32(pdu
, rx
, offsetp
, ", st_gid");
188 pprint_int64(pdu
, rx
, offsetp
, ", st_rdev");
189 pprint_int64(pdu
, rx
, offsetp
, ", st_size");
190 pprint_int64(pdu
, rx
, offsetp
, ", st_blksize");
191 pprint_int64(pdu
, rx
, offsetp
, ", st_blocks");
192 pprint_int64(pdu
, rx
, offsetp
, ", atime");
193 pprint_int64(pdu
, rx
, offsetp
, ", atime_nsec");
194 pprint_int64(pdu
, rx
, offsetp
, ", mtime");
195 pprint_int64(pdu
, rx
, offsetp
, ", mtime_nsec");
196 pprint_int64(pdu
, rx
, offsetp
, ", ctime");
197 pprint_int64(pdu
, rx
, offsetp
, ", ctime_nsec");
198 fprintf(llogfile
, "}");
203 static void pprint_strs(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
205 int sg_count
= get_sg_count(pdu
, rx
);
206 struct iovec
*sg
= get_sg(pdu
, rx
);
207 size_t offset
= *offsetp
;
208 uint16_t tmp_count
, count
, i
;
211 fprintf(llogfile
, "%s={", name
);
214 copied
= do_pdu_unpack(&tmp_count
, sg
, sg_count
, offset
, sizeof(tmp_count
));
215 BUG_ON(copied
!= sizeof(tmp_count
));
216 count
= le16_to_cpupu(&tmp_count
);
219 for (i
= 0; i
< count
; i
++) {
222 fprintf(llogfile
, ", ");
224 snprintf(str
, sizeof(str
), "[%d]", i
);
225 pprint_str(pdu
, rx
, &offset
, str
);
228 fprintf(llogfile
, "}");
233 static void pprint_qids(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
235 int sg_count
= get_sg_count(pdu
, rx
);
236 struct iovec
*sg
= get_sg(pdu
, rx
);
237 size_t offset
= *offsetp
;
238 uint16_t tmp_count
, count
, i
;
241 fprintf(llogfile
, "%s={", name
);
243 copied
= do_pdu_unpack(&tmp_count
, sg
, sg_count
, offset
, sizeof(tmp_count
));
244 BUG_ON(copied
!= sizeof(tmp_count
));
245 count
= le16_to_cpupu(&tmp_count
);
248 for (i
= 0; i
< count
; i
++) {
251 fprintf(llogfile
, ", ");
253 snprintf(str
, sizeof(str
), "[%d]", i
);
254 pprint_qid(pdu
, rx
, &offset
, str
);
257 fprintf(llogfile
, "}");
262 static void pprint_sg(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
264 struct iovec
*sg
= get_sg(pdu
, rx
);
269 count
= pdu
->elem
.in_num
;
271 count
= pdu
->elem
.out_num
;
274 fprintf(llogfile
, "%s={", name
);
275 for (i
= 0; i
< count
; i
++) {
277 fprintf(llogfile
, ", ");
279 fprintf(llogfile
, "(%p, 0x%zx)", sg
[i
].iov_base
, sg
[i
].iov_len
);
281 fprintf(llogfile
, "}");
284 /* FIXME: read from a directory fid returns serialized stat_t's */
286 static void pprint_data(V9fsPDU
*pdu
, int rx
, size_t *offsetp
, const char *name
)
288 struct iovec
*sg
= get_sg(pdu
, rx
);
289 size_t offset
= *offsetp
;
296 count
= pdu
->elem
.in_num
;
298 count
= pdu
->elem
.out_num
;
301 BUG_ON((offset
+ sizeof(size
)) > sg
[0].iov_len
);
303 memcpy(&size
, sg
[0].iov_base
+ offset
, sizeof(size
));
304 offset
+= sizeof(size
);
306 fprintf(llogfile
, "size: %x\n", size
);
308 sg
[0].iov_base
+= 11; /* skip header */
312 for (i
= 0; i
< count
; i
++) {
313 total
+= sg
[i
].iov_len
;
315 /* trim sg list so writev does the right thing */
316 sg
[i
].iov_len
-= (total
- size
);
322 fprintf(llogfile
, "%s={\"", name
);
324 for (j
= 0; j
< i
; j
++) {
326 fprintf(llogfile
, "\", \"");
331 len
= writev(fileno(llogfile
), &sg
[j
], 1);
332 } while (len
== -1 && errno
== EINTR
);
333 fprintf(llogfile
, "len == %ld: %m\n", len
);
334 BUG_ON(len
!= sg
[j
].iov_len
);
336 fprintf(llogfile
, "\"}");
338 sg
[0].iov_base
-= 11;
344 void pprint_pdu(V9fsPDU
*pdu
)
348 if (llogfile
== NULL
) {
349 llogfile
= fopen("/tmp/pdu.log", "w");
356 fprintf(llogfile
, "TREADDIR: (");
357 pprint_int32(pdu
, 0, &offset
, "fid");
358 pprint_int64(pdu
, 0, &offset
, ", initial offset");
359 pprint_int32(pdu
, 0, &offset
, ", max count");
362 fprintf(llogfile
, "RREADDIR: (");
363 pprint_int32(pdu
, 1, &offset
, "count");
365 pprint_data(pdu
, 1, &offset
, ", data");
369 fprintf(llogfile
, "TMKDIR: (");
370 pprint_int32(pdu
, 0, &offset
, "fid");
371 pprint_str(pdu
, 0, &offset
, "name");
372 pprint_int32(pdu
, 0, &offset
, "mode");
373 pprint_int32(pdu
, 0, &offset
, "gid");
376 fprintf(llogfile
, "RMKDIR: (");
377 pprint_qid(pdu
, 0, &offset
, "qid");
380 fprintf(llogfile
, "TVERSION: (");
381 pprint_int32(pdu
, 0, &offset
, "msize");
382 pprint_str(pdu
, 0, &offset
, ", version");
385 fprintf(llogfile
, "RVERSION: (");
386 pprint_int32(pdu
, 1, &offset
, "msize");
387 pprint_str(pdu
, 1, &offset
, ", version");
390 fprintf(llogfile
, "TGETATTR: (");
391 pprint_int32(pdu
, 0, &offset
, "fid");
394 fprintf(llogfile
, "RGETATTR: (");
395 pprint_stat_dotl(pdu
, 1, &offset
, "getattr");
398 fprintf(llogfile
, "TAUTH: (");
399 pprint_int32(pdu
, 0, &offset
, "afid");
400 pprint_str(pdu
, 0, &offset
, ", uname");
401 pprint_str(pdu
, 0, &offset
, ", aname");
402 pprint_int32(pdu
, 0, &offset
, ", n_uname");
405 fprintf(llogfile
, "RAUTH: (");
406 pprint_qid(pdu
, 1, &offset
, "qid");
409 fprintf(llogfile
, "TATTACH: (");
410 pprint_int32(pdu
, 0, &offset
, "fid");
411 pprint_int32(pdu
, 0, &offset
, ", afid");
412 pprint_str(pdu
, 0, &offset
, ", uname");
413 pprint_str(pdu
, 0, &offset
, ", aname");
414 pprint_int32(pdu
, 0, &offset
, ", n_uname");
417 fprintf(llogfile
, "RATTACH: (");
418 pprint_qid(pdu
, 1, &offset
, "qid");
421 fprintf(llogfile
, "TERROR: (");
424 fprintf(llogfile
, "RERROR: (");
425 pprint_str(pdu
, 1, &offset
, "ename");
426 pprint_int32(pdu
, 1, &offset
, ", ecode");
429 fprintf(llogfile
, "TFLUSH: (");
430 pprint_int16(pdu
, 0, &offset
, "oldtag");
433 fprintf(llogfile
, "RFLUSH: (");
436 fprintf(llogfile
, "TWALK: (");
437 pprint_int32(pdu
, 0, &offset
, "fid");
438 pprint_int32(pdu
, 0, &offset
, ", newfid");
439 pprint_strs(pdu
, 0, &offset
, ", wnames");
442 fprintf(llogfile
, "RWALK: (");
443 pprint_qids(pdu
, 1, &offset
, "wqids");
446 fprintf(llogfile
, "TOPEN: (");
447 pprint_int32(pdu
, 0, &offset
, "fid");
448 pprint_int8(pdu
, 0, &offset
, ", mode");
451 fprintf(llogfile
, "ROPEN: (");
452 pprint_qid(pdu
, 1, &offset
, "qid");
453 pprint_int32(pdu
, 1, &offset
, ", iounit");
456 fprintf(llogfile
, "TCREATE: (");
457 pprint_int32(pdu
, 0, &offset
, "fid");
458 pprint_str(pdu
, 0, &offset
, ", name");
459 pprint_int32(pdu
, 0, &offset
, ", perm");
460 pprint_int8(pdu
, 0, &offset
, ", mode");
461 pprint_str(pdu
, 0, &offset
, ", extension");
464 fprintf(llogfile
, "RCREATE: (");
465 pprint_qid(pdu
, 1, &offset
, "qid");
466 pprint_int32(pdu
, 1, &offset
, ", iounit");
469 fprintf(llogfile
, "TSYMLINK: (");
470 pprint_int32(pdu
, 0, &offset
, "fid");
471 pprint_str(pdu
, 0, &offset
, ", name");
472 pprint_str(pdu
, 0, &offset
, ", symname");
473 pprint_int32(pdu
, 0, &offset
, ", gid");
476 fprintf(llogfile
, "RSYMLINK: (");
477 pprint_qid(pdu
, 1, &offset
, "qid");
480 fprintf(llogfile
, "TLCREATE: (");
481 pprint_int32(pdu
, 0, &offset
, "dfid");
482 pprint_str(pdu
, 0, &offset
, ", name");
483 pprint_int32(pdu
, 0, &offset
, ", flags");
484 pprint_int32(pdu
, 0, &offset
, ", mode");
485 pprint_int32(pdu
, 0, &offset
, ", gid");
488 fprintf(llogfile
, "RLCREATE: (");
489 pprint_qid(pdu
, 1, &offset
, "qid");
490 pprint_int32(pdu
, 1, &offset
, ", iounit");
493 fprintf(llogfile
, "TMKNOD: (");
494 pprint_int32(pdu
, 0, &offset
, "fid");
495 pprint_str(pdu
, 0, &offset
, "name");
496 pprint_int32(pdu
, 0, &offset
, "mode");
497 pprint_int32(pdu
, 0, &offset
, "major");
498 pprint_int32(pdu
, 0, &offset
, "minor");
499 pprint_int32(pdu
, 0, &offset
, "gid");
502 fprintf(llogfile
, "RMKNOD: )");
503 pprint_qid(pdu
, 0, &offset
, "qid");
506 fprintf(llogfile
, "TREADLINK: (");
507 pprint_int32(pdu
, 0, &offset
, "fid");
510 fprintf(llogfile
, "RREADLINK: (");
511 pprint_str(pdu
, 0, &offset
, "target");
514 fprintf(llogfile
, "TREAD: (");
515 pprint_int32(pdu
, 0, &offset
, "fid");
516 pprint_int64(pdu
, 0, &offset
, ", offset");
517 pprint_int32(pdu
, 0, &offset
, ", count");
518 pprint_sg(pdu
, 0, &offset
, ", sg");
521 fprintf(llogfile
, "RREAD: (");
522 pprint_int32(pdu
, 1, &offset
, "count");
523 pprint_sg(pdu
, 1, &offset
, ", sg");
526 pprint_data(pdu
, 1, &offset
, ", data");
530 fprintf(llogfile
, "TWRITE: (");
531 pprint_int32(pdu
, 0, &offset
, "fid");
532 pprint_int64(pdu
, 0, &offset
, ", offset");
533 pprint_int32(pdu
, 0, &offset
, ", count");
536 fprintf(llogfile
, "RWRITE: (");
537 pprint_int32(pdu
, 1, &offset
, "count");
540 fprintf(llogfile
, "TCLUNK: (");
541 pprint_int32(pdu
, 0, &offset
, "fid");
544 fprintf(llogfile
, "RCLUNK: (");
547 fprintf(llogfile
, "TFSYNC: (");
548 pprint_int32(pdu
, 0, &offset
, "fid");
551 fprintf(llogfile
, "RFSYNC: (");
554 fprintf(llogfile
, "TLINK: (");
555 pprint_int32(pdu
, 0, &offset
, "dfid");
556 pprint_int32(pdu
, 0, &offset
, ", fid");
557 pprint_str(pdu
, 0, &offset
, ", newpath");
560 fprintf(llogfile
, "RLINK: (");
563 fprintf(llogfile
, "TREMOVE: (");
564 pprint_int32(pdu
, 0, &offset
, "fid");
567 fprintf(llogfile
, "RREMOVE: (");
570 fprintf(llogfile
, "TSTAT: (");
571 pprint_int32(pdu
, 0, &offset
, "fid");
574 fprintf(llogfile
, "RSTAT: (");
575 offset
+= 2; /* ignored */
576 pprint_stat(pdu
, 1, &offset
, "stat");
579 fprintf(llogfile
, "TWSTAT: (");
580 pprint_int32(pdu
, 0, &offset
, "fid");
581 offset
+= 2; /* ignored */
582 pprint_stat(pdu
, 0, &offset
, ", stat");
585 fprintf(llogfile
, "RWSTAT: (");
588 fprintf(llogfile
, "TXATTRWALK: (");
589 pprint_int32(pdu
, 0, &offset
, "fid");
590 pprint_int32(pdu
, 0, &offset
, ", newfid");
591 pprint_str(pdu
, 0, &offset
, ", xattr name");
594 fprintf(llogfile
, "RXATTRWALK: (");
595 pprint_int64(pdu
, 1, &offset
, "xattrsize");
596 case P9_TXATTRCREATE
:
597 fprintf(llogfile
, "TXATTRCREATE: (");
598 pprint_int32(pdu
, 0, &offset
, "fid");
599 pprint_str(pdu
, 0, &offset
, ", name");
600 pprint_int64(pdu
, 0, &offset
, ", xattrsize");
601 pprint_int32(pdu
, 0, &offset
, ", flags");
603 case P9_RXATTRCREATE
:
604 fprintf(llogfile
, "RXATTRCREATE: (");
607 fprintf(llogfile
, "TLOCK: (");
608 pprint_int32(pdu
, 0, &offset
, "fid");
609 pprint_int8(pdu
, 0, &offset
, ", type");
610 pprint_int32(pdu
, 0, &offset
, ", flags");
611 pprint_int64(pdu
, 0, &offset
, ", start");
612 pprint_int64(pdu
, 0, &offset
, ", length");
613 pprint_int32(pdu
, 0, &offset
, ", proc_id");
614 pprint_str(pdu
, 0, &offset
, ", client_id");
617 fprintf(llogfile
, "RLOCK: (");
618 pprint_int8(pdu
, 0, &offset
, "status");
621 fprintf(llogfile
, "TGETLOCK: (");
622 pprint_int32(pdu
, 0, &offset
, "fid");
623 pprint_int8(pdu
, 0, &offset
, ", type");
624 pprint_int64(pdu
, 0, &offset
, ", start");
625 pprint_int64(pdu
, 0, &offset
, ", length");
626 pprint_int32(pdu
, 0, &offset
, ", proc_id");
627 pprint_str(pdu
, 0, &offset
, ", client_id");
630 fprintf(llogfile
, "RGETLOCK: (");
631 pprint_int8(pdu
, 0, &offset
, "type");
632 pprint_int64(pdu
, 0, &offset
, ", start");
633 pprint_int64(pdu
, 0, &offset
, ", length");
634 pprint_int32(pdu
, 0, &offset
, ", proc_id");
635 pprint_str(pdu
, 0, &offset
, ", client_id");
638 fprintf(llogfile
, "unknown(%d): (", pdu
->id
);
642 fprintf(llogfile
, ")\n");
643 /* Flush the log message out */