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 --- |