From owner-svn-src-stable@freebsd.org Wed Jan 2 19:46:02 2019 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 35F2C142E346; Wed, 2 Jan 2019 19:46:02 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id CB9F76D47B; Wed, 2 Jan 2019 19:46:01 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BDF16E651; Wed, 2 Jan 2019 19:46:01 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x02Jk1JP086829; Wed, 2 Jan 2019 19:46:01 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x02Jk13v086828; Wed, 2 Jan 2019 19:46:01 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201901021946.x02Jk13v086828@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 2 Jan 2019 19:46:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r342705 - stable/12/usr.bin/ktrdump X-SVN-Group: stable-12 X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: stable/12/usr.bin/ktrdump X-SVN-Commit-Revision: 342705 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: CB9F76D47B X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.970,0]; NEURAL_HAM_LONG(-1.00)[-0.998,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Jan 2019 19:46:02 -0000 Author: jhb Date: Wed Jan 2 19:46:01 2019 New Revision: 342705 URL: https://svnweb.freebsd.org/changeset/base/342705 Log: MFC 339620: Add a "live" mode to ktrdump. Support a "live" mode in ktrdump enabled via the -l flag. In this mode, ktrdump polls the kernel's trace buffer periodically (currently hardcoded as a 50 millisecond interval) and dumps any newly added entries. Fancier logic for the timeout (e.g. a command line option or some kind of backoff based on the time since the last entry) can be added later as the need arises. While here, fix some bugs from when this was Capsicum-ized: - Use caph_limit_stream() for the output stream so that isatty() works and the output can be line-buffered (especially useful for live mode). - Use caph_limit_stderr() to permit error messages to be displayed if an error occurs after cap_enter(). Modified: stable/12/usr.bin/ktrdump/ktrdump.8 stable/12/usr.bin/ktrdump/ktrdump.c Directory Properties: stable/12/ (props changed) Modified: stable/12/usr.bin/ktrdump/ktrdump.8 ============================================================================== --- stable/12/usr.bin/ktrdump/ktrdump.8 Wed Jan 2 19:11:49 2019 (r342704) +++ stable/12/usr.bin/ktrdump/ktrdump.8 Wed Jan 2 19:46:01 2019 (r342705) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 6, 2015 +.Dd October 22, 2018 .Dt KTRDUMP 8 .Os .Sh NAME @@ -33,7 +33,7 @@ .Nd print kernel ktr trace buffer .Sh SYNOPSIS .Nm -.Op Fl cfqrtH +.Op Fl cflqrtH .Op Fl i Ar ktrfile .Op Fl M Ar core .Op Fl N Ar system @@ -47,6 +47,9 @@ The following options are available: .Bl -tag -width ".Fl i Ar ktrfile" .It Fl c Print the CPU number that each entry was logged from. +.It Fl l +Poll the kernel ktr trace buffer periodically dumping any new events after +each poll. .It Fl f Print the file and line number that each entry was logged from. .It Fl q Modified: stable/12/usr.bin/ktrdump/ktrdump.c ============================================================================== --- stable/12/usr.bin/ktrdump/ktrdump.c Wed Jan 2 19:11:49 2019 (r342704) +++ stable/12/usr.bin/ktrdump/ktrdump.c Wed Jan 2 19:46:01 2019 (r342705) @@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$"); #define SBUFLEN 128 #define USAGE \ - "usage: ktrdump [-cfqrtH] [-i ktrfile] [-M core] [-N system] [-o outfile]\n" + "usage: ktrdump [-cflqrtH] [-i ktrfile] [-M core] [-N system] [-o outfile]\n" static void usage(void); @@ -65,6 +65,7 @@ static struct nlist nl[] = { static int cflag; static int fflag; +static int lflag; static int Mflag; static int Nflag; static int qflag; @@ -111,7 +112,7 @@ main(int ac, char **av) * Parse commandline arguments. */ out = stdout; - while ((c = getopt(ac, av, "cfqrtHe:i:m:M:N:o:")) != -1) + while ((c = getopt(ac, av, "cflqrtHe:i:m:M:N:o:")) != -1) switch (c) { case 'c': cflag = 1; @@ -136,6 +137,9 @@ main(int ac, char **av) err(1, "unable to limit rights for %s", optarg); break; + case 'l': + lflag = 1; + break; case 'M': case 'm': if (strlcpy(corefile, optarg, sizeof(corefile)) @@ -169,9 +173,10 @@ main(int ac, char **av) if (ac != 0) usage(); - cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); - if (cap_rights_limit(fileno(out), &rights) < 0 && errno != ENOSYS) + if (caph_limit_stream(fileno(out), CAPH_WRITE) < 0) err(1, "unable to limit rights for %s", outfile); + if (caph_limit_stderr() < 0) + err(1, "unable to limit rights for stderr"); /* * Open our execfile and corefile, resolve needed symbols and read in @@ -258,15 +263,29 @@ main(int ac, char **av) fprintf(out, "\n"); } + tlast = -1; /* * Now tear through the trace buffer. + * + * In "live" mode, find the oldest entry (first non-NULL entry + * after index2) and walk forward. Otherwise, start with the + * most recent entry and walk backwards. */ if (!iflag) { - i = index - 1; - if (i < 0) - i = entries - 1; + if (lflag) { + i = index2 + 1 % entries; + while (buf[i].ktr_desc == NULL && i != index) { + i++; + if (i == entries) + i = 0; + } + } else { + i = index - 1; + if (i < 0) + i = entries - 1; + } } - tlast = -1; +dump_entries: for (;;) { if (buf[i].ktr_desc == NULL) break; @@ -338,14 +357,40 @@ next: if ((c = *p++) == '\0') * 'index2' were in flux while the KTR buffer was * being copied to userspace we don't dump them. */ - if (i == index2) - break; - if (--i < 0) - i = entries - 1; + if (lflag) { + if (++i == entries) + i = 0; + if (i == index) + break; + } else { + if (i == index2) + break; + if (--i < 0) + i = entries - 1; + } } else { if (++i == entries) break; } + } + + /* + * In "live" mode, poll 'ktr_idx' periodically and dump any + * new entries since our last pass through the ring. + */ + if (lflag && !iflag) { + while (index == index2) { + usleep(50 * 1000); + if (kvm_read(kd, nl[2].n_value, &index2, + sizeof(index2)) == -1) + errx(1, "%s", kvm_geterr(kd)); + } + i = index; + index = index2; + if (kvm_read(kd, bufptr, buf, sizeof(*buf) * entries) == -1 || + kvm_read(kd, nl[2].n_value, &index2, sizeof(index2)) == -1) + errx(1, "%s", kvm_geterr(kd)); + goto dump_entries; } return (0);