Date: Wed, 19 Apr 2006 06:45:35 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 95581 for review Message-ID: <200604190645.k3J6jZgu024594@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=95581 Change 95581 by jb@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604190645.k3J6jZgu024594>