public inbox for dtrace@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH v5 02/19] Add a dt_provider_discover() function
@ 2024-10-28 17:05 eugene.loh
  2024-10-28 17:13 ` Kris Van Hees
  0 siblings, 1 reply; 2+ messages in thread
From: eugene.loh @ 2024-10-28 17:05 UTC (permalink / raw)
  To: dtrace, dtrace-devel

From: Eugene Loh <eugene.loh@oracle.com>

It is possible for new providers and probes to appear after dtrace_go().
Add a function that can be called for such discovery, on a per-provider
basis.  Each provider that supports such discovery needs to provide:

*)  a function discover() that performs discovery on behalf of the provider

*)  a function add_probe() that adds a particular (discovered) probe

To support looping over providers, move dt_providers[] from
dt_open.c to dt_provider.c and extern it in dt_provider.h.

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
 libdtrace/dt_bpf.c      |  4 ++++
 libdtrace/dt_open.c     | 22 +-----------------
 libdtrace/dt_provider.c | 51 +++++++++++++++++++++++++++++++++++++++++
 libdtrace/dt_provider.h |  6 +++++
 libdtrace/dt_work.c     |  3 +++
 5 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index ad11d178e..856110306 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -1275,6 +1275,10 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
 		int		fd;
 		int		rc = -1;
 
+		/* Handle probes discovered after compilation. */
+		if (prp->prov->impl->add_probe)
+			prp->prov->impl->add_probe(dtp, prp);
+
 		dp = prp->difo;
 		if (dp == NULL)
 			continue;
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 848141ddc..1f586fc4f 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -61,26 +61,6 @@ const dt_version_t _dtrace_versions[] = {
 	0
 };
 
-/*
- * List of provider modules that register providers and probes.  A single
- * provider module may create multiple providers.
- */
-static const dt_provimpl_t *dt_providers[] = {
-	&dt_dtrace,		/* list dt_dtrace first */
-	&dt_cpc,
-	&dt_fbt_fprobe,
-	&dt_io,
-	&dt_ip,
-	&dt_lockstat,
-	&dt_proc,
-	&dt_profile,
-	&dt_rawtp,
-	&dt_sched,
-	&dt_sdt,
-	&dt_syscall,
-	&dt_uprobe,
-};
-
 /*
  * Table of global identifiers.  This is used to populate the global identifier
  * hash when a new dtrace client open occurs.  For more info see dt_ident.h.
@@ -1210,7 +1190,7 @@ dtrace_init(dtrace_hdl_t *dtp)
 	 * known providers.
 	 */
 	dt_probe_init(dtp);
-	for (i = 0; i < ARRAY_SIZE(dt_providers); i++) {
+	for (i = 0; dt_providers[i]; i++) {
 		int	n;
 
 		n = dt_providers[i]->populate(dtp);
diff --git a/libdtrace/dt_provider.c b/libdtrace/dt_provider.c
index 8cfef0ba2..354dfa1ee 100644
--- a/libdtrace/dt_provider.c
+++ b/libdtrace/dt_provider.c
@@ -18,10 +18,32 @@
 #include <port.h>
 
 #include <dt_provider.h>
+#include <dt_probe.h>
 #include <dt_module.h>
 #include <dt_string.h>
 #include <dt_list.h>
 
+/*
+ * List of provider modules that register providers and probes.  A single
+ * provider module may create multiple providers.
+ */
+const dt_provimpl_t *dt_providers[] = {
+	&dt_dtrace,		/* list dt_dtrace first */
+	&dt_cpc,
+	&dt_fbt_fprobe,
+	&dt_io,
+	&dt_ip,
+	&dt_lockstat,
+	&dt_proc,
+	&dt_profile,
+	&dt_rawtp,
+	&dt_sched,
+	&dt_sdt,
+	&dt_syscall,
+	&dt_uprobe,
+	NULL
+};
+
 static uint32_t
 dt_provider_hval(const dt_provider_t *pvp)
 {
@@ -149,3 +171,32 @@ dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id)
 	BT_SET(pvp->pv_xrefs, id);
 	return 0;
 }
+
+int
+dt_provider_discover(dtrace_hdl_t *dtp)
+{
+	int i, prid = dtp->dt_probe_id;
+
+	/* Discover new probes. */
+	for (i = 0; dt_providers[i]; i++) {
+		if (dt_providers[i]->discover && dt_providers[i]->discover(dtp) < 0)
+			return -1;        /* errno is already set */
+	}
+
+	/* Add them. */
+	for ( ; prid < dtp->dt_probe_id; prid++) {
+		dt_probe_t	*prp = dtp->dt_probes[prid];
+		int		rc;
+
+		dt_probe_enable(dtp, prp);
+
+		if (prp->prov->impl->add_probe == NULL)
+			continue;
+
+		rc = prp->prov->impl->add_probe(dtp, prp);
+		if (rc < 0)
+			return rc;
+	}
+
+	return 0;
+}
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index 17b1844cb..384d4fd33 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -62,6 +62,9 @@ typedef struct dt_provimpl {
 	int (*probe_info)(dtrace_hdl_t *dtp,	/* get probe info */
 			  const struct dt_probe *prp,
 			  int *argcp, dt_argdesc_t **argvp);
+	int (*discover)(dtrace_hdl_t *dtp);	/* discover new probes */
+	int (*add_probe)(dtrace_hdl_t *dtp,	/* add a new probe */
+			 struct dt_probe *prp);
 	void (*detach)(dtrace_hdl_t *dtp,	/* probe cleanup */
 		       const struct dt_probe *prb);
 	void (*probe_destroy)(dtrace_hdl_t *dtp, /* free probe data */
@@ -86,6 +89,8 @@ extern dt_provimpl_t dt_sdt;
 extern dt_provimpl_t dt_syscall;
 extern dt_provimpl_t dt_uprobe;
 
+extern const dt_provimpl_t *dt_providers[];
+
 typedef struct dt_provider {
 	dt_list_t pv_list;		/* list forward/back pointers */
 	struct dt_hentry he;		/* htab links */
@@ -110,6 +115,7 @@ extern dt_provider_t *dt_provider_create(dtrace_hdl_t *, const char *,
 					 const dt_provimpl_t *,
 					 const dtrace_pattr_t *, void *);
 extern int dt_provider_xref(dtrace_hdl_t *, dt_provider_t *, id_t);
+extern int dt_provider_discover(dtrace_hdl_t *dtp);
 
 #ifdef	__cplusplus
 }
diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
index 11335345a..5318cdb7e 100644
--- a/libdtrace/dt_work.c
+++ b/libdtrace/dt_work.c
@@ -362,6 +362,9 @@ dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
 	dtrace_workstatus_t	rval;
 	int			gen;
 
+	if (dt_provider_discover(dtp) < 0)
+		return DTRACE_WORKSTATUS_ERROR;
+
 	switch (dtrace_status(dtp)) {
 	case DTRACE_STATUS_EXITED:
 	case DTRACE_STATUS_STOPPED:
-- 
2.43.5


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v5 02/19] Add a dt_provider_discover() function
  2024-10-28 17:05 [PATCH v5 02/19] Add a dt_provider_discover() function eugene.loh
@ 2024-10-28 17:13 ` Kris Van Hees
  0 siblings, 0 replies; 2+ messages in thread
