]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_acct.c
xnu-3248.30.4.tar.gz
[apple/xnu.git] / bsd / kern / kern_acct.c
index 1e378b1dbb09f6b2efea0b4374300bc72a1b46e8..aec90c9e0d3b876f785a08bdc2c2de958dc2b63d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * The former's operation is described in Leffler, et al., and the latter
  * was provided by UCB with the 4.4BSD-Lite release
  */
-comp_t encode_comp_t(u_long, u_long);
+comp_t encode_comp_t(uint32_t, uint32_t);
 void   acctwatch(void *);
-void   acctwatch_funnel(void *);
+void   acct_init(void);
 
 /*
  * Accounting vnode pointer, and suspended accounting vnode pointer.  States
@@ -139,6 +139,21 @@ int        acctsuspend = 2;        /* stop accounting when < 2% free space left */
 int    acctresume = 4;         /* resume when free space risen to > 4% */
 int    acctchkfreq = 15;       /* frequency (in seconds) to check space */
 
+
+static lck_grp_t       *acct_subsys_lck_grp;
+static lck_mtx_t       *acct_subsys_mutex;
+
+#define ACCT_SUBSYS_LOCK() lck_mtx_lock(acct_subsys_mutex)
+#define ACCT_SUBSYS_UNLOCK() lck_mtx_unlock(acct_subsys_mutex)
+
+void
+acct_init(void)
+{
+       acct_subsys_lck_grp = lck_grp_alloc_init("acct", NULL);
+       acct_subsys_mutex = lck_mtx_alloc_init(acct_subsys_lck_grp, NULL);
+}
+
+
 /*
  * Accounting system call.  Written based on the specification and
  * previous implementation done by Mark Tinguely.
@@ -161,7 +176,7 @@ acct(proc_t p, struct acct_args *uap, __unused int *retval)
         * writing and make sure it's a 'normal'.
         */
        if (uap->path != USER_ADDR_NULL) {
-               NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, ctx);
+               NDINIT(&nd, LOOKUP, OP_OPEN, NOFOLLOW, UIO_USERSPACE, uap->path, ctx);
                if ((error = vn_open(&nd, FWRITE, 0)))
                        return (error);
 #if CONFIG_MACF
@@ -191,21 +206,26 @@ acct(proc_t p, struct acct_args *uap, __unused int *retval)
         * If accounting was previously enabled, kill the old space-watcher,
         * close the file, and (if no new file was specified, leave).
         */
+       ACCT_SUBSYS_LOCK();
        if (acctp != NULLVP || suspend_acctp != NULLVP) {
-               untimeout(acctwatch_funnel, NULL);
+               untimeout(acctwatch, NULL);
                error = vn_close((acctp != NULLVP ? acctp : suspend_acctp),
                                FWRITE, vfs_context_current());
 
                acctp = suspend_acctp = NULLVP;
        }
-       if (uap->path == USER_ADDR_NULL)
+       if (uap->path == USER_ADDR_NULL) {
+               ACCT_SUBSYS_UNLOCK();
                return (error);
+       }
 
        /*
         * Save the new accounting file vnode, and schedule the new
         * free space watcher.
         */
        acctp = nd.ni_vp;
+       ACCT_SUBSYS_UNLOCK();
+
        acctwatch(NULL);
        return (error);
 }
@@ -227,12 +247,15 @@ acct_process(proc_t p)
        struct vnode *vp;
        kauth_cred_t safecred;
        struct session * sessp;
-       boolean_t fstate;
+       struct  tty *tp;
 
        /* If accounting isn't enabled, don't bother */
+       ACCT_SUBSYS_LOCK();
        vp = acctp;
-       if (vp == NULLVP)
+       if (vp == NULLVP) {
+               ACCT_SUBSYS_UNLOCK();
                return (0);
+       }
 
        /*
         * Get process accounting information.
@@ -271,16 +294,16 @@ acct_process(proc_t p)
        /* (6) The UID and GID of the process */
        safecred = kauth_cred_proc_ref(p);
 
