don't panic getdirentries when a union stack has no lower layer
[unix-history] / usr / src / sys / kern / kern_ktrace.c
index d9f2481..43e9c39 100644 (file)
@@ -1,27 +1,29 @@
 /*
 /*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)kern_ktrace.c       7.12 (Berkeley) %G%
+ *     @(#)kern_ktrace.c       8.2 (Berkeley) %G%
  */
 
 #ifdef KTRACE
 
  */
 
 #ifdef KTRACE
 
-#include "param.h"
-#include "proc.h"
-#include "file.h"
-#include "vnode.h"
-#include "ktrace.h"
-#include "malloc.h"
-#include "syslog.h"
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/namei.h>
+#include <sys/vnode.h>
+#include <sys/ktrace.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
 
 struct ktr_header *
 ktrgetheader(type)
 
 struct ktr_header *
 ktrgetheader(type)
+       int type;
 {
        register struct ktr_header *kth;
 {
        register struct ktr_header *kth;
-       struct proc *p = curproc;
+       struct proc *p = curproc;       /* XXX */
 
        MALLOC(kth, struct ktr_header *, sizeof (struct ktr_header), 
                M_TEMP, M_WAITOK);
 
        MALLOC(kth, struct ktr_header *, sizeof (struct ktr_header), 
                M_TEMP, M_WAITOK);
@@ -36,11 +38,14 @@ ktrsyscall(vp, code, narg, args)
        struct vnode *vp;
        int code, narg, args[];
 {
        struct vnode *vp;
        int code, narg, args[];
 {
-       struct  ktr_header *kth = ktrgetheader(KTR_SYSCALL);
+       struct  ktr_header *kth;
        struct  ktr_syscall *ktp;
        register len = sizeof(struct ktr_syscall) + (narg * sizeof(int));
        struct  ktr_syscall *ktp;
        register len = sizeof(struct ktr_syscall) + (narg * sizeof(int));
+       struct proc *p = curproc;       /* XXX */
        int     *argp, i;
 
        int     *argp, i;
 
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_SYSCALL);
        MALLOC(ktp, struct ktr_syscall *, len, M_TEMP, M_WAITOK);
        ktp->ktr_code = code;
        ktp->ktr_narg = narg;
        MALLOC(ktp, struct ktr_syscall *, len, M_TEMP, M_WAITOK);
        ktp->ktr_code = code;
        ktp->ktr_narg = narg;
@@ -52,15 +57,19 @@ ktrsyscall(vp, code, narg, args)
        ktrwrite(vp, kth);
        FREE(ktp, M_TEMP);
        FREE(kth, M_TEMP);
        ktrwrite(vp, kth);
        FREE(ktp, M_TEMP);
        FREE(kth, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
 }
 
 ktrsysret(vp, code, error, retval)
        struct vnode *vp;
        int code, error, retval;
 {
 }
 
 ktrsysret(vp, code, error, retval)
        struct vnode *vp;
        int code, error, retval;
 {
-       struct ktr_header *kth = ktrgetheader(KTR_SYSRET);
+       struct ktr_header *kth;
        struct ktr_sysret ktp;
        struct ktr_sysret ktp;
+       struct proc *p = curproc;       /* XXX */
 
 
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_SYSRET);
        ktp.ktr_code = code;
        ktp.ktr_error = error;
        ktp.ktr_retval = retval;                /* what about val2 ? */
        ktp.ktr_code = code;
        ktp.ktr_error = error;
        ktp.ktr_retval = retval;                /* what about val2 ? */
@@ -70,19 +79,24 @@ ktrsysret(vp, code, error, retval)
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
 }
 
 ktrnamei(vp, path)
        struct vnode *vp;
        char *path;
 {
 }
 
 ktrnamei(vp, path)
        struct vnode *vp;
        char *path;
 {
-       struct ktr_header *kth = ktrgetheader(KTR_NAMEI);
+       struct ktr_header *kth;
+       struct proc *p = curproc;       /* XXX */
 
 
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_NAMEI);
        kth->ktr_len = strlen(path);
        kth->ktr_buf = path;
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
        kth->ktr_len = strlen(path);
        kth->ktr_buf = path;
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
 }
 
 ktrgenio(vp, fd, rw, iov, len, error)
 }
 
 ktrgenio(vp, fd, rw, iov, len, error)
@@ -90,14 +104,18 @@ ktrgenio(vp, fd, rw, iov, len, error)
        int fd;
        enum uio_rw rw;
        register struct iovec *iov;
        int fd;
        enum uio_rw rw;
        register struct iovec *iov;
