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

Kris Van Hees kris.van.hees at oracle.com
Wed Sep 7 20:54:24 UTC 2022


On Wed, Sep 07, 2022 at 04:15:05PM -0400, Kris Van Hees via DTrace-devel wrote:
> 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";

Eugene brings up a valid point (that was even a problem on v1 I expect) - one
could set the strsize to a ridiculous size and this might fail.  But I *can*
validly check the alignment of the data record.  If it is 1, we have a string.
If it is > 1 then we have something else which thereby indicates this is a
toggle (option without value).

I will make that change because even if something prevents the strsize to be
set less than 8, I still agree it far from ideal.

> +
> +				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
> 
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list