Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 May 2006 01:38:10 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 97122 for review
Message-ID:  <200605140138.k4E1cAkU082504@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=97122

Change 97122 by jb@jb_freebsd2 on 2006/05/14 01:38:10

	On Solaris the kernel always seems to be called 'genunix'. On FreeBSD a
	hardcoded kernel module name will often end in tears because it is so
	easy for an admin to use a different kernel other than '/boot/kernel/kernel'.
	
	Part of this difference comes from the fact that DTrace on Solaris
	accesses modules via the object file system (objfs) whereas on FreeBSD
	the kldstat(1) syscall returns the exact name of the file loaded as the
	module.
	
	So, on FreeBSD, DTrace needs to take care to determine the kernel module
	name by using the 'kern.bootfile' sysctl. Then it needs to convert that
	file name to a DTrace module name by converting slashes to underscores to
	get around the DTrace module name parser. Finally those global variables
	which apply to the kernel, like 'curthread', need to be formatted using
	the actual kernel boot file.
	
	There are more global variables which need to be converted, but we're out
	on a ledge so let's do one at a time and deal with the tests that use
	that one.

Affected files ...

.. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#11 edit

Differences ...

==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#11 (text) ====

@@ -119,6 +119,13 @@
 };
 
 /*
+ * Global varaiables that are formatted on FreeBSD based on the kernel file name.
+ */
+#if !defined(sun)
+static char	curthread_str[MAXPATHLEN];
+#endif
+
+/*
  * 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.
  * The global identifiers that represent functions use the dt_idops_func ops
@@ -192,7 +199,11 @@
 { "curthread", DT_IDENT_SCALAR, 0, DIF_VAR_CURTHREAD,
 	{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_PRIVATE,
 	DTRACE_CLASS_COMMON }, DT_VERS_1_0,
+#if defined(sun)
 	&dt_idops_type, "genunix`kthread_t *" },
+#else
+	&dt_idops_type, curthread_str },
+#endif
 { "ddi_pathname", DT_IDENT_FUNC, 0, DIF_SUBR_DDI_PATHNAME,
 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
 	&dt_idops_func, "string(void *, int64_t)" },
@@ -1075,6 +1086,36 @@
 	else
 		bcopy(_dtrace_ints_64, dtp->dt_ints, sizeof (_dtrace_ints_64));
 
+	/*
+	 * On FreeBSD the kernel module name can't be hard-coded. The
+	 * 'kern.bootfile' sysctl value tells us exactly which file is being
+	 * used as the kernel.
+	 */
+#if !defined(sun)
+	{
+	char bootfile[MAXPATHLEN];
+	int i;
+	size_t len = sizeof(bootfile);
+
+	/* This call shouldn't fail, but use a default just in case. */
+	if (sysctlbyname("kern.bootfile", bootfile, &len, NULL, 0) != 0)
+		strlcpy(bootfile, "_boot_kernel_kernel", sizeof(bootfile));
+
+	/*
+	 * Convert the kernel file name to a DTrace module name because DTrace
+	 * doesn't like slashes in module names.
+	 */
+	for (i = 0; i < len; i++)
+		if (bootfile[i] == '/')
+			bootfile[i] = '_';
+
+	/*
+	 * Format the global variables based on the kernel module name.
+	 */
+	snprintf(curthread_str, sizeof(curthread_str), "%s`struct thread *",bootfile);
+	}
+#endif
+
 	dtp->dt_macros = dt_idhash_create("macro", NULL, 0, UINT_MAX);
 	dtp->dt_aggs = dt_idhash_create("aggregation", NULL,
 	    DTRACE_AGGVARIDNONE + 1, UINT_MAX);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605140138.k4E1cAkU082504>