-       an_acct.ac_uid = safecred->cr_ruid;
-       an_acct.ac_gid = safecred->cr_rgid;
+       an_acct.ac_uid = kauth_cred_getruid(safecred);
+       an_acct.ac_gid = kauth_cred_getrgid(safecred);
 
        /* (7) The terminal from which the process was started */
        
        sessp = proc_session(p);
-       if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && (sessp->s_ttyp != TTY_NULL)) {
-               fstate = thread_funnel_set(kernel_flock, TRUE);
-               an_acct.ac_tty = sessp->s_ttyp->t_dev;
-               (void) thread_funnel_set(kernel_flock, fstate);
+       if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && ((tp = SESSION_TP(sessp)) != TTY_NULL)) {
+               tty_lock(tp);
+               an_acct.ac_tty = tp->t_dev;
+               tty_unlock(tp);
         }else
                an_acct.ac_tty = NODEV;
 
@@ -295,12 +318,14 @@ acct_process(proc_t p)
         */
        if ((error = vnode_getwithref(vp)) == 0) {
                error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&an_acct, sizeof (an_acct),
-                               (off_t)0, UIO_SYSSPACE32, IO_APPEND|IO_UNIT, safecred,
+                               (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, safecred,
                                (int *)0, p);
                vnode_put(vp);
        }
 
        kauth_cred_unref(&safecred);
+       ACCT_SUBSYS_UNLOCK();
+
        return (error);
 }
 
@@ -315,7 +340,7 @@ acct_process(proc_t p)
 #define        MAXFRACT        ((1 << MANTSIZE) - 1)   /* Maximum fractional value. */
 
 comp_t
-encode_comp_t(u_long s, u_long us)
+encode_comp_t(uint32_t s, uint32_t us)
 {
        int exp, rnd;
 
@@ -342,15 +367,6 @@ encode_comp_t(u_long s, u_long us)
        return (exp);
 }
 
-void
-acctwatch_funnel(void *a)
-{
-        thread_funnel_set(kernel_flock, TRUE);
-       acctwatch(a);
-        thread_funnel_set(kernel_flock, FALSE);
-}
-
-
 /*
  * Periodically check the file system to see if accounting
  * should be turned on or off.  Beware the case where the vnode
@@ -368,6 +384,7 @@ acctwatch(__unused void *a)
        VFSATTR_WANTED(&va, f_blocks);
        VFSATTR_WANTED(&va, f_bavail);
 
+       ACCT_SUBSYS_LOCK();
        if (suspend_acctp != NULLVP) {
                /*
                 * Resuming accounting when accounting is suspended, and the
@@ -377,6 +394,7 @@ acctwatch(__unused void *a)
                if (suspend_acctp->v_type == VBAD) {
                        (void) vn_close(suspend_acctp, FWRITE, vfs_context_kernel());
                        suspend_acctp = NULLVP;
+                       ACCT_SUBSYS_UNLOCK();
                        return;
                }
                (void)vfs_getattr(suspend_acctp->v_mount, &va, ctx);
@@ -394,6 +412,7 @@ acctwatch(__unused void *a)
                if (acctp->v_type == VBAD) {
                        (void) vn_close(acctp, FWRITE, vfs_context_kernel());
                        acctp = NULLVP;
+                       ACCT_SUBSYS_UNLOCK();
                        return;
                }
                (void)vfs_getattr(acctp->v_mount, &va, ctx);
@@ -403,8 +422,10 @@ acctwatch(__unused void *a)
                        log(LOG_NOTICE, "Accounting suspended\n");
                }
        } else {
+               ACCT_SUBSYS_UNLOCK();
                return;
-        }
-        
-       timeout(acctwatch_funnel, NULL, acctchkfreq * hz);
+       }
+       ACCT_SUBSYS_UNLOCK();
+    
+       timeout(acctwatch, NULL, acctchkfreq * hz);
 }