Deleted Added
full compact
kern_acct.c (234927) kern_acct.c (241896)
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * Copyright (c) 2005 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * All or some portions of this file are derived from material licensed

--- 54 unchanged lines hidden (view full) ---

63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 *
67 * @(#)kern_acct.c 8.1 (Berkeley) 6/14/93
68 */
69
70#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * Copyright (c) 2005 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * All or some portions of this file are derived from material licensed

--- 54 unchanged lines hidden (view full) ---

63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE.
66 *
67 * @(#)kern_acct.c 8.1 (Berkeley) 6/14/93
68 */
69
70#include <sys/cdefs.h>
71__FBSDID("$FreeBSD: head/sys/kern/kern_acct.c 234927 2012-05-02 14:25:39Z jhb $");
71__FBSDID("$FreeBSD: head/sys/kern/kern_acct.c 241896 2012-10-22 17:50:54Z kib $");
72
73#include <sys/param.h>
74#include <sys/systm.h>
75#include <sys/acct.h>
76#include <sys/fcntl.h>
77#include <sys/kernel.h>
78#include <sys/kthread.h>
79#include <sys/limits.h>

--- 111 unchanged lines hidden (view full) ---

191/*
192 * Accounting system call. Written based on the specification and previous
193 * implementation done by Mark Tinguely.
194 */
195int
196sys_acct(struct thread *td, struct acct_args *uap)
197{
198 struct nameidata nd;
72
73#include <sys/param.h>
74#include <sys/systm.h>
75#include <sys/acct.h>
76#include <sys/fcntl.h>
77#include <sys/kernel.h>
78#include <sys/kthread.h>
79#include <sys/limits.h>

--- 111 unchanged lines hidden (view full) ---

191/*
192 * Accounting system call. Written based on the specification and previous
193 * implementation done by Mark Tinguely.
194 */
195int
196sys_acct(struct thread *td, struct acct_args *uap)
197{
198 struct nameidata nd;
199 int error, flags, vfslocked, replacing;
199 int error, flags, replacing;
200
201 error = priv_check(td, PRIV_ACCT);
202 if (error)
203 return (error);
204
205 /*
206 * If accounting is to be started to a file, open that file for
207 * appending and make sure it's a 'normal'.
208 */
209 if (uap->path != NULL) {
200
201 error = priv_check(td, PRIV_ACCT);
202 if (error)
203 return (error);
204
205 /*
206 * If accounting is to be started to a file, open that file for
207 * appending and make sure it's a 'normal'.
208 */
209 if (uap->path != NULL) {
210 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1,
210 NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1,
211 UIO_USERSPACE, uap->path, td);
212 flags = FWRITE | O_APPEND;
213 error = vn_open(&nd, &flags, 0, NULL);
214 if (error)
215 return (error);
211 UIO_USERSPACE, uap->path, td);
212 flags = FWRITE | O_APPEND;
213 error = vn_open(&nd, &flags, 0, NULL);
214 if (error)
215 return (error);
216 vfslocked = NDHASGIANT(&nd);
217 NDFREE(&nd, NDF_ONLY_PNBUF);
218#ifdef MAC
219 error = mac_system_check_acct(td->td_ucred, nd.ni_vp);
220 if (error) {
221 VOP_UNLOCK(nd.ni_vp, 0);
222 vn_close(nd.ni_vp, flags, td->td_ucred, td);
216 NDFREE(&nd, NDF_ONLY_PNBUF);
217#ifdef MAC
218 error = mac_system_check_acct(td->td_ucred, nd.ni_vp);
219 if (error) {
220 VOP_UNLOCK(nd.ni_vp, 0);
221 vn_close(nd.ni_vp, flags, td->td_ucred, td);
223 VFS_UNLOCK_GIANT(vfslocked);
224 return (error);
225 }
226#endif
227 VOP_UNLOCK(nd.ni_vp, 0);
228 if (nd.ni_vp->v_type != VREG) {
229 vn_close(nd.ni_vp, flags, td->td_ucred, td);
222 return (error);
223 }
224#endif
225 VOP_UNLOCK(nd.ni_vp, 0);
226 if (nd.ni_vp->v_type != VREG) {
227 vn_close(nd.ni_vp, flags, td->td_ucred, td);
230 VFS_UNLOCK_GIANT(vfslocked);
231 return (EACCES);
232 }
228 return (EACCES);
229 }
233 VFS_UNLOCK_GIANT(vfslocked);
234#ifdef MAC
235 } else {
236 error = mac_system_check_acct(td->td_ucred, NULL);
237 if (error)
238 return (error);
239#endif
240 }
241

--- 12 unchanged lines hidden (view full) ---

254
255 /*
256 * If accounting was previously enabled, kill the old space-watcher,
257 * close the file, and (if no new file was specified, leave). Reset
258 * the suspended state regardless of whether accounting remains
259 * enabled.
260 */
261 acct_suspended = 0;
230#ifdef MAC
231 } else {
232 error = mac_system_check_acct(td->td_ucred, NULL);
233 if (error)
234 return (error);
235#endif
236 }
237

--- 12 unchanged lines hidden (view full) ---

250
251 /*
252 * If accounting was previously enabled, kill the old space-watcher,
253 * close the file, and (if no new file was specified, leave). Reset
254 * the suspended state regardless of whether accounting remains
255 * enabled.
256 */
257 acct_suspended = 0;
262 if (acct_vp != NULL) {
263 vfslocked = VFS_LOCK_GIANT(acct_vp->v_mount);
258 if (acct_vp != NULL)
264 error = acct_disable(td, !replacing);
259 error = acct_disable(td, !replacing);
265 VFS_UNLOCK_GIANT(vfslocked);
266 }
267 if (uap->path == NULL) {
268 if (acct_state & ACCT_RUNNING) {
269 acct_state |= ACCT_EXITREQ;
270 wakeup(&acct_state);
271 }
272 sx_xunlock(&acct_sx);
273 return (error);
274 }

--- 11 unchanged lines hidden (view full) ---

286 /*
287 * Try to start up an accounting kthread. We may start more
288 * than one, but if so the extras will commit suicide as
289 * soon as they start up.
290 */
291 error = kproc_create(acct_thread, NULL, NULL, 0, 0,
292 "accounting");
293 if (error) {
260 if (uap->path == NULL) {
261 if (acct_state & ACCT_RUNNING) {
262 acct_state |= ACCT_EXITREQ;
263 wakeup(&acct_state);
264 }
265 sx_xunlock(&acct_sx);
266 return (error);
267 }

--- 11 unchanged lines hidden (view full) ---

279 /*
280 * Try to start up an accounting kthread. We may start more
281 * than one, but if so the extras will commit suicide as
282 * soon as they start up.
283 */
284 error = kproc_create(acct_thread, NULL, NULL, 0, 0,
285 "accounting");
286 if (error) {
294 vfslocked = VFS_LOCK_GIANT(acct_vp->v_mount);
295 (void) vn_close(acct_vp, acct_flags, acct_cred, td);
287 (void) vn_close(acct_vp, acct_flags, acct_cred, td);
296 VFS_UNLOCK_GIANT(vfslocked);
297 crfree(acct_cred);
298 acct_configured = 0;
299 acct_vp = NULL;
300 acct_cred = NULL;
301 acct_flags = 0;
302 sx_xunlock(&acct_sx);
303 log(LOG_NOTICE, "Unable to start accounting thread\n");
304 return (error);

--- 36 unchanged lines hidden (view full) ---

341int
342acct_process(struct thread *td)
343{
344 struct acctv2 acct;
345 struct timeval ut, st, tmp;
346 struct plimit *newlim, *oldlim;
347 struct proc *p;
348 struct rusage ru;
288 crfree(acct_cred);
289 acct_configured = 0;
290 acct_vp = NULL;
291 acct_cred = NULL;
292 acct_flags = 0;
293 sx_xunlock(&acct_sx);
294 log(LOG_NOTICE, "Unable to start accounting thread\n");
295 return (error);

--- 36 unchanged lines hidden (view full) ---

332int
333acct_process(struct thread *td)
334{
335 struct acctv2 acct;
336 struct timeval ut, st, tmp;
337 struct plimit *newlim, *oldlim;
338 struct proc *p;
339 struct rusage ru;
349 int t, ret, vfslocked;
340 int t, ret;
350
351 /*
352 * Lockless check of accounting condition before doing the hard
353 * work.
354 */
355 if (acct_vp == NULL || acct_suspended)
356 return (0);
357

--- 79 unchanged lines hidden (view full) ---

437 newlim->pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
438 p->p_limit = newlim;
439 PROC_UNLOCK(p);
440 lim_free(oldlim);
441
442 /*
443 * Write the accounting information to the file.
444 */
341
342 /*
343 * Lockless check of accounting condition before doing the hard
344 * work.
345 */
346 if (acct_vp == NULL || acct_suspended)
347 return (0);
348

--- 79 unchanged lines hidden (view full) ---

428 newlim->pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
429 p->p_limit = newlim;
430 PROC_UNLOCK(p);
431 lim_free(oldlim);
432
433 /*
434 * Write the accounting information to the file.
435 */
445 vfslocked = VFS_LOCK_GIANT(acct_vp->v_mount);
446 ret = vn_rdwr(UIO_WRITE, acct_vp, (caddr_t)&acct, sizeof (acct),
447 (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED,
448 NULL, td);
436 ret = vn_rdwr(UIO_WRITE, acct_vp, (caddr_t)&acct, sizeof (acct),
437 (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED,
438 NULL, td);
449 VFS_UNLOCK_GIANT(vfslocked);
450 sx_sunlock(&acct_sx);
451 return (ret);
452}
453
454/* FLOAT_CONVERSION_START (Regression testing; don't remove this line.) */
455
456/* Convert timevals and longs into IEEE-754 bit patterns. */
457

--- 100 unchanged lines hidden (view full) ---

558 * has been vgone()'d out from underneath us, e.g. when the file
559 * system containing the accounting file has been forcibly unmounted.
560 */
561/* ARGSUSED */
562static void
563acctwatch(void)
564{
565 struct statfs sb;
439 sx_sunlock(&acct_sx);
440 return (ret);
441}
442
443/* FLOAT_CONVERSION_START (Regression testing; don't remove this line.) */
444
445/* Convert timevals and longs into IEEE-754 bit patterns. */
446

--- 100 unchanged lines hidden (view full) ---

547 * has been vgone()'d out from underneath us, e.g. when the file
548 * system containing the accounting file has been forcibly unmounted.
549 */
550/* ARGSUSED */
551static void
552acctwatch(void)
553{
554 struct statfs sb;
566 int vfslocked;
567
568 sx_assert(&acct_sx, SX_XLOCKED);
569
570 /*
571 * If accounting was disabled before our kthread was scheduled,
572 * then acct_vp might be NULL. If so, just ask our kthread to
573 * exit and return.
574 */
575 if (acct_vp == NULL) {
576 acct_state |= ACCT_EXITREQ;
577 return;
578 }
579
580 /*
581 * If our vnode is no longer valid, tear it down and signal the
582 * accounting thread to die.
583 */
555
556 sx_assert(&acct_sx, SX_XLOCKED);
557
558 /*
559 * If accounting was disabled before our kthread was scheduled,
560 * then acct_vp might be NULL. If so, just ask our kthread to
561 * exit and return.
562 */
563 if (acct_vp == NULL) {
564 acct_state |= ACCT_EXITREQ;
565 return;
566 }
567
568 /*
569 * If our vnode is no longer valid, tear it down and signal the
570 * accounting thread to die.
571 */
584 vfslocked = VFS_LOCK_GIANT(acct_vp->v_mount);
585 if (acct_vp->v_type == VBAD) {
586 (void) acct_disable(NULL, 1);
572 if (acct_vp->v_type == VBAD) {
573 (void) acct_disable(NULL, 1);
587 VFS_UNLOCK_GIANT(vfslocked);
588 acct_state |= ACCT_EXITREQ;
589 return;
590 }
591
592 /*
593 * Stopping here is better than continuing, maybe it will be VBAD
594 * next time around.
595 */
574 acct_state |= ACCT_EXITREQ;
575 return;
576 }
577
578 /*
579 * Stopping here is better than continuing, maybe it will be VBAD
580 * next time around.
581 */
596 if (VFS_STATFS(acct_vp->v_mount, &sb) < 0) {
597 VFS_UNLOCK_GIANT(vfslocked);
582 if (VFS_STATFS(acct_vp->v_mount, &sb) < 0)
598 return;
583 return;
599 }
600 VFS_UNLOCK_GIANT(vfslocked);
601 if (acct_suspended) {
602 if (sb.f_bavail > (int64_t)(acctresume * sb.f_blocks /
603 100)) {
604 acct_suspended = 0;
605 log(LOG_NOTICE, "Accounting resumed\n");
606 }
607 } else {
608 if (sb.f_bavail <= (int64_t)(acctsuspend * sb.f_blocks /

--- 55 unchanged lines hidden ---
584 if (acct_suspended) {
585 if (sb.f_bavail > (int64_t)(acctresume * sb.f_blocks /
586 100)) {
587 acct_suspended = 0;
588 log(LOG_NOTICE, "Accounting resumed\n");
589 }
590 } else {
591 if (sb.f_bavail <= (int64_t)(acctsuspend * sb.f_blocks /

--- 55 unchanged lines hidden ---