PERFORCE change 95581 for review
John Birrell
jb at FreeBSD.org
Wed Apr 19 06:45:36 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=95581
Change 95581 by jb at jb_freebsd2 on 2006/04/19 06:44:40
Read the sysctl debug.dtrace.providers to get a string with space-separated
provider device names, then parse it and act on each name in the same way
as Solaris.
The debug.dtrace.providers sysctl variable is managed by the dtrace device
and the string is formatted from the list of providers registered at the
time of the sysctl call.
Affected files ...
.. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#5 edit
Differences ...
==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#5 (text) ====
@@ -56,6 +56,10 @@
#include <dt_printf.h>
#include <dt_string.h>
#include <dt_provider.h>
+#if !defined(sun)
+#include <sys/sysctl.h>
+#include <string.h>
+#endif
/*
* Stability and versioning definitions. These #defines are used in the tables
@@ -624,7 +628,7 @@
int _dtrace_debug = 0; /* debug messages enabled (off) */
const char *const _dtrace_version = DT_VERS_STRING; /* API version string */
-#ifdef DOODAD
+#if defined(sun)
int _dtrace_rdvers = RD_VERSION; /* rtld_db feature version */
#endif
@@ -634,7 +638,7 @@
uint_t df_size; /* size of df_fds[] */
} dt_fdlist_t;
-#ifdef DOODAD
+#if defined(sun)
#pragma init(_dtrace_init)
void
_dtrace_init(void)
@@ -663,9 +667,10 @@
{
dt_provmod_t *prov;
char path[PATH_MAX];
+ int fd;
+#if defined(sun)
struct dirent *dp, *ep;
DIR *dirp;
- int fd;
if ((dirp = opendir(_dtrace_provdir)) == NULL)
return; /* failed to open directory; just skip it */
@@ -710,6 +715,92 @@
}
(void) closedir(dirp);
+#else
+ char *p;
+ char *p1;
+ char *p_providers = NULL;
+ int error;
+ size_t len = 0;
+
+ /*
+ * Loop to allocate/reallocate memory for the string of provider
+ * names and retry:
+ */
+ while(1) {
+ /*
+ * The first time around, get the string length. The next time,
+ * hopefully we've allocated enough memory.
+ */
+ error = sysctlbyname("debug.dtrace.providers",p_providers,&len,NULL,0);
+ if (len == 0)
+ /* No providers? That's strange. Where's dtrace? */
+ break;
+ else if (error == 0 && p_providers == NULL) {
+ /*
+ * Allocate the initial memory which should be enough
+ * unless another provider loads before we have
+ * time to go back and get the string.
+ */
+ if ((p_providers = malloc(len)) == NULL)
+ /* How do we report errors here? */
+ return;
+ } else if (error == -1 && errno == ENOMEM) {
+ /*
+ * The current buffer isn't large enough, so
+ * reallocate it. We normally won't need to do this
+ * because providers aren't being loaded all the time.
+ */
+ if ((p = realloc(p_providers,len)) == NULL)
+ /* How do we report errors here? */
+ return;
+ p_providers = p;
+ } else
+ break;
+ }
+
+ /* Check if we got a string of provider names: */
+ if (error == 0 && len > 0 && p_providers != NULL) {
+ p = p_providers;
+
+ /*
+ * Parse the string containing the space separated
+ * provider names.
+ */
+ while ((p1 = strsep(&p," ")) != NULL) {
+ if (dfp->df_ents == dfp->df_size) {
+ uint_t size = dfp->df_size ? dfp->df_size * 2 : 16;
+ int *fds = realloc(dfp->df_fds, size * sizeof (int));
+
+ if (fds == NULL)
+ break;
+
+ dfp->df_fds = fds;
+ dfp->df_size = size;
+ }
+
+ (void) snprintf(path, sizeof (path), "/dev/%s", p1);
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ continue; /* failed to open driver; just skip it */
+
+ if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
+ (prov->dp_name = malloc(strlen(p1) + 1)) == NULL) {
+ free(prov);
+ (void) close(fd);
+ break;
+ }
+
+ (void) strcpy(prov->dp_name, p1);
+ prov->dp_next = *provmod;
+ *provmod = prov;
+
+ dt_dprintf("opened provider %s\n", p1);
+ dfp->df_fds[dfp->df_ents++] = fd;
+ }
+ }
+ if (p_providers != NULL)
+ free(p_providers);
+#endif
}
static void
More information about the p4-projects
mailing list