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 <[email protected]>
--- 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;
}