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

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to