[DTrace-devel] [PATCH v5 1/5] Implement setopt()

Kris Van Hees kris.van.hees at oracle.com
Thu Sep 8 20:30:03 UTC 2022


The basic mechanics of the setopt() action are implemented in this
patch.  Each dynamic runtime option that can be set using setopt()
must provide support for it.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_cg.c                             | 11 ++++
 libdtrace/dt_consume.c                        | 53 +++++++++++++++----
 .../unittest/actions/setopt/err.D_PROTO_ARG.d | 19 +++++++
 .../unittest/actions/setopt/err.D_PROTO_ARG.r |  4 ++
 .../setopt/err.D_PROTO_LEN.missing_arg.d      | 19 +++++++
 .../setopt/err.D_PROTO_LEN.missing_arg.r      |  2 +
 .../setopt/err.D_PROTO_LEN.too_many_args.d}   |  6 +--
 .../setopt/err.D_PROTO_LEN.too_many_args.r    |  2 +
 .../{misc => actions/setopt}/tst.badopt.d     |  5 +-
 test/unittest/actions/setopt/tst.badopt.r     | 16 ++++++
 test/unittest/misc/tst.badopt.r               | 16 ------
 .../unittest/setopt/err.D_PROTO_LEN.toomany.r |  2 -
 12 files changed, 121 insertions(+), 34 deletions(-)
 create mode 100644 test/unittest/actions/setopt/err.D_PROTO_ARG.d
 create mode 100644 test/unittest/actions/setopt/err.D_PROTO_ARG.r
 create mode 100644 test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.d
 create mode 100644 test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.r
 rename test/unittest/{setopt/err.D_PROTO_LEN.toomany.d => actions/setopt/err.D_PROTO_LEN.too_many_args.d} (67%)
 create mode 100644 test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.r
 rename test/unittest/{misc => actions/setopt}/tst.badopt.d (74%)
 create mode 100644 test/unittest/actions/setopt/tst.badopt.r
 delete mode 100644 test/unittest/misc/tst.badopt.r
 delete mode 100644 test/unittest/setopt/err.D_PROTO_LEN.toomany.r

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index cb51c474..06ab0974 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -1751,6 +1751,17 @@ dt_cg_act_raise(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 static void
 dt_cg_act_setopt(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
 {
+	dt_node_t	*opt = dnp->dn_args;
+	dt_node_t	*val = opt->dn_list;
+
+	TRACE_REGSET("setopt(): Begin ");
+	dt_cg_store_val(pcb, opt, DTRACEACT_LIBACT, NULL, DT_ACT_SETOPT);
+
+	/* If no value is given, we default to NULL. */
+	if (val == NULL)
+		val = dt_node_int(0);
+	dt_cg_store_val(pcb, val, DTRACEACT_LIBACT, NULL, DT_ACT_SETOPT);
+	TRACE_REGSET("setopt(): End   ");
 }
 
 /*
diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index 44d7e935..932b6cb4 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -2150,6 +2150,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 		     void *arg)
 {
 	dtrace_epid_t		epid;
+	dtrace_datadesc_t	*epd;
 	dt_spec_buf_t		tmpl;
 	dt_spec_buf_t		*dtsb;
 	int			specid;
@@ -2170,11 +2171,12 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 	pdat->dtpda_data = data;
 
 	rval = dt_epid_lookup(dtp, epid, &pdat->dtpda_ddesc,
-			      &pdat->dtpda_pdesc);
+					 &pdat->dtpda_pdesc);
 	if (rval != 0)
 		return dt_set_errno(dtp, EDT_BADEPID);
 
-	if (pdat->dtpda_ddesc->dtdd_uarg != DT_ECB_DEFAULT) {
+	epd = pdat->dtpda_ddesc;
+	if (epd->dtdd_uarg != DT_ECB_DEFAULT) {
 		rval = dt_handle(dtp, pdat);
 
 		if (rval == DTRACE_CONSUME_NEXT)
@@ -2222,8 +2224,8 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 				return -1;
 		}
 
-		if (dt_spec_buf_add_data(dtp, dtsb, epid, pdat->dtpda_cpu,
-					 pdat->dtpda_ddesc, data, size) == NULL)
+		if (dt_spec_buf_add_data(dtp, dtsb, epid, pdat->dtpda_cpu, epd,
+					 data, size) == NULL)
 			return -1;
 
 		return DTRACE_WORKSTATUS_OKAY;
@@ -2242,11 +2244,11 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 	 */
 	commit_discard_seen = 0;
 	only_commit_discards = 1;
-	for (i = 0; !committing && i < pdat->dtpda_ddesc->dtdd_nrecs; i++) {
+	for (i = 0; !committing && i < epd->dtdd_nrecs; i++) {
 		dtrace_recdesc_t	*rec;
 		dtrace_actkind_t	act;
 
-		rec = &pdat->dtpda_ddesc->dtdd_recs[i];
+		rec = &epd->dtdd_recs[i];
 		act = rec->dtrd_action;
 
 		if (act == DTRACEACT_COMMIT || act == DTRACEACT_DISCARD) {
@@ -2294,7 +2296,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 	 *
 	 * FIXME: This code is temporary.
 	 */
-	for (i = 0; i < pdat->dtpda_ddesc->dtdd_nrecs; i++) {
+	for (i = 0; i < epd->dtdd_nrecs; i++) {
 		int			n;
 		dtrace_recdesc_t	*rec;
 		dtrace_actkind_t	act;
@@ -2304,7 +2306,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 			    const void *buf, size_t) = NULL;
 		caddr_t			recdata;
 
-		rec = &pdat->dtpda_ddesc->dtdd_recs[i];
+		rec = &epd->dtdd_recs[i];
 		act = rec->dtrd_action;
 		pdat->dtpda_data = recdata = data + rec->dtrd_offset;
 
@@ -2316,7 +2318,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 
 				continue;
 			case DT_ACT_NORMALIZE:
-				if (i == pdat->dtpda_ddesc->dtdd_nrecs - 1)
+				if (i == epd->dtdd_nrecs - 1)
 					return dt_set_errno(dtp, EDT_BADNORMAL);
 
 				if (dt_normalize(dtp, data, rec) != 0)
@@ -2332,6 +2334,37 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 				ftruncate(fileno(fp), 0);
 				fseeko(fp, 0, SEEK_SET);
 
+				continue;
+			case DT_ACT_SETOPT: {
+				caddr_t			opt = recdata;
+				caddr_t			val;
+				dtrace_recdesc_t	*vrec;
+
+				if (i == epd->dtdd_nrecs - 1)
+					return dt_set_errno(dtp, EDT_BADSETOPT);
+
+				vrec = &epd->dtdd_recs[++i];
+				if (vrec->dtrd_action != act &&
+				    vrec->dtrd_arg != rec->dtrd_arg)
+					return dt_set_errno(dtp, EDT_BADSETOPT);
+
+				/*
+				 * Two possibilities: either a string was
+				 * passed (alignment 1), or a uint32_t was
+				 * passed (alignment 4).  The latter indicates
+				 * a toggle option (no value).
+				 */
+				if (vrec->dtrd_alignment == 1)
+					val = data + vrec->dtrd_offset;
+				else
+					val = "1";
+
+				if (dt_setopt(dtp, pdat, opt, val) != 0)
+					return DTRACE_WORKSTATUS_ERROR;
+
+				continue;
+			}
+			default:
 				continue;
 			}
 		}
@@ -2443,7 +2476,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
 		if (func) {
 			int	nrecs;
 
-			nrecs = pdat->dtpda_ddesc->dtdd_nrecs - i;
+			nrecs = epd->dtdd_nrecs - i;
 			n = (*func)(dtp, fp, rec->dtrd_format, pdat,
 				    rec, nrecs, data, size);
 			if (n < 0)
diff --git a/test/unittest/actions/setopt/err.D_PROTO_ARG.d b/test/unittest/actions/setopt/err.D_PROTO_ARG.d
new file mode 100644
index 00000000..c327bebb
--- /dev/null
+++ b/test/unittest/actions/setopt/err.D_PROTO_ARG.d
@@ -0,0 +1,19 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: The setopt() action requires a string as first argument.
+ *
+ * SECTION: Actions and Subroutines/setopt()
+ *
+ */
+
+BEGIN
+{
+	setopt(1);
+	exit(0);
+}
diff --git a/test/unittest/actions/setopt/err.D_PROTO_ARG.r b/test/unittest/actions/setopt/err.D_PROTO_ARG.r
new file mode 100644
index 00000000..6c57ed13
--- /dev/null
+++ b/test/unittest/actions/setopt/err.D_PROTO_ARG.r
@@ -0,0 +1,4 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/actions/setopt/err.D_PROTO_ARG.d: [D_PROTO_ARG] line 17: setopt( ) argument #1 is incompatible with prototype:
+	prototype: char *
+	 argument: int
diff --git a/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.d b/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.d
new file mode 100644
index 00000000..74d57271
--- /dev/null
+++ b/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.d
@@ -0,0 +1,19 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Licensed under the Universal Permissive License v 1.0 as shown at
+ * http://oss.oracle.com/licenses/upl.
+ */
+
+/*
+ * ASSERTION: Test setop() with no arguments.
+ *
+ * SECTION: Actions and Subroutines/setopt()
+ *
+ */
+
+BEGIN
+{
+	setopt();
+	exit(0);
+}
diff --git a/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.r b/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.r
new file mode 100644
index 00000000..4c0a6c60
--- /dev/null
+++ b/test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/actions/setopt/err.D_PROTO_LEN.missing_arg.d: [D_PROTO_LEN] line 17: setopt( ) prototype mismatch: 0 args passed, at least 1 expected
diff --git a/test/unittest/setopt/err.D_PROTO_LEN.toomany.d b/test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.d
similarity index 67%
rename from test/unittest/setopt/err.D_PROTO_LEN.toomany.d
rename to test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.d
index f8bf47d6..b70d554c 100644
--- a/test/unittest/setopt/err.D_PROTO_LEN.toomany.d
+++ b/test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.d
@@ -1,13 +1,12 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
 
 /*
- * ASSERTION:
- *  Test setop() with too many arguments.
+ * ASSERTION: Test setop() with too many arguments.
  *
  * SECTION: Actions and Subroutines/setopt()
  *
@@ -16,4 +15,5 @@
 BEGIN
 {
 	setopt("bufsize", "20m", "dummy");
+	exit(0);
 }
diff --git a/test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.r b/test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.r
new file mode 100644
index 00000000..6ea249c5
--- /dev/null
+++ b/test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/actions/setopt/err.D_PROTO_LEN.too_many_args.d: [D_PROTO_LEN] line 17: setopt( ) prototype mismatch: 3 args passed, at most 2 expected
diff --git a/test/unittest/misc/tst.badopt.d b/test/unittest/actions/setopt/tst.badopt.d
similarity index 74%
rename from test/unittest/misc/tst.badopt.d
rename to test/unittest/actions/setopt/tst.badopt.d
index c5d4d746..05b5687c 100644
--- a/test/unittest/misc/tst.badopt.d
+++ b/test/unittest/actions/setopt/tst.badopt.d
@@ -1,10 +1,9 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 #pragma D option quiet
 
@@ -14,7 +13,7 @@ BEGIN
 	setopt("Harding");
 	setopt("Hoover");
 	setopt("Bush");
-	setopt("quiet", "hell no");
+	setopt("quiet", "um, no");
 	setopt("aggrate", "0.5hz");
 	setopt("bufsize", "1m");
 	exit(0);
diff --git a/test/unittest/actions/setopt/tst.badopt.r b/test/unittest/actions/setopt/tst.badopt.r
new file mode 100644
index 00000000..29e39fd4
--- /dev/null
+++ b/test/unittest/actions/setopt/tst.badopt.r
@@ -0,0 +1,16 @@
+
+-- @@stderr --
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Nixon" to "1": Invalid option name
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Harding" to "1": Invalid option name
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Hoover" to "1": Invalid option name
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Bush" to "1": Invalid option name
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "quiet" to "um, no": Invalid value for specified option
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "aggrate" to "0.5hz": Invalid value for specified option
+
+dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "bufsize" to "1m": Operation illegal when tracing is active
+
diff --git a/test/unittest/misc/tst.badopt.r b/test/unittest/misc/tst.badopt.r
deleted file mode 100644
index 9cb25fd7..00000000
--- a/test/unittest/misc/tst.badopt.r
+++ /dev/null
@@ -1,16 +0,0 @@
-
--- @@stderr --
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "Nixon" to "1": Invalid option name
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "Harding" to "1": Invalid option name
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "Hoover" to "1": Invalid option name
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "Bush" to "1": Invalid option name
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "quiet" to "hell no": Invalid value for specified option
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "aggrate" to "0.5hz": Invalid value for specified option
-
-dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): couldn't set option "bufsize" to "1m": Operation illegal when tracing is active
-
diff --git a/test/unittest/setopt/err.D_PROTO_LEN.toomany.r b/test/unittest/setopt/err.D_PROTO_LEN.toomany.r
deleted file mode 100644
index 773bc104..00000000
--- a/test/unittest/setopt/err.D_PROTO_LEN.toomany.r
+++ /dev/null
@@ -1,2 +0,0 @@
--- @@stderr --
-dtrace: failed to compile script test/unittest/setopt/err.D_PROTO_LEN.toomany.d: [D_PROTO_LEN] line 18: setopt( ) prototype mismatch: 3 args passed, at most 2 expected
-- 
2.34.1




More information about the DTrace-devel mailing list