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

Kris Van Hees kris.van.hees at oracle.com
Wed Sep 7 20:15:05 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 ++++++++++++++++++++++++++++++++++--------
 2 files changed, 54 insertions(+), 10 deletions(-)

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..15ba667b 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 (the option value), or a uint64_t
+				 * was passed (representing NULL, i.e. no value
+				 * was given).
+				 */
+				if (vrec->dtrd_size > sizeof(uint64_t))
+					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)
-- 
2.34.1




More information about the DTrace-devel mailing list