diff options
author | ed <ed@FreeBSD.org> | 2008-08-21 15:02:17 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2008-08-21 15:02:17 +0000 |
commit | 2be6ecbc22e75accec1b8856bc22f6f3c32fe681 (patch) | |
tree | 4fe43dd524674a82f31d9b038b5ec16f1d8348ba /sys/kern/kern_acct.c | |
parent | 4dd155254adc4e96a9b0713f38332ed3eb7f84b9 (diff) | |
download | FreeBSD-src-2be6ecbc22e75accec1b8856bc22f6f3c32fe681.zip FreeBSD-src-2be6ecbc22e75accec1b8856bc22f6f3c32fe681.tar.gz |
Properly lock proctree_lock before locking the process while accounting.
During the import of the MPSAFE TTY layer (r181905), I changed
acct_process() to lock proctree_lock instead of SESS_LOCK, because
s_ttyp is now locked using proctree_lock. One of the things I forgot,
was to lock it before we PROC_LOCK.
Commit this patch, written by kib@. To ensure we hold proctree_lock as
short as possible, obtaining `ac_tty' has now been made the first step
of filling `acct'.
Reported by: Kevin <kevinxlinuz 163 com>
Solved by: kib
Diffstat (limited to 'sys/kern/kern_acct.c')
-rw-r--r-- | sys/kern/kern_acct.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index e505f62..d45e3b7 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -366,16 +366,25 @@ acct_process(struct thread *td) * Get process accounting information. */ + sx_slock(&proctree_lock); PROC_LOCK(p); - /* (1) The name of the command that ran */ + + /* (1) The terminal from which the process was started */ + if ((p->p_flag & P_CONTROLT) && p->p_pgrp->pg_session->s_ttyp) + acct.ac_tty = tty_udev(p->p_pgrp->pg_session->s_ttyp); + else + acct.ac_tty = NODEV; + sx_sunlock(&proctree_lock); + + /* (2) 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 */ + /* (3) The amount of user and system time that was used */ rufetchcalc(p, &ru, &ut, &st); acct.ac_utime = encode_timeval(ut); acct.ac_stime = encode_timeval(st); - /* (3) The elapsed time the command ran (and its starting time) */ + /* (4) The elapsed time the command ran (and its starting time) */ tmp = boottime; timevaladd(&tmp, &p->p_stats->p_start); acct.ac_btime = tmp.tv_sec; @@ -383,7 +392,7 @@ acct_process(struct thread *td) timevalsub(&tmp, &p->p_stats->p_start); acct.ac_etime = encode_timeval(tmp); - /* (4) The average amount of memory used */ + /* (5) The average amount of memory used */ tmp = ut; timevaladd(&tmp, &st); /* Convert tmp (i.e. u + s) into hz units to match ru_i*. */ @@ -394,21 +403,13 @@ acct_process(struct thread *td) else acct.ac_mem = 0; - /* (5) The number of disk I/O operations done */ + /* (6) The number of disk I/O operations done */ acct.ac_io = encode_long(ru.ru_inblock + ru.ru_oublock); - /* (6) The UID and GID of the process */ + /* (7) The UID and GID of the process */ acct.ac_uid = p->p_ucred->cr_ruid; acct.ac_gid = p->p_ucred->cr_rgid; - /* (7) The terminal from which the process was started */ - sx_slock(&proctree_lock); - if ((p->p_flag & P_CONTROLT) && p->p_pgrp->pg_session->s_ttyp) - acct.ac_tty = tty_udev(p->p_pgrp->pg_session->s_ttyp); - else - acct.ac_tty = NODEV; - sx_sunlock(&proctree_lock); - /* (8) The boolean flags that tell how the process terminated, etc. */ acct.ac_flagx = p->p_acflag; PROC_UNLOCK(p); |