linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* devfsd hangs on restart - is_devfsd_or_child() problem
@ 2003-07-11 18:47 Andrey Borzenkov
  2003-07-12 10:11 ` [PATCH][2.5.75] " Andrey Borzenkov
  0 siblings, 1 reply; 2+ messages in thread
From: Andrey Borzenkov @ 2003-07-11 18:47 UTC (permalink / raw)
  To: devfs; +Cc: linux-kernel, Thierry Vignaud

I cannot believe it is so fragile ...

is_devfsd_or_child() simplemindedly checks for pgrp:

static int is_devfsd_or_child (struct fs_info *fs_info)
{
    if (current == fs_info->devfsd_task) return (TRUE);
    if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
    return (FALSE);
}   /*  End Function is_devfsd_or_child  */

unfortunately, bash (I do not know if it does it always or not) resets pgrp on 
startup. I.e. if your action is using shell it is no more considered devfsd 
descendant ... and it will attempt in turn start devfsd action while devfsd 
is waiting for it ot finish.

Thierry, i refer mostly to dynamics scripts currently. Every time I update 
devfsd it hangs in one of them. And actually it is enough to do service 
devfsd restart to trigger this. It may be 2.5 specific again in that it is 
not as easily seen under 2.4.

I have no idea what can be done. Is there any way in kernel to find out if one 
task is descendant of other task? Even rewriting devfsd to use non-blocking 
calls and request queue does not help as it apprently just results in endless 
loop (action triggering action triggering action ...)

-andrey

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

* [PATCH][2.5.75] devfsd hangs on restart - is_devfsd_or_child() problem
  2003-07-11 18:47 devfsd hangs on restart - is_devfsd_or_child() problem Andrey Borzenkov
@ 2003-07-12 10:11 ` Andrey Borzenkov
  0 siblings, 0 replies; 2+ messages in thread
From: Andrey Borzenkov @ 2003-07-12 10:11 UTC (permalink / raw)
  To: devfs; +Cc: linux-kernel, Thierry Vignaud, Andrew Morton

[-- Attachment #1: Type: text/plain, Size: 1335 bytes --]

On Friday 11 July 2003 22:47, Andrey Borzenkov wrote:
> I cannot believe it is so fragile ...
>
> is_devfsd_or_child() simplemindedly checks for pgrp:
>
> static int is_devfsd_or_child (struct fs_info *fs_info)
> {
>     if (current == fs_info->devfsd_task) return (TRUE);
>     if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
>     return (FALSE);
> }   /*  End Function is_devfsd_or_child  */
>

Andrew, one more for your collection :)

The code that did proper check existed in 2.4 and was removed in 2.5 for 
whatever reason. The patch restores it slightly modified as below.

2.4 code looks somewhat unclean in that

- it traverses task list without lock. 
- is starts from current->real_parent but nothing prevents current be 
init_task itself. This hung for me on 2.5 during boot. May be 2.4 does 
something differently.

Comments?

regards

-andrey

This is trivially reproduced under 2.5 by using devfsd.conf lines

LOOKUP  ^foo$   EXECUTE /home/bor/tmp/devfsd/handler /dev/bar
LOOKUP  ^bar$   EXECUTE /home/bor/tmp/devfsd/handler /dev/foo

and handler like

-------- cut here ----------
#include <unistd.h>

int
main(int argc, char **argv, char **envp)
{
        if (argc <= 1)
                return 0;

        setpgrp();
        return access(argv[1], R_OK);
}
-------- cut here ----------

and doing ls /dev/foo

[-- Attachment #2: 2.5.75-is_devfsd_or_child.patch --]
[-- Type: text/x-diff, Size: 1023 bytes --]

--- linux-2.5.75-smp/fs/devfs/base.c.devfsd_child	2003-07-11 19:41:46.000000000 +0400
+++ linux-2.5.75-smp/fs/devfs/base.c	2003-07-12 13:51:49.000000000 +0400
@@ -676,6 +676,7 @@
 #include <linux/smp.h>
 #include <linux/version.h>
 #include <linux/rwsem.h>
+#include <linux/sched.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1325,8 +1326,20 @@ static void free_dentry (struct devfs_en
 
 static int is_devfsd_or_child (struct fs_info *fs_info)
 {
-    if (current == fs_info->devfsd_task) return (TRUE);
-    if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
+    struct task_struct *p = current;
+
+    if (p == fs_info->devfsd_task) return (TRUE);
+    if (p->pgrp == fs_info->devfsd_pgrp) return (TRUE);
+    read_lock(&tasklist_lock);
+    for ( ; p != &init_task; p = p->real_parent)
+    {
+	if (p == fs_info->devfsd_task)
+	{
+	    read_unlock (&tasklist_lock);
+	    return (TRUE);
+	}
+    }
+    read_unlock (&tasklist_lock);
     return (FALSE);
 }   /*  End Function is_devfsd_or_child  */
 

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

end of thread, other threads:[~2003-07-12  9:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-11 18:47 devfsd hangs on restart - is_devfsd_or_child() problem Andrey Borzenkov
2003-07-12 10:11 ` [PATCH][2.5.75] " Andrey Borzenkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).