2 * Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/param.h>
39 #if defined(__FreeBSD__)
42 #include "sbuf/sbuf.h"
46 #include "linux_errno.h"
49 #define GETGROUPS_GROUP_TYPE_IS_INT
52 #define N(ary) (sizeof(ary) / sizeof(*ary))
54 /* See l9p_describe_bits() below. */
56 uint64_t db_mask; /* mask value */
57 uint64_t db_match; /* match value */
58 const char *db_name; /* name for matched value */
62 static bool l9p_describe_bits(const char *, uint64_t, const char *,
63 const struct descbits *, struct sbuf *);
64 static void l9p_describe_fid(const char *, uint32_t, struct sbuf *);
65 static void l9p_describe_mode(const char *, uint32_t, struct sbuf *);
66 static void l9p_describe_name(const char *, char *, struct sbuf *);
67 static void l9p_describe_perm(const char *, uint32_t, struct sbuf *);
68 static void l9p_describe_lperm(const char *, uint32_t, struct sbuf *);
69 static void l9p_describe_qid(const char *, struct l9p_qid *, struct sbuf *);
70 static void l9p_describe_l9stat(const char *, struct l9p_stat *,
71 enum l9p_version, struct sbuf *);
72 static void l9p_describe_statfs(const char *, struct l9p_statfs *,
74 static void l9p_describe_time(struct sbuf *, const char *, uint64_t, uint64_t);
75 static void l9p_describe_readdir(struct sbuf *, struct l9p_f_io *);
76 static void l9p_describe_size(const char *, uint64_t, struct sbuf *);
77 static void l9p_describe_ugid(const char *, uint32_t, struct sbuf *);
78 static void l9p_describe_getattr_mask(uint64_t, struct sbuf *);
79 static void l9p_describe_unlinkat_flags(const char *, uint32_t, struct sbuf *);
80 static const char *lookup_linux_errno(uint32_t);
83 * Using indexed initializers, we can have these occur in any order.
84 * Using adjacent-string concatenation ("T" #name, "R" #name), we
85 * get both Tfoo and Rfoo strings with one copy of the name.
86 * Alas, there is no stupid cpp trick to lowercase-ify, so we
87 * have to write each name twice. In which case we might as well
88 * make the second one a string in the first place and not bother
89 * with the stringizing.
91 * This table should have entries for each enum value in fcall.h.
93 #define X(NAME, name) [L9P_T##NAME - L9P__FIRST] = "T" name, \
94 [L9P_R##NAME - L9P__FIRST] = "R" name
95 static const char *ftype_names[] = {
96 X(VERSION, "version"),
113 X(LCREATE, "lcreate"),
114 X(SYMLINK, "symlink"),
117 X(READLINK, "readlink"),
118 X(GETATTR, "getattr"),
119 X(SETATTR, "setattr"),
120 X(XATTRWALK, "xattrwalk"),
121 X(XATTRCREATE, "xattrcreate"),
122 X(READDIR, "readdir"),
125 X(GETLOCK, "getlock"),
128 X(RENAMEAT, "renameat"),
129 X(UNLINKAT, "unlinkat"),
134 l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2,
135 size_t *niov2, size_t seek)
137 size_t remainder = 0;
141 for (i = 0; i < niov1; i++) {
142 size_t toseek = MIN(left, iov1[i].iov_len);
145 if (toseek == iov1[i].iov_len)
154 for (j = i; j < niov1; j++) {
155 iov2[j - i].iov_base = (char *)iov1[j].iov_base + remainder;
156 iov2[j - i].iov_len = iov1[j].iov_len - remainder;
164 l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length)
168 for (i = 0; i < niov; i++) {
169 size_t toseek = MIN(length - done, iov[i].iov_len);
172 if (toseek < iov[i].iov_len) {
173 iov[i].iov_len = toseek;
182 * This wrapper for getgrouplist() that malloc'ed memory, and
183 * papers over FreeBSD vs Mac differences in the getgrouplist()
186 * Note that this function guarantees that *either*:
187 * return value != NULL and *angroups has been set
188 * or: return value == NULL and *angroups is 0
191 l9p_getgrlist(const char *name, gid_t basegid, int *angroups)
193 #ifdef GETGROUPS_GROUP_TYPE_IS_INT
200 * Todo, perhaps: while getgrouplist() returns -1, expand.
201 * For now just use NGROUPS_MAX.
203 ngroups = NGROUPS_MAX;
204 groups = malloc((size_t)ngroups * sizeof(*groups));
205 #ifdef GETGROUPS_GROUP_TYPE_IS_INT
206 int_groups = groups ? malloc((size_t)ngroups * sizeof(*int_groups)) :
208 if (int_groups == NULL) {
213 if (groups == NULL) {
217 #ifdef GETGROUPS_GROUP_TYPE_IS_INT
218 (void) getgrouplist(name, (int)basegid, int_groups, &ngroups);
219 for (i = 0; i < ngroups; i++)
220 groups[i] = (gid_t)int_groups[i];
222 (void) getgrouplist(name, basegid, groups, &ngroups);
229 * For the various debug describe ops: decode bits in a bit-field-y
230 * value. For example, we might produce:
231 * value=0x3c[FOO,BAR,QUUX,?0x20]
232 * when FOO is bit 0x10, BAR is 0x08, and QUUX is 0x04 (as defined
233 * by the table). This leaves 0x20 (bit 5) as a mystery, while bits
234 * 4, 3, and 2 were decoded. (Bits 0 and 1 were 0 on input hence
235 * were not attempted here.)
237 * For general use we take a uint64_t <value>. The bit description
238 * table <db> is an array of {mask, match, str} values ending with
241 * If <str> is non-NULL we'll print it and the mask as well (if
242 * str is NULL we'll print neither). The mask is always printed in
243 * hex at the moment. See undec description too.
245 * For convenience, you can use a mask-and-match value, e.g., to
246 * decode a 2-bit field in bits 0 and 1 you can mask against 3 and
247 * match the values 0, 1, 2, and 3. To handle this, make sure that
248 * all masks-with-same-match are sequential.
250 * If there are any nonzero undecoded bits, print them after
251 * all the decode-able bits have been handled.
253 * The <oc> argument defines the open and close bracket characters,
254 * typically "[]", that surround the entire string. If NULL, no
255 * brackets are added, else oc[0] goes in the front and oc[1] at
256 * the end, after printing any <str><value> part.
258 * Returns true if it printed anything (other than the implied
259 * str-and-value, that is).
262 l9p_describe_bits(const char *str, uint64_t value, const char *oc,
263 const struct descbits *db, struct sbuf *sb)
266 char bracketbuf[2] = "";
267 bool printed = false;
270 sbuf_printf(sb, "%s0x%" PRIx64, str, value);
273 bracketbuf[0] = oc[0];
275 for (; db->db_name != NULL; db++) {
276 if ((value & db->db_mask) == db->db_match) {
277 sbuf_printf(sb, "%s%s", sep, db->db_name);
282 * Clear the field, and make sure we
283 * won't match a zero-valued field with
286 value &= ~db->db_mask;
287 while (db[1].db_mask == db->db_mask &&
288 db[1].db_name != NULL)
293 sbuf_printf(sb, "%s?0x%" PRIx64, sep, value);
296 if (printed && oc != NULL) {
297 bracketbuf[0] = oc[1];
298 sbuf_cat(sb, bracketbuf);
307 l9p_describe_fid(const char *str, uint32_t fid, struct sbuf *sb)
310 sbuf_printf(sb, "%s%" PRIu32, str, fid);
314 * Show user or group ID.
317 l9p_describe_ugid(const char *str, uint32_t ugid, struct sbuf *sb)
320 sbuf_printf(sb, "%s%" PRIu32, str, ugid);
324 * Show file mode (O_RDWR, O_RDONLY, etc). The argument is
325 * an l9p_omode, not a Linux flags mode. Linux flags are
326 * decoded with l9p_describe_lflags.
329 l9p_describe_mode(const char *str, uint32_t mode, struct sbuf *sb)
331 static const struct descbits bits[] = {
332 { L9P_OACCMODE, L9P_OREAD, "OREAD" },
333 { L9P_OACCMODE, L9P_OWRITE, "OWRITE" },
334 { L9P_OACCMODE, L9P_ORDWR, "ORDWR" },
335 { L9P_OACCMODE, L9P_OEXEC, "OEXEC" },
337 { L9P_OCEXEC, L9P_OCEXEC, "OCEXEC" },
338 { L9P_ODIRECT, L9P_ODIRECT, "ODIRECT" },
339 { L9P_ORCLOSE, L9P_ORCLOSE, "ORCLOSE" },
340 { L9P_OTRUNC, L9P_OTRUNC, "OTRUNC" },
344 (void) l9p_describe_bits(str, mode, "[]", bits, sb);
348 * Show Linux mode/flags.
351 l9p_describe_lflags(const char *str, uint32_t flags, struct sbuf *sb)
353 static const struct descbits bits[] = {
354 { L9P_OACCMODE, L9P_OREAD, "O_READ" },
355 { L9P_OACCMODE, L9P_OWRITE, "O_WRITE" },
356 { L9P_OACCMODE, L9P_ORDWR, "O_RDWR" },
357 { L9P_OACCMODE, L9P_OEXEC, "O_EXEC" },
359 { L9P_L_O_APPEND, L9P_L_O_APPEND, "O_APPEND" },
360 { L9P_L_O_CLOEXEC, L9P_L_O_CLOEXEC, "O_CLOEXEC" },
361 { L9P_L_O_CREAT, L9P_L_O_CREAT, "O_CREAT" },
362 { L9P_L_O_DIRECT, L9P_L_O_DIRECT, "O_DIRECT" },
363 { L9P_L_O_DIRECTORY, L9P_L_O_DIRECTORY, "O_DIRECTORY" },
364 { L9P_L_O_DSYNC, L9P_L_O_DSYNC, "O_DSYNC" },
365 { L9P_L_O_EXCL, L9P_L_O_EXCL, "O_EXCL" },
366 { L9P_L_O_FASYNC, L9P_L_O_FASYNC, "O_FASYNC" },
367 { L9P_L_O_LARGEFILE, L9P_L_O_LARGEFILE, "O_LARGEFILE" },
368 { L9P_L_O_NOATIME, L9P_L_O_NOATIME, "O_NOATIME" },
369 { L9P_L_O_NOCTTY, L9P_L_O_NOCTTY, "O_NOCTTY" },
370 { L9P_L_O_NOFOLLOW, L9P_L_O_NOFOLLOW, "O_NOFOLLOW" },
371 { L9P_L_O_NONBLOCK, L9P_L_O_NONBLOCK, "O_NONBLOCK" },
372 { L9P_L_O_PATH, L9P_L_O_PATH, "O_PATH" },
373 { L9P_L_O_SYNC, L9P_L_O_SYNC, "O_SYNC" },
374 { L9P_L_O_TMPFILE, L9P_L_O_TMPFILE, "O_TMPFILE" },
375 { L9P_L_O_TMPFILE, L9P_L_O_TMPFILE, "O_TMPFILE" },
376 { L9P_L_O_TRUNC, L9P_L_O_TRUNC, "O_TRUNC" },
380 (void) l9p_describe_bits(str, flags, "[]", bits, sb);
384 * Show file name or other similar, potentially-very-long string.
385 * Actual strings get quotes, a NULL name (if it occurs) gets
386 * <null> (no quotes), so you can tell the difference.
389 l9p_describe_name(const char *str, char *name, struct sbuf *sb)
394 sbuf_printf(sb, "%s<null>", str);
401 sbuf_printf(sb, "%s\"%.*s...\"", str, 32 - 3, name);
403 sbuf_printf(sb, "%s\"%.*s\"", str, (int)len, name);
407 * Show permissions (rwx etc). Prints the value in hex only if
408 * the rwx bits do not cover the entire value.
411 l9p_describe_perm(const char *str, uint32_t mode, struct sbuf *sb)
415 strmode(mode & 0777, pbuf);
416 if ((mode & ~(uint32_t)0777) != 0)
417 sbuf_printf(sb, "%s0x%" PRIx32 "<%.9s>", str, mode, pbuf + 1);
419 sbuf_printf(sb, "%s<%.9s>", str, pbuf + 1);
423 * Show "extended" permissions: regular permissions, but also the
424 * various DM* extension bits from 9P2000.u.
427 l9p_describe_ext_perm(const char *str, uint32_t mode, struct sbuf *sb)
429 static const struct descbits bits[] = {
430 { L9P_DMDIR, L9P_DMDIR, "DMDIR" },
431 { L9P_DMAPPEND, L9P_DMAPPEND, "DMAPPEND" },
432 { L9P_DMEXCL, L9P_DMEXCL, "DMEXCL" },
433 { L9P_DMMOUNT, L9P_DMMOUNT, "DMMOUNT" },
434 { L9P_DMAUTH, L9P_DMAUTH, "DMAUTH" },
435 { L9P_DMTMP, L9P_DMTMP, "DMTMP" },
436 { L9P_DMSYMLINK, L9P_DMSYMLINK, "DMSYMLINK" },
437 { L9P_DMDEVICE, L9P_DMDEVICE, "DMDEVICE" },
438 { L9P_DMNAMEDPIPE, L9P_DMNAMEDPIPE, "DMNAMEDPIPE" },
439 { L9P_DMSOCKET, L9P_DMSOCKET, "DMSOCKET" },
440 { L9P_DMSETUID, L9P_DMSETUID, "DMSETUID" },
441 { L9P_DMSETGID, L9P_DMSETGID, "DMSETGID" },
446 sbuf_printf(sb, "%s[", str);
447 need_sep = l9p_describe_bits(NULL, mode & ~(uint32_t)0777, NULL,
449 l9p_describe_perm(need_sep ? "," : "", mode & 0777, sb);
454 * Show Linux-specific permissions: regular permissions, but also
458 l9p_describe_lperm(const char *str, uint32_t mode, struct sbuf *sb)
460 static const struct descbits bits[] = {
461 { S_IFMT, S_IFIFO, "S_IFIFO" },
462 { S_IFMT, S_IFCHR, "S_IFCHR" },
463 { S_IFMT, S_IFDIR, "S_IFDIR" },
464 { S_IFMT, S_IFBLK, "S_IFBLK" },
465 { S_IFMT, S_IFREG, "S_IFREG" },
466 { S_IFMT, S_IFLNK, "S_IFLNK" },
467 { S_IFMT, S_IFSOCK, "S_IFSOCK" },
472 sbuf_printf(sb, "%s[", str);
473 need_sep = l9p_describe_bits(NULL, mode & ~(uint32_t)0777, NULL,
475 l9p_describe_perm(need_sep ? "," : "", mode & 0777, sb);
480 * Show qid (<type, version, path> tuple).
483 l9p_describe_qid(const char *str, struct l9p_qid *qid, struct sbuf *sb)
485 static const struct descbits bits[] = {
487 * NB: L9P_QTFILE is 0, i.e., is implied by no
488 * other bits being set. We get this produced
489 * when we mask against 0xff and compare for
490 * L9P_QTFILE, but we must do it first so that
491 * we mask against the original (not-adjusted)
494 { 0xff, L9P_QTFILE, "FILE" },
495 { L9P_QTDIR, L9P_QTDIR, "DIR" },
496 { L9P_QTAPPEND, L9P_QTAPPEND, "APPEND" },
497 { L9P_QTEXCL, L9P_QTEXCL, "EXCL" },
498 { L9P_QTMOUNT, L9P_QTMOUNT, "MOUNT" },
499 { L9P_QTAUTH, L9P_QTAUTH, "AUTH" },
500 { L9P_QTTMP, L9P_QTTMP, "TMP" },
501 { L9P_QTSYMLINK, L9P_QTSYMLINK, "SYMLINK" },
508 (void) l9p_describe_bits("<", qid->type, "[]", bits, sb);
509 sbuf_printf(sb, ",%" PRIu32 ",0x%016" PRIx64 ">",
510 qid->version, qid->path);
517 l9p_describe_size(const char *str, uint64_t size, struct sbuf *sb)
520 sbuf_printf(sb, "%s%" PRIu64, str, size);
524 * Show l9stat (including 9P2000.u extensions if appropriate).
527 l9p_describe_l9stat(const char *str, struct l9p_stat *st,
528 enum l9p_version version, struct sbuf *sb)
530 bool dotu = version >= L9P_2000U;
534 sbuf_printf(sb, "%stype=0x%04" PRIx32 " dev=0x%08" PRIx32, str,
536 l9p_describe_qid(" qid=", &st->qid, sb);
537 l9p_describe_ext_perm(" mode=", st->mode, sb);
538 if (st->atime != (uint32_t)-1)
539 sbuf_printf(sb, " atime=%" PRIu32, st->atime);
540 if (st->mtime != (uint32_t)-1)
541 sbuf_printf(sb, " mtime=%" PRIu32, st->mtime);
542 if (st->length != (uint64_t)-1)
543 sbuf_printf(sb, " length=%" PRIu64, st->length);
544 l9p_describe_name(" name=", st->name, sb);
546 * It's pretty common to have NULL name+gid+muid. They're
547 * just noise if NULL *and* dot-u; decode only if non-null
550 if (st->uid != NULL || !dotu)
551 l9p_describe_name(" uid=", st->uid, sb);
552 if (st->gid != NULL || !dotu)
553 l9p_describe_name(" gid=", st->gid, sb);
554 if (st->muid != NULL || !dotu)
555 l9p_describe_name(" muid=", st->muid, sb);
557 if (st->extension != NULL)
558 l9p_describe_name(" extension=", st->extension, sb);
560 " n_uid=%" PRIu32 " n_gid=%" PRIu32 " n_muid=%" PRIu32,
561 st->n_uid, st->n_gid, st->n_muid);
566 l9p_describe_statfs(const char *str, struct l9p_statfs *st, struct sbuf *sb)
571 sbuf_printf(sb, "%stype=0x%04lx bsize=%lu blocks=%" PRIu64
572 " bfree=%" PRIu64 " bavail=%" PRIu64 " files=%" PRIu64
573 " ffree=%" PRIu64 " fsid=0x%" PRIx64 " namelen=%" PRIu32 ">",
574 str, (u_long)st->type, (u_long)st->bsize, st->blocks,
575 st->bfree, st->bavail, st->files,
576 st->ffree, st->fsid, st->namelen);
580 * Decode a <seconds,nsec> timestamp.
582 * Perhaps should use asctime_r. For now, raw values.
585 l9p_describe_time(struct sbuf *sb, const char *s, uint64_t sec, uint64_t nsec)
589 if (nsec > 999999999)
590 sbuf_printf(sb, "%" PRIu64 ".<invalid nsec %" PRIu64 ">)",
593 sbuf_printf(sb, "%" PRIu64 ".%09" PRIu64, sec, nsec);
597 * Decode readdir data (.L format, variable length names).
600 l9p_describe_readdir(struct sbuf *sb, struct l9p_f_io *io)
605 struct l9p_message msg;
606 struct l9p_dirent de;
609 if ((count = io->count) == 0) {
610 sbuf_printf(sb, " EOF (count=0)");
615 * Can't do this yet because we do not have the original
619 sbuf_printf(sb, " count=%" PRIu32 " [", count);
621 l9p_init_msg(&msg, req, L9P_UNPACK);
622 for (i = 0; msg.lm_size < count; i++) {
623 if (l9p_pudirent(&msg, &de) < 0) {
624 sbuf_printf(sb, " bad count");
628 sbuf_printf(sb, i ? ", " : " ");
629 l9p_describe_qid(" qid=", &de.qid, sb);
630 sbuf_printf(sb, " offset=%" PRIu64 " type=%d",
632 l9p_describe_name(" name=", de.name);
635 sbuf_printf(sb, "]=%d dir entries", i);
637 sbuf_printf(sb, " count=%" PRIu32, count);
642 * Decode Tgetattr request_mask field.
645 l9p_describe_getattr_mask(uint64_t request_mask, struct sbuf *sb)
647 static const struct descbits bits[] = {
649 * Note: ALL and BASIC must occur first and second.
650 * This is a little dirty: it depends on the way the
651 * describe_bits code clears the values. If we
652 * match ALL, we clear all those bits and do not
653 * match BASIC; if we match BASIC, we clear all
654 * those bits and do not match individual bits. Thus
655 * if we have BASIC but not all the additional bits,
656 * we'll see, e.g., [BASIC,BTIME,GEN]; if we have
657 * all the additional bits too, we'll see [ALL].
659 * Since <undec> is true below, we'll also spot any
660 * bits added to the protocol since we made this table.
662 { L9PL_GETATTR_ALL, L9PL_GETATTR_ALL, "ALL" },
663 { L9PL_GETATTR_BASIC, L9PL_GETATTR_BASIC, "BASIC" },
665 /* individual bits in BASIC */
666 { L9PL_GETATTR_MODE, L9PL_GETATTR_MODE, "MODE" },
667 { L9PL_GETATTR_NLINK, L9PL_GETATTR_NLINK, "NLINK" },
668 { L9PL_GETATTR_UID, L9PL_GETATTR_UID, "UID" },
669 { L9PL_GETATTR_GID, L9PL_GETATTR_GID, "GID" },
670 { L9PL_GETATTR_RDEV, L9PL_GETATTR_RDEV, "RDEV" },
671 { L9PL_GETATTR_ATIME, L9PL_GETATTR_ATIME, "ATIME" },
672 { L9PL_GETATTR_MTIME, L9PL_GETATTR_MTIME, "MTIME" },
673 { L9PL_GETATTR_CTIME, L9PL_GETATTR_CTIME, "CTIME" },
674 { L9PL_GETATTR_INO, L9PL_GETATTR_INO, "INO" },
675 { L9PL_GETATTR_SIZE, L9PL_GETATTR_SIZE, "SIZE" },
676 { L9PL_GETATTR_BLOCKS, L9PL_GETATTR_BLOCKS, "BLOCKS" },
678 /* additional bits in ALL */
679 { L9PL_GETATTR_BTIME, L9PL_GETATTR_BTIME, "BTIME" },
680 { L9PL_GETATTR_GEN, L9PL_GETATTR_GEN, "GEN" },
681 { L9PL_GETATTR_DATA_VERSION, L9PL_GETATTR_DATA_VERSION,
686 (void) l9p_describe_bits(" request_mask=", request_mask, "[]", bits,
691 * Decode Tunlinkat flags.
694 l9p_describe_unlinkat_flags(const char *str, uint32_t flags, struct sbuf *sb)
696 static const struct descbits bits[] = {
697 { L9PL_AT_REMOVEDIR, L9PL_AT_REMOVEDIR, "AT_REMOVEDIR" },
701 (void) l9p_describe_bits(str, flags, "[]", bits, sb);
705 lookup_linux_errno(uint32_t linux_errno)
707 static char unknown[50];
710 * Error numbers in the "base" range (1..ERANGE) are common
711 * across BSD, MacOS, Linux, and Plan 9.
713 * Error numbers outside that range require translation.
715 const char *const table[] = {
716 #define X0(name) [name] = name ## _STR
717 #define X(name) [name] = name ## _STR
720 X(LINUX_ENAMETOOLONG),
771 X(LINUX_EDESTADDRREQ),
774 X(LINUX_ENOPROTOOPT),
775 X(LINUX_EPROTONOSUPPORT),
776 X(LINUX_ESOCKTNOSUPPORT),
778 X(LINUX_EPFNOSUPPORT),
779 X(LINUX_EAFNOSUPPORT),
781 X(LINUX_EADDRNOTAVAIL),
783 X(LINUX_ENETUNREACH),
785 X(LINUX_ECONNABORTED),
791 X(LINUX_ETOOMANYREFS),
793 X(LINUX_ECONNREFUSED),
795 X(LINUX_EHOSTUNREACH),
797 X(LINUX_EINPROGRESS),
806 X(LINUX_EMEDIUMTYPE),
809 X(LINUX_EKEYEXPIRED),
810 X(LINUX_EKEYREVOKED),
811 X(LINUX_EKEYREJECTED),
813 X(LINUX_ENOTRECOVERABLE),
819 if ((size_t)linux_errno < N(table) && table[linux_errno] != NULL)
820 return (table[linux_errno]);
821 if (linux_errno <= ERANGE)
822 return (strerror((int)linux_errno));
823 (void) snprintf(unknown, sizeof(unknown),
824 "Unknown error %d", linux_errno);
829 l9p_describe_fcall(union l9p_fcall *fcall, enum l9p_version version,
836 assert(fcall != NULL);
838 assert(version <= L9P_2000L && version >= L9P_INVALID_VERSION);
840 type = fcall->hdr.type;
842 if (type < L9P__FIRST || type >= L9P__LAST_PLUS_1 ||
843 ftype_names[type - L9P__FIRST] == NULL) {
847 * Can't say for sure that this distinction --
848 * an even number is a request, an odd one is
849 * a response -- will be maintained forever,
850 * but it's good enough for now.
852 rr = (type & 1) != 0 ? "response" : "request";
853 sbuf_printf(sb, "<unknown %s %d> tag=%d", rr, type,
856 sbuf_printf(sb, "%s tag=%d", ftype_names[type - L9P__FIRST],
863 sbuf_printf(sb, " version=\"%s\" msize=%d", fcall->version.version,
864 fcall->version.msize);
868 l9p_describe_fid(" afid=", fcall->hdr.fid, sb);
869 sbuf_printf(sb, " uname=\"%s\" aname=\"%s\"",
870 fcall->tauth.uname, fcall->tauth.aname);
874 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
875 l9p_describe_fid(" afid=", fcall->tattach.afid, sb);
876 sbuf_printf(sb, " uname=\"%s\" aname=\"%s\"",
877 fcall->tattach.uname, fcall->tattach.aname);
878 if (version >= L9P_2000U)
879 sbuf_printf(sb, " n_uname=%d", fcall->tattach.n_uname);
883 l9p_describe_qid(" ", &fcall->rattach.qid, sb);
887 sbuf_printf(sb, " ename=\"%s\" errnum=%d", fcall->error.ename,
888 fcall->error.errnum);
892 sbuf_printf(sb, " errnum=%d (%s)", fcall->error.errnum,
893 lookup_linux_errno(fcall->error.errnum));
897 sbuf_printf(sb, " oldtag=%d", fcall->tflush.oldtag);
904 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
905 l9p_describe_fid(" newfid=", fcall->twalk.newfid, sb);
906 if (fcall->twalk.nwname) {
907 sbuf_cat(sb, " wname=\"");
908 for (i = 0; i < fcall->twalk.nwname; i++)
909 sbuf_printf(sb, "%s%s", i == 0 ? "" : "/",
910 fcall->twalk.wname[i]);
916 sbuf_printf(sb, " wqid=[");
917 for (i = 0; i < fcall->rwalk.nwqid; i++)
918 l9p_describe_qid(i == 0 ? "" : ",",
919 &fcall->rwalk.wqid[i], sb);
924 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
925 l9p_describe_mode(" mode=", fcall->tcreate.mode, sb);
929 l9p_describe_qid(" qid=", &fcall->ropen.qid, sb);
930 sbuf_printf(sb, " iounit=%d", fcall->ropen.iounit);
934 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
935 l9p_describe_name(" name=", fcall->tcreate.name, sb);
936 l9p_describe_ext_perm(" perm=", fcall->tcreate.perm, sb);
937 l9p_describe_mode(" mode=", fcall->tcreate.mode, sb);
938 if (version >= L9P_2000U && fcall->tcreate.extension != NULL)
939 l9p_describe_name(" extension=",
940 fcall->tcreate.extension, sb);
944 l9p_describe_qid(" qid=", &fcall->rcreate.qid, sb);
945 sbuf_printf(sb, " iounit=%d", fcall->rcreate.iounit);
949 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
950 sbuf_printf(sb, " offset=%" PRIu64 " count=%" PRIu32,
951 fcall->io.offset, fcall->io.count);
956 sbuf_printf(sb, " count=%" PRIu32, fcall->io.count);
961 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
962 sbuf_printf(sb, " offset=%" PRIu64 " count=%" PRIu32,
963 fcall->io.offset, fcall->io.count);
967 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
974 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
981 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
985 l9p_describe_l9stat(" ", &fcall->rstat.stat, version, sb);
989 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
990 l9p_describe_l9stat(" ", &fcall->twstat.stat, version, sb);
997 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1001 l9p_describe_statfs(" ", &fcall->rstatfs.statfs, sb);
1005 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1006 l9p_describe_lflags(" flags=", fcall->tlcreate.flags, sb);
1010 l9p_describe_qid(" qid=", &fcall->rlopen.qid, sb);
1011 sbuf_printf(sb, " iounit=%d", fcall->rlopen.iounit);
1015 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1016 l9p_describe_name(" name=", fcall->tlcreate.name, sb);
1017 /* confusing: "flags" is open-mode, "mode" is permissions */
1018 l9p_describe_lflags(" flags=", fcall->tlcreate.flags, sb);
1019 /* TLCREATE mode/permissions have S_IFREG (0x8000) set */
1020 l9p_describe_lperm(" mode=", fcall->tlcreate.mode, sb);
1021 l9p_describe_ugid(" gid=", fcall->tlcreate.gid, sb);
1025 l9p_describe_qid(" qid=", &fcall->rlcreate.qid, sb);
1026 sbuf_printf(sb, " iounit=%d", fcall->rlcreate.iounit);
1030 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1031 l9p_describe_name(" name=", fcall->tsymlink.name, sb);
1032 l9p_describe_name(" symtgt=", fcall->tsymlink.symtgt, sb);
1033 l9p_describe_ugid(" gid=", fcall->tsymlink.gid, sb);
1037 l9p_describe_qid(" qid=", &fcall->ropen.qid, sb);
1041 l9p_describe_fid(" dfid=", fcall->hdr.fid, sb);
1042 l9p_describe_name(" name=", fcall->tmknod.name, sb);
1044 * TMKNOD mode/permissions have S_IFBLK/S_IFCHR/S_IFIFO
1045 * bits. The major and minor values are only meaningful
1046 * for S_IFBLK and S_IFCHR, but just decode always here.
1048 l9p_describe_lperm(" mode=", fcall->tmknod.mode, sb);
1049 sbuf_printf(sb, " major=%u minor=%u",
1050 fcall->tmknod.major, fcall->tmknod.minor);
1051 l9p_describe_ugid(" gid=", fcall->tmknod.gid, sb);
1055 l9p_describe_qid(" qid=", &fcall->rmknod.qid, sb);
1059 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1060 l9p_describe_fid(" dfid=", fcall->trename.dfid, sb);
1061 l9p_describe_name(" name=", fcall->trename.name, sb);
1068 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1072 l9p_describe_name(" target=", fcall->rreadlink.target, sb);
1076 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1077 l9p_describe_getattr_mask(fcall->tgetattr.request_mask, sb);
1081 /* Don't need to decode bits: they're implied by the output */
1082 mask = fcall->rgetattr.valid;
1083 sbuf_printf(sb, " valid=0x%016" PRIx64, mask);
1084 l9p_describe_qid(" qid=", &fcall->rgetattr.qid, sb);
1085 if (mask & L9PL_GETATTR_MODE)
1086 l9p_describe_lperm(" mode=", fcall->rgetattr.mode, sb);
1087 if (mask & L9PL_GETATTR_UID)
1088 l9p_describe_ugid(" uid=", fcall->rgetattr.uid, sb);
1089 if (mask & L9PL_GETATTR_GID)
1090 l9p_describe_ugid(" gid=", fcall->rgetattr.gid, sb);
1091 if (mask & L9PL_GETATTR_NLINK)
1092 sbuf_printf(sb, " nlink=%" PRIu64,
1093 fcall->rgetattr.nlink);
1094 if (mask & L9PL_GETATTR_RDEV)
1095 sbuf_printf(sb, " rdev=0x%" PRIx64,
1096 fcall->rgetattr.rdev);
1097 if (mask & L9PL_GETATTR_SIZE)
1098 l9p_describe_size(" size=", fcall->rgetattr.size, sb);
1099 if (mask & L9PL_GETATTR_BLOCKS)
1100 sbuf_printf(sb, " blksize=%" PRIu64 " blocks=%" PRIu64,
1101 fcall->rgetattr.blksize, fcall->rgetattr.blocks);
1102 if (mask & L9PL_GETATTR_ATIME)
1103 l9p_describe_time(sb, " atime=",
1104 fcall->rgetattr.atime_sec,
1105 fcall->rgetattr.atime_nsec);
1106 if (mask & L9PL_GETATTR_MTIME)
1107 l9p_describe_time(sb, " mtime=",
1108 fcall->rgetattr.mtime_sec,
1109 fcall->rgetattr.mtime_nsec);
1110 if (mask & L9PL_GETATTR_CTIME)
1111 l9p_describe_time(sb, " ctime=",
1112 fcall->rgetattr.ctime_sec,
1113 fcall->rgetattr.ctime_nsec);
1114 if (mask & L9PL_GETATTR_BTIME)
1115 l9p_describe_time(sb, " btime=",
1116 fcall->rgetattr.btime_sec,
1117 fcall->rgetattr.btime_nsec);
1118 if (mask & L9PL_GETATTR_GEN)
1119 sbuf_printf(sb, " gen=0x%" PRIx64, fcall->rgetattr.gen);
1120 if (mask & L9PL_GETATTR_DATA_VERSION)
1121 sbuf_printf(sb, " data_version=0x%" PRIx64,
1122 fcall->rgetattr.data_version);
1126 /* As with RGETATTR, we'll imply decode via output. */
1127 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1128 mask = fcall->tsetattr.valid;
1129 /* NB: tsetattr valid mask is only 32 bits, hence %08x */
1130 sbuf_printf(sb, " valid=0x%08" PRIx64, mask);
1131 if (mask & L9PL_SETATTR_MODE)
1132 l9p_describe_lperm(" mode=", fcall->tsetattr.mode, sb);
1133 if (mask & L9PL_SETATTR_UID)
1134 l9p_describe_ugid(" uid=", fcall->tsetattr.uid, sb);
1135 if (mask & L9PL_SETATTR_GID)
1136 l9p_describe_ugid(" uid=", fcall->tsetattr.gid, sb);
1137 if (mask & L9PL_SETATTR_SIZE)
1138 l9p_describe_size(" size=", fcall->tsetattr.size, sb);
1139 if (mask & L9PL_SETATTR_ATIME) {
1140 if (mask & L9PL_SETATTR_ATIME_SET)
1141 l9p_describe_time(sb, " atime=",
1142 fcall->tsetattr.atime_sec,
1143 fcall->tsetattr.atime_nsec);
1145 sbuf_cat(sb, " atime=now");
1147 if (mask & L9PL_SETATTR_MTIME) {
1148 if (mask & L9PL_SETATTR_MTIME_SET)
1149 l9p_describe_time(sb, " mtime=",
1150 fcall->tsetattr.mtime_sec,
1151 fcall->tsetattr.mtime_nsec);
1153 sbuf_cat(sb, " mtime=now");
1155 if (mask & L9PL_SETATTR_CTIME)
1156 sbuf_cat(sb, " ctime=now");
1162 case L9P_TXATTRWALK:
1163 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1164 l9p_describe_fid(" newfid=", fcall->txattrwalk.newfid, sb);
1165 l9p_describe_name(" name=", fcall->txattrwalk.name, sb);
1168 case L9P_RXATTRWALK:
1169 l9p_describe_size(" size=", fcall->rxattrwalk.size, sb);
1172 case L9P_TXATTRCREATE:
1173 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1174 l9p_describe_name(" name=", fcall->txattrcreate.name, sb);
1175 l9p_describe_size(" size=", fcall->txattrcreate.attr_size, sb);
1176 sbuf_printf(sb, " flags=%" PRIu32, fcall->txattrcreate.flags);
1179 case L9P_RXATTRCREATE:
1183 l9p_describe_readdir(sb, &fcall->io);
1187 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1194 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1195 /* decode better later */
1196 sbuf_printf(sb, " type=%d flags=0x%" PRIx32
1197 " start=%" PRIu64 " length=%" PRIu64
1198 " proc_id=0x%" PRIx32 " client_id=\"%s\"",
1199 fcall->tlock.type, fcall->tlock.flags,
1200 fcall->tlock.start, fcall->tlock.length,
1201 fcall->tlock.proc_id, fcall->tlock.client_id);
1205 sbuf_printf(sb, " status=%d", fcall->rlock.status);
1209 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1213 /* decode better later */
1214 sbuf_printf(sb, " type=%d "
1215 " start=%" PRIu64 " length=%" PRIu64
1216 " proc_id=0x%" PRIx32 " client_id=\"%s\"",
1217 fcall->getlock.type,
1218 fcall->getlock.start, fcall->getlock.length,
1219 fcall->getlock.proc_id, fcall->getlock.client_id);
1223 l9p_describe_fid(" dfid=", fcall->tlink.dfid, sb);
1224 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1225 l9p_describe_name(" name=", fcall->tlink.name, sb);
1232 l9p_describe_fid(" fid=", fcall->hdr.fid, sb);
1233 l9p_describe_name(" name=", fcall->tmkdir.name, sb);
1234 /* TMKDIR mode/permissions have S_IFDIR set */
1235 l9p_describe_lperm(" mode=", fcall->tmkdir.mode, sb);
1236 l9p_describe_ugid(" gid=", fcall->tmkdir.gid, sb);
1240 l9p_describe_qid(" qid=", &fcall->rmkdir.qid, sb);
1244 l9p_describe_fid(" olddirfid=", fcall->hdr.fid, sb);
1245 l9p_describe_name(" oldname=", fcall->trenameat.oldname,
1247 l9p_describe_fid(" newdirfid=", fcall->trenameat.newdirfid, sb);
1248 l9p_describe_name(" newname=", fcall->trenameat.newname,
1256 l9p_describe_fid(" dirfd=", fcall->hdr.fid, sb);
1257 l9p_describe_name(" name=", fcall->tunlinkat.name, sb);
1258 l9p_describe_unlinkat_flags(" flags=",
1259 fcall->tunlinkat.flags, sb);
1266 sbuf_printf(sb, " <missing case in %s()>", __func__);