Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 08 Jan 2026 06:24:38 +0000
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: cd1aa5f9917c - main - tools/cam: Start to add the testing tools for CAM
Message-ID:  <695f4da6.36269.3bd4f8ad@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=cd1aa5f9917cc7de255e854954c818e5ef3e9c9b

commit cd1aa5f9917cc7de255e854954c818e5ef3e9c9b
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-01-08 06:20:34 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-01-08 06:20:34 +0000

    tools/cam: Start to add the testing tools for CAM
    
    Create a directory for testing tools arond CAM. These are snippets of
    what will eventually be camio. At the moment, it was written using fbt
    traces. This is OK, but fragile, so they need to be re-written with the
    cam provider. cam_all_but_scsi.d is the first step. It shows how to do
    this with the new cam dtrace provider.
    
    Sponsored by:           Netflix
    Reviewed by:            adrian
    Differential Revision:  https://reviews.freebsd.org/D54472
---
 tools/cam/README             |  9 +++++
 tools/cam/cam_all_but_scsi.d | 89 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/tools/cam/README b/tools/cam/README
new file mode 100644
index 000000000000..fd93ccd15e1f
--- /dev/null
+++ b/tools/cam/README
@@ -0,0 +1,9 @@
+This directory has snippets of what will eventually become camio. This program
+can take an expression for the types of things to trace, and then custom write a
+dtrace script to do that.
+
+camio is a d-traced tcpdump-like program for examining CAM traffic (and
+therefore I/O and other traffic to storage media) that written during covid, but
+with fbp providers that recent clang optimizations make unuseable, hence the
+shift to the cam provider, but retooling them and finishing the grammar will
+take some time (but these scripts are useful today).
diff --git a/tools/cam/cam_all_but_scsi.d b/tools/cam/cam_all_but_scsi.d
new file mode 100644
index 000000000000..a20d7fa0cba9
--- /dev/null
+++ b/tools/cam/cam_all_but_scsi.d
@@ -0,0 +1,89 @@
+#!/usr/sbin/dtrace -s
+
+/* Sample use of the cam dtrace provider */
+
+/*
+ * Trace all the non I/O commands flowing through CAM
+ */
+
+dtrace:::BEGIN
+{
+}
+
+/*
+ * There's two choke points in CAM. We can intercept the request on the way down
+ * in xpt_action, just before it's sent to the SIM. This can be a good place to
+ * see what's going on before it happens. However, most I/O happens quite
+ * quickly, this isn't much of an advantage. The other place is on completion
+ * when the transaction is finally done. The retry mechanism is built into the
+ * periph driver, which is responsible for submitting the request.
+ *
+ * cam::xpt_action is a single logical point that handles both xpt_action and
+ * xpt_action_direct. Thie example hooks into it. The style is funky because
+ * D doesn't have looping or generalized if constructs.
+ *
+ * The 'trace' context local variable controls printing of different types
+ * of results. This is all controlled by camio.lua.
+ */
+
+
+/*
+ * CAM queues a CCB to the SIM in xpt_action. Save interesting bits
+ * for later winnowing.
+ */
+/* fbt::xpt_action_default:entry */
+cam::xpt:action
+{
+	this->ccb = ((union ccb *)arg0);
+	this->func = this->ccb->ccb_h.func_code & 0xff;
+	this->periph = this->ccb->ccb_h.path->periph;
+	this->bus = this->ccb->ccb_h.path->bus;
+	this->target = this->ccb->ccb_h.path->target;
+	this->device = this->ccb->ccb_h.path->device;
+	this->trace = 1;
+}
+
+/*
+ * Omit the I/O CCBs. Go ahead and pass the other semi I/O enclosure
+ * commands, though.
+ */
+cam::xpt:action
+/this->func == XPT_SCSI_IO || this->func == XPT_NVME_IO || this->func == XPT_NVME_ADMIN || this->func == XPT_ATA_IO/
+{
+	this->trace = 0;
+}
+
+/*
+ * Print out the non I/O and non ASYNC commands here.
+ */
+cam::xpt:action
+/this->trace && this->func != XPT_ASYNC/
+{
+	printf("(%s%d:%s%d:%d:%d:%d): %s",
+	    this->periph == NULL ? "noperiph" : stringof(this->periph->periph_name),
+	    this->periph == NULL ? 0 : this->periph->unit_number,
+	    this->bus == NULL ? "nobus" : this->bus->sim->sim_name,
+	    this->bus == NULL ? 0 : this->bus->sim->unit_number,
+	    this->bus == NULL ? 0 : this->bus->sim->bus_id,
+	    this->target == NULL ? 0 : this->target->target_id,
+	    this->device == NULL ? 0 : this->device->lun_id,
+	    xpt_action_string[this->func]);
+}
+
+/*
+ * For async calls, print out the async message type.
+ */
+cam::xpt:action
+/this->trace && this->func == XPT_ASYNC/
+{
+	printf("(%s%d:%s%d:%d:%d:%d): %s %s",
+	    this->periph == NULL ? "noperiph" : stringof(this->periph->periph_name),
+	    this->periph == NULL ? 0 : this->periph->unit_number,
+	    this->bus == NULL ? "nobus" : this->bus->sim->sim_name,
+	    this->bus == NULL ? 0 : this->bus->sim->unit_number,
+	    this->bus == NULL ? 0 : this->bus->sim->bus_id,
+	    this->target == NULL ? 0 : this->target->target_id,
+	    this->device == NULL ? 0 : this->device->lun_id,
+	    xpt_action_string[this->func],
+	    xpt_async_string[this->ccb->casync.async_code]);
+}


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?695f4da6.36269.3bd4f8ad>