int
osf1_sys_getrusage(struct lwp *l, const struct osf1_sys_getrusage_args *uap, register_t *retval)
{
	struct osf1_rusage osf1_rusage;
	struct rusage ru;
	struct proc *p = l->l_proc;


	switch (SCARG(uap, who)) {
	case OSF1_RUSAGE_SELF:
		mutex_enter(p->p_lock);
		ru = p->p_stats->p_ru;
		calcru(p, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
		rulwps(p, &ru);
		mutex_exit(p->p_lock);
		break;

	case OSF1_RUSAGE_CHILDREN:
		ru = p->p_stats->p_cru;
		break;

	case OSF1_RUSAGE_THREAD:		/* XXX not supported */
	default:
		return (EINVAL);
	}

	osf1_cvt_rusage_from_native(&ru, &osf1_rusage);

	return copyout(&osf1_rusage, SCARG(uap, rusage), sizeof osf1_rusage);
}
Exemple #2
0
int get_process_info_sysdep(ProcInfo_T p) {

  struct kinfo_proc *pinfo;

  /* Only needed for older versions of BSD that use kvm_uread */
  /* struct user *u_addr = (struct user *)USRSTACK; */
  struct pstats pstats;
  struct plimit plimit;
  struct vmspace *vms;
  register struct rusage *rup;
  long stat_utime;
  long stat_stime;
  long stat_cutime;
  long stat_cstime;

  u_int64_t rss_lim;

  int count;

  /* Got it from libgtop */

  pinfo = kvm_getprocs(kvm_handle, KERN_PROC_PID, p->pid, &count);

  if ((pinfo == NULL) || (count < 1)) {

    return FALSE;

  }

  /* ----------------------------- CPU TIMING ----------------------------*/
  /* Got it from libgtop/sysdep/freebsd/proctime.c */
  

  if (kvm_read (kvm_handle, 
#if (__FreeBSD_version > 500000)
		(unsigned long) &pinfo->ki_addr->u_stats,
#else
		(unsigned long) pinfo [0].kp_proc.p_stats,
#endif
		&pstats, sizeof (pstats)) == sizeof (pstats)) {
    
    /* Need to fix for different versions of BSD - I think older ones
       use kvm_uread, and newer use kvm_read */

  /*  if ((pinfo [0].kp_proc.p_flag & P_INMEM) &&
      kvm_uread (kvm_handle, &(pinfo [0]).kp_proc,
		 (unsigned long) &u_addr->u_stats,
		 (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) {
  */
    rup = &pstats.p_ru;
#if (__FreeBSD_version > 500000)
    calcru(&pinfo->ki_addr,
#else
    calcru(&(pinfo [0]).kp_proc,
#endif
	   &rup->ru_utime, &rup->ru_stime, NULL);

    stat_utime = tv2sec (pstats.p_ru.ru_utime);
    stat_stime = tv2sec (pstats.p_ru.ru_stime);

    stat_cutime = tv2sec (pstats.p_cru.ru_utime);
    stat_cstime = tv2sec (pstats.p_cru.ru_stime);

  } else {
Exemple #3
0
int
procfs_doprocstatus(PFS_FILL_ARGS)
{
	struct session *sess;
	struct thread *tdfirst;
	struct tty *tp;
	struct ucred *cr;
	const char *wmesg;
	char *pc;
	char *sep;
	int pid, ppid, pgid, sid;
	int i;

	pid = p->p_pid;
	PROC_LOCK(p);
	ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
	pgid = p->p_pgrp->pg_id;
	sess = p->p_pgrp->pg_session;
	SESS_LOCK(sess);
	sid = sess->s_leader ? sess->s_leader->p_pid : 0;

/* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg
				euid ruid rgid,egid,groups[1 .. ngroups]
*/

	pc = p->p_comm;
	do {
		if (*pc < 33 || *pc > 126 || *pc == '\\')
			sbuf_printf(sb, "\\%03o", *pc);
		else
			sbuf_putc(sb, *pc);
	} while (*++pc);
	sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid);
	if ((p->p_flag & P_CONTROLT) && (tp = sess->s_ttyp))
		sbuf_printf(sb, "%s ", devtoname(tp->t_dev));
	else
		sbuf_printf(sb, "- ");

	sep = "";
	if (sess->s_ttyvp) {
		sbuf_printf(sb, "%sctty", sep);
		sep = ",";
	}
	if (SESS_LEADER(p)) {
		sbuf_printf(sb, "%ssldr", sep);
		sep = ",";
	}
	SESS_UNLOCK(sess);
	if (*sep != ',') {
		sbuf_printf(sb, "noflags");
	}

	tdfirst = FIRST_THREAD_IN_PROC(p);
	thread_lock(tdfirst);
	if (tdfirst->td_wchan != NULL) {
		KASSERT(tdfirst->td_wmesg != NULL,
		    ("wchan %p has no wmesg", tdfirst->td_wchan));
		wmesg = tdfirst->td_wmesg;
	} else
		wmesg = "nochan";
	thread_unlock(tdfirst);

	if (p->p_flag & P_INMEM) {
		struct timeval start, ut, st;

		PROC_SLOCK(p);
		calcru(p, &ut, &st);
		PROC_SUNLOCK(p);
		start = p->p_stats->p_start;
		timevaladd(&start, &boottime);
		sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld",
		    (intmax_t)start.tv_sec, start.tv_usec,
		    (intmax_t)ut.tv_sec, ut.tv_usec,
		    (intmax_t)st.tv_sec, st.tv_usec);
	} else
		sbuf_printf(sb, " -1,-1 -1,-1 -1,-1");

	sbuf_printf(sb, " %s", wmesg);

	cr = p->p_ucred;

	sbuf_printf(sb, " %lu %lu %lu",
		(u_long)cr->cr_uid,
		(u_long)cr->cr_ruid,
		(u_long)cr->cr_rgid);

	/* egid (cr->cr_svgid) is equal to cr_ngroups[0]
	   see also getegid(2) in /sys/kern/kern_prot.c */

	for (i = 0; i < cr->cr_ngroups; i++) {
		sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]);
	}

	if (jailed(cr)) {
		mtx_lock(&cr->cr_prison->pr_mtx);
		sbuf_printf(sb, " %s",
		    prison_name(td->td_ucred->cr_prison, cr->cr_prison));
		mtx_unlock(&cr->cr_prison->pr_mtx);
	} else {
		sbuf_printf(sb, " -");
	}
	PROC_UNLOCK(p);
	sbuf_printf(sb, "\n");

	return (0);
}
Exemple #4
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;
}
Exemple #5
0
/*
 * Linux compatible /proc/<pid>/stat. Only active when the -o linux
 * mountflag is used.
 */
int
procfs_do_pid_stat(struct lwp *curl, struct lwp *l,
    struct pfsnode *pfs, struct uio *uio)
{
	char *bf;
	struct proc *p = l->l_proc;
	int len;
	struct tty *tty = p->p_session->s_ttyp;
	struct rusage *ru = &p->p_stats->p_ru;
	struct rusage *cru = &p->p_stats->p_cru;
	unsigned long stext = 0, etext = 0, sstack = 0;
	struct timeval rt;
	struct vmspace	*vm;
	int error = 0;

	bf = malloc(LBFSZ, M_TEMP, M_WAITOK);

	if ((error = proc_vmspace_getref(p, &vm)) != 0) {
		goto out;
	}

	get_proc_size_info(l, &stext, &etext, &sstack);

	mutex_enter(proc_lock);
	mutex_enter(p->p_lock);

	calcru(p, NULL, NULL, NULL, &rt);

	len = snprintf(bf, LBFSZ,
	    "%d (%s) %c %d %d %d %lld %d "
	    "%u "
	    "%lu %lu %lu %lu %lu %lu %lu %lu "
	    "%d %d %d "
	    "%lld %lld %lu %lu %" PRIu64 " "
	    "%lu %lu %lu "
	    "%u %u "
	    "%u %u %u %u "
	    "%lu %lu %lu %d %d\n",

	    p->p_pid,
	    p->p_comm,
	    "0IR3SZD"[(p->p_stat > 6) ? 0 : (int)p->p_stat],
	    (p->p_pptr != NULL) ? p->p_pptr->p_pid : 0,

	    p->p_pgid,
	    p->p_session->s_sid,
	    (unsigned long long)(tty ? tty->t_dev : 0),
	    (tty && tty->t_pgrp) ? tty->t_pgrp->pg_id : 0,

	    p->p_flag,

	    ru->ru_minflt,
	    cru->ru_minflt,
	    ru->ru_majflt,
	    cru->ru_majflt,
	    (long)USEC_2_TICKS(ru->ru_utime.tv_usec),
	    (long)USEC_2_TICKS(ru->ru_stime.tv_usec),
	    (long)USEC_2_TICKS(cru->ru_utime.tv_usec),
	    (long)USEC_2_TICKS(cru->ru_stime.tv_usec),

	    l->l_priority,				/* XXX: priority */
	    p->p_nice - 20,
	    0,

	    (long long)rt.tv_sec,
	    (long long)p->p_stats->p_start.tv_sec,
	    (unsigned long)(vm->vm_tsize + vm->vm_dsize + vm->vm_ssize), /* size */
	    (unsigned long)(vm->vm_rssize),	/* resident */
	    p->p_rlimit[RLIMIT_RSS].rlim_cur,

	    stext,					/* start code */
	    etext,					/* end code */
	    sstack,					/* mm start stack */
	    0,						/* XXX: pc */
	    0,						/* XXX: sp */
	    p->p_sigpend.sp_set.__bits[0],		/* XXX: pending */
	    0,						/* XXX: held */
	    p->p_sigctx.ps_sigignore.__bits[0],		/* ignored */
	    p->p_sigctx.ps_sigcatch.__bits[0],		/* caught */

	    (unsigned long)(intptr_t)l->l_wchan,
	    ru->ru_nvcsw,
	    ru->ru_nivcsw,
	    p->p_exitsig,
	    0);						/* XXX: processor */

	mutex_exit(p->p_lock);
	mutex_exit(proc_lock);

	uvmspace_free(vm);

	if (len == 0)
		goto out;

	error = uiomove_frombuf(bf, len, uio);
out:
	free(bf, M_TEMP);
	return error;
}
Exemple #6
0
/*
 * Linux compatible /proc/<pid>/stat. Only active when the -o linux
 * mountflag is used.
 */
int
procfs_do_pid_stat(struct lwp *curl, struct lwp *l,
    struct pfsnode *pfs, struct uio *uio)
{
	char *bf;
	struct proc *p = l->l_proc;
	int len;
	struct rusage *cru = &p->p_stats->p_cru;
	unsigned long stext = 0, etext = 0, sstack = 0;
	struct timeval rt;
	struct vmspace	*vm;
	struct kinfo_proc2 ki;
	int error = 0;

	bf = malloc(LBFSZ, M_TEMP, M_WAITOK);

	if ((error = proc_vmspace_getref(p, &vm)) != 0) {
		goto out;
	}

	get_proc_size_info(l, &stext, &etext, &sstack);

	mutex_enter(proc_lock);
	mutex_enter(p->p_lock);

	fill_kproc2(p, &ki, false);
	calcru(p, NULL, NULL, NULL, &rt);

	len = snprintf(bf, LBFSZ,
	    "%d (%s) %c %d %d %d %u %d "
	    "%u "
	    "%"PRIu64" %lu %"PRIu64" %lu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" "
	    "%d %d %"PRIu64" "
	    "%lld %"PRIu64" %"PRId64" %lu %"PRIu64" "
	    "%lu %lu %lu "
	    "%u %u "
	    "%u %u %u %u "
	    "%"PRIu64" %"PRIu64" %"PRIu64" %d %"PRIu64"\n",

	    ki.p_pid,						/* 1 pid */
	    ki.p_comm,						/* 2 tcomm */
	    "0RRSTZXR8"[(ki.p_stat > 8) ? 0 : (int)ki.p_stat],	/* 3 state */
	    ki.p_ppid,						/* 4 ppid */
	    ki.p__pgid,						/* 5 pgrp */
	    ki.p_sid,						/* 6 sid */
	    (ki.p_tdev != (uint32_t)NODEV) ? ki.p_tdev : 0,	/* 7 tty_nr */
	    ki.p_tpgid,						/* 8 tty_pgrp */

	    ki.p_flag,						/* 9 flags */

	    ki.p_uru_minflt,					/* 10 min_flt */
	    cru->ru_minflt,
	    ki.p_uru_majflt,					/* 12 maj_flt */
	    cru->ru_majflt,
	    UTIME2TICKS(ki.p_uutime_sec, ki.p_uutime_usec),	/* 14 utime */
	    UTIME2TICKS(ki.p_ustime_sec, ki.p_ustime_usec),	/* 15 stime */
	    UTIME2TICKS(cru->ru_utime.tv_sec, cru->ru_utime.tv_usec), /* 16 cutime */
	    UTIME2TICKS(cru->ru_stime.tv_sec, cru->ru_stime.tv_usec), /* 17 cstime */

	    ki.p_priority,				/* XXX: 18 priority */
	    ki.p_nice - NZERO,				/* 19 nice */
	    ki.p_nlwps,					/* 20 num_threads */

	    (long long)rt.tv_sec,
	    UTIME2TICKS(ki.p_ustart_sec, ki.p_ustart_usec), /* 22 start_time */
	    ki.p_vm_msize,				/* 23 vsize */
	    PGTOKB(ki.p_vm_rssize),			/* 24 rss */
	    p->p_rlimit[RLIMIT_RSS].rlim_cur,		/* 25 rsslim */

	    stext,					/* 26 start_code */
	    etext,					/* 27 end_code */
	    sstack,					/* 28 start_stack */

	    0,						/* XXX: 29 esp */
	    0,						/* XXX: 30 eip */

	    ki.p_siglist.__bits[0],			/* XXX: 31 pending */
	    0,						/* XXX: 32 blocked */
	    ki.p_sigignore.__bits[0],		/* 33 sigign */
	    ki.p_sigcatch.__bits[0],		/* 34 sigcatch */

	    ki.p_wchan,					/* 35 wchan */
	    ki.p_uru_nvcsw,
	    ki.p_uru_nivcsw,
	    ki.p_exitsig,				/* 38 exit_signal */
	    ki.p_cpuid);				/* 39 task_cpu */

	mutex_exit(p->p_lock);
	mutex_exit(proc_lock);

	uvmspace_free(vm);

	if (len == 0)
		goto out;

	error = uiomove_frombuf(bf, len, uio);
out:
	free(bf, M_TEMP);
	return error;
}
/*
 * 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);
}