Ejemplo n.º 1
0
/*
 * Write out process accounting information, on process exit.
 * Data to be written out is specified in Leffler, et al.
 * and are enumerated below.  (They're also noted in the system
 * "acct.h" header file.)
 */
int
acct_process(struct proc *p)
{
	struct acct acct;
	struct process *pr = p->p_p;
	struct rusage *r;
	struct timespec ut, st, tmp;
	int t;
	struct vnode *vp;
	int error;

	/* If accounting isn't enabled, don't bother */
	vp = acctp;
	if (vp == NULL)
		return (0);

	/*
	 * Get process accounting information.
	 */

	/* (1) The name of the command that ran */
	memcpy(acct.ac_comm, p->p_comm, sizeof acct.ac_comm);

	/* (2) The amount of user and system time that was used */
	calctsru(&pr->ps_tu, &ut, &st, NULL);
	acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_nsec);
	acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_nsec);

	/* (3) The elapsed time the command ran (and its starting time) */
	acct.ac_btime = pr->ps_start.tv_sec;
	getnanotime(&tmp);
	timespecsub(&tmp, &pr->ps_start, &tmp);
	acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_nsec);

	/* (4) The average amount of memory used */
	r = &p->p_ru;
	timespecadd(&ut, &st, &tmp);
	t = tmp.tv_sec * hz + tmp.tv_nsec / (1000 * tick);
	if (t)
		acct.ac_mem = (r->ru_ixrss + r->ru_idrss + r->ru_isrss) / t;
	else
		acct.ac_mem = 0;

	/* (5) The number of disk I/O operations done */
	acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0);

	/* (6) The UID and GID of the process */
	acct.ac_uid = pr->ps_ucred->cr_ruid;
	acct.ac_gid = pr->ps_ucred->cr_rgid;

	/* (7) The terminal from which the process was started */
	if ((pr->ps_flags & PS_CONTROLT) &&
	    pr->ps_pgrp->pg_session->s_ttyp)
		acct.ac_tty = pr->ps_pgrp->pg_session->s_ttyp->t_dev;
	else
		acct.ac_tty = NODEV;

	/* (8) The boolean flags that tell how the process terminated, etc. */
	acct.ac_flag = pr->ps_acflag;

	/*
	 * Now, just write the accounting information to the file.
	 */
	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&acct, sizeof (acct),
	    (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT|IO_NOLIMIT,
	    p->p_ucred, NULL, p);

	return error;
}
Ejemplo n.º 2
0
/*
 * Write out process accounting information, on process exit.
 * Data to be written out is specified in Leffler, et al.
 * and are enumerated below.  (They're also noted in the system
 * "acct.h" header file.)
 */
int
acct_process(struct proc *p)
{
	struct acct acct;
	struct process *pr = p->p_p;
	struct rusage *r;
	struct timeval ut, st, tmp;
	int t;
	struct vnode *vp;
	struct plimit *oplim = NULL;
	int error;

	/* If accounting isn't enabled, don't bother */
	vp = acctp;
	if (vp == NULL)
		return (0);

	/*
	 * Raise the file limit so that accounting can't be stopped by the
	 * user. (XXX - we should think about the cpu limit too).
	 */
	if (pr->ps_limit->p_refcnt > 1) {
		oplim = pr->ps_limit;
		pr->ps_limit = limcopy(pr->ps_limit);
	}
	p->p_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;

	/*
	 * Get process accounting information.
	 */

	/* (1) The name of the command that ran */
	bcopy(p->p_comm, acct.ac_comm, sizeof acct.ac_comm);

	/* (2) The amount of user and system time that was used */
	calcru(&pr->ps_tu, &ut, &st, NULL);
	acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_usec);
	acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec);

	/* (3) The elapsed time the command ran (and its starting time) */
	acct.ac_btime = pr->ps_start.tv_sec;
	getmicrotime(&tmp);
	timersub(&tmp, &pr->ps_start, &tmp);
	acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec);

	/* (4) The average amount of memory used */
	r = &p->p_ru;
	timeradd(&ut, &st, &tmp);
	t = tmp.tv_sec * hz + tmp.tv_usec / tick;
	if (t)
		acct.ac_mem = (r->ru_ixrss + r->ru_idrss + r->ru_isrss) / t;
	else
		acct.ac_mem = 0;

	/* (5) The number of disk I/O operations done */
	acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0);

	/* (6) The UID and GID of the process */
	acct.ac_uid = p->p_cred->p_ruid;
	acct.ac_gid = p->p_cred->p_rgid;

	/* (7) The terminal from which the process was started */
	if ((pr->ps_flags & PS_CONTROLT) &&
	    pr->ps_pgrp->pg_session->s_ttyp)
		acct.ac_tty = pr->ps_pgrp->pg_session->s_ttyp->t_dev;
	else
		acct.ac_tty = NODEV;

	/* (8) The boolean flags that tell how the process terminated, etc. */
	acct.ac_flag = pr->ps_acflag;

	/*
	 * Now, just write the accounting information to the file.
	 */
	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&acct, sizeof (acct),
	    (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, p->p_ucred, NULL, p);

	if (oplim) {
		limfree(pr->ps_limit);
		pr->ps_limit = oplim;
	}

	return error;
}
Ejemplo n.º 3
0
/*
 * Write out process accounting information, on process exit.
 * Data to be written out is specified in Leffler, et al.
 * and are enumerated below.  (They're also noted in the system
 * "acct.h" header file.)
 */
int
acct_process(proc_t p)
{
	struct acct an_acct;
	struct rusage rup, *r;
	struct timeval ut, st, tmp;
	int t;
	int error;
	struct vnode *vp;
	kauth_cred_t safecred;
	struct session * sessp;
	boolean_t fstate;

	/* If accounting isn't enabled, don't bother */
	vp = acctp;
	if (vp == NULLVP)
		return (0);

	/*
	 * Get process accounting information.
	 */

	/* (1) The name of the command that ran */
	bcopy(p->p_comm, an_acct.ac_comm, sizeof an_acct.ac_comm);

	/* (2) The amount of user and system time that was used */
	calcru(p, &ut, &st, NULL);
	an_acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_usec);
	an_acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec);

	/* (3) The elapsed time the commmand ran (and its starting time) */
	an_acct.ac_btime = p->p_start.tv_sec;
	microtime(&tmp);
	timevalsub(&tmp, &p->p_start);
	an_acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec);

	/* (4) The average amount of memory used */
	proc_lock(p);
	rup = p->p_stats->p_ru;
	proc_unlock(p);
	r = &rup;
	tmp = ut;
	timevaladd(&tmp, &st);
	t = tmp.tv_sec * hz + tmp.tv_usec / tick;
	if (t)
		an_acct.ac_mem = (r->ru_ixrss + r->ru_idrss + r->ru_isrss) / t;
	else
		an_acct.ac_mem = 0;

	/* (5) The number of disk I/O operations done */
	an_acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0);

	/* (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;

	/* (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);
	 }else
		an_acct.ac_tty = NODEV;

	if (sessp != SESSION_NULL)
		session_rele(sessp);

	/* (8) The boolean flags that tell how the process terminated, etc. */
	an_acct.ac_flag = p->p_acflag;

	/*
	 * Now, just write the accounting information to the file.
	 */
	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,
				(int *)0, p);
		vnode_put(vp);
	}

	kauth_cred_unref(&safecred);
	return (error);
}