+       int len, error;
 {
 {
-       struct ktr_header *kth = ktrgetheader(KTR_GENIO);
+       struct ktr_header *kth;
        register struct ktr_genio *ktp;
        register caddr_t cp;
        register int resid = len, cnt;
        register struct ktr_genio *ktp;
        register caddr_t cp;
        register int resid = len, cnt;
+       struct proc *p = curproc;       /* XXX */
        
        if (error)
                return;
        
        if (error)
                return;
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_GENIO);
        MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
                M_TEMP, M_WAITOK);
        ktp->ktr_fd = fd;
        MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
                M_TEMP, M_WAITOK);
        ktp->ktr_fd = fd;
@@ -119,15 +137,21 @@ ktrgenio(vp, fd, rw, iov, len, error)
 done:
        FREE(kth, M_TEMP);
        FREE(ktp, M_TEMP);
 done:
        FREE(kth, M_TEMP);
        FREE(ktp, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
 }
 
 ktrpsig(vp, sig, action, mask, code)
 }
 
 ktrpsig(vp, sig, action, mask, code)
-       struct  vnode *vp;
-       sig_t   action;
+       struct vnode *vp;
+       int sig;
+       sig_t action;
+       int mask, code;
 {
 {
-       struct ktr_header *kth = ktrgetheader(KTR_PSIG);
+       struct ktr_header *kth;
        struct ktr_psig kp;
        struct ktr_psig kp;
+       struct proc *p = curproc;       /* XXX */
 
 
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_PSIG);
        kp.signo = (char)sig;
        kp.action = action;
        kp.mask = mask;
        kp.signo = (char)sig;
        kp.action = action;
        kp.mask = mask;
@@ -137,6 +161,27 @@ ktrpsig(vp, sig, action, mask, code)
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
 
        ktrwrite(vp, kth);
        FREE(kth, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
+}
+
+ktrcsw(vp, out, user)
+       struct vnode *vp;
+       int out, user;
+{
+       struct ktr_header *kth;
+       struct  ktr_csw kc;
+       struct proc *p = curproc;       /* XXX */
+
+       p->p_traceflag |= KTRFAC_ACTIVE;
+       kth = ktrgetheader(KTR_CSW);
+       kc.out = out;
+       kc.user = user;
+       kth->ktr_buf = (caddr_t)&kc;
+       kth->ktr_len = sizeof (struct ktr_csw);
+
+       ktrwrite(vp, kth);
+       FREE(kth, M_TEMP);
+       p->p_traceflag &= ~KTRFAC_ACTIVE;
 }
 
 /* Interface and common routines */
 }
 
 /* Interface and common routines */
@@ -144,15 +189,16 @@ ktrpsig(vp, sig, action, mask, code)
 /*
  * ktrace system call
  */
 /*
  * ktrace system call
  */
+struct ktrace_args {
+       char    *fname;
+       int     ops;
+       int     facs;
+       int     pid;
+};
 /* ARGSUSED */
 ktrace(curp, uap, retval)
        struct proc *curp;
 /* ARGSUSED */
 ktrace(curp, uap, retval)
        struct proc *curp;
