All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] fork historic module
@ 2004-12-17 14:58 Guillaume Thouvenin
  2004-12-17 15:11 ` [Lse-tech] " Andi Kleen
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Guillaume Thouvenin @ 2004-12-17 14:58 UTC (permalink / raw)
  To: lkml, Andrew Morton
  Cc: elsa-announce, elsa-devel, Gerrit Huizenga, Jean Pierre Dion,
	guillaume.thouvenin, lse-tech

Hello,

  Here is the fork historic module. This module keeps the historic about
the creation of processes and it gives this information to a user space
application if one is registered. Currently, only one application can
use it. If needed it could be extended to several applications.

Here is how it works:

  The module registers itself to the kernel via a LSM hook in order to
receive a signal when a fork occurs in the kernel. We are using the
"task_alloc_security" security hook. When a fork occurs, information is
following up to a registered application. When an application registers
itself, it gives to the fork historic driver a RT signal that will be
used to pass the information. The application registers to this driver
by using ioctl command on the /dev/fh interface.

  This driver is used by the daemon part of ELSA project. The daemon
manages groups of processes called jobs in order to do per-group of
processes accounting. I tested the module with kernel 2.6.9 and also
with 2.6.10-rc3-mm1 and I was able to manage jobs in user space by using
the job daemon which is a part of the Enhanced Linux System Accounting. 

  ELSA can be downloaded from http://elsa.sf.net

  Andrew, do you think that this module can be integrated in your
development tree? I hope that it can be useful for someone else.

Any comments and suggestions are welcome.

Guillaume


 drivers/char/Kconfig          |   23 ++++
 drivers/char/Makefile         |    2
 drivers/char/fork_historic.c  |  211 ++++++++++++++++++++++++++++...
 include/linux/fork_historic.h |   36 +++++++
 4 files changed, 272 insertions(+)


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


diff -uprN -X dontdiff linux-2.6.10-rc3-mm1/drivers/char/fork_historic.c linux-2.6.10-rc3-mm1+fh/drivers/char/fork_historic.c
--- linux-2.6.10-rc3-mm1/drivers/char/fork_historic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc3-mm1+fh/drivers/char/fork_historic.c	2004-12-17 14:03:46.147439208 +0100
@@ -0,0 +1,211 @@
+/*
+ * fork_historic.c - fork historic interface
+ *
+ * Author: Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ *
+ * This driver allows to keep the historic about the creation of
+ * processes and it gives this information to a user space application.
+ * Currently, only one application can use it. If needed it could be 
+ * extended to several applications. 
+ *
+ * It registers itself to the kernel via a LSM hook in order to receive
+ * a signal when a fork occurs in the kernel. When a fork occurs, it
+ * follows up the information to an application if one is registered. When
+ * an application registers itself, it gives to the driver a RT signal 
+ * that will be used to pass the information. The application communicates to 
+ * this driver by using ioctl command on the /dev/fh interface. 
+ *
+ *
+ * 	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, version 2.
+ *
+ *	This program is distributed in the hope that it would be useful, but
+ * 	WITHOUT ANY WARRANTY; without even the implied warranty of
+ * 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/module.h>	/* for all modules      */
+#include <linux/kernel.h>	/* for KERN_ALERT       */
+#include <linux/init.h>		/* for the macros       */
+#include <linux/spinlock.h>	/* for spinlock         */
+#include <linux/sched.h>	/* for task_struct      */
+#include <linux/fs.h>		/* for register_chrdev  */
+#include <linux/security.h>	/* for LSM hook         */
+#include <linux/fork_historic.h>
+
+#include <asm/errno.h>		/* used to set ernno      */
+#include <asm/uaccess.h>	/* used to copy from user */
+
+static int fh_ioctl(struct inode *inode, struct file *file,
+		    unsigned int cmd, unsigned long arg);
+static int fh_task_alloc_security(struct task_struct *p);
+
+/* fh_lock protects fh_pid and fh_sig */
+static spinlock_t fh_lock = SPIN_LOCK_UNLOCKED;
+static int fh_pid;
+static int fh_sig;
+
+
+/* this is the major number dynamically got when registered */
+static int fh_major;
+
+struct security_operations fh_sops = {
+	.task_alloc_security = fh_task_alloc_security,
+};
+
+static struct file_operations fh_fops = {
+	.owner = THIS_MODULE,
+	.ioctl = fh_ioctl,
+};
+
+static int
+fh_ioctl(struct inode *inode, struct file *file,
+	 unsigned int cmd, unsigned long arg)
+{
+	struct fh_ioctl_parm iarg;
+	int retval = 0;
+
+	/* We can make some checks */
+	if (_IOC_TYPE(cmd) != FH_MAGIC)
+		return -ENOTTY;
+	if (_IOC_NR(cmd) > FH_MAXNR)
+		return -ENOTTY;
+	if ((cmd != FH_REGISTER) && (cmd != FH_UNREGISTER))
+		return -ENOTTY;
+
+	/* Recover ioctl parameters */
+	if (copy_from_user(&iarg, (void __user *) arg,
+			   sizeof(struct fh_ioctl_parm)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case FH_REGISTER:
+		spin_lock_irq(&fh_lock);
+		if (fh_pid == 0) {
+			/* There is no application already registered */
+			fh_pid = iarg.pid;
+			fh_sig = iarg.sig;
+		} else
+			/* Someone uses this module */
+			retval = -EUSERS;
+		spin_unlock_irq(&fh_lock);
+		break;
+	case FH_UNREGISTER:
+		spin_lock_irq(&fh_lock);
+		fh_pid = 0;
+		fh_sig = 0;
+		spin_unlock_irq(&fh_lock);
+		break;
+	default:
+		/*
+		 * The POSIX standard, states that if an inappropriate ioctl 
+		 * command has been issued, then -ENOTTY should be returned.
+		 */
+		retval = -ENOTTY;
+	};
+
+	return retval;
+}
+
+/**
+ * fh_task_alloc_security - send SIGRTFORK signal to a register process
+ * @ppid: parent ID
+ * @cpid: child ID
+ *
+ * This routine send a SIGRTFORK to a register process if there is one. We use
+ * a real time signal because we don't want to loose information. With non real
+ * time signals, additional signals of that same type that arrive in the 
+ * meantime might be discarded.
+ * 
+ */
+static int fh_task_alloc_security(struct task_struct *p)
+{
+	struct siginfo sinfo;
+	struct task_struct *fh_p;
+
+	/* 
+	 * We need to be sure that fh_pid is not modified when sending 
+	 * fork information. As we check if the process still exists and 
+	 * if not, we change the global fh_pid, we protect this part.
+	 * A process can be killed and still registered...
+	 */
+	spin_lock_irq(&fh_lock);
+	if (fh_pid) {
+		read_lock(&tasklist_lock);
+		fh_p = find_task_by_pid(fh_pid);
+		if (fh_p) {
+			sinfo.si_signo = fh_sig;
+			sinfo.si_errno = 0;
+			sinfo.si_code = SI_ASYNCIO;
+			/* 
+			 * should be the sender ID but in our case, it is set
+			 * to the pid of the process that initiates the fork.
+			 */
+			sinfo.si_pid = current->pid;
+			/* 
+			 * process created during the fork. This information
+			 *  is needed to keep jobs coherent. 
+			 */
+			sinfo.si_value.sival_int = p->pid;
+
+			send_sig_info(fh_sig, &sinfo, fh_p);
+		} else {
+			/* 
+			 * process #fh_pid doesn't exist so we don't need to 
+			 * check that each time and we reset the values.
+			 */
+			fh_pid = 0;
+			fh_sig = 0;
+		}
+		read_unlock(&tasklist_lock);
+	}
+	spin_unlock_irq(&fh_lock);
+
+	return 0;
+}
+
+/**
+ * fh_init - called when module is loaded
+ *
+ * Register the character device. It aslo register an LSM hook
+ * in order to be inform by the creation of a new process.
+ */
+static int __init fh_init(void)
+{
+	fh_major = register_chrdev(0, "fh", &fh_fops);
+	if (!fh_major) {
+		printk(KERN_ERR "fh: failed to register fh device\n");
+		return -EIO;
+	}
+
+	if (register_security(&fh_sops)) {
+		printk(KERN_ERR "fh: failed to set the fork hook \n");
+		return -EIO;
+	}
+
+	printk(KERN_INFO "fh: fork historic started\n");
+	return 0;
+}
+
+/**
+ * fh_exit - called when module is unloaded
+ *
+ * Un-register the character device and the LSM hook.
+ */
+static void __exit fh_exit(void)
+{
+	if (unregister_security(&fh_sops))
+		printk(KERN_ERR "fh: Unable to register with kernel\n");
+
+	unregister_chrdev(fh_major, "fh");
+
+	printk(KERN_INFO "fh: fork historic ended\n");
+}
+
+module_init(fh_init);
+module_exit(fh_exit);
+
+MODULE_AUTHOR("Guillaume Thouvenin <guillaume.thouvenin@bull.net>");
+MODULE_DESCRIPTION("Fork Historic Module");
+MODULE_LICENSE("GPL");
diff -uprN -X dontdiff linux-2.6.10-rc3-mm1/drivers/char/Kconfig linux-2.6.10-rc3-mm1+fh/drivers/char/Kconfig
--- linux-2.6.10-rc3-mm1/drivers/char/Kconfig	2004-12-03 22:52:14.000000000 +0100
+++ linux-2.6.10-rc3-mm1+fh/drivers/char/Kconfig	2004-12-17 14:04:08.753002640 +0100
@@ -4,6 +4,29 @@
 
 menu "Character devices"
 
+config FORK_HISTORIC
+	tristate "Fork historic"
+	depends on SECURITY
+	default n
+	---help---
+	  This driver allows to keep the historic about the creation of
+	  processes and it gives this information to a user space 
+	  application. Currently, only one application can use it. If 
+	  needed it could be extended to several applications.
+
+ 	  It registers itself to the kernel via a LSM hook in order to 
+	  receive a signal when a fork occurs in the kernel. When a fork 
+	  occures, it follows up the information to an application if one 
+	  is registered. When an application registers itself, it gives to 
+	  the driver a RT signal that will be used to pass the information. 
+
+	  The application communicates to this driver by using ioctl command 
+	  on the "/dev/fh" interface. So, to be able to use it you need to
+	  create the "/dev/fh" character device with the correct major number
+	  that can be found by looking into the "/proc/devices".
+
+	  If unsure, say N.
+	
 config VT
 	bool "Virtual terminal" if EMBEDDED
 	select INPUT
diff -uprN -X dontdiff linux-2.6.10-rc3-mm1/drivers/char/Makefile linux-2.6.10-rc3-mm1+fh/drivers/char/Makefile
--- linux-2.6.10-rc3-mm1/drivers/char/Makefile	2004-12-03 22:54:50.000000000 +0100
+++ linux-2.6.10-rc3-mm1+fh/drivers/char/Makefile	2004-12-17 09:59:22.000000000 +0100
@@ -91,6 +91,8 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/
 
 obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
 
+obj-$(CONFIG_FORK_HISTORIC) += fork_historic.o
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
 
diff -uprN -X dontdiff linux-2.6.10-rc3-mm1/include/linux/fork_historic.h linux-2.6.10-rc3-mm1+fh/include/linux/fork_historic.h
--- linux-2.6.10-rc3-mm1/include/linux/fork_historic.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-rc3-mm1+fh/include/linux/fork_historic.h	2004-12-17 09:58:21.000000000 +0100
@@ -0,0 +1,36 @@
+/*
+ * fork_historic.h - fork historic interface header file
+ *
+ * Author: Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ *
+ * 	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, version 2.
+ *
+ *	This program is distributed in the hope that it would be useful, but
+ * 	WITHOUT ANY WARRANTY; without even the implied warranty of
+ * 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef FORK_HISTORIC_H
+#define FORK_HISTORIC_H
+
+#include <linux/ioctl.h>
+
+/* Information given by the registered application */
+struct fh_ioctl_parm {
+	int pid;
+	int sig;
+};
+
+#define FH_ERRNO	38
+
+/* IOCTL numbers */
+/* If you add a new IOCTL number don't forget to update FH_MAXNR */
+#define FH_MAGIC	0x35
+#define FH_REGISTER	_IO(FH_MAGIC,0)
+#define FH_UNREGISTER	_IO(FH_MAGIC,1)
+
+#define FH_MAXNR 	1
+
+#endif				/* !(FORK_HISTORIC_H) */



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

* Re: [Lse-tech] [RFC] fork historic module
  2004-12-17 14:58 [RFC] fork historic module Guillaume Thouvenin
@ 2004-12-17 15:11 ` Andi Kleen
  2004-12-20  7:28   ` Guillaume Thouvenin
  2004-12-17 15:24 ` David Vrabel
  2004-12-17 17:39 ` [Lse-tech] " Erich Focht
  2 siblings, 1 reply; 8+ messages in thread
From: Andi Kleen @ 2004-12-17 15:11 UTC (permalink / raw)
  To: Guillaume Thouvenin
  Cc: lkml, Andrew Morton, elsa-announce, elsa-devel, Gerrit Huizenga,
	Jean Pierre Dion, lse-tech

> +/* IOCTL numbers */
> +/* If you add a new IOCTL number don't forget to update FH_MAXNR */
> +#define FH_MAGIC	0x35
> +#define FH_REGISTER	_IO(FH_MAGIC,0)
> +#define FH_UNREGISTER	_IO(FH_MAGIC,1)

Is this really unique? 32bit emulation currently needs unique ioctl numbers.

-Andi

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

* Re: [RFC] fork historic module
  2004-12-17 14:58 [RFC] fork historic module Guillaume Thouvenin
  2004-12-17 15:11 ` [Lse-tech] " Andi Kleen
@ 2004-12-17 15:24 ` David Vrabel
  2004-12-17 17:06   ` Randy.Dunlap
  2004-12-17 17:39 ` [Lse-tech] " Erich Focht
  2 siblings, 1 reply; 8+ messages in thread
From: David Vrabel @ 2004-12-17 15:24 UTC (permalink / raw)
  To: Guillaume Thouvenin
  Cc: lkml, Andrew Morton, elsa-announce, elsa-devel, Gerrit Huizenga,
	Jean Pierre Dion, lse-tech

Guillaume Thouvenin wrote:
> Hello,
> 
>   Here is the fork historic module. This module keeps the historic about

Shouldn't it be "history" (noun) instead of "historic" (adjective)? 
It's kinda confusing as is.

David Vrabel

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

* Re: [RFC] fork historic module
  2004-12-17 15:24 ` David Vrabel
@ 2004-12-17 17:06   ` Randy.Dunlap
  0 siblings, 0 replies; 8+ messages in thread
From: Randy.Dunlap @ 2004-12-17 17:06 UTC (permalink / raw)
  To: David Vrabel
  Cc: Guillaume Thouvenin, lkml, Andrew Morton, elsa-announce,
	elsa-devel, Gerrit Huizenga, Jean Pierre Dion, lse-tech

David Vrabel wrote:
> Guillaume Thouvenin wrote:
> 
>> Hello,
>>
>>   Here is the fork historic module. This module keeps the historic about
> 
> 
> Shouldn't it be "history" (noun) instead of "historic" (adjective)? It's 
> kinda confusing as is.

Yes, there are several typo-like corrections needed in the Help text
also, if this is merged...

-- 
~Randy

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

* Re: [Lse-tech] [RFC] fork historic module
  2004-12-17 14:58 [RFC] fork historic module Guillaume Thouvenin
  2004-12-17 15:11 ` [Lse-tech] " Andi Kleen
  2004-12-17 15:24 ` David Vrabel
@ 2004-12-17 17:39 ` Erich Focht
  2 siblings, 0 replies; 8+ messages in thread
From: Erich Focht @ 2004-12-17 17:39 UTC (permalink / raw)
  To: lse-tech
  Cc: Guillaume Thouvenin, lkml, Andrew Morton, elsa-announce,
	elsa-devel, Gerrit Huizenga, Jean Pierre Dion, lse-tech

On Friday 17 December 2004 15:58, Guillaume Thouvenin wrote:
>   Here is the fork historic module. This module keeps the historic about
> the creation of processes and it gives this information to a user space
> application if one is registered. Currently, only one application can
> use it. If needed it could be extended to several applications.

This sounds very useful for a lot of interesting stuff. Though in the
current form maybe the name is not appropriate: the module doesn't
keep track of the fork history, this would be done in user-space. The
module is more like a relay for fork monitoring.

If you plan to extend this to multiple registered user space processes
it would be great to have per process reporting policies, for example:
 - all forks,
 - only forks of descendants (children, etc).

Erich


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

* Re: [Lse-tech] [RFC] fork historic module
  2004-12-17 15:11 ` [Lse-tech] " Andi Kleen
@ 2004-12-20  7:28   ` Guillaume Thouvenin
  0 siblings, 0 replies; 8+ messages in thread
From: Guillaume Thouvenin @ 2004-12-20  7:28 UTC (permalink / raw)
  To: Andi Kleen; +Cc: lkml, elsa-announce, elsa-devel

