public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch 1/2] fork_connector: add a fork connector
@ 2005-03-17  9:04 Guillaume Thouvenin
  2005-03-17 16:56 ` Jesse Barnes
  0 siblings, 1 reply; 55+ messages in thread
From: Guillaume Thouvenin @ 2005-03-17  9:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: lkml, Evgeniy Polyakov, Jay Lan, Erich Focht, Ram,
	Gerrit Huizenga, elsa-devel, Greg KH

  This patch adds a fork connector in the do_fork() routine. It sends a
netlink datagram when enabled. The message can be read by a user space
application. By this way, the user space application is alerted when a
fork occurs.

  It uses the userspace <-> kernelspace connector that works on top of
the netlink protocol. The fork connector is enabled or disabled by
sending a message to the connector. The unique sequence number of
messages can be used to check if a message is lost.

  When the fork connector is disabled, the "lat_proc fork" test returns
a value equal to:
     Process fork+exit: 154.6944 microseconds
  
  When the fork connector is enabled, the same test returns:
     Process fork+exit: 165.6667 microseconds

  So the overhead (the construction and the sending of the message) is
around 7%.

  This patch applies to 2.6.11-mm4. Some other patches are needed that
fix problems in the connector.c file. At least, you need to apply the
patch provided in the second email.

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

 drivers/connector/Kconfig   |   11 +++++
 drivers/connector/Makefile  |    1
 drivers/connector/cn_fork.c |   85 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/connector.h   |    4 ++
 kernel/fork.c               |   44 ++++++++++++++++++++++
 5 files changed, 145 insertions(+)

Index: linux-2.6.11-mm4-cnfork/drivers/connector/Kconfig
===================================================================
--- linux-2.6.11-mm4-cnfork.orig/drivers/connector/Kconfig	2005-03-16 14:21:46.000000000 +0100
+++ linux-2.6.11-mm4-cnfork/drivers/connector/Kconfig	2005-03-16 14:34:41.000000000 +0100
@@ -10,4 +10,15 @@
 	  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
+	default 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.
+	  The fork connector can be enable/disable by sending a message to the
+	  connector with the corresponding group id.
+	  
 endmenu
Index: linux-2.6.11-mm4-cnfork/drivers/connector/Makefile
===================================================================
--- linux-2.6.11-mm4-cnfork.orig/drivers/connector/Makefile	2005-03-16 14:21:46.000000000 +0100
+++ linux-2.6.11-mm4-cnfork/drivers/connector/Makefile	2005-03-16 14:34:41.000000000 +0100
@@ -1,2 +1,3 @@
 obj-$(CONFIG_CONNECTOR)		+= cn.o
+obj-$(CONFIG_FORK_CONNECTOR)	+= cn_fork.o 
 cn-objs		:= cn_queue.o connector.o
Index: linux-2.6.11-mm4-cnfork/drivers/connector/cn_fork.c
===================================================================
--- linux-2.6.11-mm4-cnfork.orig/drivers/connector/cn_fork.c	2003-01-30 11:24:37.000000000 +0100
+++ linux-2.6.11-mm4-cnfork/drivers/connector/cn_fork.c	2005-03-16 14:34:41.000000000 +0100
@@ -0,0 +1,85 @@
+/*
+ * 	cn_fork.c
+ * 
+ * 2005 Copyright (c) Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ * 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
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <linux/connector.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Guillaume Thouvenin <guillaume.thouvenin@bull.net>");
+MODULE_DESCRIPTION("Enable or disable the usage of the fork connector");
+
+int cn_fork_enable = 0;
+struct cb_id cb_fork_id = { CN_IDX_FORK, CN_VAL_FORK };
+
+/**
+ * cn_fork_callback - enable or disable the fork connector
+ * @data: message send by the connector 
+ *
+ * The callback allows to enable or disable the sending of information
+ * about fork in the do_fork() routine. To enable the fork, the user 
+ * space application must send the integer 1 in the data part of the 
+ * message. To disable the fork connector, it must send the integer 0.
+ */
+static void cn_fork_callback(void *data) 
+{
+	struct cn_msg *msg = (struct cn_msg *)data;
+
+	if (cn_already_initialized && (msg->len == sizeof(cn_fork_enable)))
+		memcpy(&cn_fork_enable, msg->data, sizeof(cn_fork_enable));
+}
+
+/**
+ * cn_fork_init - initialization entry point
+ *
+ * This routine will be run at kernel boot time because this driver is
+ * built in the kernel. It adds the connector callback to the connector 
+ * driver.
+ */
+static int cn_fork_init(void)
+{
+	int err;
+	
+	err = cn_add_callback(&cb_fork_id, "cn_fork", &cn_fork_callback);
+	if (err) {
+		printk(KERN_WARNING "Failed to register cn_fork\n");
+		return -EINVAL;
+	}	
+		
+	printk(KERN_NOTICE "cn_fork is registered\n");
+	return 0;
+}
+
+/**
+ * cn_fork_exit - exit entry point
+ *
+ * As this driver is always statically compiled into the kernel the
+ * cn_fork_exit has no effect.
+ */
+static void cn_fork_exit(void)
+{
+	cn_del_callback(&cb_fork_id);
+}
+
+module_init(cn_fork_init);
+module_exit(cn_fork_exit);
Index: linux-2.6.11-mm4-cnfork/include/linux/connector.h
===================================================================
--- linux-2.6.11-mm4-cnfork.orig/include/linux/connector.h	2005-03-16 14:21:49.000000000 +0100
+++ linux-2.6.11-mm4-cnfork/include/linux/connector.h	2005-03-16 14:34:41.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
@@ -133,6 +135,8 @@
 };
 
 extern int cn_already_initialized;
+extern int cn_fork_enable;
+extern struct cb_id cb_fork_id;
 
 int cn_add_callback(struct cb_id *, char *, void (* callback)(void *));
 void cn_del_callback(struct cb_id *);
Index: linux-2.6.11-mm4-cnfork/kernel/fork.c
===================================================================
--- linux-2.6.11-mm4-cnfork.orig/kernel/fork.c	2005-03-16 14:21:49.000000000 +0100
+++ linux-2.6.11-mm4-cnfork/kernel/fork.c	2005-03-16 14:34:41.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,47 @@
 
 EXPORT_SYMBOL(tasklist_lock);
 
+#ifdef CONFIG_FORK_CONNECTOR
+
+#define CN_FORK_INFO_SIZE	64
+#define CN_FORK_MSG_SIZE 	(sizeof(struct cn_msg) + CN_FORK_INFO_SIZE)
+
+static inline void fork_connector(pid_t parent, pid_t child)
+{
+	static DEFINE_SPINLOCK(cn_fork_lock);
+	static __u32 seq;   /* used to test if message is lost */
+
+	if (cn_fork_enable) {
+		struct cn_msg *msg;
+
+		__u8 buffer[CN_FORK_MSG_SIZE];	
+
+		msg = (struct cn_msg *)buffer;
+			
+		memcpy(&msg->id, &cb_fork_id, sizeof(msg->id));
+		spin_lock(&cn_fork_lock);
+		msg->seq = seq++;
+		spin_unlock(&cn_fork_lock);
+		msg->ack = 0; /* not used */
+		/* 
+		 * size of data is the number of characters 
+		 * printed plus one for the trailing '\0'
+		 */
+		/* just fill the data part with '\0' */
+		memset(msg->data, '\0', CN_FORK_INFO_SIZE);
+		msg->len = scnprintf(msg->data, CN_FORK_INFO_SIZE-1, 
+				    "%i %i", parent, child) + 1;
+
+		cn_netlink_send(msg, CN_IDX_FORK);
+	}
+}
+#else
+static inline void fork_connector(pid_t parent, pid_t child) 
+{
+	return; 
+}
+#endif /* CONFIG_FORK_CONNECTOR */
+
 int nr_processes(void)
 {
 	int cpu;
@@ -1253,6 +1295,8 @@
 			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);




^ permalink raw reply	[flat|nested] 55+ messages in thread
* [patch 1/2] fork_connector: add a fork connector
@ 2005-03-25 10:03 Guillaume Thouvenin
  2005-03-25 22:45 ` dean gaudet
  2005-03-28 21:42 ` Paul Jackson
  0 siblings, 2 replies; 55+ messages in thread
From: Guillaume Thouvenin @ 2005-03-25 10:03 UTC (permalink / raw)
  To: Andrew Morton, Greg KH
  Cc: lkml, Evgeniy Polyakov, Jay Lan, Erich Focht, Ram,
	Gerrit Huizenga, elsa-devel

  This patch adds a fork connector in the do_fork() routine. It sends a
netlink datagram when enabled. The message can be read by a user space
application. By this way, the user space application is alerted when a
fork occurs.

  It uses the userspace <-> kernelspace connector that works on top of
the netlink protocol. The fork connector is enabled or disabled by
sending a message to the connector. This operation should be done by
only one application. Such application can be downloaded from
http://cvs.sourceforge.net/viewcvs.py/elsa/elsa_project/utils/fcctl.c

  The unique sequence number of messages can be used to check if a
message is lost. This sequence number is relative to a CPU.

  The lmbench shows that the overhead (the construction and the sending
of the message) in the fork() routine is around 7%.

  This patch applies to 2.6.12-rc1-mm3. Some other patches are needed
that fix problems in the connector.c file. At least, you need to apply
the patch provided in the second email. 

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

 drivers/connector/Kconfig   |   11 ++++
 drivers/connector/Makefile  |    1
 drivers/connector/cn_fork.c |  104 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/connector.h   |    8 +++
 kernel/fork.c               |   44 ++++++++++++++++++
 5 files changed, 168 insertions(+)


Index: linux-2.6.12-rc1-mm3-cnfork/drivers/connector/Kconfig
===================================================================
--- linux-2.6.12-rc1-mm3-cnfork.orig/drivers/connector/Kconfig	2005-03-25 09:47:09.000000000 +0100
+++ linux-2.6.12-rc1-mm3-cnfork/drivers/connector/Kconfig	2005-03-25 10:14:21.000000000 +0100
@@ -10,4 +10,15 @@ 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
+	default 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.
+	  The fork connector can be enable/disable by sending a message to the
+	  connector with the corresponding group id.
+	  
 endmenu
Index: linux-2.6.12-rc1-mm3-cnfork/drivers/connector/Makefile
===================================================================
--- linux-2.6.12-rc1-mm3-cnfork.orig/drivers/connector/Makefile	2005-03-25 09:47:09.000000000 +0100
+++ linux-2.6.12-rc1-mm3-cnfork/drivers/connector/Makefile	2005-03-25 10:14:21.000000000 +0100
@@ -1,2 +1,3 @@
 obj-$(CONFIG_CONNECTOR)		+= cn.o
+obj-$(CONFIG_FORK_CONNECTOR)	+= cn_fork.o 
 cn-objs		:= cn_queue.o connector.o
Index: linux-2.6.12-rc1-mm3-cnfork/drivers/connector/cn_fork.c
===================================================================
--- linux-2.6.12-rc1-mm3-cnfork.orig/drivers/connector/cn_fork.c	2003-01-30 11:24:37.000000000 +0100
+++ linux-2.6.12-rc1-mm3-cnfork/drivers/connector/cn_fork.c	2005-03-25 10:14:21.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ * 	cn_fork.c
+ * 
+ * 2005 Copyright (c) Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ * 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
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <linux/connector.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Guillaume Thouvenin <guillaume.thouvenin@bull.net>");
+MODULE_DESCRIPTION("Enable or disable the usage of the fork connector");
+
+int cn_fork_enable = 0;
+struct cb_id cb_fork_id = { CN_IDX_FORK, CN_VAL_FORK };
+
+static inline void cn_fork_send_status(void)
+{
+	/* TODO */
+	printk(KERN_INFO "cn_fork_enable == %d\n", cn_fork_enable);
+}
+
+/**
+ * cn_fork_callback - enable or disable the fork connector
+ * @data: message send by the connector 
+ *
+ * The callback allows to enable or disable the sending of information
+ * about fork in the do_fork() routine. To enable the fork, the user 
+ * space application must send the integer 1 in the data part of the 
+ * message. To disable the fork connector, it must send the integer 0.
+ */
+static void cn_fork_callback(void *data) 
+{
+	struct cn_msg *msg = (struct cn_msg *)data;
+	int action;
+
+	if (cn_already_initialized && (msg->len == sizeof(cn_fork_enable))) {
+		memcpy(&action, msg->data, sizeof(cn_fork_enable));
+		switch(action) {
+			case FORK_CN_START:
+				cn_fork_enable = 1;
+				break;
+			case FORK_CN_STOP:
+				cn_fork_enable = 0;
+				break;
+			case FORK_CN_STATUS:
+				cn_fork_send_status();
+				break;
+		}
+	}
+}
+
+/**
+ * cn_fork_init - initialization entry point
+ *
+ * This routine will be run at kernel boot time because this driver is
+ * built in the kernel. It adds the connector callback to the connector 
+ * driver.
+ */
+static int cn_fork_init(void)
+{
+	int err;
+	
+	err = cn_add_callback(&cb_fork_id, "cn_fork", &cn_fork_callback);
+	if (err) {
+		printk(KERN_WARNING "Failed to register cn_fork\n");
+		return -EINVAL;
+	}	
+		
+	printk(KERN_NOTICE "cn_fork is registered\n");
+	return 0;
+}
+
+/**
+ * cn_fork_exit - exit entry point
+ *
+ * As this driver is always statically compiled into the kernel the
+ * cn_fork_exit has no effect.
+ */
+static void cn_fork_exit(void)
+{
+	cn_del_callback(&cb_fork_id);
+}
+
+module_init(cn_fork_init);
+module_exit(cn_fork_exit);
Index: linux-2.6.12-rc1-mm3-cnfork/include/linux/connector.h
===================================================================
--- linux-2.6.12-rc1-mm3-cnfork.orig/include/linux/connector.h	2005-03-25 09:47:11.000000000 +0100
+++ linux-2.6.12-rc1-mm3-cnfork/include/linux/connector.h	2005-03-25 10:14:21.000000000 +0100
@@ -28,10 +28,16 @@
 #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
 
+#define FORK_CN_STOP	0
+#define FORK_CN_START	1
+#define FORK_CN_STATUS	2
+
 struct cb_id
 {
 	__u32			idx;
@@ -133,6 +139,8 @@ struct cn_dev
 };
 
 extern int cn_already_initialized;
+extern int cn_fork_enable;
+extern struct cb_id cb_fork_id;
 
 int cn_add_callback(struct cb_id *, char *, void (* callback)(void *));
 void cn_del_callback(struct cb_id *);
Index: linux-2.6.12-rc1-mm3-cnfork/kernel/fork.c
===================================================================
--- linux-2.6.12-rc1-mm3-cnfork.orig/kernel/fork.c	2005-03-25 09:47:11.000000000 +0100
+++ linux-2.6.12-rc1-mm3-cnfork/kernel/fork.c	2005-03-25 10:14:21.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,47 @@ DEFINE_PER_CPU(unsigned long, process_co
 
 EXPORT_SYMBOL(tasklist_lock);
 
+#ifdef CONFIG_FORK_CONNECTOR
+
+#define CN_FORK_INFO_SIZE	64
+#define CN_FORK_MSG_SIZE 	(sizeof(struct cn_msg) + CN_FORK_INFO_SIZE)
+
+static DEFINE_PER_CPU(unsigned long, fork_counts);
+
+static inline void fork_connector(pid_t parent, pid_t child)
+{
+	if (cn_fork_enable) {
+		struct cn_msg *msg;
+		__u8 buffer[CN_FORK_MSG_SIZE];	
+
+		msg = (struct cn_msg *)buffer;
+			
+		memcpy(&msg->id, &cb_fork_id, sizeof(msg->id));
+		
+		msg->ack = 0; /* not used */
+		msg->seq = get_cpu_var(fork_counts)++;
+		
+		/* 
+		 * size of data is the number of characters 
+		 * printed plus one for the trailing '\0'
+		 */
+		memset(msg->data, '\0', CN_FORK_INFO_SIZE);
+		msg->len = scnprintf(msg->data, CN_FORK_INFO_SIZE-1, 
+				    "%i %i %i", 
+				    smp_processor_id(), parent, child) + 1;
+		
+		put_cpu_var(fork_counts);
+
+		cn_netlink_send(msg, CN_IDX_FORK);
+	}
+}
+#else
+static inline void fork_connector(pid_t parent, pid_t child) 
+{
+	return; 
+}
+#endif /* CONFIG_FORK_CONNECTOR */
+
 int nr_processes(void)
 {
 	int cpu;
@@ -1253,6 +1295,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);



^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2005-04-01  3:26 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-17  9:04 [patch 1/2] fork_connector: add a fork connector Guillaume Thouvenin
2005-03-17 16:56 ` Jesse Barnes
2005-03-17 21:38   ` Evgeniy Polyakov
2005-03-17 22:05     ` Jesse Barnes
2005-03-21  8:23       ` Guillaume Thouvenin
2005-03-21 12:48       ` Guillaume Thouvenin
2005-03-21 20:52         ` Ram
2005-03-22  4:36           ` Evgeniy Polyakov
2005-03-22 18:40             ` Ram
2005-03-22  7:07           ` Guillaume Thouvenin
2005-03-22 18:15             ` Jay Lan
2005-03-23  8:15               ` Guillaume Thouvenin
2005-03-22 18:26             ` Ram
2005-03-22 19:22               ` Evgeniy Polyakov
2005-03-22 19:18                 ` Ram
2005-03-22 20:25                   ` Evgeniy Polyakov
2005-03-22 20:42                     ` Ram
2005-03-23  4:52                       ` Evgeniy Polyakov
2005-03-22 22:51                   ` Jay Lan
2005-03-22 23:51                 ` Jay Lan
2005-03-23  5:01                   ` Evgeniy Polyakov
     [not found]                     ` <1111557106.23532.65.camel@uganda>
2005-03-23 19:00                       ` Ram
  -- strict thread matches above, loose matches on Subject: below --
2005-03-25 10:03 Guillaume Thouvenin
2005-03-25 22:45 ` dean gaudet
2005-03-28 21:42 ` Paul Jackson
2005-03-29  7:04   ` Evgeniy Polyakov
2005-03-29  7:02     ` Greg KH
2005-03-29  7:10       ` Evgeniy Polyakov
2005-03-29  8:49     ` Paul Jackson
2005-03-29  9:17       ` Guillaume Thouvenin
2005-03-29 15:23         ` Paul Jackson
2005-03-29 18:44           ` Jay Lan
2005-03-30  1:05             ` Paul Jackson
2005-03-30  5:39           ` Guillaume Thouvenin
2005-03-30  6:35             ` Paul Jackson
2005-03-30 10:25               ` Herbert Xu
2005-03-30 10:57                 ` Evgeniy Polyakov
2005-03-30 11:01                 ` Guillaume Thouvenin
2005-04-01  3:26           ` Drew Hess
2005-03-29 10:29       ` Evgeniy Polyakov
2005-03-29 17:03         ` Paul Jackson
2005-03-29 21:09           ` Jay Lan
2005-03-29 22:01             ` Paul Jackson
2005-03-30 14:14               ` Evgeniy Polyakov
2005-03-30 20:56                 ` Paul Jackson
2005-03-30  6:06             ` dean gaudet
2005-03-30  6:25               ` Paul Jackson
2005-03-30  6:38               ` Guillaume Thouvenin
2005-03-30 18:11               ` Jay Lan
2005-03-29  8:05   ` Guillaume Thouvenin
2005-03-29 14:47     ` Paul Jackson
2005-03-29 12:51   ` Guillaume Thouvenin
2005-03-29 15:35     ` Paul Jackson
2005-03-30  5:52       ` Guillaume Thouvenin
2005-03-30  6:41         ` Paul Jackson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox