[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