Re: [PATCH 2.6.11-rc3-mm2] connector: Add a fork connector

From: Guillaume Thouvenin
Date: Wed Feb 23 2005 - 03:54:44 EST


Hello,

This patch replaces the relay_fork module and it implements a fork
connector in the kernel/fork.c:do_fork() routine. The connector sends
information about parent PID and child PID over a netlink interface. It
allows to several user space applications to be informed when a fork
occurs in the kernel. The main drawback is that even if nobody listens,
message is send. I don't know how to avoid that.

It is used by ELSA to manage group of processes in user space.

ChangeLog:

- Add a "depends on CONNECTOR=y" in the Kconfig
- Remove the macro #if defined(CONFIG_CONNECTOR)
- cn_netlink_send() sends messages to the correct group which is
CN_IDX_FORK


Thanks to Evgeniy and to everyone for the comments,
Guillaume

Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@xxxxxxxx>

---

drivers/connector/Kconfig | 8 ++++++++
include/linux/connector.h | 2 ++
kernel/fork.c | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+)

diff -uprN -X dontdiff linux-2.6.11-rc3-mm2/drivers/connector/Kconfig linux-2.6.11-rc3-mm2-cnfork/drivers/connector/Kconfig
--- linux-2.6.11-rc3-mm2/drivers/connector/Kconfig 2005-02-11 11:00:16.000000000 +0100
+++ linux-2.6.11-rc3-mm2-cnfork/drivers/connector/Kconfig 2005-02-21 09:52:22.000000000 +0100
@@ -10,4 +10,12 @@ config CONNECTOR
Connector support can also be built as a module. If so, the module
will be called cn.ko.

+config FORK_CONNECTOR
+ bool "Enable fork connector"
+ depends on CONNECTOR=y
+ ---help---
+ It adds a connector in kernel/fork.c:do_fork() function. When a fork
+ occurs, netlink is used to transfer information about the parent and
+ its child. This information can be used by a user space application.
+
endmenu
diff -uprN -X dontdiff linux-2.6.11-rc3-mm2/include/linux/connector.h linux-2.6.11-rc3-mm2-cnfork/include/linux/connector.h
--- linux-2.6.11-rc3-mm2/include/linux/connector.h 2005-02-11 11:00:18.000000000 +0100
+++ linux-2.6.11-rc3-mm2-cnfork/include/linux/connector.h 2005-02-16 15:07:46.000000000 +0100
@@ -28,6 +28,8 @@
#define CN_VAL_KOBJECT_UEVENT 0x0000
#define CN_IDX_SUPERIO 0xaabb /* SuperIO subsystem */
#define CN_VAL_SUPERIO 0xccdd
+#define CN_IDX_FORK 0xfeed /* fork events */
+#define CN_VAL_FORK 0xbeef


#define CONNECTOR_MAX_MSG_SIZE 1024
diff -uprN -X dontdiff linux-2.6.11-rc3-mm2/kernel/fork.c linux-2.6.11-rc3-mm2-cnfork/kernel/fork.c
--- linux-2.6.11-rc3-mm2/kernel/fork.c 2005-02-11 11:00:18.000000000 +0100
+++ linux-2.6.11-rc3-mm2-cnfork/kernel/fork.c 2005-02-21 09:52:40.000000000 +0100
@@ -41,6 +41,7 @@
#include <linux/profile.h>
#include <linux/rmap.h>
#include <linux/acct.h>
+#include <linux/connector.h>

#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -63,6 +64,44 @@ DEFINE_PER_CPU(unsigned long, process_co

EXPORT_SYMBOL(tasklist_lock);

+#ifdef CONFIG_FORK_CONNECTOR
+#define FORK_CN_INFO_SIZE 64
+static inline void fork_connector(pid_t parent, pid_t child)
+{
+ struct cb_id fork_id = {CN_IDX_FORK, CN_VAL_FORK};
+ static __u32 seq; /* used to test if we lost message */
+
+ if (cn_already_initialized) {
+ struct cn_msg *msg;
+ size_t size;
+
+ size = sizeof(*msg) + FORK_CN_INFO_SIZE;
+ msg = kmalloc(size, GFP_KERNEL);
+ if (msg) {
+ memset(msg, '\0', size);
+ memcpy(&msg->id, &fork_id, sizeof(msg->id));
+ msg->seq = seq++;
+ msg->ack = 0; /* not used */
+ /*
+ * size of data is the number of characters
+ * printed plus one for the trailing '\0'
+ */
+ msg->len = snprintf(msg->data, FORK_CN_INFO_SIZE-1,
+ "%i %i", parent, child) + 1;
+
+ cn_netlink_send(msg, CN_IDX_FORK);
+
+ kfree(msg);
+ }
+ }
+}
+#else
+static inline void fork_connector(pid_t parent, pid_t child)
+{
+ return;
+}
+#endif
+
int nr_processes(void)
{
int cpu;
@@ -1238,6 +1277,8 @@ long do_fork(unsigned long clone_flags,
if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
}
+
+ fork_connector(current->pid, p->pid);
} else {
free_pidmap(pid);
pid = PTR_ERR(p);


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