Index: linux/kernel/fork.c =================================================================== --- linux.orig/kernel/fork.c 2005-02-17 19:24:54.388927143 -0800 +++ linux/kernel/fork.c 2005-02-18 09:59:14.179816325 -0800 @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include Index: linux/fs/exec.c =================================================================== --- linux.orig/fs/exec.c 2005-02-18 05:45:19.868493728 -0800 +++ linux/fs/exec.c 2005-02-18 09:59:14.196418021 -0800 @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include Index: linux/kernel/exit.c =================================================================== --- linux.orig/kernel/exit.c 2005-02-17 19:24:54.380138011 -0800 +++ linux/kernel/exit.c 2005-02-18 10:05:43.506174767 -0800 @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -814,7 +814,7 @@ fastcall NORET_TYPE void do_exit(long co group_dead = atomic_dec_and_test(&tsk->signal->live); if (group_dead) { del_timer_sync(&tsk->signal->real_timer); - acct_process(code); + acct_do_exit(code, tsk); } exit_mm(tsk); Index: linux/include/linux/acct_common.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux/include/linux/acct_common.h 2005-02-18 12:41:28.232626074 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2005 Silicon Graphics, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Jay Lan + */ + +/* + * include/linux/acct_common.h + * + * Common Accounting for Linux - Definitions + * + * 02/17/05 Jay Lan . Initial creation of the header file. + * This header file contains the definitions needed to support + * registration/unregistration of various accounting agents to + * the kernel. It also contains prototypes of common routines. + * + */ + +#ifndef _LINUX_ACCT_COMMON_H +#define _LINUX_ACCT_COMMON_H + +#include +#include +#include + + +/* + * Various accounting modules ID's + */ +#define ACCT_BSD 0 +#define ACCT_CSA 1 +#define ACCT_ELSA 2 +#define LAST_ACCT_ID ACCT_ELSA +#define ACCT_PKG_COUNT (LAST_ACCT_ID+1) + +/* + * Used by accounting packages to define the callback functions into the + * packages. + * + * STRUCT MEMBERS: + * pkg_id: Accounting package ID. This should be set the package + * when register. + * do_exit: Function pointer to function used when do_exit() + * hook is needed. + * This is optional and may be set to NULL if it is + * not needed by the accounting package. + */ +struct acct_hook { + int pkg_id; /* accounting package ID */ + void (*do_exit)(long exitcode, void *data); +}; + + +/* Common accounting routines prototypes */ +extern int acct_register(struct acct_hook *); +extern int acct_unregister(struct acct_hook *); + +#ifdef CONFIG_ACCT_COMMON +extern void acct_do_exit(long, struct task_struct *tsk); +extern void acct_update_integrals(struct task_struct *tsk); +extern void acct_clear_integrals(struct task_struct *tsk); +#else +#define acct_do_exit(x,y) do { } while (0) +#define acct_update_integrals(x) do { } while (0) +#define acct_clear_integrals(x) do { } while (0) +#endif + +#endif /* _LINUX_ACCT_COMMON_H */ Index: linux/include/linux/acct.h =================================================================== --- linux.orig/include/linux/acct.h 2005-02-17 19:24:52.843016528 -0800 +++ linux/include/linux/acct.h 2005-02-18 10:02:00.557125382 -0800 @@ -119,14 +119,10 @@ struct acct_v3 #ifdef CONFIG_BSD_PROCESS_ACCT struct super_block; extern void acct_auto_close(struct super_block *sb); -extern void acct_process(long exitcode); -extern void acct_update_integrals(struct task_struct *tsk); -extern void acct_clear_integrals(struct task_struct *tsk); +extern void acct_process(long exitcode, void *data); #else #define acct_auto_close(x) do { } while (0) -#define acct_process(x) do { } while (0) -#define acct_update_integrals(x) do { } while (0) -#define acct_clear_integrals(task) do { } while (0) +#define acct_process(x,y) do { } while (0) #endif /* Index: linux/kernel/acct.c =================================================================== --- linux.orig/kernel/acct.c 2005-02-17 19:24:54.307871817 -0800 +++ linux/kernel/acct.c 2005-02-18 12:43:38.704382273 -0800 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,37 @@ struct acct_glbs { }; static struct acct_glbs acct_globals __cacheline_aligned = {SPIN_LOCK_UNLOCKED}; +static struct acct_hook bsd_hook = { + .pkg_id = ACCT_BSD, + .do_exit = acct_process, +}; + +/* + * init routine of BSD Process Accounting + */ +static int __init +acct_bsd_init(void) +{ + int retval = 0; + + retval = acct_register(&bsd_hook); + if (retval == 0) + printk(KERN_INFO "BSD Process Accounting Initialized\n"); + else + printk(KERN_ERR "BSD Process Accounting Init Failed\n"); + return retval; +} + +/* + * cleanup routine of BSD Process Accounting + */ +static void __exit +acct_bsd_cleanup(void) +{ + (void)acct_unregister(&bsd_hook); + printk(KERN_INFO "BSD Proces Accounting Unregistered\n"); + return; +} /* * Called whenever the timer says to check the free space. @@ -506,7 +538,7 @@ static void do_acct_process(long exitcod /* * acct_process - now just a wrapper around do_acct_process */ -void acct_process(long exitcode) +void acct_process(long exitcode, void *data) { struct file *file = NULL; @@ -530,32 +562,5 @@ void acct_process(long exitcode) } -/* - * acct_update_integrals - * - update mm integral fields in task_struct - */ -void acct_update_integrals(struct task_struct *tsk) -{ - if (likely(tsk->mm)) { - long delta = tsk->stime - tsk->acct_stimexpd; - - if (delta == 0) - return; - tsk->acct_stimexpd = tsk->stime; - tsk->acct_rss_mem1 += delta * tsk->mm->rss; - tsk->acct_vm_mem1 += delta * tsk->mm->total_vm; - } -} - -/* - * acct_clear_integrals - * - clear the mm integral fields in task_struct - */ -void acct_clear_integrals(struct task_struct *tsk) -{ - if (tsk) { - tsk->acct_stimexpd = 0; - tsk->acct_rss_mem1 = 0; - tsk->acct_vm_mem1 = 0; - } -} +module_init(acct_bsd_init); +module_exit(acct_bsd_cleanup); Index: linux/kernel/acct_common.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux/kernel/acct_common.c 2005-02-18 12:39:06.266636027 -0800 @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2005 Silicon Graphics, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Jay Lan + */ + +/* + * kernel/acct_common.c + * + * Common Accounting routines for Linux Accounting + * + * The acct.c mainly is BSD-style process accounting. However, + * as more accounting packages are created, such as CSA and + * ELSA, to extend the usage of the BSD accounting, there is + * a need to have a common file for all accounting packages + * including the BSD-style process accounting. + * + * 02/17/05 Jay Lan . Initial creation of the file to + * provide common codes of Linux accounting. It also provides + * mechanism for various accounting agents to register and + * unregister to the kernel with callback hook. Only + * do_exit callback is supported initially. + * + */ + +#include +#include + + +/* Accounting packages list */ +static struct acct_hook *acct_list[ACCT_PKG_COUNT] = {0}; +static DECLARE_RWSEM(acct_list_sem); + + +/* + * acct_register - accounting package registers to the kernel. + * @ap: The registering accounting package, in struct acct_pkg pointer type + * + * returns -errno value on failure, 0 on success. + */ +int +acct_register(struct acct_hook *ap) +{ + if (!ap) + return -EINVAL; /* Invalid value */ + if (ap->pkg_id < 0 || ap->pkg_id > LAST_ACCT_ID) + return -EINVAL; /* Invalid value */ + + down_write(&acct_list_sem); + if (acct_list[ap->pkg_id] != NULL) { + up_write(&acct_list_sem); + return -EBUSY; /* Already registered */ + } + + acct_list[ap->pkg_id] = ap; + up_write(&acct_list_sem); + return 0; +} +EXPORT_SYMBOL_GPL(acct_register); + + +/* + * acct_unregister - accounting package unregister to the kernel. + * @ap: The unregistering accounting package, in struct acct_hook pointer type + * + * Returns -errno on failure, 0 on success. + */ +int +acct_unregister(struct acct_hook *ap) +{ + if (!ap) + return -EINVAL; /* Invalid value */ + if (ap->pkg_id < 0 || ap->pkg_id > LAST_ACCT_ID) + return -EINVAL; /* Invalid value */ + + down_write(&acct_list_sem); + + if (acct_list[ap->pkg_id] != ap) { + up_write(&acct_list_sem); + return -EFAULT; /* Not matching entry */ + } + + acct_list[ap->pkg_id] = NULL; + up_write(&acct_list_sem); + return 0; +} +EXPORT_SYMBOL_GPL(acct_unregister); + + +/* + * do_exit() hook for accounting packages + * @exitcode: the exitcode to pass along + * + */ +void acct_do_exit(long exitcode, struct task_struct *tsk) +{ + int i; + + down_write(&acct_list_sem); + for (i=0; i < ACCT_PKG_COUNT; i++) { + if (acct_list[i] == NULL) /* not registered */ + continue; + if (acct_list[i]->do_exit != NULL) { /* do_exit callback */ + switch (acct_list[i]->pkg_id) { + case ACCT_BSD: + acct_list[i]->do_exit(exitcode, NULL); + break; + case ACCT_CSA: + acct_list[i]->do_exit(exitcode, tsk); + break; + default: + break; + } + } + } + up_write(&acct_list_sem); + return; +} + + +/* + * acct_update_integrals + * - update mm integral fields in task_struct + */ +void acct_update_integrals(struct task_struct *tsk) +{ + if (likely(tsk->mm)) { + long delta = tsk->stime - tsk->acct_stimexpd; + + if (delta == 0) return; + tsk->acct_stimexpd = tsk->stime; + tsk->acct_rss_mem1 += delta * tsk->mm->rss; + tsk->acct_vm_mem1 += delta * tsk->mm->total_vm; + } +} + + +/* + * acct_clear_integrals + * - clear the mm integral fields in task_struct + */ +void acct_clear_integrals(struct task_struct *tsk) +{ + if (tsk) { + tsk->acct_stimexpd = 0; + tsk->acct_rss_mem1 = 0; + tsk->acct_vm_mem1 = 0; + } +} + + Index: linux/kernel/Makefile =================================================================== --- linux.orig/kernel/Makefile 2005-02-17 19:24:54.485607592 -0800 +++ linux/kernel/Makefile 2005-02-18 10:04:23.279947003 -0800 @@ -16,6 +16,7 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ +obj-$(CONFIG_ACCT_COMMON) += acct_common.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_COMPAT) += compat.o Index: linux/init/Kconfig =================================================================== --- linux.orig/init/Kconfig 2005-02-17 19:24:54.282480992 -0800 +++ linux/init/Kconfig 2005-02-18 09:59:14.330208158 -0800 @@ -113,8 +113,19 @@ config POSIX_MQUEUE If unsure, say Y. +config ACCT_COMMON + bool "Accounting Comon Layer" + help + If you say Y here, an accounting common code is built into the + kernel. In addition to common code for various accounting + agents, such as BSD Process Accounting, CSA, ELSA, etc., this code + allows various accounting agents to register to it. + + If you ever need system accounting, you need this; so say Y. + config BSD_PROCESS_ACCT bool "BSD Process Accounting" + depends on ACCT_COMMON help If you say Y here, a user level program will be able to instruct the kernel (via a special system call) to write process accounting Index: linux/kernel/sched.c =================================================================== --- linux.orig/kernel/sched.c 2005-02-17 19:24:54.628186840 -0800 +++ linux/kernel/sched.c 2005-02-18 11:13:14.200643593 -0800 @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include