diff --git a/src/libdiod/diod_log.c b/src/libdiod/diod_log.c index e5a48ce0..1140c841 100644 --- a/src/libdiod/diod_log.c +++ b/src/libdiod/diod_log.c @@ -111,9 +111,19 @@ _verr (int errnum, const char *fmt, va_list ap) } void +diod_log_buf (const char *buf) +{ + if (logf && buf) { + fputs (buf, logf); + fputc ('\n', logf); + fflush (logf); + } +} + +static void diod_log_msg (const char *fmt, va_list ap) { - char buf[1024]; /* make it large enough for protocol debug output */ + char buf[1024]; if (logf) { vsnprintf (buf, sizeof (buf), fmt, ap); /* ignore overflow */ diff --git a/src/libdiod/diod_log.h b/src/libdiod/diod_log.h index d2c5b0c6..909ee8cd 100644 --- a/src/libdiod/diod_log.h +++ b/src/libdiod/diod_log.h @@ -17,7 +17,7 @@ void diod_log_init (char *p); void diod_log_fini (void); void diod_log_set_dest (char *dest); char *diod_log_get_dest (void); -void diod_log_msg (const char *fmt, va_list ap); +void diod_log_buf (const char *buf); void err_exit (const char *fmt, ...) __attribute__ ((format (printf, 1, 2), noreturn)); diff --git a/src/libdiod/diod_ops.c b/src/libdiod/diod_ops.c index daa19724..d1336d08 100644 --- a/src/libdiod/diod_ops.c +++ b/src/libdiod/diod_ops.c @@ -159,7 +159,7 @@ diod_init (Npsrv *srv) { srv->msize = DIOD_SRV_MAX_MSIZE; srv->fiddestroy = diod_fiddestroy; - srv->logmsg = diod_log_msg; + srv->logmsg = diod_log_buf; srv->remapuser = diod_remapuser; srv->exportok = diod_exportok; srv->auth_required = diod_auth_required; @@ -218,11 +218,12 @@ diod_ustat2qid (struct stat *st, Npqid *qid) qid->path = st->st_ino; //qid->version = st->st_mtime ^ (st->st_size << 8); qid->version = 0; - qid->type = 0; if (S_ISDIR(st->st_mode)) - qid->type |= Qtdir; - if (S_ISLNK(st->st_mode)) - qid->type |= Qtsymlink; + qid->type = Qtdir; + else if (S_ISLNK(st->st_mode)) + qid->type = Qtsymlink; + else + qid->type = Qtfile; } static void @@ -231,11 +232,12 @@ _dirent2qid (struct dirent *d, Npqid *qid) NP_ASSERT (d->d_type != DT_UNKNOWN); qid->path = d->d_ino; qid->version = 0; - qid->type = 0; if (d->d_type == DT_DIR) - qid->type |= Qtdir; - if (d->d_type == DT_LNK) - qid->type |= Qtsymlink; + qid->type = Qtdir; + else if (d->d_type == DT_LNK) + qid->type = Qtsymlink; + else + qid->type = Qtfile; } int diff --git a/src/libnpclient/test/simple.c b/src/libnpclient/test/simple.c index b44f4558..6fd8fd08 100644 --- a/src/libnpclient/test/simple.c +++ b/src/libnpclient/test/simple.c @@ -29,11 +29,11 @@ #define TEST_MSIZE 8192 -static void diag_logger (const char *fmt, va_list ap) +static void diag_logger (const char *buf) { - char buf[1024]; /* make it large enough for protocol debug output */ - vsnprintf (buf, sizeof (buf), fmt, ap); /* ignore overflow */ - fprintf (stderr, "# %s\n", buf); + fputs ("# ", stderr); + fputs (buf, stderr); + fputc ('\n', stderr); } static void check_data_trimmed (const char *name, const char *s, const char *expect) diff --git a/src/libnpfs/conn.c b/src/libnpfs/conn.c index c678b244..dc6ef5a5 100644 --- a/src/libnpfs/conn.c +++ b/src/libnpfs/conn.c @@ -122,21 +122,34 @@ np_conn_destroy(Npconn *conn) static void _debug_trace (Npsrv *srv, Npfcall *fc) { - if ((srv->flags & SRV_FLAGS_DEBUG_9PTRACE)) { - char s[512]; - static struct timeval b = { 0, 0 }; - struct timeval a, c; + if ((srv->flags & SRV_FLAGS_DEBUG_9PTRACE) && srv->logmsg) { + xpthread_mutex_lock (&srv->tracebuf_lock); + + char *buf = srv->tracebuf; + size_t size = srv->tracebuf_size; - np_snprintfcall(s, sizeof (s), fc); if ((srv->flags & SRV_FLAGS_DEBUG_TIMES)) { + static struct timeval b = { 0, 0 }; + struct timeval a, c; + int n; + if (b.tv_sec == 0) (void)gettimeofday(&b, NULL); - (void)gettimeofday(&a, NULL); - timersub(&a, &b, &c); - np_logmsg(srv, "[%"PRIdMAX".%-3"PRIdMAX"] %s", - (intmax_t)c.tv_sec, (intmax_t)c.tv_usec/1000, s); - } else - np_logmsg(srv, "%s", s); + (void)gettimeofday (&a, NULL); + timersub (&a, &b, &c); + n = snprintf (buf, size, "[%"PRIdMAX".%-3"PRIdMAX"] ", + (intmax_t)c.tv_sec, + (intmax_t)c.tv_usec/1000); + if (n < size) { + buf += n; + size -= n; + } + } + np_snprintfcall (buf, size, fc); + + srv->logmsg (srv->tracebuf); + + xpthread_mutex_unlock (&srv->tracebuf_lock); } } diff --git a/src/libnpfs/fmt.c b/src/libnpfs/fmt.c index ea61d1d9..d2b550f0 100644 --- a/src/libnpfs/fmt.c +++ b/src/libnpfs/fmt.c @@ -11,6 +11,7 @@ #if HAVE_CONFIG_H #include "config.h" #endif +#include #include #include #include @@ -33,16 +34,21 @@ np_printqid(char *s, int len, Npqid *q) if (q->type & Qtdir) buf[n++] = 'd'; + else if (q->type & Qtauth) + buf[n++] = 'A'; + else if (q->type & Qtsymlink) + buf[n++] = 'L'; + else if (q->type & Qtlink) + buf[n++] = 'l'; + else /* Qtfile = 0 */ + buf[n++] = 'f'; + if (q->type & Qtappend) buf[n++] = 'a'; - if (q->type & Qtauth) - buf[n++] = 'A'; if (q->type & Qtexcl) - buf[n++] = 'l'; + buf[n++] = 'x'; if (q->type & Qttmp) buf[n++] = 't'; - if (q->type & Qtsymlink) - buf[n++] = 'L'; buf[n] = '\0'; spf (s, len, "(%.16"PRIx64" %x '%s')", q->path, q->version, buf); @@ -84,13 +90,33 @@ np_timestr(const u64 sec, const u64 nsec) return s; } +static void +np_printdentry(char *s, int len, Npqid *qid, char *dname, u8 type, u64 off) +{ + spf (s, len, "\n"); + np_printqid (s, len, qid); + spf (s, len, " %u %-21ju %s", type, (uintmax_t)off, dname); +} + static void np_printdents(char *s, int len, u8 *buf, int buflen) { - if (buflen > 0) - spf (s, len, "\n"); - /* FIXME: decode directory entries here */ - np_sndump(s, len, buf, buflen < 64 ? buflen : 64); + int res; + + do { + Npqid qid; + char dname[PATH_MAX + 1]; + u64 offset; + u8 type; + + res = np_deserialize_p9dirent (&qid, &offset, &type, dname, + sizeof (dname), buf, buflen); + if (res > 0) { + np_printdentry (s, len, &qid, dname, type, offset); + buf += res; + buflen -= res; + } + } while (res > 0); } static void diff --git a/src/libnpfs/npfs.h b/src/libnpfs/npfs.h index 4035d89c..dbc5d8f4 100644 --- a/src/libnpfs/npfs.h +++ b/src/libnpfs/npfs.h @@ -270,7 +270,7 @@ struct Npsrv { void* srvaux; Npfile* ctlroot; void* usercache; - void (*logmsg)(const char *, va_list); + void (*logmsg)(const char *buf); int (*remapuser)(Npfid *fid); int (*auth_required)(Npstr *, u32, Npstr *); int (*exportok)(Npfid *fid); @@ -278,6 +278,10 @@ struct Npsrv { Npauth* auth; int flags; + char *tracebuf; + size_t tracebuf_size; + pthread_mutex_t tracebuf_lock; + void (*fiddestroy)(Npfid *); Npfcall* (*version)(Npconn *conn, u32 msize, Npstr *version); diff --git a/src/libnpfs/npstring.c b/src/libnpfs/npstring.c index 896250f0..6ed093eb 100644 --- a/src/libnpfs/npstring.c +++ b/src/libnpfs/npstring.c @@ -110,12 +110,12 @@ vaspf (char **sp, int *lp, const char *fmt, va_list ap) int aspf (char **sp, int *lp, const char *fmt, ...) { - va_list ap; - int n; + va_list ap; + int n; - va_start (ap, fmt); - n = vaspf (sp, lp, fmt, ap); - va_end (ap); + va_start (ap, fmt); + n = vaspf (sp, lp, fmt, ap); + va_end (ap); return n; } @@ -123,16 +123,17 @@ aspf (char **sp, int *lp, const char *fmt, ...) void spf (char *s, int len, const char *fmt, ...) { - va_list ap; - int n = strlen (s); + va_list ap; + int n = strlen (s); - len -= n; - s += n; - NP_ASSERT (len > 0); + len -= n; + s += n; + NP_ASSERT (len > 0); - va_start (ap, fmt); - vsnprintf (s, len, fmt, ap); /* ignore overflow */ - va_end (ap); + va_start (ap, fmt); + if (vsnprintf (s, len, fmt, ap) >= len) + strncpy (&s[len - 4], "...", 4); + va_end (ap); } #if NPSTATS_RWCOUNT_BINS != 12 diff --git a/src/libnpfs/srv.c b/src/libnpfs/srv.c index 14ab5e21..6a809232 100644 --- a/src/libnpfs/srv.c +++ b/src/libnpfs/srv.c @@ -70,6 +70,12 @@ np_srv_create(int nwthread, int flags) goto error; np_tpool_incref (srv->tpool); np_assert_srv = srv; + if ((flags & SRV_FLAGS_DEBUG_9PTRACE)) { + pthread_mutex_init (&srv->tracebuf_lock, NULL); + srv->tracebuf_size = 1048576; + if (!(srv->tracebuf = calloc (1, srv->tracebuf_size))) + goto error; + } return srv; error: if (srv) @@ -102,6 +108,7 @@ np_srv_destroy(Npsrv *srv) np_usercache_destroy (srv); np_ctl_finalize (srv); np_assert_srv = NULL; + free (srv->tracebuf); free (srv); } @@ -869,10 +876,13 @@ void np_logmsg(Npsrv *srv, const char *fmt, ...) { va_list ap; + char buf[1024]; va_start (ap, fmt); - if (srv->logmsg) - srv->logmsg (fmt, ap); + if (srv->logmsg) { + (void)vsnprintf (buf, sizeof (buf), fmt, ap); + srv->logmsg (buf); + } va_end (ap); } diff --git a/src/libnpfs/test/fidpool.c b/src/libnpfs/test/fidpool.c index 40870a67..22cfd880 100644 --- a/src/libnpfs/test/fidpool.c +++ b/src/libnpfs/test/fidpool.c @@ -16,11 +16,11 @@ #include "src/libtap/tap.h" -void diag_logger (const char *fmt, va_list ap) +void diag_logger (const char *buf) { - char buf[1024]; /* make it large enough for protocol debug output */ - vsnprintf (buf, sizeof (buf), fmt, ap); /* ignore overflow */ - fprintf (stderr, "# %s\n", buf); + fputs ("# ", stderr); + fputs (buf, stderr); + fputc ('\n', stderr); }