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