From: Kris Van Hees @ 2024-10-28 17:13 UTC (permalink / raw)
  To: eugene.loh; +Cc: dtrace, dtrace-devel

On Mon, Oct 28, 2024 at 01:05:33PM -0400, eugene.loh@oracle.com wrote:
> From: Eugene Loh <eugene.loh@oracle.com>
> 
> It is possible for new providers and probes to appear after dtrace_go().
> Add a function that can be called for such discovery, on a per-provider
> basis.  Each provider that supports such discovery needs to provide:
> 
> *)  a function discover() that performs discovery on behalf of the provider
> 
> *)  a function add_probe() that adds a particular (discovered) probe
> 
> To support looping over providers, move dt_providers[] from
> dt_open.c to dt_provider.c and extern it in dt_provider.h.
> 
> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>

> ---
>  libdtrace/dt_bpf.c      |  4 ++++
>  libdtrace/dt_open.c     | 22 +-----------------
>  libdtrace/dt_provider.c | 51 +++++++++++++++++++++++++++++++++++++++++
>  libdtrace/dt_provider.h |  6 +++++
>  libdtrace/dt_work.c     |  3 +++
>  5 files changed, 65 insertions(+), 21 deletions(-)
> 
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> index ad11d178e..856110306 100644
> --- a/libdtrace/dt_bpf.c
> +++ b/libdtrace/dt_bpf.c
> @@ -1275,6 +1275,10 @@ dt_bpf_load_progs(dtrace_hdl_t *dtp, uint_t cflags)
>  		int		fd;
>  		int		rc = -1;
>  
> +		/* Handle probes discovered after compilation. */
> +		if (prp->prov->impl->add_probe)
> +			prp->prov->impl->add_probe(dtp, prp);
> +
>  		dp = prp->difo;
>  		if (dp == NULL)
>  			continue;
> diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
> index 848141ddc..1f586fc4f 100644
> --- a/libdtrace/dt_open.c
> +++ b/libdtrace/dt_open.c
> @@ -61,26 +61,6 @@ const dt_version_t _dtrace_versions[] = {
>  	0
>  };
>  
> -/*
> - * List of provider modules that register providers and probes.  A single
> - * provider module may create multiple providers.
> - */
> -static const dt_provimpl_t *dt_providers[] = {
> -	&dt_dtrace,		/* list dt_dtrace first */
> -	&dt_cpc,
> -	&dt_fbt_fprobe,
> -	&dt_io,
> -	&dt_ip,
> -	&dt_lockstat,
> -	&dt_proc,
> -	&dt_profile,
> -	&dt_rawtp,
> -	&dt_sched,
> -	&dt_sdt,
> -	&dt_syscall,
> -	&dt_uprobe,
> -};
> -
>  /*
>   * Table of global identifiers.  This is used to populate the global identifier
>   * hash when a new dtrace client open occurs.  For more info see dt_ident.h.
> @@ -1210,7 +1190,7 @@ dtrace_init(dtrace_hdl_t *dtp)
>  	 * known providers.
>  	 */
>  	dt_probe_init(dtp);
> -	for (i = 0; i < ARRAY_SIZE(dt_providers); i++) {
> +	for (i = 0; dt_providers[i]; i++) {
>  		int	n;
>  
>  		n = dt_providers[i]->populate(dtp);
> diff --git a/libdtrace/dt_provider.c b/libdtrace/dt_provider.c
> index 8cfef0ba2..354dfa1ee 100644
> --- a/libdtrace/dt_provider.c
> +++ b/libdtrace/dt_provider.c
> @@ -18,10 +18,32 @@
>  #include <port.h>
>  
>  #include <dt_provider.h>
> +#include <dt_probe.h>
>  #include <dt_module.h>
>  #include <dt_string.h>
>  #include <dt_list.h>
>  
> +/*
> + * List of provider modules that register providers and probes.  A single
> + * provider module may create multiple providers.
> + */
> +const dt_provimpl_t *dt_providers[] = {
> +	&dt_dtrace,		/* list dt_dtrace first */
> +	&dt_cpc,
> +	&dt_fbt_fprobe,
> +	&dt_io,
> +	&dt_ip,
> +	&dt_lockstat,
> +	&dt_proc,
> +	&dt_profile,
> +	&dt_rawtp,
> +	&dt_sched,
> +	&dt_sdt,
> +	&dt_syscall,
> +	&dt_uprobe,
> +	NULL
> +};
> +
>  static uint32_t
>  dt_provider_hval(const dt_provider_t *pvp)
>  {
> @@ -149,3 +171,32 @@ dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id)
>  	BT_SET(pvp->pv_xrefs, id);
>  	return 0;
>  }
> +
> +int
> +dt_provider_discover(dtrace_hdl_t *dtp)
> +{
> +	int i, prid = dtp->dt_probe_id;
> +
> +	/* Discover new probes. */
> +	for (i = 0; dt_providers[i]; i++) {
> +		if (dt_providers[i]->discover && dt_providers[i]->discover(dtp) < 0)
> +			return -1;        /* errno is already set */
> +	}
> +
> +	/* Add them. */
> +	for ( ; prid < dtp->dt_probe_id; prid++) {
> +		dt_probe_t	*prp = dtp->dt_probes[prid];
> +		int		rc;
> +
> +		dt_probe_enable(dtp, prp);
> +
> +		if (prp->prov->impl->add_probe == NULL)
> +			continue;
> +
> +		rc = prp->prov->impl->add_probe(dtp, prp);
> +		if (rc < 0)
> +			return rc;
> +	}
> +
> +	return 0;
> +}
> diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
> index 17b1844cb..384d4fd33 100644
> --- a/libdtrace/dt_provider.h
> +++ b/libdtrace/dt_provider.h
> @@ -62,6 +62,9 @@ typedef struct dt_provimpl {
>  	int (*probe_info)(dtrace_hdl_t *dtp,	/* get probe info */
>  			  const struct dt_probe *prp,
>  			  int *argcp, dt_argdesc_t **argvp);
> +	int (*discover)(dtrace_hdl_t *dtp);	/* discover new probes */
> +	int (*add_probe)(dtrace_hdl_t *dtp,	/* add a new probe */
> +			 struct dt_probe *prp);
>  	void (*detach)(dtrace_hdl_t *dtp,	/* probe cleanup */
>  		       const struct dt_probe *prb);
>  	void (*probe_destroy)(dtrace_hdl_t *dtp, /* free probe data */
> @@ -86,6 +89,8 @@ extern dt_provimpl_t dt_sdt;
>  extern dt_provimpl_t dt_syscall;
>  extern dt_provimpl_t dt_uprobe;
>  
> +extern const dt_provimpl_t *dt_providers[];
> +
>  typedef struct dt_provider {
>  	dt_list_t pv_list;		/* list forward/back pointers */
>  	struct dt_hentry he;		/* htab links */
> @@ -110,6 +115,7 @@ extern dt_provider_t *dt_provider_create(dtrace_hdl_t *, const char *,
>  					 const dt_provimpl_t *,
>  					 const dtrace_pattr_t *, void *);
>  extern int dt_provider_xref(dtrace_hdl_t *, dt_provider_t *, id_t);
> +extern int dt_provider_discover(dtrace_hdl_t *dtp);
>  
>  #ifdef	__cplusplus
>  }
> diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
> index 11335345a..5318cdb7e 100644
> --- a/libdtrace/dt_work.c
> +++ b/libdtrace/dt_work.c
> @@ -362,6 +362,9 @@ dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
>  	dtrace_workstatus_t	rval;
>  	int			gen;
>  
> +	if (dt_provider_discover(dtp) < 0)
> +		return DTRACE_WORKSTATUS_ERROR;
> +
>  	switch (dtrace_status(dtp)) {
>  	case DTRACE_STATUS_EXITED:
>  	case DTRACE_STATUS_STOPPED:
> -- 
> 2.43.5
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-10-28 17:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-28 17:05 [PATCH v5 02/19] Add a dt_provider_discover() function eugene.loh
2024-10-28 17:13 ` Kris Van Hees

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox