From owner-p4-projects@FreeBSD.ORG Thu Jun 22 05:27:35 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4D67416A47E; Thu, 22 Jun 2006 05:27:35 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0CE4F16A479 for ; Thu, 22 Jun 2006 05:27:35 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9E3C14468D for ; Thu, 22 Jun 2006 05:27:34 +0000 (GMT) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k5M5RYfK007437 for ; Thu, 22 Jun 2006 05:27:34 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k5M5RYgM007434 for perforce@freebsd.org; Thu, 22 Jun 2006 05:27:34 GMT (envelope-from jb@freebsd.org) Date: Thu, 22 Jun 2006 05:27:34 GMT Message-Id: <200606220527.k5M5RYgM007434@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 99798 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jun 2006 05:27:35 -0000 http://perforce.freebsd.org/chv.cgi?CH=99798 Change 99798 by jb@jb_freebsd2 on 2006/06/22 05:26:53 Load the DTrace modules if the dtrace_load environment variable is set. This still belongs in 4th because the DTrace providers should be readily customisable. I just don't know how to do that. When booting with DTrace enabled, load the anonymous enablings from '/boot/dtrace.dof' in lieu of the driver configuration file system that Solaris has. The DOF strings are likely to be longer than the 255 character maximum that FreeBSD's forth implementation supports, so it is easier to do it in C and re-allocate the input buffer size if a larger string is required. Once the DOF strings read, add them to the kernel environment from where the 'dtrace' module can access them in the usual getenv() way. Affected files ... .. //depot/projects/dtrace/src/sys/boot/common/boot.c#2 edit Differences ... ==== //depot/projects/dtrace/src/sys/boot/common/boot.c#2 (text+ko) ==== @@ -52,6 +52,8 @@ static int command_boot(int argc, char *argv[]) { + int error; + int fd; struct preloaded_file *fp; /* @@ -102,6 +104,119 @@ if (archsw.arch_autoload() != 0) return(CMD_ERROR); + /* Check if DTrace is to be loaded prior to boot. */ + if (getenv("dtrace_load")) { + /* + * Load the DTrace modules. This would be better done + * in 4th so that extra providers can be added easily. + */ + error = mod_load("cyclic", NULL, 0, NULL); + if (error != 0) + printf("cyclic autoload failed - %s\n", strerror(error)); + error = mod_load("dtrace", NULL, 0, NULL); + if (error != 0) + printf("dtrace autoload failed - %s\n", strerror(error)); + error = mod_load("profile", NULL, 0, NULL); + if (error != 0) + printf("profile autoload failed - %s\n", strerror(error)); + error = mod_load("systrace", NULL, 0, NULL); + if (error != 0) + printf("systrace autoload failed - %s\n", strerror(error)); + error = mod_load("fbt", NULL, 0, NULL); + if (error != 0) + printf("fbt autoload failed - %s\n", strerror(error)); + error = mod_load("sdt", NULL, 0, NULL); + if (error != 0) + printf("sdt autoload failed - %s\n", strerror(error)); + + /* + * Open the DTrace DOF file if it exists. Don't worry if + * it doesn't. + */ + if ((fd = open("/boot/dtrace.dof", O_RDONLY)) >= 0) { + char *p; /* Temporary pointer. */ + char *p_buf; /* Ptr to the read buffer. */ + int n; /* Number of bytes in string. */ + size_t n_buf; /* Number of characters buffered. */ + size_t s_buf = 4096; /* Size of the read buffer. */ + + /* + * Allocate memory for the initial DOF buffer. This + * will be re-allocated if necessary. + */ + if ((p_buf = malloc(s_buf)) != NULL) { + /* + * Enter a loop to read each line in the DOF + * file and add it to the environment. + */ + do { + /* Start each line with an empty buffer. */ + n_buf = 0; + + /* + * Enter a loop to read the string in the + * current line, re-allocating the input + * buffer if it is too small. + */ + while ((n = fgetstr(p_buf + n_buf, s_buf - n_buf, + fd)) > 0 && n == s_buf - n_buf - 1 && + p_buf[s_buf - 2] != '\n') { + /* + * Update the number of characters + * buffered. + */ + n_buf += n; + + /* Double the buffer size. */ + s_buf *= 2; + + /* Re-allocate the buffer. */ + if ((p = realloc(p_buf, s_buf)) == NULL) { + /* + * Can't re-allocate memory, so + * just give up. + */ + n = 0; + n_buf = 0; + break; + } + + /* Use the newly re-allocated buffer. */ + p_buf = p; + } + + /* Update the number of characters buffered. */ + if (n > 0) + n_buf += n; + + /* + * If there are characters buffered, add the + * input line to the environment. + */ + if (n_buf > 0 && (p = strchr(p_buf, '=')) != NULL) { + /* Zero terminate the name. */ + *p = '\0'; + + /* Point to the value. */ + p++; + + /* Set the environment variable. */ + setenv(p_buf, p, 1); + } + + /* + * Keep looping until there are no more lines in + * the file. + */ + } while (n > 0 && n_buf != 0); + + free(p_buf); + } + + close(fd); + } + } + /* Call the exec handler from the loader matching the kernel */ file_formats[fp->f_loader]->l_exec(fp); return(CMD_ERROR);