linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Alexander E. Patrakov" <patrakov@ums.usu.ru>
To: linux-hotplug@vger.kernel.org
Subject: [REPOST] uevent leak
Date: Sun, 26 Mar 2006 04:21:37 +0000	[thread overview]
Message-ID: <442616D1.4020707@ums.usu.ru> (raw)

I have already reported the case where some uevents that happened after the 
"official" waiting loop exits:

http://marc.theaimsgroup.com/?l=linux-hotplug-devel&m\x113724427424947&w=2

At that time, only USB related uevents were reported and thus the report was 
ignored as unimportant. However, we have the case when other (more 
important) uevents leak, such as those for ttys. Details are below.

It seems that this bug is easier to trigger on fast machines with very 
simple rules, such as 
http://downloads.linuxfromscratch.org/udev-config-6.rules (one single file 
contains all rules). To see the problem, one must compile a simple event 
recorder. A C program is used instead of the shell script in order to reduce 
the change in timing:

/* Simple event recorder */
/* gcc -o /lib/udev/bug this_file.c */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <argz.h>

int main(int argc, char * argv[])
{
         char * envz;
         size_t len;
         int bug;
         bug = open("/dev/bug", O_WRONLY | O_APPEND);
         if (bug = -1)
                 return 0;
         setenv("_SEPARATOR", "--------------------------------------", 1);
         argz_create(environ, &envz, &len);
         argz_stringify(envz, len, '\n');
         envz[len-1]='\n';
         write(bug, envz, len);
         close(bug);
         free(envz);
         return 0;
}

This program appends the uevent environment to the /dev/bug file if it 
exists, and does nothing otherwise. Add a single rule to 90-debug.rules to 
run this program for every "add" uevent:

ACTION="add", RUN+="bug"

The important part of the failing initscript is:

================
         # Start the udev daemon to continually watch for, and act on, 
   uevents
         /sbin/udevd --daemon

         # Now traverse /sys in order to "coldplug" devices that have
         # already been discovered
         mkdir -p /dev/.udev/queue
         /sbin/udevtrigger  # or the old bash "for" loop with echo "add"

         # until we know how to do better, just wait for _all_ events to finish
         loop00
         while test -d /dev/.udev/queue; do
             sleep 0.1
             test "$loop" -gt 0 || break
             loop=$(($loop - 1))
         done
         >/dev/bug   # enable the logger above
         test "$loop" -gt 0
         evaluate_retval  # prints "OK" or "FAILED"
         sleep 6     # if the logger logs anything, it is a bug
         if test -s /dev/bug; then
             mv /dev/bug /dev/bugreport
             echo "Please paste the /dev/bugreport file to"
             echo "http://wiki.linuxfromscratch.org/lfs/ticket/1720"
             # and we actually have some pasted bugreports
             sleep 10
         else
             rm -f /dev/bug
         fi
================

The /dev/bugreport file is generated, as can be seen from the script, if 
there are any uevents within 6 seconds after the waiting loop exits.

The theory (well, not theory, just an unconfirmed guess) behind this 
bugreport, so far, is that udevd responds to uevents very quickly, faster 
than the kernel can deliver them from the netlink socket buffer. This leads 
to some moments when the queue is actually empty, and the loop exits 
prematurely.

The workaround is to exit the loop not when the queue disappears, but when 
it doesn't reappear for a sufficiently long time (6 seconds in the example 
below, but 1 second is sufficient for the bugreport to be reduced to USB 
devices only):

         loop00
         confirm=0
         while true ; do
             sleep 0.1
             test -d /dev/.udev/queue && confirm=0 || confirm=$(( $confirm + 
1 ))
             loop=$(( $loop - 1 ))
             test $loop -gt 0 || break
             test $confirm -lt 60 || break
         done
         test "$loop" -gt 0
         evaluate_retval  # prints "OK" or "FAILED"

-- 
Alexander E. Patrakov


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x110944&bid$1720&dat\x121642
_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

             reply	other threads:[~2006-03-26  4:21 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-26  4:21 Alexander E. Patrakov [this message]
2006-03-26 19:46 ` [REPOST] uevent leak Sergey Vlasov
2006-03-26 21:05 ` Jürg Billeter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=442616D1.4020707@ums.usu.ru \
    --to=patrakov@ums.usu.ru \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).