PERFORCE change 95902 for review
John Birrell
jb at FreeBSD.org
Sat Apr 22 23:30:23 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=95902
Change 95902 by jb at jb_freebsd2 on 2006/04/22 23:29:54
Create/destroy the dtrace state when opening/closing the cloned
device.
Affected files ...
.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_close.c#3 edit
.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_open.c#3 edit
Differences ...
==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_close.c#3 (text+ko) ====
@@ -27,13 +27,40 @@
dtrace_close(struct cdev *dev __unused, int flags, int fmt __unused,
struct thread *td)
{
- /* Check if this is a cloned device. */
- if (minor(dev) > 0) {
- /* XXX Do the state destruction cleanup here. */
+ dtrace_state_t *state = dev->si_drv1;
+
+ /* Check if this is not a cloned device. */
+ if (minor(dev) == 0)
+ return (0);
+printf("%s: struct cdev %p curthread %p si_drv0 %u\n",__FUNCTION__,dev,curthread,dev->si_drv0);
+
+ mutex_enter(&cpu_lock);
+ mutex_enter(&dtrace_lock);
+
+ if (state != NULL) {
+ if (state->dts_anon) {
+ /*
+ * There is anonymous state.
+ * Destroy that first.
+ */
+ ASSERT(dtrace_anon.dta_state == NULL);
+ dtrace_state_destroy(state->dts_anon);
+ }
+
+ dtrace_state_destroy(state);
- /* Destroy the cloned device. */
- destroy_dev(dev);
+ free(state, M_DTRACE);
+ dev->si_drv1 = NULL;
}
+ mutex_exit(&dtrace_lock);
+ mutex_exit(&cpu_lock);
+ ASSERT(dtrace_opens > 0);
+ if (--dtrace_opens == 0)
+ (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
+
+ /* Destroy the cloned device. */
+ destroy_dev(dev);
+
return (0);
}
==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_open.c#3 (text+ko) ====
@@ -26,7 +26,11 @@
static int
dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
+ dtrace_state_t *state = NULL;
int error = 0;
+ uint32_t priv;
+ uid_t uid;
+ zoneid_t zoneid;
/*
* The first minor device is the one that is cloned so there is
@@ -34,7 +38,58 @@
*/
if (minor(dev) == 0)
return 0;
+printf("%s: struct cdev %p curthread %p si_drv0 %u si_cred %p\n",__FUNCTION__,dev,curthread,dev->si_drv0,dev->si_cred);
-printf("%s: struct cdev %p curthread %p si_drv0 %u\n",__FUNCTION__,dev,curthread,dev->si_drv0);
+ /*
+ * If no DTRACE_PRIV_* bits are set in the credential, then the
+ * caller lacks sufficient permission to do anything with DTrace.
+ */
+ dtrace_cred2priv(dev->si_cred, &priv, &uid, &zoneid);
+ if (priv == DTRACE_PRIV_NONE) {
+ /* Destroy the cloned device. */
+ destroy_dev(dev);
+ return (EACCES);
+ }
+
+ /*
+ * Ask all providers to provide all their probes.
+ */
+ mutex_enter(&dtrace_provider_lock);
+ dtrace_probe_provide(NULL, NULL);
+ mutex_exit(&dtrace_provider_lock);
+
+ mutex_enter(&cpu_lock);
+ mutex_enter(&dtrace_lock);
+ dtrace_opens++;
+ dtrace_membar_producer();
+
+ /*
+ * If the kernel debugger is active (that is, if the kernel debugger
+ * modified text in some way), we won't allow the open.
+ */
+ if (kdi_dtrace_set(KDI_DTSET_DTRACE_ACTIVATE) != 0) {
+ dtrace_opens--;
+ mutex_exit(&cpu_lock);
+ mutex_exit(&dtrace_lock);
+
+ /* Destroy the cloned device. */
+ destroy_dev(dev);
+ return (EBUSY);
+ }
+
+ state = dtrace_state_create(dev);
+ mutex_exit(&cpu_lock);
+
+ if (state == NULL) {
+ if (--dtrace_opens == 0)
+ (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
+ mutex_exit(&dtrace_lock);
+
+ /* Destroy the cloned device. */
+ destroy_dev(dev);
+ return (EAGAIN);
+ }
+
+ mutex_exit(&dtrace_lock);
return (error);
}
More information about the p4-projects
mailing list