On Fri, 2004-12-17 at 16:11 +0100, Andi Kleen wrote:
> > +/* IOCTL numbers */
> > +/* If you add a new IOCTL number don't forget to update FH_MAXNR */
> > +#define FH_MAGIC	0x35
> > +#define FH_REGISTER	_IO(FH_MAGIC,0)
> > +#define FH_UNREGISTER	_IO(FH_MAGIC,1)
> 
> Is this really unique? 32bit emulation currently needs unique ioctl numbers.

I read the Documentation/ioctl-number.txt file and 0x35 is not mentioned
in this file. But I made a grep on 'MAGIC' and '35' in the Linux source
tree and you're right, this number is already used by POR_MAGIC_2. 

Is a grep in the Linux source tree is enough to know if the value is
unique?

Thanks,
Guillaume  


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

* Re: [Lse-tech] [RFC] fork historic module
  2004-12-17 16:52 Manfred Spraul
@ 2004-12-17 16:59 ` Andi Kleen
  0 siblings, 0 replies; 8+ messages in thread
From: Andi Kleen @ 2004-12-17 16:59 UTC (permalink / raw)
  To: Manfred Spraul; +Cc: Andi Kleen, Linux Kernel Mailing List

On Fri, Dec 17, 2004 at 05:52:38PM +0100, Manfred Spraul wrote:
> Andi wrote:
> 
> >>+/* IOCTL numbers */
> >>+/* If you add a new IOCTL number don't forget to update FH_MAXNR */
> >>+#define FH_MAGIC	0x35
> >>+#define FH_REGISTER	_IO(FH_MAGIC,0)
> >>+#define FH_UNREGISTER	_IO(FH_MAGIC,1)
> >
> >Is this really unique? 32bit emulation currently needs unique ioctl 
> >numbers.
> > 
> >
> Are there plans to fix that? Perhaps move the emulation callback into 
> struct file?

Yes. See the thread on l-k i started two days ago.

Actually the main reason is that the current conversion setup has a 
unfixable module unload race.

-Andi

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

* Re: [Lse-tech] [RFC] fork historic module
@ 2004-12-17 16:52 Manfred Spraul
  2004-12-17 16:59 ` Andi Kleen
  0 siblings, 1 reply; 8+ messages in thread
From: Manfred Spraul @ 2004-12-17 16:52 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Linux Kernel Mailing List

Andi wrote:

>> +/* IOCTL numbers */
>> +/* If you add a new IOCTL number don't forget to update FH_MAXNR */
>> +#define FH_MAGIC	0x35
>> +#define FH_REGISTER	_IO(FH_MAGIC,0)
>> +#define FH_UNREGISTER	_IO(FH_MAGIC,1)
>
>Is this really unique? 32bit emulation currently needs unique ioctl numbers.
>  
>
Are there plans to fix that? Perhaps move the emulation callback into 
struct file?

--
    Manfred


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

end of thread, other threads:[~2004-12-20  8:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-17 14:58 [RFC] fork historic module Guillaume Thouvenin
2004-12-17 15:11 ` [Lse-tech] " Andi Kleen
2004-12-20  7:28   ` Guillaume Thouvenin
2004-12-17 15:24 ` David Vrabel
2004-12-17 17:06   ` Randy.Dunlap
2004-12-17 17:39 ` [Lse-tech] " Erich Focht
2004-12-17 16:52 Manfred Spraul
2004-12-17 16:59 ` Andi Kleen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.