Messages in this thread Patch in this message | | | Subject | [PATCH 2.6.10] add a fork_hook for the relay_fork module | From | Guillaume Thouvenin <> | Date | Wed, 19 Jan 2005 14:55:44 +0100 |
| |
Hello,
For the relay fork module (I posted it today), I need to execute a function when a fork occurs. My solution is to add a pointer to a function (called fork_hook) in the do_fork() and if this pointer isn't NULL, I call the function. To update the pointer to the function I export a symbol (called trace_fork) that defines another function with one parameter (the hook).
I know that such hooks are provided by PAGG patches but they are not available in the main Linux kernel tree and that's why I provide this one.
Thus, if you know a better solution I will be happy to read it.
Guillaume
Signed-Off-By: Guillaume Thouvenin <guillaume.thouvenin@bull.net>
--- linux-2.6.10/kernel/fork.c.orig 2005-01-04 11:28:58.000000000 +0100 +++ linux-2.6.10/kernel/fork.c 2005-01-19 14:23:25.000000000 +0100 @@ -61,6 +61,46 @@ rwlock_t tasklist_lock __cacheline_align EXPORT_SYMBOL(tasklist_lock); +/* + * fork_hook is a pointer to a function to call when forking if it + * isn't NULL. + */ +spinlock_t fork_hook_lock = SPIN_LOCK_UNLOCKED; +void (*fork_hook) (int, int) = NULL; + +/** + * trace_fork: call a given external function when forking + * @func: function to call + * + * This function sets the fork_hook and makes some sanity checks. + * Function returns 0 on success, -1 on failure (ie hook is + * already used). + * Limitation: currently, it can be used by only one module + */ +int trace_fork(void (*func) (int, int)) +{ + int err; + + err = 0; + + spin_lock(&fork_hook_lock); + + /* We can set the hook if it's not already used */ + if (func != NULL) { + if (fork_hook == NULL) + fork_hook = func; + else + err = -EBUSY; + } else + /* no check when releasing */ + fork_hook = NULL; + + spin_unlock(&fork_hook_lock); + + return err; +} +EXPORT_SYMBOL_GPL(trace_fork); + int nr_processes(void) { int cpu; @@ -1168,6 +1208,10 @@ long do_fork(unsigned long clone_flags, free_pidmap(pid); pid = PTR_ERR(p); } + + if (fork_hook != NULL) + fork_hook(current->pid, pid); + return pid; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |