[DTrace-devel] [PATCH v4 1/5] Implement setopt()
Kris Van Hees
kris.van.hees at oracle.com
Thu Sep 8 19:40:13 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 = pdat->dtpda_ddesc;
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