On Thu, 22-Jan-2026 at 08:31:15 -0700, Warner Losh wrote:
> On Thu, Jan 22, 2026 at 1:46 AM Andre Albsmeier <[email protected]> wrote:
>
> > On Fri, 19-Dec-2025 at 20:37:41 +0000, Jamie Landeg-Jones wrote:
> > > void <[email protected]> wrote:
> > >
> > > >...
> > > > and so dmsg has things like
> > > >
> > > > [1353919] swp_pager_getswapspace(32): failed
> > > >
> > > > the [1353919] I guess being the timestamp.
> > > >
> > > > ...
> > > >
> > > Yes! You can get the value from sysctl kern.boottime.
> > >
> > > Here is a small program I wrote a while back, just call it
> > > as a dmesg substitute.
> > > ...
> > > Cheers, Jamie
> > >
> > > #!/bin/sh -efu
> > > set -efu
> > >
> > > boottime="$(/sbin/sysctl -n kern.boottime | /usr/local/bin/gawk '{printf
> > "%d", gensub ("^.* sec = ([1-9][0-9]*), .*$", "\\1", 1)}')"
> > >
> > > [ -z "$(printf '%s' "$boottime" | /usr/bin/egrep '^0$|^[1-9][0-9]*$')" ]
> > && { printf 'Invalid boottime retrieved.\n' >& 2; exit 1; }
> > >
> > > /sbin/dmesg "$@" | /usr/local/bin/gawk -v boottime="$boottime" '
> > >
> > > {
> > > uptime = gensub ("^\\[([1-9][0-9]*)\\] .*$", "\\1", 1)
> > > if (uptime == $0) realtime = "??? ?? ??:??;??"
> > > else realtime = strftime ("%b %d %T", uptime + boottime)
> > >
> > > print realtime " " $0
> > > }'
> >
> > FWIW, this is a patch for dmesg(1) I use. You can enable timestamp
> > conversion using -t and optionally specify a different output format
> > using -f "fmt".
> >
> > If interested for inclusion in base, I could try to re-format it
> > and come up with a manpage diff...
> >
>
> Yes. I've done a quick review inline.
Thanks...
> > --- sbin/dmesg/dmesg.c 2023-12-27 17:49:57.000000000 +0100
> > +++ sbin/dmesg/dmesg.c 2026-01-22 09:20:28.987020000 +0100
> > @@ -60,6 +60,7 @@
> > #include <unistd.h>
> > #include <vis.h>
> > #include <sys/syslog.h>
> > +#include <time.h>
> >
> > static struct nlist nl[] = {
> > #define X_MSGBUF 0
> > @@ -76,18 +77,23 @@
> > main(int argc, char *argv[])
> > {
> > struct msgbuf *bufp, cur;
> > + struct timeval boottime;
> > + char timebuf[64];
> >
>
> Why 64?
Well, any recommendation? Is the a _MAX define somewhere?
I always use 64 but if there is something better I'll use it.
>
>
> > char *bp, *ep, *memf, *nextp, *nlistf, *p, *q, *visbp;
> > + const char *timefmt = "%d %b %T";
> > kvm_t *kd;
> > + time_t time;
> > size_t buflen, bufpos;
> > long pri;
> > - int ch, clear;
> > + int ch, clear, timeconv;
> >
>
> timeconv should be a bool.
OK...
>
>
> > bool all;
> >
> > all = false;
> > clear = false;
> > + timeconv = false;
> > (void) setlocale(LC_CTYPE, "");
> > memf = nlistf = NULL;
> > - while ((ch = getopt(argc, argv, "acM:N:")) != -1)
> > + while ((ch = getopt(argc, argv, "actf:M:N:")) != -1)
> > switch(ch) {
> > case 'a':
> > all = true;
> > @@ -95,6 +101,12 @@
> > case 'c':
> > clear = true;
> > break;
> > + case 't':
> > + timeconv = true;
> > + break;
> > + case 'f':
> > + timefmt = optarg;
> > + break;
> > case 'M':
> > memf = optarg;
> > break;
> > @@ -109,6 +121,13 @@
> > if (argc != 0)
> > usage();
> >
> > + if( timeconv ) {
> >
>
> So the spacing doesn't meet style(9). "if (timeconv) {" is the preferred
> spacing.
Yes, that's why I offered to re-format it...
>
>
> > + int mib[6] = { CTL_KERN, KERN_BOOTTIME };
> > + size_t l = sizeof boottime;
> >
>
> sizeof(boottime) is the preferred spelling here.
>
>
> > + if (sysctl(mib, 2, &boottime, &l, 0, 0) < 0)
> > + err(1, "sysctl kern.boottime");
> > + }
> > +
> > if (memf == NULL) {
> > /*
> > * Running kernel. Use sysctl. This gives an unwrapped
> > buffer
> > @@ -200,7 +219,22 @@
> > }
> >
> > (void)strvisx(visbp, p, nextp - p, 0);
> > - (void)printf("%s", visbp);
> > + bufpos = strspn( visbp+1, "0123456789" ) + 1;
> >
>
> No check for overflow here. *bufpos may point to a NUL and +1 will point
> it past that NULL.
bufpos is no pointer but size_t. visbp[ bufpos ] will never point past
'\0' as I start at visbp + 1 for the strspn().
But the test of visbp[ bufpos+1 ] below is not OK. I'll fix that...
> It shouldn't, but it might. And you should do something more like
>
> if (!timeconv) {
> <the existing printf>;
> } else {
> decode the buffer
> }
I din't want to duplicate <the existing printf> too often in case
timeconv is desired but fails later for whatever reasons. So would
is the recommendation here?
1. Whenever it fails, do <the existing printf> and continue?
2. Place <the existing printf> at the end and "goto" it?
3. ??
>
> But you should check things in the right order so you can't overflow. Your
> code already has a fallback for printing things...
>
> *ALSO* The parsing is wrong. When show_timestamp=2 it will have a
> fractional part (so .xxxx) that should be parsed as well. This also throws
> off the math that just adds to the second of time timeval.
Right, the conversion gets aborted in this case (I never used
show_timestamp=2 ;-)). I'll have a look at it...
>
> > + if( timeconv != true
> > + || bufpos < 2
> > + || visbp[0] != '['
> > + || visbp[bufpos] != ']'
> > + || visbp[bufpos+1] != ' ' ) {
> > + (void)printf("%s", visbp);
> > + continue;
> > + }
> > +
> > + visbp[bufpos] = '\0';
> > + time = boottime.tv_sec + strtoull( visbp+1, NULL, 10 );
> > + if( strftime( timebuf, sizeof timebuf, timefmt, localtime(
> > &time ) ) != 0 )
> >
>
> Same spacing. comment about parens. And note that we're strongly
> encouraging {} even for single line statements.
OK...
> ...
> So that's my feedback on the first round of patches. You should do a github
> pull request
> or a Phabricator review. Do not put this in a bugzilla bug. Bugzilla is not
> a code review tool
> and I suspect that feedback on the revision will be needed (if nothing else
> than for the man
> page that we've not seen yet). github is likely easiest for you, and I'll
> keep an eye out there.
> Phabricator is a lot more work to get started. If you are going to do a
> bunch of reviews, it
> may make sense to climb the hill (or for other parts of the code whose
> maintainers don't do
> github). If it's just this one, and you have a github account, I'd
> recommend that as the path
I used Phabricator once (https://reviews.freebsd.org/D46313) but I think
I'll follow your advice and try the github way...
-Andre