-       register struct args {
-               char    *fname;
-               int     ops;
-               int     facs;
-               int     pid;
-       } *uap;
+       register struct ktrace_args *uap;
        int *retval;
 {
        register struct vnode *vp = NULL;
        int *retval;
 {
        register struct vnode *vp = NULL;
@@ -165,17 +211,21 @@ ktrace(curp, uap, retval)
        int error = 0;
        struct nameidata nd;
 
        int error = 0;
        struct nameidata nd;
 
+       curp->p_traceflag |= KTRFAC_ACTIVE;
        if (ops != KTROP_CLEAR) {
                /*
                 * an operation which requires a file argument.
                 */
        if (ops != KTROP_CLEAR) {
                /*
                 * an operation which requires a file argument.
                 */
-               nd.ni_segflg = UIO_USERSPACE;
-               nd.ni_dirp = uap->fname;
-               if (error = vn_open(&nd, curp, FREAD|FWRITE, 0))
+               NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, curp);
+               if (error = vn_open(&nd, FREAD|FWRITE, 0)) {
+                       curp->p_traceflag &= ~KTRFAC_ACTIVE;
                        return (error);
                        return (error);
+               }
                vp = nd.ni_vp;
                vp = nd.ni_vp;
+               VOP_UNLOCK(vp);
                if (vp->v_type != VREG) {
                if (vp->v_type != VREG) {
-                       vrele(vp);
+                       (void) vn_close(vp, FREAD|FWRITE, curp->p_ucred, curp);
+                       curp->p_traceflag &= ~KTRFAC_ACTIVE;
                        return (EACCES);
                }
        }
                        return (EACCES);
                }
        }
@@ -183,12 +233,13 @@ ktrace(curp, uap, retval)
         * Clear all uses of the tracefile
         */
        if (ops == KTROP_CLEARFILE) {
         * Clear all uses of the tracefile
         */
        if (ops == KTROP_CLEARFILE) {
-               for (p = allproc; p != NULL; p = p->p_nxt) {
+               for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
                        if (p->p_tracep == vp) {
                                if (ktrcanset(curp, p)) {
                                        p->p_tracep = NULL;
                                        p->p_traceflag = 0;
                        if (p->p_tracep == vp) {
                                if (ktrcanset(curp, p)) {
                                        p->p_tracep = NULL;
                                        p->p_traceflag = 0;
-                                       vrele(vp);
+                                       (void) vn_close(vp, FREAD|FWRITE,
+                                               p->p_ucred, p);
                                } else
                                        error = EPERM;
                        }
                                } else
                                        error = EPERM;
                        }
@@ -238,12 +289,15 @@ ktrace(curp, uap, retval)
                error = EPERM;
 done:
        if (vp != NULL)
                error = EPERM;
 done:
        if (vp != NULL)
-               vrele(vp);
+               (void) vn_close(vp, FWRITE, curp->p_ucred, curp);
+       curp->p_traceflag &= ~KTRFAC_ACTIVE;
        return (error);
 }
 
        return (error);
 }
 
+int
 ktrops(curp, p, ops, facs, vp)
 ktrops(curp, p, ops, facs, vp)
-       struct proc *curp, *p;
+       struct proc *p, *curp;
+       int ops, facs;
        struct vnode *vp;
 {
 
        struct vnode *vp;
 {
 
@@ -279,6 +333,7 @@ ktrops(curp, p, ops, facs, vp)
 
 ktrsetchildren(curp, top, ops, facs, vp)
        struct proc *curp, *top;
 
 ktrsetchildren(curp, top, ops, facs, vp)
        struct proc *curp, *top;
+       int ops, facs;
        struct vnode *vp;
 {
        register struct proc *p;
        struct vnode *vp;
 {
        register struct proc *p;
@@ -317,7 +372,7 @@ ktrwrite(vp, kth)
 {
        struct uio auio;
        struct iovec aiov[2];
 {
        struct uio auio;
        struct iovec aiov[2];
-       struct proc *p;
+       register struct proc *p = curproc;      /* XXX */
        int error;
 
        if (vp == NULL)
        int error;
 
        if (vp == NULL)
@@ -330,6 +385,7 @@ ktrwrite(vp, kth)
        aiov[0].iov_len = sizeof(struct ktr_header);
        auio.uio_resid = sizeof(struct ktr_header);
        auio.uio_iovcnt = 1;
        aiov[0].iov_len = sizeof(struct ktr_header);
        auio.uio_resid = sizeof(struct ktr_header);
        auio.uio_iovcnt = 1;
+       auio.uio_procp = (struct proc *)0;
        if (kth->ktr_len > 0) {
                auio.uio_iovcnt++;
                aiov[1].iov_base = kth->ktr_buf;
        if (kth->ktr_len > 0) {
                auio.uio_iovcnt++;
                aiov[1].iov_base = kth->ktr_buf;
@@ -337,7 +393,7 @@ ktrwrite(vp, kth)
                auio.uio_resid += kth->ktr_len;
        }
        VOP_LOCK(vp);
                auio.uio_resid += kth->ktr_len;
        }
        VOP_LOCK(vp);
-       error = VOP_WRITE(vp, &auio, IO_UNIT|IO_APPEND, curproc->p_ucred);
+       error = VOP_WRITE(vp, &auio, IO_UNIT|IO_APPEND, p->p_ucred);
        VOP_UNLOCK(vp);
        if (!error)
                return;
        VOP_UNLOCK(vp);
        if (!error)
                return;
@@ -346,7 +402,7 @@ ktrwrite(vp, kth)
         */
        log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
            error);
         */
        log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
            error);
-       for (p = allproc; p != NULL; p = p->p_nxt) {
+       for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
                if (p->p_tracep == vp) {
                        p->p_tracep = NULL;
                        p->p_traceflag = 0;
                if (p->p_tracep == vp) {
                        p->p_tracep = NULL;
                        p->p_traceflag = 0;