[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
/*
2008-09-10 04:40:42 +04:00
* Copyright ( C ) 2004 - 2008 Kay Sievers < kay . sievers @ vrfy . org >
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
* Copyright ( C ) 2004 Chris Friesen < chris_friesen @ sympatico . ca >
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
*
2008-09-10 04:40:42 +04:00
* 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 .
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
*
2008-09-10 04:40:42 +04:00
* 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 .
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
*
2008-09-10 04:40:42 +04:00
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
*/
2004-01-27 05:19:33 +03:00
# include <stddef.h>
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
# include <signal.h>
# include <unistd.h>
# include <errno.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2005-01-17 02:53:08 +03:00
# include <ctype.h>
# include <dirent.h>
# include <fcntl.h>
2005-08-15 13:57:04 +04:00
# include <syslog.h>
2005-11-07 04:22:44 +03:00
# include <time.h>
2006-09-08 13:27:03 +04:00
# include <getopt.h>
2005-03-10 02:58:01 +03:00
# include <sys/select.h>
# include <sys/wait.h>
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/un.h>
2004-10-14 09:37:59 +04:00
# include <sys/stat.h>
2005-10-27 23:04:38 +04:00
# include <sys/ioctl.h>
2005-11-12 07:09:34 +03:00
# include <linux/types.h>
2005-06-05 06:38:10 +04:00
# include <linux/netlink.h>
2008-07-30 03:45:23 +04:00
# ifdef HAVE_INOTIFY
# include <sys/inotify.h>
# endif
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
# include "udev.h"
2005-10-27 23:04:38 +04:00
# include "udev_rules.h"
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
2008-09-08 19:59:00 +04:00
# define UDEVD_PRIORITY -4
# define UDEV_PRIORITY -2
/* maximum limit of forked childs */
# define UDEVD_MAX_CHILDS 256
2008-04-20 23:07:06 +04:00
static int debug ;
2006-09-08 13:28:38 +04:00
2008-09-06 17:45:31 +04:00
static void log_fn ( struct udev * udev , int priority ,
const char * file , int line , const char * fn ,
const char * format , va_list args )
{
if ( debug ) {
fprintf ( stderr , " [%d] %s: " , ( int ) getpid ( ) , fn ) ;
vfprintf ( stderr , format , args ) ;
} else {
vsyslog ( priority , format , args ) ;
}
}
struct udevd_uevent_msg {
struct udev * udev ;
struct list_head node ;
pid_t pid ;
int exitstatus ;
time_t queue_time ;
char * action ;
char * devpath ;
char * subsystem ;
char * driver ;
dev_t devt ;
unsigned long long seqnum ;
char * devpath_old ;
char * physdevpath ;
unsigned int timeout ;
char * envp [ UEVENT_NUM_ENVP + 1 ] ;
char envbuf [ ] ;
} ;
static int debug_trace ;
2006-01-09 23:18:00 +03:00
static struct udev_rules rules ;
2008-09-08 19:59:00 +04:00
static struct udev_ctrl * udev_ctrl ;
2006-08-05 15:24:05 +04:00
static int uevent_netlink_sock = - 1 ;
static int inotify_fd = - 1 ;
2004-11-12 08:18:28 +03:00
2005-08-28 22:25:37 +04:00
static int signal_pipe [ 2 ] = { - 1 , - 1 } ;
2004-10-19 15:37:30 +04:00
static volatile int sigchilds_waiting ;
2005-08-08 07:07:36 +04:00
static volatile int udev_exit ;
2005-10-27 23:04:38 +04:00
static volatile int reload_config ;
2004-04-01 11:03:07 +04:00
static int run_exec_q ;
2005-06-05 06:41:09 +04:00
static int stop_exec_q ;
2005-06-05 06:53:17 +04:00
static int max_childs ;
2008-09-06 17:45:31 +04:00
static char udev_log_env [ 32 ] ;
2005-08-15 13:57:04 +04:00
static LIST_HEAD ( exec_list ) ;
static LIST_HEAD ( running_list ) ;
2005-06-05 06:53:17 +04:00
2005-10-27 23:04:38 +04:00
static void asmlinkage udev_event_sig_handler ( int signum )
{
if ( signum = = SIGALRM )
exit ( 1 ) ;
}
2006-08-05 15:22:44 +04:00
static int udev_event_process ( struct udevd_uevent_msg * msg )
2005-10-27 23:04:38 +04:00
{
struct sigaction act ;
2008-09-06 17:45:31 +04:00
struct udevice * udevice ;
2005-10-27 23:04:38 +04:00
int i ;
int retval ;
/* set signal handlers */
memset ( & act , 0x00 , sizeof ( act ) ) ;
act . sa_handler = ( void ( * ) ( int ) ) udev_event_sig_handler ;
sigemptyset ( & act . sa_mask ) ;
act . sa_flags = 0 ;
sigaction ( SIGALRM , & act , NULL ) ;
2006-03-16 12:46:30 +03:00
/* reset to default */
act . sa_handler = SIG_DFL ;
sigaction ( SIGINT , & act , NULL ) ;
sigaction ( SIGTERM , & act , NULL ) ;
sigaction ( SIGCHLD , & act , NULL ) ;
sigaction ( SIGHUP , & act , NULL ) ;
2005-10-27 23:04:38 +04:00
/* trigger timeout to prevent hanging processes */
2008-04-21 21:00:54 +04:00
alarm ( UDEV_EVENT_TIMEOUT ) ;
2005-10-27 23:04:38 +04:00
2006-01-09 23:18:00 +03:00
/* reconstruct event environment from message */
2005-10-27 23:04:38 +04:00
for ( i = 0 ; msg - > envp [ i ] ; i + + )
putenv ( msg - > envp [ i ] ) ;
2008-09-06 17:45:31 +04:00
udevice = udev_device_init ( msg - > udev ) ;
if ( udevice = = NULL )
2006-01-09 23:18:00 +03:00
return - 1 ;
2008-09-10 20:59:42 +04:00
util_strlcpy ( udevice - > action , msg - > action , sizeof ( udevice - > action ) ) ;
2008-09-06 17:45:31 +04:00
sysfs_device_set_values ( udevice - > udev , udevice - > dev , msg - > devpath , msg - > subsystem , msg - > driver ) ;
udevice - > devpath_old = msg - > devpath_old ;
udevice - > devt = msg - > devt ;
2006-01-09 23:18:00 +03:00
2008-09-06 17:45:31 +04:00
retval = udev_device_event ( & rules , udevice ) ;
2005-10-27 23:04:38 +04:00
2008-04-21 21:00:54 +04:00
/* rules may change/disable the timeout */
2008-09-06 17:45:31 +04:00
if ( udevice - > event_timeout > = 0 )
alarm ( udevice - > event_timeout ) ;
2008-04-21 21:00:54 +04:00
2005-10-27 23:04:38 +04:00
/* run programs collected by RUN-key*/
2008-09-06 17:45:31 +04:00
if ( retval = = 0 & & ! udevice - > ignore_device & & udev_get_run ( msg - > udev ) )
retval = udev_rules_run ( udevice ) ;
2005-10-27 23:04:38 +04:00
2008-09-06 17:45:31 +04:00
udev_device_cleanup ( udevice ) ;
2005-11-16 04:06:46 +03:00
return retval ;
2005-10-27 23:04:38 +04:00
}
2005-11-16 06:12:53 +03:00
enum event_state {
EVENT_QUEUED ,
EVENT_FINISHED ,
EVENT_FAILED ,
} ;
2006-08-05 15:22:44 +04:00
static void export_event_state ( struct udevd_uevent_msg * msg , enum event_state state )
2005-11-16 06:12:53 +03:00
{
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
char filename_failed [ UTIL_PATH_SIZE ] ;
2007-03-14 23:41:33 +03:00
size_t start ;
2005-11-16 06:12:53 +03:00
2007-08-26 07:22:35 +04:00
/* location of queue file */
2008-09-06 17:45:31 +04:00
snprintf ( filename , sizeof ( filename ) , " %s/.udev/queue/%llu " , udev_get_dev_path ( msg - > udev ) , msg - > seqnum ) ;
2005-11-16 06:12:53 +03:00
2007-08-26 07:22:35 +04:00
/* location of failed file */
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename_failed , udev_get_dev_path ( msg - > udev ) , sizeof ( filename_failed ) ) ;
util_strlcat ( filename_failed , " / " , sizeof ( filename_failed ) ) ;
start = util_strlcat ( filename_failed , " .udev/failed/ " , sizeof ( filename_failed ) ) ;
util_strlcat ( filename_failed , msg - > devpath , sizeof ( filename_failed ) ) ;
2008-09-10 20:39:23 +04:00
util_path_encode ( & filename_failed [ start ] , sizeof ( filename_failed ) - start ) ;
2005-11-16 06:12:53 +03:00
switch ( state ) {
case EVENT_QUEUED :
unlink ( filename_failed ) ;
2008-09-06 17:45:31 +04:00
delete_path ( msg - > udev , filename_failed ) ;
create_path ( msg - > udev , filename ) ;
2008-09-10 02:46:17 +04:00
udev_selinux_setfscreatecon ( msg - > udev , filename , S_IFLNK ) ;
2007-09-20 02:41:54 +04:00
symlink ( msg - > devpath , filename ) ;
2008-09-10 02:46:17 +04:00
udev_selinux_resetfscreatecon ( msg - > udev ) ;
2007-09-20 02:41:54 +04:00
break ;
2005-11-16 06:12:53 +03:00
case EVENT_FINISHED :
2007-08-26 07:22:35 +04:00
if ( msg - > devpath_old ! = NULL ) {
/* "move" event - rename failed file to current name, do not delete failed */
2008-09-10 23:50:21 +04:00
char filename_failed_old [ UTIL_PATH_SIZE ] ;
2007-08-26 07:22:35 +04:00
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename_failed_old , udev_get_dev_path ( msg - > udev ) , sizeof ( filename_failed_old ) ) ;
util_strlcat ( filename_failed_old , " / " , sizeof ( filename_failed_old ) ) ;
start = util_strlcat ( filename_failed_old , " .udev/failed/ " , sizeof ( filename_failed_old ) ) ;
util_strlcat ( filename_failed_old , msg - > devpath_old , sizeof ( filename_failed_old ) ) ;
2008-09-10 20:39:23 +04:00
util_path_encode ( & filename_failed_old [ start ] , sizeof ( filename ) - start ) ;
2007-08-26 07:22:35 +04:00
if ( rename ( filename_failed_old , filename_failed ) = = 0 )
2008-09-06 17:45:31 +04:00
info ( msg - > udev , " renamed devpath, moved failed state of '%s' to %s' \n " ,
2007-08-26 07:22:35 +04:00
msg - > devpath_old , msg - > devpath ) ;
} else {
unlink ( filename_failed ) ;
2008-09-06 17:45:31 +04:00
delete_path ( msg - > udev , filename_failed ) ;
2007-08-26 07:22:35 +04:00
}
2005-11-16 06:12:53 +03:00
2007-09-20 02:41:54 +04:00
unlink ( filename ) ;
2008-09-06 17:45:31 +04:00
delete_path ( msg - > udev , filename ) ;
2007-09-20 02:41:54 +04:00
break ;
case EVENT_FAILED :
2007-08-26 07:22:35 +04:00
/* move failed event to the failed directory */
2008-09-06 17:45:31 +04:00
create_path ( msg - > udev , filename_failed ) ;
2007-09-20 02:41:54 +04:00
rename ( filename , filename_failed ) ;
2005-11-22 17:49:49 +03:00
2007-08-26 07:22:35 +04:00
/* clean up possibly empty queue directory */
2008-09-06 17:45:31 +04:00
delete_path ( msg - > udev , filename ) ;
2007-09-20 02:41:54 +04:00
break ;
2005-11-16 06:12:53 +03:00
}
2007-09-20 02:41:54 +04:00
return ;
2005-11-16 06:12:53 +03:00
}
2006-08-05 15:22:44 +04:00
static void msg_queue_delete ( struct udevd_uevent_msg * msg )
2005-11-07 16:10:09 +03:00
{
list_del ( & msg - > node ) ;
2005-11-16 06:12:53 +03:00
2007-08-26 07:22:35 +04:00
/* mark as failed, if "add" event returns non-zero */
2005-11-16 06:12:53 +03:00
if ( msg - > exitstatus & & strcmp ( msg - > action , " add " ) = = 0 )
export_event_state ( msg , EVENT_FAILED ) ;
else
export_event_state ( msg , EVENT_FINISHED ) ;
2005-11-07 16:10:09 +03:00
free ( msg ) ;
}
2006-08-05 15:22:44 +04:00
static void udev_event_run ( struct udevd_uevent_msg * msg )
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
{
2004-01-23 15:01:09 +03:00
pid_t pid ;
2005-11-16 04:06:46 +03:00
int retval ;
2004-01-23 15:01:09 +03:00
pid = fork ( ) ;
switch ( pid ) {
case 0 :
[PATCH] udev - next round of udev event order daemon
Here is the next round of udevd/udevsend:
udevsend - If the IPC message we send is not catched by a receiver we fork
the udevd daemon to process this and the following events
udevd - We reorder the events we receive and execute our current udev for
every event. If one or more events are missing, we wait
10 seconds and then go ahead in the queue.
If the queue is empty and we don't receive any event for the next
30 seconds, the daemon exits.
The next incoming event will fork the daemon again.
config - The path's to the executable are specified in udevd.h
Now they are pointing to the current directory only.
I don't like daemons hiding secrets (and mem leaks :)) inside,
so I want to try this model. It should be enough logic to get all possible
hotplug events executed in the right order.
If no event, then no daemon! So everybody should be happy :)
Here we see:
1. the daemon fork,
2. the udev work,
3. the 10 sec timeout and the skipped events,
4. the udev work,
...,
5. and the 30 sec timeout and exit.
EVENTS:
pim:/home/kay/src/udev.kay# test/udevd_test.sh
pim:/home/kay/src/udev.kay# SEQNUM=15 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=16 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=17 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=18 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=20 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=21 ./udevsend block
LOG:
Jan 23 15:35:35 pim udev[11795]: message is still in the ipc queue, starting daemon...
Jan 23 15:35:35 pim udev[11799]: configured rule in '/etc/udev/udev.rules' at line 19 applied, 'sda' becomes '%k-flash'
Jan 23 15:35:35 pim udev[11799]: creating device node '/udev/sda-flash'
Jan 23 15:35:35 pim udev[11800]: creating device node '/udev/sdb'
Jan 23 15:35:35 pim udev[11804]: creating device node '/udev/sdc'
Jan 23 15:35:35 pim udev[11805]: removing device node '/udev/sda-flash'
Jan 23 15:35:35 pim udev[11808]: removing device node '/udev/sdb'
Jan 23 15:35:35 pim udev[11809]: removing device node '/udev/sdc'
Jan 23 15:35:45 pim udev[11797]: timeout reached, skip events 7 - 7
Jan 23 15:35:45 pim udev[11811]: creating device node '/udev/sdb'
Jan 23 15:35:45 pim udev[11812]: creating device node '/udev/sdc'
Jan 23 15:36:01 pim udev[11797]: timeout reached, skip events 10 - 14
Jan 23 15:36:01 pim udev[11814]: creating device node '/udev/sdc'
Jan 23 15:36:04 pim udev[11816]: creating device node '/udev/sdc'
Jan 23 15:36:12 pim udev[11818]: creating device node '/udev/sdc'
Jan 23 15:36:16 pim udev[11820]: creating device node '/udev/sdc'
Jan 23 15:36:38 pim udev[11797]: timeout reached, skip events 19 - 19
Jan 23 15:36:38 pim udev[11823]: creating device node '/udev/sdc'
Jan 23 15:36:38 pim udev[11824]: creating device node '/udev/sdc'
Jan 23 15:37:08 pim udev[11797]: we have nothing to do, so daemon exits...
2004-01-24 08:25:17 +03:00
/* child */
2005-11-04 07:25:15 +03:00
close ( uevent_netlink_sock ) ;
2008-09-08 19:59:00 +04:00
udev_ctrl_unref ( udev_ctrl ) ;
2006-04-25 20:50:56 +04:00
if ( inotify_fd > = 0 )
2005-10-27 23:04:38 +04:00
close ( inotify_fd ) ;
close ( signal_pipe [ READ_END ] ) ;
close ( signal_pipe [ WRITE_END ] ) ;
2004-11-23 05:30:13 +03:00
logging_close ( ) ;
2005-10-27 23:04:38 +04:00
logging_init ( " udevd-event " ) ;
2005-01-17 02:53:08 +03:00
setpriority ( PRIO_PROCESS , 0 , UDEV_PRIORITY ) ;
2006-07-25 16:45:09 +04:00
2005-11-16 04:06:46 +03:00
retval = udev_event_process ( msg ) ;
2008-09-06 17:45:31 +04:00
info ( msg - > udev , " seq %llu finished with %i \n " , msg - > seqnum , retval ) ;
2005-10-27 23:04:38 +04:00
logging_close ( ) ;
2005-11-16 04:06:46 +03:00
if ( retval )
exit ( 1 ) ;
2005-10-27 23:04:38 +04:00
exit ( 0 ) ;
2004-01-23 15:01:09 +03:00
case - 1 :
2008-09-29 19:01:32 +04:00
err ( msg - > udev , " fork of child failed: %m \n " ) ;
2005-07-06 04:02:05 +04:00
msg_queue_delete ( msg ) ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
break ;
2004-01-23 15:01:09 +03:00
default :
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
/* get SIGCHLD in main loop */
2008-09-06 17:45:31 +04:00
info ( msg - > udev , " seq %llu forked, pid [%d], '%s' '%s', %ld seconds old \n " ,
2005-11-07 04:22:44 +03:00
msg - > seqnum , pid , msg - > action , msg - > subsystem , time ( NULL ) - msg - > queue_time ) ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
msg - > pid = pid ;
2004-01-23 15:01:09 +03:00
}
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
}
2006-08-05 15:22:44 +04:00
static void msg_queue_insert ( struct udevd_uevent_msg * msg )
2005-11-07 16:10:09 +03:00
{
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2006-04-05 02:08:10 +04:00
int fd ;
2005-11-07 16:10:09 +03:00
msg - > queue_time = time ( NULL ) ;
2006-04-05 02:08:10 +04:00
2008-05-30 11:43:58 +04:00
export_event_state ( msg , EVENT_QUEUED ) ;
2008-09-06 17:45:31 +04:00
info ( msg - > udev , " seq %llu queued, '%s' '%s' \n " , msg - > seqnum , msg - > action , msg - > subsystem ) ;
2008-05-30 11:43:58 +04:00
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename , udev_get_dev_path ( msg - > udev ) , sizeof ( filename ) ) ;
util_strlcat ( filename , " /.udev/uevent_seqnum " , sizeof ( filename ) ) ;
2006-04-05 02:08:10 +04:00
fd = open ( filename , O_WRONLY | O_TRUNC | O_CREAT , 0644 ) ;
2006-04-25 20:50:56 +04:00
if ( fd > = 0 ) {
2006-04-05 02:08:10 +04:00
char str [ 32 ] ;
int len ;
len = sprintf ( str , " %llu \n " , msg - > seqnum ) ;
write ( fd , str , len ) ;
close ( fd ) ;
}
2005-11-07 16:10:09 +03:00
2006-09-08 13:30:00 +04:00
/* run one event after the other in debug mode */
if ( debug_trace ) {
list_add_tail ( & msg - > node , & running_list ) ;
udev_event_run ( msg ) ;
waitpid ( msg - > pid , NULL , 0 ) ;
msg_queue_delete ( msg ) ;
return ;
}
2005-11-07 16:10:09 +03:00
/* run all events with a timeout set immediately */
if ( msg - > timeout ! = 0 ) {
list_add_tail ( & msg - > node , & running_list ) ;
udev_event_run ( msg ) ;
return ;
}
list_add_tail ( & msg - > node , & exec_list ) ;
run_exec_q = 1 ;
}
2006-08-10 14:50:53 +04:00
static int mem_size_mb ( void )
{
2007-05-04 01:21:11 +04:00
FILE * f ;
char buf [ 4096 ] ;
long int memsize = - 1 ;
2006-08-10 14:50:53 +04:00
2007-05-04 01:21:11 +04:00
f = fopen ( " /proc/meminfo " , " r " ) ;
if ( f = = NULL )
2006-08-10 14:50:53 +04:00
return - 1 ;
2007-05-04 01:21:11 +04:00
while ( fgets ( buf , sizeof ( buf ) , f ) ! = NULL ) {
long int value ;
2006-08-10 14:50:53 +04:00
2007-05-04 01:21:11 +04:00
if ( sscanf ( buf , " MemTotal: %ld kB " , & value ) = = 1 ) {
memsize = value / 1024 ;
break ;
}
}
2006-08-10 14:50:53 +04:00
2007-05-11 18:53:56 +04:00
fclose ( f ) ;
2007-05-04 01:21:11 +04:00
return memsize ;
2006-08-10 14:50:53 +04:00
}
2005-01-05 07:35:24 +03:00
static int compare_devpath ( const char * running , const char * waiting )
{
int i ;
2008-09-10 23:50:21 +04:00
for ( i = 0 ; i < UTIL_PATH_SIZE ; i + + ) {
2005-01-05 07:35:24 +03:00
/* identical device event found */
if ( running [ i ] = = ' \0 ' & & waiting [ i ] = = ' \0 ' )
return 1 ;
/* parent device event found */
if ( running [ i ] = = ' \0 ' & & waiting [ i ] = = ' / ' )
return 2 ;
/* child device event found */
if ( running [ i ] = = ' / ' & & waiting [ i ] = = ' \0 ' )
return 3 ;
/* no matching event */
if ( running [ i ] ! = waiting [ i ] )
break ;
}
return 0 ;
}
2007-04-20 00:21:05 +04:00
/* lookup event for identical, parent, child, or physical device */
static int devpath_busy ( struct udevd_uevent_msg * msg , int limit )
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
{
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * loop_msg ;
2005-06-05 06:53:17 +04:00
int childs_count = 0 ;
2005-01-05 07:35:24 +03:00
2007-04-20 00:21:05 +04:00
/* check exec-queue which may still contain delayed events we depend on */
list_for_each_entry ( loop_msg , & exec_list , node ) {
/* skip ourself and all later events */
if ( loop_msg - > seqnum > = msg - > seqnum )
break ;
2007-08-26 07:22:35 +04:00
/* check our old name */
if ( msg - > devpath_old ! = NULL )
if ( strcmp ( loop_msg - > devpath , msg - > devpath_old ) = = 0 )
return 2 ;
2007-04-20 00:21:05 +04:00
/* check identical, parent, or child device event */
if ( compare_devpath ( loop_msg - > devpath , msg - > devpath ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, device event still pending %llu (%s) \n " ,
2007-04-20 00:21:05 +04:00
msg - > seqnum , loop_msg - > seqnum , loop_msg - > devpath ) ;
2007-08-26 07:22:35 +04:00
return 3 ;
2007-04-20 00:21:05 +04:00
}
2008-04-02 06:32:17 +04:00
/* check for our major:minor number */
if ( msg - > devt & & loop_msg - > devt = = msg - > devt & &
strcmp ( msg - > subsystem , loop_msg - > subsystem ) = = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, device event still pending %llu (%d:%d) \n " , msg - > seqnum ,
2008-04-02 06:32:17 +04:00
loop_msg - > seqnum , major ( loop_msg - > devt ) , minor ( loop_msg - > devt ) ) ;
return 4 ;
}
2007-04-20 00:21:05 +04:00
/* check physical device event (special case of parent) */
if ( msg - > physdevpath & & msg - > action & & strcmp ( msg - > action , " add " ) = = 0 )
if ( compare_devpath ( loop_msg - > devpath , msg - > physdevpath ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, physical device event still pending %llu (%s) \n " ,
2007-04-20 00:21:05 +04:00
msg - > seqnum , loop_msg - > seqnum , loop_msg - > devpath ) ;
2008-04-02 06:32:17 +04:00
return 5 ;
2007-04-20 00:21:05 +04:00
}
}
2007-08-29 16:04:55 +04:00
/* check run queue for still running events */
2005-02-24 22:13:25 +03:00
list_for_each_entry ( loop_msg , & running_list , node ) {
2008-09-09 17:14:38 +04:00
childs_count + + ;
if ( childs_count + + > = limit ) {
info ( msg - > udev , " %llu, maximum number (%i) of childs reached \n " , msg - > seqnum , childs_count ) ;
2005-06-05 06:53:17 +04:00
return 1 ;
}
2004-11-19 05:49:13 +03:00
2007-08-26 07:22:35 +04:00
/* check our old name */
if ( msg - > devpath_old ! = NULL )
if ( strcmp ( loop_msg - > devpath , msg - > devpath_old ) = = 0 )
return 2 ;
2007-04-20 00:21:05 +04:00
/* check identical, parent, or child device event */
2005-06-05 06:53:17 +04:00
if ( compare_devpath ( loop_msg - > devpath , msg - > devpath ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, device event still running %llu (%s) \n " ,
2005-06-05 06:53:17 +04:00
msg - > seqnum , loop_msg - > seqnum , loop_msg - > devpath ) ;
2007-08-26 07:22:35 +04:00
return 3 ;
2005-06-05 06:53:17 +04:00
}
[PATCH] udevd: serialization of the event sequence of a chain of devices
Currently udevd delays only events for the same DEVPATH.
Example of an "add" event sequence:
/block/sda
/block/sda/sda1
With this change, we make sure, that the udev process handling
/block/sda has finished its work (waited for all attributes,
created the node) before we fork the udev event for /block/sda/sda1.
This way the event for sda1 can be sure, that the node for the
main device is already created (may be useful for disk labels).
It will not affect any parallel device handling, only the sequence
of the devices directory chain is serialized. The 10.000 disks
plugged in will still run as parallel events. :)
The main motivation to do this is the program execution of the
dev.d/ and hotplug.d/ directory. If we don't wait for the parent
event to exit, we can't be sure that the executed scripts are
run in the right order.
On Thu, Dec 09, 2004 at 09:18:28AM +0100, Kay Sievers wrote:
> On Wed, 2004-12-08 at 19:07 -0800, David Brownell wrote:
> > Could that argument apply to the underlying hardware, too?
> We now make sure that the sequence of events for a device
> is serialized for every device chain and the class/block
> devices which have a "device" link to a physical device are
> handled after the physical device is fully populated and
> notified to userspace. It will only work this way on kernels
> later than 2.6.10-rc1 cause it depends on the PHYSDEVPATH
> value in the hotplug environment.
2004-12-11 23:43:08 +03:00
2008-04-02 06:32:17 +04:00
/* check for our major:minor number */
if ( msg - > devt & & loop_msg - > devt = = msg - > devt & &
strcmp ( msg - > subsystem , loop_msg - > subsystem ) = = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, device event still running %llu (%d:%d) \n " , msg - > seqnum ,
2008-04-02 06:32:17 +04:00
loop_msg - > seqnum , major ( loop_msg - > devt ) , minor ( loop_msg - > devt ) ) ;
return 4 ;
}
2007-04-20 00:21:05 +04:00
/* check physical device event (special case of parent) */
[PATCH] udevd: serialization of the event sequence of a chain of devices
Currently udevd delays only events for the same DEVPATH.
Example of an "add" event sequence:
/block/sda
/block/sda/sda1
With this change, we make sure, that the udev process handling
/block/sda has finished its work (waited for all attributes,
created the node) before we fork the udev event for /block/sda/sda1.
This way the event for sda1 can be sure, that the node for the
main device is already created (may be useful for disk labels).
It will not affect any parallel device handling, only the sequence
of the devices directory chain is serialized. The 10.000 disks
plugged in will still run as parallel events. :)
The main motivation to do this is the program execution of the
dev.d/ and hotplug.d/ directory. If we don't wait for the parent
event to exit, we can't be sure that the executed scripts are
run in the right order.
On Thu, Dec 09, 2004 at 09:18:28AM +0100, Kay Sievers wrote:
> On Wed, 2004-12-08 at 19:07 -0800, David Brownell wrote:
> > Could that argument apply to the underlying hardware, too?
> We now make sure that the sequence of events for a device
> is serialized for every device chain and the class/block
> devices which have a "device" link to a physical device are
> handled after the physical device is fully populated and
> notified to userspace. It will only work this way on kernels
> later than 2.6.10-rc1 cause it depends on the PHYSDEVPATH
> value in the hotplug environment.
2004-12-11 23:43:08 +03:00
if ( msg - > physdevpath & & msg - > action & & strcmp ( msg - > action , " add " ) = = 0 )
2005-06-05 06:53:17 +04:00
if ( compare_devpath ( loop_msg - > devpath , msg - > physdevpath ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( msg - > udev , " %llu, physical device event still running %llu (%s) \n " ,
2005-06-05 06:53:17 +04:00
msg - > seqnum , loop_msg - > seqnum , loop_msg - > devpath ) ;
2008-04-02 06:32:17 +04:00
return 5 ;
2005-06-05 06:53:17 +04:00
}
2004-11-19 05:49:13 +03:00
}
2005-06-05 06:53:17 +04:00
return 0 ;
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
}
2007-04-20 00:21:05 +04:00
/* serializes events for the identical and parent and child devices */
2008-09-06 17:45:31 +04:00
static void msg_queue_manager ( struct udev * udev )
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
{
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * loop_msg ;
struct udevd_uevent_msg * tmp_msg ;
2005-01-17 02:53:08 +03:00
2005-06-16 03:58:47 +04:00
if ( list_empty ( & exec_list ) )
return ;
2005-02-24 22:13:25 +03:00
list_for_each_entry_safe ( loop_msg , tmp_msg , & exec_list , node ) {
2007-04-20 00:21:05 +04:00
/* serialize and wait for parent or child events */
if ( devpath_busy ( loop_msg , max_childs ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
dbg ( udev , " delay seq %llu (%s) \n " , loop_msg - > seqnum , loop_msg - > devpath ) ;
2005-11-07 16:10:09 +03:00
continue ;
}
/* move event to run list */
list_move_tail ( & loop_msg - > node , & running_list ) ;
udev_event_run ( loop_msg ) ;
2008-09-06 17:45:31 +04:00
dbg ( udev , " moved seq %llu to running list \n " , loop_msg - > seqnum ) ;
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
}
}
2008-09-06 17:45:31 +04:00
static struct udevd_uevent_msg * get_msg_from_envbuf ( struct udev * udev , const char * buf , int buf_size )
2005-06-05 06:38:10 +04:00
{
int bufpos ;
int i ;
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * msg ;
2006-08-20 20:19:08 +04:00
char * physdevdriver_key = NULL ;
2006-08-24 12:25:34 +04:00
int maj = 0 ;
int min = 0 ;
2005-06-05 06:38:10 +04:00
2006-08-05 15:22:44 +04:00
msg = malloc ( sizeof ( struct udevd_uevent_msg ) + buf_size ) ;
2005-06-05 06:38:10 +04:00
if ( msg = = NULL )
return NULL ;
2006-08-05 15:22:44 +04:00
memset ( msg , 0x00 , sizeof ( struct udevd_uevent_msg ) + buf_size ) ;
2008-09-06 17:45:31 +04:00
msg - > udev = udev ;
2005-06-05 06:38:10 +04:00
/* copy environment buffer and reconstruct envp */
memcpy ( msg - > envbuf , buf , buf_size ) ;
bufpos = 0 ;
2005-06-05 06:41:09 +04:00
for ( i = 0 ; ( bufpos < buf_size ) & & ( i < UEVENT_NUM_ENVP - 2 ) ; i + + ) {
2005-06-05 06:38:10 +04:00
int keylen ;
char * key ;
key = & msg - > envbuf [ bufpos ] ;
keylen = strlen ( key ) ;
msg - > envp [ i ] = key ;
bufpos + = keylen + 1 ;
2008-09-06 17:45:31 +04:00
dbg ( udev , " add '%s' to msg.envp[%i] \n " , msg - > envp [ i ] , i ) ;
2005-06-05 06:38:10 +04:00
/* remember some keys for further processing */
if ( strncmp ( key , " ACTION= " , 7 ) = = 0 )
msg - > action = & key [ 7 ] ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " DEVPATH= " , 8 ) = = 0 )
2005-06-05 06:38:10 +04:00
msg - > devpath = & key [ 8 ] ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " SUBSYSTEM= " , 10 ) = = 0 )
2005-06-05 06:38:10 +04:00
msg - > subsystem = & key [ 10 ] ;
2006-08-13 07:32:09 +04:00
else if ( strncmp ( key , " DRIVER= " , 7 ) = = 0 )
msg - > driver = & key [ 7 ] ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " SEQNUM= " , 7 ) = = 0 )
2005-06-05 06:38:10 +04:00
msg - > seqnum = strtoull ( & key [ 7 ] , NULL , 10 ) ;
2007-08-26 07:22:35 +04:00
else if ( strncmp ( key , " DEVPATH_OLD= " , 12 ) = = 0 )
msg - > devpath_old = & key [ 12 ] ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " PHYSDEVPATH= " , 12 ) = = 0 )
2005-06-05 06:38:10 +04:00
msg - > physdevpath = & key [ 12 ] ;
2006-08-20 20:19:08 +04:00
else if ( strncmp ( key , " PHYSDEVDRIVER= " , 14 ) = = 0 )
physdevdriver_key = key ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " MAJOR= " , 6 ) = = 0 )
2006-08-24 12:25:34 +04:00
maj = strtoull ( & key [ 6 ] , NULL , 10 ) ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " MINOR= " , 6 ) = = 0 )
2006-08-24 12:25:34 +04:00
min = strtoull ( & key [ 6 ] , NULL , 10 ) ;
2005-07-06 04:02:05 +04:00
else if ( strncmp ( key , " TIMEOUT= " , 8 ) = = 0 )
2005-06-05 06:38:10 +04:00
msg - > timeout = strtoull ( & key [ 8 ] , NULL , 10 ) ;
}
2006-08-24 12:25:34 +04:00
msg - > devt = makedev ( maj , min ) ;
2005-06-05 06:38:10 +04:00
msg - > envp [ i + + ] = " UDEVD_EVENT=1 " ;
2006-08-20 20:19:08 +04:00
if ( msg - > driver = = NULL & & msg - > physdevpath = = NULL & & physdevdriver_key ! = NULL ) {
/* for older kernels DRIVER is empty for a bus device, export PHYSDEVDRIVER as DRIVER */
msg - > envp [ i + + ] = & physdevdriver_key [ 7 ] ;
msg - > driver = & physdevdriver_key [ 14 ] ;
}
2005-06-05 06:38:10 +04:00
msg - > envp [ i ] = NULL ;
2006-01-20 04:54:31 +03:00
if ( msg - > devpath = = NULL | | msg - > action = = NULL ) {
2008-09-06 17:45:31 +04:00
info ( udev , " DEVPATH or ACTION missing, ignore message \n " ) ;
2005-11-16 02:13:28 +03:00
free ( msg ) ;
return NULL ;
}
2005-06-05 06:38:10 +04:00
return msg ;
}
2005-06-05 06:41:09 +04:00
/* receive the udevd message from userspace */
2008-09-08 19:59:00 +04:00
static void handle_ctrl_msg ( struct udev_ctrl * uctrl )
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
{
2008-09-08 19:59:00 +04:00
struct udev * udev = udev_ctrl_get_udev ( uctrl ) ;
struct udev_ctrl_msg * ctrl_msg ;
const char * str ;
int i ;
2004-02-12 12:23:59 +03:00
2008-09-08 19:59:00 +04:00
ctrl_msg = udev_ctrl_receive_msg ( uctrl ) ;
if ( ctrl_msg = = NULL )
2006-07-25 16:45:09 +04:00
return ;
2004-11-06 16:30:15 +03:00
2008-09-08 19:59:00 +04:00
i = udev_ctrl_get_set_log_level ( ctrl_msg ) ;
if ( i > = 0 ) {
info ( udev , " udevd message (SET_LOG_PRIORITY) received, log_priority=%i \n " , i ) ;
udev_set_log_priority ( udev , i ) ;
sprintf ( udev_log_env , " UDEV_LOG=%i " , i ) ;
putenv ( udev_log_env ) ;
2004-02-12 09:32:11 +03:00
}
2008-09-08 19:59:00 +04:00
if ( udev_ctrl_get_stop_exec_queue ( ctrl_msg ) > 0 ) {
2008-09-06 17:45:31 +04:00
info ( udev , " udevd message (STOP_EXEC_QUEUE) received \n " ) ;
2005-06-05 06:41:09 +04:00
stop_exec_q = 1 ;
2008-09-08 19:59:00 +04:00
}
if ( udev_ctrl_get_start_exec_queue ( ctrl_msg ) > 0 ) {
2008-09-06 17:45:31 +04:00
info ( udev , " udevd message (START_EXEC_QUEUE) received \n " ) ;
2005-06-05 06:41:09 +04:00
stop_exec_q = 0 ;
2008-09-06 17:45:31 +04:00
msg_queue_manager ( udev ) ;
2008-09-08 19:59:00 +04:00
}
if ( udev_ctrl_get_reload_rules ( ctrl_msg ) > 0 ) {
2008-09-06 17:45:31 +04:00
info ( udev , " udevd message (RELOAD_RULES) received \n " ) ;
2005-10-27 23:04:38 +04:00
reload_config = 1 ;
2005-06-05 06:41:09 +04:00
}
2008-09-08 19:59:00 +04:00
str = udev_ctrl_get_set_env ( ctrl_msg ) ;
if ( str ! = NULL ) {
char * key = strdup ( str ) ;
char * val ;
val = strchr ( str , ' = ' ) ;
if ( val ! = NULL ) {
val [ 0 ] = ' \0 ' ;
val = & val [ 1 ] ;
if ( val [ 0 ] = = ' \0 ' ) {
info ( udev , " udevd message (ENV) received, unset '%s' \n " , key ) ;
unsetenv ( str ) ;
} else {
info ( udev , " udevd message (ENV) received, set '%s=%s' \n " , key , val ) ;
setenv ( key , val , 1 ) ;
}
} else {
err ( udev , " wrong key format '%s' \n " , key ) ;
}
free ( key ) ;
}
i = udev_ctrl_get_set_max_childs ( ctrl_msg ) ;
if ( i > = 0 ) {
info ( udev , " udevd message (SET_MAX_CHILDS) received, max_childs=%i \n " , i ) ;
max_childs = i ;
}
udev_ctrl_msg_unref ( ctrl_msg ) ;
2005-06-05 06:38:10 +04:00
}
2004-11-06 16:30:15 +03:00
2005-06-05 06:38:10 +04:00
/* receive the kernel user event message and do some sanity checks */
2008-09-06 17:45:31 +04:00
static struct udevd_uevent_msg * get_netlink_msg ( struct udev * udev )
2005-06-05 06:38:10 +04:00
{
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * msg ;
2005-06-05 06:38:10 +04:00
int bufpos ;
ssize_t size ;
2006-01-24 14:12:07 +03:00
static char buffer [ UEVENT_BUFFER_SIZE + 512 ] ;
2005-06-05 06:38:10 +04:00
char * pos ;
2004-11-06 16:30:15 +03:00
2005-06-16 03:58:47 +04:00
size = recv ( uevent_netlink_sock , & buffer , sizeof ( buffer ) , 0 ) ;
2005-06-05 06:38:10 +04:00
if ( size < 0 ) {
if ( errno ! = EINTR )
2008-09-29 19:01:32 +04:00
err ( udev , " unable to receive kernel netlink message: %m \n " ) ;
2005-06-05 06:38:10 +04:00
return NULL ;
}
2004-11-06 16:30:15 +03:00
2005-06-05 06:38:10 +04:00
if ( ( size_t ) size > sizeof ( buffer ) - 1 )
size = sizeof ( buffer ) - 1 ;
buffer [ size ] = ' \0 ' ;
2008-09-06 17:45:31 +04:00
dbg ( udev , " uevent_size=%zi \n " , size ) ;
2004-11-06 16:30:15 +03:00
2005-06-05 06:38:10 +04:00
/* start of event payload */
bufpos = strlen ( buffer ) + 1 ;
2008-09-06 17:45:31 +04:00
msg = get_msg_from_envbuf ( udev , & buffer [ bufpos ] , size - bufpos ) ;
2005-06-05 06:38:10 +04:00
if ( msg = = NULL )
return NULL ;
2004-11-06 16:30:15 +03:00
2005-06-05 06:38:10 +04:00
/* validate message */
pos = strchr ( buffer , ' @ ' ) ;
if ( pos = = NULL ) {
2008-09-06 17:45:31 +04:00
err ( udev , " invalid uevent '%s' \n " , buffer ) ;
2005-06-05 06:38:10 +04:00
free ( msg ) ;
return NULL ;
}
pos [ 0 ] = ' \0 ' ;
[PATCH] udevd: serialization of the event sequence of a chain of devices
Currently udevd delays only events for the same DEVPATH.
Example of an "add" event sequence:
/block/sda
/block/sda/sda1
With this change, we make sure, that the udev process handling
/block/sda has finished its work (waited for all attributes,
created the node) before we fork the udev event for /block/sda/sda1.
This way the event for sda1 can be sure, that the node for the
main device is already created (may be useful for disk labels).
It will not affect any parallel device handling, only the sequence
of the devices directory chain is serialized. The 10.000 disks
plugged in will still run as parallel events. :)
The main motivation to do this is the program execution of the
dev.d/ and hotplug.d/ directory. If we don't wait for the parent
event to exit, we can't be sure that the executed scripts are
run in the right order.
On Thu, Dec 09, 2004 at 09:18:28AM +0100, Kay Sievers wrote:
> On Wed, 2004-12-08 at 19:07 -0800, David Brownell wrote:
> > Could that argument apply to the underlying hardware, too?
> We now make sure that the sequence of events for a device
> is serialized for every device chain and the class/block
> devices which have a "device" link to a physical device are
> handled after the physical device is fully populated and
> notified to userspace. It will only work this way on kernels
> later than 2.6.10-rc1 cause it depends on the PHYSDEVPATH
> value in the hotplug environment.
2004-12-11 23:43:08 +03:00
2005-06-05 06:38:10 +04:00
if ( msg - > action = = NULL ) {
2008-09-06 17:45:31 +04:00
info ( udev , " no ACTION in payload found, skip event '%s' \n " , buffer ) ;
2005-06-05 06:38:10 +04:00
free ( msg ) ;
return NULL ;
}
2005-03-17 13:51:37 +03:00
2005-06-05 06:38:10 +04:00
if ( strcmp ( msg - > action , buffer ) ! = 0 ) {
2008-09-06 17:45:31 +04:00
err ( udev , " ACTION in payload does not match uevent, skip event '%s' \n " , buffer ) ;
2005-06-05 06:38:10 +04:00
free ( msg ) ;
return NULL ;
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
}
2004-01-27 05:19:33 +03:00
2005-01-05 07:37:50 +03:00
return msg ;
2004-01-27 05:19:33 +03:00
}
2004-01-24 09:26:19 +03:00
2004-10-14 09:38:15 +04:00
static void asmlinkage sig_handler ( int signum )
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
{
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
switch ( signum ) {
case SIGINT :
case SIGTERM :
2005-08-08 07:07:36 +04:00
udev_exit = 1 ;
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
break ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
case SIGCHLD :
2004-04-01 11:03:07 +04:00
/* set flag, then write to pipe if needed */
2004-10-19 15:37:30 +04:00
sigchilds_waiting = 1 ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
break ;
2005-10-27 23:04:38 +04:00
case SIGHUP :
reload_config = 1 ;
break ;
2004-04-01 11:03:07 +04:00
}
2004-11-05 15:16:32 +03:00
2005-08-29 01:13:14 +04:00
/* write to pipe, which will wakeup select() in our mainloop */
write ( signal_pipe [ WRITE_END ] , " " , 1 ) ;
[PATCH] udev - next round of udev event order daemon
Here is the next round of udevd/udevsend:
udevsend - If the IPC message we send is not catched by a receiver we fork
the udevd daemon to process this and the following events
udevd - We reorder the events we receive and execute our current udev for
every event. If one or more events are missing, we wait
10 seconds and then go ahead in the queue.
If the queue is empty and we don't receive any event for the next
30 seconds, the daemon exits.
The next incoming event will fork the daemon again.
config - The path's to the executable are specified in udevd.h
Now they are pointing to the current directory only.
I don't like daemons hiding secrets (and mem leaks :)) inside,
so I want to try this model. It should be enough logic to get all possible
hotplug events executed in the right order.
If no event, then no daemon! So everybody should be happy :)
Here we see:
1. the daemon fork,
2. the udev work,
3. the 10 sec timeout and the skipped events,
4. the udev work,
...,
5. and the 30 sec timeout and exit.
EVENTS:
pim:/home/kay/src/udev.kay# test/udevd_test.sh
pim:/home/kay/src/udev.kay# SEQNUM=15 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=16 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=17 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=18 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=20 ./udevsend block
pim:/home/kay/src/udev.kay# SEQNUM=21 ./udevsend block
LOG:
Jan 23 15:35:35 pim udev[11795]: message is still in the ipc queue, starting daemon...
Jan 23 15:35:35 pim udev[11799]: configured rule in '/etc/udev/udev.rules' at line 19 applied, 'sda' becomes '%k-flash'
Jan 23 15:35:35 pim udev[11799]: creating device node '/udev/sda-flash'
Jan 23 15:35:35 pim udev[11800]: creating device node '/udev/sdb'
Jan 23 15:35:35 pim udev[11804]: creating device node '/udev/sdc'
Jan 23 15:35:35 pim udev[11805]: removing device node '/udev/sda-flash'
Jan 23 15:35:35 pim udev[11808]: removing device node '/udev/sdb'
Jan 23 15:35:35 pim udev[11809]: removing device node '/udev/sdc'
Jan 23 15:35:45 pim udev[11797]: timeout reached, skip events 7 - 7
Jan 23 15:35:45 pim udev[11811]: creating device node '/udev/sdb'
Jan 23 15:35:45 pim udev[11812]: creating device node '/udev/sdc'
Jan 23 15:36:01 pim udev[11797]: timeout reached, skip events 10 - 14
Jan 23 15:36:01 pim udev[11814]: creating device node '/udev/sdc'
Jan 23 15:36:04 pim udev[11816]: creating device node '/udev/sdc'
Jan 23 15:36:12 pim udev[11818]: creating device node '/udev/sdc'
Jan 23 15:36:16 pim udev[11820]: creating device node '/udev/sdc'
Jan 23 15:36:38 pim udev[11797]: timeout reached, skip events 19 - 19
Jan 23 15:36:38 pim udev[11823]: creating device node '/udev/sdc'
Jan 23 15:36:38 pim udev[11824]: creating device node '/udev/sdc'
Jan 23 15:37:08 pim udev[11797]: we have nothing to do, so daemon exits...
2004-01-24 08:25:17 +03:00
}
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
2005-11-16 04:06:46 +03:00
static void udev_done ( int pid , int exitstatus )
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
{
/* find msg associated with pid and delete it */
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * msg ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
2005-02-24 22:13:25 +03:00
list_for_each_entry ( msg , & running_list , node ) {
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
if ( msg - > pid = = pid ) {
2008-09-06 17:45:31 +04:00
info ( msg - > udev , " seq %llu, pid [%d] exit with %i, %ld seconds old \n " , msg - > seqnum , msg - > pid ,
2005-11-16 04:06:46 +03:00
exitstatus , time ( NULL ) - msg - > queue_time ) ;
msg - > exitstatus = exitstatus ;
2005-07-06 04:02:05 +04:00
msg_queue_delete ( msg ) ;
2004-09-05 20:05:29 +04:00
2005-11-07 16:10:09 +03:00
/* there may be events waiting with the same devpath */
2004-04-01 11:03:07 +04:00
run_exec_q = 1 ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
return ;
}
}
}
2004-10-19 15:37:30 +04:00
static void reap_sigchilds ( void )
2004-04-01 11:03:07 +04:00
{
2005-08-15 13:57:04 +04:00
pid_t pid ;
2005-11-16 04:06:46 +03:00
int status ;
2005-01-16 06:39:02 +03:00
2005-08-15 13:57:04 +04:00
while ( 1 ) {
2005-11-16 04:06:46 +03:00
pid = waitpid ( - 1 , & status , WNOHANG ) ;
2005-08-15 13:57:04 +04:00
if ( pid < = 0 )
2004-04-01 11:03:07 +04:00
break ;
2005-11-16 04:06:46 +03:00
if ( WIFEXITED ( status ) )
status = WEXITSTATUS ( status ) ;
2005-11-17 18:34:37 +03:00
else if ( WIFSIGNALED ( status ) )
status = WTERMSIG ( status ) + 128 ;
2005-11-16 04:06:46 +03:00
else
status = 0 ;
udev_done ( pid , status ) ;
2004-04-01 11:03:07 +04:00
}
}
2008-09-06 17:45:31 +04:00
static int init_uevent_netlink_sock ( struct udev * udev )
2005-06-05 06:38:10 +04:00
{
struct sockaddr_nl snl ;
2005-10-11 23:06:50 +04:00
const int buffersize = 16 * 1024 * 1024 ;
2005-06-05 06:38:10 +04:00
int retval ;
memset ( & snl , 0x00 , sizeof ( struct sockaddr_nl ) ) ;
snl . nl_family = AF_NETLINK ;
snl . nl_pid = getpid ( ) ;
2006-07-21 23:41:11 +04:00
snl . nl_groups = 1 ;
2005-06-05 06:38:10 +04:00
2005-06-16 03:58:47 +04:00
uevent_netlink_sock = socket ( PF_NETLINK , SOCK_DGRAM , NETLINK_KOBJECT_UEVENT ) ;
if ( uevent_netlink_sock = = - 1 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error getting socket: %m \n " ) ;
2005-06-05 06:38:10 +04:00
return - 1 ;
}
2005-07-12 13:44:51 +04:00
/* set receive buffersize */
2005-10-11 23:06:50 +04:00
setsockopt ( uevent_netlink_sock , SOL_SOCKET , SO_RCVBUFFORCE , & buffersize , sizeof ( buffersize ) ) ;
2005-07-12 13:44:51 +04:00
2005-11-04 07:25:15 +03:00
retval = bind ( uevent_netlink_sock , ( struct sockaddr * ) & snl , sizeof ( struct sockaddr_nl ) ) ;
2005-06-05 06:38:10 +04:00
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " bind failed: %m \n " ) ;
2005-06-16 03:58:47 +04:00
close ( uevent_netlink_sock ) ;
uevent_netlink_sock = - 1 ;
2005-06-05 06:38:10 +04:00
return - 1 ;
}
return 0 ;
}
2008-09-06 17:45:31 +04:00
static void export_initial_seqnum ( struct udev * udev )
2006-04-25 20:50:56 +04:00
{
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2006-04-25 20:50:56 +04:00
int fd ;
char seqnum [ 32 ] ;
ssize_t len = 0 ;
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename , udev_get_sys_path ( udev ) , sizeof ( filename ) ) ;
util_strlcat ( filename , " /kernel/uevent_seqnum " , sizeof ( filename ) ) ;
2006-04-25 20:50:56 +04:00
fd = open ( filename , O_RDONLY ) ;
if ( fd > = 0 ) {
len = read ( fd , seqnum , sizeof ( seqnum ) - 1 ) ;
close ( fd ) ;
}
if ( len < = 0 ) {
strcpy ( seqnum , " 0 \n " ) ;
len = 3 ;
}
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename , udev_get_dev_path ( udev ) , sizeof ( filename ) ) ;
util_strlcat ( filename , " /.udev/uevent_seqnum " , sizeof ( filename ) ) ;
2008-09-06 17:45:31 +04:00
create_path ( udev , filename ) ;
2006-04-25 20:50:56 +04:00
fd = open ( filename , O_WRONLY | O_TRUNC | O_CREAT , 0644 ) ;
if ( fd > = 0 ) {
write ( fd , seqnum , len ) ;
close ( fd ) ;
}
}
2008-09-03 01:19:36 +04:00
int main ( int argc , char * argv [ ] )
2005-01-16 06:08:54 +03:00
{
2008-09-06 17:45:31 +04:00
struct udev * udev ;
2005-01-16 06:08:54 +03:00
int retval ;
2005-11-05 21:41:00 +03:00
int fd ;
2004-02-12 09:29:15 +03:00
struct sigaction act ;
2004-04-01 11:03:07 +04:00
fd_set readfds ;
2005-06-05 06:53:17 +04:00
const char * value ;
2005-06-08 13:57:53 +04:00
int daemonize = 0 ;
2006-09-08 13:27:03 +04:00
static const struct option options [ ] = {
2008-10-02 18:49:05 +04:00
{ " daemon " , no_argument , NULL , ' d ' } ,
{ " debug-trace " , no_argument , NULL , ' t ' } ,
{ " debug " , no_argument , NULL , ' D ' } ,
{ " help " , no_argument , NULL , ' h ' } ,
{ " version " , no_argument , NULL , ' V ' } ,
2006-09-08 13:27:03 +04:00
{ }
} ;
2006-08-21 04:38:20 +04:00
int rc = 1 ;
2005-11-07 04:22:44 +03:00
int maxfd ;
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
2008-09-06 17:45:31 +04:00
udev = udev_new ( ) ;
if ( udev = = NULL )
goto exit ;
2004-10-19 05:15:10 +04:00
logging_init ( " udevd " ) ;
2008-09-06 17:45:31 +04:00
udev_set_log_fn ( udev , log_fn ) ;
dbg ( udev , " version %s \n " , VERSION ) ;
2008-10-02 20:48:40 +04:00
selinux_init ( udev ) ;
2004-02-02 19:19:41 +03:00
2006-09-08 13:27:03 +04:00
while ( 1 ) {
2008-09-06 17:45:31 +04:00
int option ;
2008-04-20 23:07:06 +04:00
option = getopt_long ( argc , argv , " dDthV " , options , NULL ) ;
2006-09-08 13:27:03 +04:00
if ( option = = - 1 )
break ;
switch ( option ) {
case ' d ' :
2005-06-08 13:57:53 +04:00
daemonize = 1 ;
2006-09-08 13:27:03 +04:00
break ;
2006-09-08 13:30:00 +04:00
case ' t ' :
debug_trace = 1 ;
break ;
2008-04-20 23:07:06 +04:00
case ' D ' :
debug = 1 ;
2008-09-06 17:45:31 +04:00
if ( udev_get_log_priority ( udev ) < LOG_INFO )
udev_set_log_priority ( udev , LOG_INFO ) ;
2006-09-08 13:28:38 +04:00
break ;
2006-09-08 13:27:03 +04:00
case ' h ' :
2008-04-20 23:07:06 +04:00
printf ( " Usage: udevd [--help] [--daemon] [--debug-trace] [--debug] [--version] \n " ) ;
2007-02-25 01:43:36 +03:00
goto exit ;
case ' V ' :
2008-07-30 03:45:23 +04:00
printf ( " %s \n " , VERSION ) ;
2006-08-21 04:38:20 +04:00
goto exit ;
2006-09-08 13:27:03 +04:00
default :
goto exit ;
2005-06-08 13:57:53 +04:00
}
}
2005-08-15 13:57:04 +04:00
2006-09-03 05:04:20 +04:00
if ( getuid ( ) ! = 0 ) {
fprintf ( stderr , " root privileges required \n " ) ;
2008-09-06 17:45:31 +04:00
err ( udev , " root privileges required \n " ) ;
2006-09-03 05:04:20 +04:00
goto exit ;
}
2007-03-14 00:27:21 +03:00
/* make sure std{in,out,err} fd's are in a sane state */
fd = open ( " /dev/null " , O_RDWR ) ;
if ( fd < 0 ) {
fprintf ( stderr , " cannot open /dev/null \n " ) ;
2008-09-06 17:45:31 +04:00
err ( udev , " cannot open /dev/null \n " ) ;
2007-03-14 00:27:21 +03:00
}
if ( fd > STDIN_FILENO )
dup2 ( fd , STDIN_FILENO ) ;
if ( write ( STDOUT_FILENO , 0 , 0 ) < 0 )
dup2 ( fd , STDOUT_FILENO ) ;
if ( write ( STDERR_FILENO , 0 , 0 ) < 0 )
dup2 ( fd , STDERR_FILENO ) ;
2008-09-08 19:59:00 +04:00
/* init control socket, bind() ensures, that only one udevd instance is running */
udev_ctrl = udev_ctrl_new_from_socket ( udev , UDEV_CTRL_SOCK_PATH ) ;
if ( udev_ctrl = = NULL ) {
fprintf ( stderr , " error initializing control socket " ) ;
err ( udev , " error initializing udevd socket " ) ;
rc = 1 ;
goto exit ;
}
if ( udev_ctrl_enable_receiving ( udev_ctrl ) < 0 ) {
fprintf ( stderr , " error binding control socket, seems udevd is already running \n " ) ;
err ( udev , " error binding control socket, seems udevd is already running \n " ) ;
rc = 1 ;
2005-11-04 07:25:15 +03:00
goto exit ;
}
2008-09-06 17:45:31 +04:00
if ( init_uevent_netlink_sock ( udev ) < 0 ) {
2006-08-21 04:38:20 +04:00
fprintf ( stderr , " error initializing netlink socket \n " ) ;
2008-09-06 17:45:31 +04:00
err ( udev , " error initializing netlink socket \n " ) ;
2005-11-04 07:25:15 +03:00
rc = 3 ;
goto exit ;
}
2007-01-22 00:51:53 +03:00
retval = pipe ( signal_pipe ) ;
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error getting pipes: %m \n " ) ;
2007-01-22 00:51:53 +03:00
goto exit ;
}
retval = fcntl ( signal_pipe [ READ_END ] , F_GETFL , 0 ) ;
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error fcntl on read pipe: %m \n " ) ;
2007-01-22 00:51:53 +03:00
goto exit ;
}
retval = fcntl ( signal_pipe [ READ_END ] , F_SETFL , retval | O_NONBLOCK ) ;
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error fcntl on read pipe: %m \n " ) ;
2007-01-22 00:51:53 +03:00
goto exit ;
}
retval = fcntl ( signal_pipe [ WRITE_END ] , F_GETFL , 0 ) ;
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error fcntl on write pipe: %m \n " ) ;
2007-01-22 00:51:53 +03:00
goto exit ;
}
retval = fcntl ( signal_pipe [ WRITE_END ] , F_SETFL , retval | O_NONBLOCK ) ;
if ( retval < 0 ) {
2008-09-29 19:01:32 +04:00
err ( udev , " error fcntl on write pipe: %m \n " ) ;
2007-01-22 00:51:53 +03:00
goto exit ;
}
2006-08-21 04:38:20 +04:00
/* parse the rules and keep them in memory */
2006-01-09 23:18:00 +03:00
sysfs_init ( ) ;
2008-09-06 17:45:31 +04:00
udev_rules_init ( udev , & rules , 1 ) ;
2005-11-04 07:25:15 +03:00
2008-09-06 17:45:31 +04:00
export_initial_seqnum ( udev ) ;
2006-04-25 20:50:56 +04:00
2005-06-08 13:57:53 +04:00
if ( daemonize ) {
2005-01-16 06:06:22 +03:00
pid_t pid ;
pid = fork ( ) ;
switch ( pid ) {
case 0 :
2008-09-06 17:45:31 +04:00
dbg ( udev , " daemonized fork running \n " ) ;
2005-01-16 06:06:22 +03:00
break ;
case - 1 :
2008-09-29 19:01:32 +04:00
err ( udev , " fork of daemon failed: %m \n " ) ;
2005-11-04 07:25:15 +03:00
rc = 4 ;
2005-01-16 06:06:22 +03:00
goto exit ;
default :
2008-09-06 17:45:31 +04:00
dbg ( udev , " child [%u] running, parent exits \n " , pid ) ;
2006-08-23 01:20:15 +04:00
rc = 0 ;
2005-11-04 07:25:15 +03:00
goto exit ;
2005-01-16 06:06:22 +03:00
}
}
2008-09-08 19:59:00 +04:00
/* redirect std{out,err} */
if ( ! debug ) {
2007-03-14 00:27:21 +03:00
dup2 ( fd , STDOUT_FILENO ) ;
2008-09-08 19:59:00 +04:00
dup2 ( fd , STDERR_FILENO ) ;
}
2007-03-14 00:27:21 +03:00
if ( fd > STDERR_FILENO )
close ( fd ) ;
2006-08-21 04:38:20 +04:00
2005-11-05 21:41:00 +03:00
/* set scheduling priority for the daemon */
2005-01-17 02:53:08 +03:00
setpriority ( PRIO_PROCESS , 0 , UDEVD_PRIORITY ) ;
2005-11-05 21:41:00 +03:00
chdir ( " / " ) ;
2005-11-06 00:02:21 +03:00
umask ( 022 ) ;
2008-09-09 17:14:38 +04:00
setsid ( ) ;
2005-11-05 21:41:00 +03:00
/* OOM_DISABLE == -17 */
fd = open ( " /proc/self/oom_adj " , O_RDWR ) ;
if ( fd < 0 )
2008-09-29 19:01:32 +04:00
err ( udev , " error disabling OOM: %m \n " ) ;
2005-11-05 21:41:00 +03:00
else {
write ( fd , " -17 " , 3 ) ;
close ( fd ) ;
}
2008-04-10 23:35:40 +04:00
fd = open ( " /dev/kmsg " , O_WRONLY ) ;
if ( fd > 0 ) {
2008-10-01 21:00:55 +04:00
const char * ver_str = " <6>udev: starting version " VERSION " \n " ;
char path [ UTIL_PATH_SIZE ] ;
struct stat statbuf ;
write ( fd , ver_str , strlen ( ver_str ) ) ;
util_strlcpy ( path , udev_get_sys_path ( udev ) , sizeof ( path ) ) ;
util_strlcat ( path , " /class/mem/null " , sizeof ( path ) ) ;
if ( lstat ( path , & statbuf ) = = 0 ) {
if ( S_ISDIR ( statbuf . st_mode ) ) {
2008-10-04 15:52:39 +04:00
const char * depr_str = " <6>udev: deprecated sysfs layout (kernel too old, "
" or CONFIG_SYSFS_DEPRECATED) is unsupported, some "
" udev features may fail \n " ;
2008-10-01 21:00:55 +04:00
write ( fd , depr_str , strlen ( depr_str ) ) ;
}
}
2008-04-10 23:35:40 +04:00
close ( fd ) ;
}
2004-04-01 11:03:07 +04:00
/* set signal handlers */
2005-02-06 02:09:34 +03:00
memset ( & act , 0x00 , sizeof ( struct sigaction ) ) ;
2005-03-27 03:11:03 +04:00
act . sa_handler = ( void ( * ) ( int ) ) sig_handler ;
2004-04-01 11:03:07 +04:00
sigemptyset ( & act . sa_mask ) ;
2004-02-12 09:29:15 +03:00
act . sa_flags = SA_RESTART ;
sigaction ( SIGINT , & act , NULL ) ;
sigaction ( SIGTERM , & act , NULL ) ;
sigaction ( SIGCHLD , & act , NULL ) ;
2005-08-08 07:07:36 +04:00
sigaction ( SIGHUP , & act , NULL ) ;
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
2005-10-27 23:04:38 +04:00
/* watch rules directory */
inotify_fd = inotify_init ( ) ;
2007-07-15 21:10:06 +04:00
if ( inotify_fd > = 0 ) {
2008-09-06 17:45:31 +04:00
if ( udev_get_rules_path ( udev ) ! = NULL ) {
inotify_add_watch ( inotify_fd , udev_get_rules_path ( udev ) ,
2008-07-18 17:56:03 +04:00
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE ) ;
} else {
char filename [ PATH_MAX ] ;
2008-07-30 03:45:23 +04:00
inotify_add_watch ( inotify_fd , UDEV_PREFIX " /lib/udev/rules.d " ,
2008-07-18 17:56:03 +04:00
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE ) ;
2008-07-30 03:45:23 +04:00
inotify_add_watch ( inotify_fd , SYSCONFDIR " /udev/rules.d " ,
2008-07-18 17:56:03 +04:00
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE ) ;
/* watch dynamic rules directory */
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename , udev_get_dev_path ( udev ) , sizeof ( filename ) ) ;
util_strlcat ( filename , " /.udev/rules.d " , sizeof ( filename ) ) ;
2008-07-18 17:56:03 +04:00
inotify_add_watch ( inotify_fd , filename ,
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE ) ;
}
2007-07-15 21:10:06 +04:00
} else if ( errno = = ENOSYS )
2008-09-06 17:45:31 +04:00
err ( udev , " the kernel does not support inotify, udevd can't monitor rules file changes \n " ) ;
2006-04-06 21:52:41 +04:00
else
2008-09-29 19:01:32 +04:00
err ( udev , " inotify_init failed: %m \n " ) ;
2004-02-12 09:32:11 +03:00
2005-06-05 06:53:17 +04:00
/* maximum limit of forked childs */
value = getenv ( " UDEVD_MAX_CHILDS " ) ;
if ( value )
max_childs = strtoul ( value , NULL , 10 ) ;
2006-08-10 14:50:53 +04:00
else {
int memsize = mem_size_mb ( ) ;
if ( memsize > 0 )
max_childs = 128 + ( memsize / 4 ) ;
else
max_childs = UDEVD_MAX_CHILDS ;
}
2008-09-06 17:45:31 +04:00
info ( udev , " initialize max_childs to %u \n " , max_childs ) ;
2005-06-05 06:53:17 +04:00
2005-10-27 23:04:38 +04:00
/* clear environment for forked event processes */
clearenv ( ) ;
2005-08-15 13:57:04 +04:00
/* export log_priority , as called programs may want to follow that setting */
2008-09-06 17:45:31 +04:00
sprintf ( udev_log_env , " UDEV_LOG=%i " , udev_get_log_priority ( udev ) ) ;
putenv ( udev_log_env ) ;
2006-09-08 13:30:00 +04:00
if ( debug_trace )
putenv ( " DEBUG=1 " ) ;
2005-08-15 13:57:04 +04:00
2008-09-08 19:59:00 +04:00
maxfd = udev_ctrl_get_fd ( udev_ctrl ) ;
2005-11-07 04:22:44 +03:00
maxfd = UDEV_MAX ( maxfd , uevent_netlink_sock ) ;
maxfd = UDEV_MAX ( maxfd , signal_pipe [ READ_END ] ) ;
maxfd = UDEV_MAX ( maxfd , inotify_fd ) ;
2005-08-08 07:07:36 +04:00
while ( ! udev_exit ) {
2006-08-05 15:22:44 +04:00
struct udevd_uevent_msg * msg ;
2005-08-15 13:57:04 +04:00
int fdcount ;
2005-01-05 07:37:50 +03:00
2005-08-15 13:57:04 +04:00
FD_ZERO ( & readfds ) ;
2005-08-28 22:25:37 +04:00
FD_SET ( signal_pipe [ READ_END ] , & readfds ) ;
2008-09-08 19:59:00 +04:00
FD_SET ( udev_ctrl_get_fd ( udev_ctrl ) , & readfds ) ;
2005-11-04 07:25:15 +03:00
FD_SET ( uevent_netlink_sock , & readfds ) ;
2006-04-25 20:50:56 +04:00
if ( inotify_fd > = 0 )
2005-10-27 23:04:38 +04:00
FD_SET ( inotify_fd , & readfds ) ;
2004-04-01 11:03:46 +04:00
2005-11-07 04:22:44 +03:00
fdcount = select ( maxfd + 1 , & readfds , NULL , NULL , NULL ) ;
2005-08-15 13:57:04 +04:00
if ( fdcount < 0 ) {
2004-04-01 11:03:46 +04:00
if ( errno ! = EINTR )
2008-09-29 19:01:32 +04:00
err ( udev , " error in select: %m \n " ) ;
2004-04-01 11:03:07 +04:00
continue ;
[PATCH] convert udevsend/udevd to DGRAM and single-threaded
On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote:
>
> Kay, you said "unless we can get rid of _all_ the threads or at least
> getting faster, I don't want to change it."
>
> Well how about we get rid of all the threads, *and* we get faster?
Yes, we are twice as fast now on my box :)
> This patch applies to current bk trees, and does the following:
>
> 1) Switch to DGRAM sockets rather than STREAM. This simplifies things
> as mentioned in the previous message.
>
> 2) Invalid sequence numbers are mapped to -1 rather than zero, since
> zero is a valid sequence number (I think). Also, this allows for real
> speed tests using scripts starting at a zero sequence number, since that
> is what the initial expected sequence number is.
>
> 3) Get rid of all threading. This is the biggie. Some highlights:
> a) timeout using setitimer() and SIGALRM
> b) async child death notification via SIGCHLD
> c) these two signal handlers do nothing but raise volatile flags,
> all the
> work is done in the main loop
> d) locking no longer required
I cleaned up the rest of the comments, the whitespace and a few names to match
the whole thing. Please recheck it. Test script is switched to work on subsystem
'test' to let udev ignore it.
2004-02-07 09:21:15 +03:00
}
2004-04-01 11:03:46 +04:00
2006-08-05 15:22:44 +04:00
/* get control message */
2008-09-08 19:59:00 +04:00
if ( FD_ISSET ( udev_ctrl_get_fd ( udev_ctrl ) , & readfds ) )
handle_ctrl_msg ( udev_ctrl ) ;
2005-06-05 06:38:10 +04:00
2006-08-05 15:22:44 +04:00
/* get netlink message */
2005-11-04 07:25:15 +03:00
if ( FD_ISSET ( uevent_netlink_sock , & readfds ) ) {
2008-09-06 17:45:31 +04:00
msg = get_netlink_msg ( udev ) ;
2005-11-07 04:22:44 +03:00
if ( msg )
2005-01-05 07:37:50 +03:00
msg_queue_insert ( msg ) ;
}
2004-04-01 11:03:46 +04:00
2005-08-08 07:07:36 +04:00
/* received a signal, clear our notification pipe */
2005-08-29 01:13:14 +04:00
if ( FD_ISSET ( signal_pipe [ READ_END ] , & readfds ) ) {
char buf [ 256 ] ;
read ( signal_pipe [ READ_END ] , & buf , sizeof ( buf ) ) ;
2005-08-15 13:57:04 +04:00
}
2004-04-01 11:03:46 +04:00
2005-10-27 23:04:38 +04:00
/* rules directory inotify watch */
2006-04-25 20:50:56 +04:00
if ( ( inotify_fd > = 0 ) & & FD_ISSET ( inotify_fd , & readfds ) ) {
2005-10-27 23:04:38 +04:00
int nbytes ;
/* discard all possible events, we can just reload the config */
2007-07-15 21:10:06 +04:00
if ( ( ioctl ( inotify_fd , FIONREAD , & nbytes ) = = 0 ) & & nbytes > 0 ) {
2005-10-27 23:04:38 +04:00
char * buf ;
reload_config = 1 ;
buf = malloc ( nbytes ) ;
2007-07-26 15:04:13 +04:00
if ( buf = = NULL ) {
2008-09-06 17:45:31 +04:00
err ( udev , " error getting buffer for inotify, disable watching \n " ) ;
2005-10-27 23:04:38 +04:00
close ( inotify_fd ) ;
inotify_fd = - 1 ;
}
read ( inotify_fd , buf , nbytes ) ;
free ( buf ) ;
}
}
2006-08-21 04:38:20 +04:00
/* rules changed, set by inotify or a HUP signal */
2005-10-27 23:04:38 +04:00
if ( reload_config ) {
reload_config = 0 ;
2006-01-09 23:18:00 +03:00
udev_rules_cleanup ( & rules ) ;
2008-09-06 17:45:31 +04:00
udev_rules_init ( udev , & rules , 1 ) ;
2005-10-27 23:04:38 +04:00
}
2005-11-07 04:22:44 +03:00
/* forked child has returned */
2004-10-19 15:37:30 +04:00
if ( sigchilds_waiting ) {
sigchilds_waiting = 0 ;
reap_sigchilds ( ) ;
2004-04-01 11:03:07 +04:00
}
2004-04-01 11:03:46 +04:00
2004-04-01 11:03:07 +04:00
if ( run_exec_q ) {
run_exec_q = 0 ;
2005-06-05 06:41:09 +04:00
if ( ! stop_exec_q )
2008-09-06 17:45:31 +04:00
msg_queue_manager ( udev ) ;
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
}
}
2006-08-21 04:38:20 +04:00
rc = 0 ;
2004-11-23 05:28:41 +03:00
[PATCH] udevd - cleanup and better timeout handling
On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote:
> On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote:
> > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote:
> > > Oh, couldn't resist to try threads.
> > > It's a multithreaded udevd that communicates through a localhost socket.
> > > The message includes a magic with the udev version, so we don't accept
> > > older udevsend's.
> > >
> > > No need for locking, cause we can't bind two sockets on the same address.
> > > The daemon tries to connect and if it fails it starts the daemon.
> > >
> > > We create a thread for every incoming connection, handle over the socket,
> > > sort the messages in the global message queue and exit the thread.
> > > Huh, that was easy with threads :)
> > >
> > > With the addition of a message we wakeup the queue manager thread and
> > > handle timeouts or move the message to the global exec list. This wakes
> > > up the exec list manager who looks if a process is already running for this
> > > device path.
> > > If yes, the exec is delayed otherwise we create a thread that execs udev.
> > > n the background. With the return of udev we free the message and wakeup
> > > the exec list manager to look if something is pending.
> > >
> > > It is just a quick shot, cause I couldn't solve the problems with fork an
> > > scheduling and I wanted to see if I'm to stupid :)
> > > But if anybody with a better idea or more experience with I/O scheduling
> > > we may go another way. The remaining problem is that klibc doesn't support
> > > threads.
> > >
> > > By now, we don't exec anything, it's just a sleep 3 for every exec,
> > > but you can see the queue management by watching syslog and do:
> > >
> > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc
>
> Next version, switched to unix domain sockets.
Next cleaned up version. Hey, nobody wants to try it :)
Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader
every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3
devices plugged in every second and don't run into any problem but a _very_
big udevd queue.
2004-02-01 20:12:36 +03:00
exit :
2006-01-09 23:18:00 +03:00
udev_rules_cleanup ( & rules ) ;
sysfs_cleanup ( ) ;
2005-10-27 23:04:38 +04:00
2006-04-25 20:50:56 +04:00
if ( signal_pipe [ READ_END ] > = 0 )
2005-08-28 22:25:37 +04:00
close ( signal_pipe [ READ_END ] ) ;
2006-04-25 20:50:56 +04:00
if ( signal_pipe [ WRITE_END ] > = 0 )
2005-08-28 22:25:37 +04:00
close ( signal_pipe [ WRITE_END ] ) ;
2005-08-11 22:34:24 +04:00
2008-09-08 19:59:00 +04:00
udev_ctrl_unref ( udev_ctrl ) ;
2006-04-25 20:50:56 +04:00
if ( inotify_fd > = 0 )
2005-10-27 23:04:38 +04:00
close ( inotify_fd ) ;
2006-04-25 20:50:56 +04:00
if ( uevent_netlink_sock > = 0 )
2005-08-08 07:07:36 +04:00
close ( uevent_netlink_sock ) ;
2008-10-02 20:48:40 +04:00
selinux_exit ( udev ) ;
udev_unref ( udev ) ;
2004-10-19 05:15:10 +04:00
logging_close ( ) ;
2005-11-04 07:25:15 +03:00
return rc ;
[PATCH] spilt udev into pieces
On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote:
> On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote:
> > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote:
> > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote:
> > > > Hi, Greg
> > > > I wrote a simple implementation for the two pieces
> > > > of send and receive hotplug event,
> > > > use a message queue and a list for the out of order
> > > > hotplug event. It also has a timeout timer of 3 seconds.
> > > > They are now separate program. the file nseq is the test script.
> > > > Could you have a look to see wether it is feasible?
> > > > If so, I'll continue to merge with udev.
> > >
> > > Yes, very nice start. Please continue on.
> > >
> > > One minor comment, please stick with the kernel coding style when you
> > > are writing new code for udev.
> >
> > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits,
> > tweaked the debugging, added the udev exec and created a patch for the current tree.
> >
> > It seems functional now, by simply executing our current udev (dirty hack).
> > It reorders the incoming events and if one is missing it delays the
> > execution of the following ones up to a maximum of 10 seconds.
> >
> > Test script is included, but you can't mix hotplug sequence numbers and
> > test script numbers, it will result in waiting for the missing numbers :)
>
> Hey, nobody want's to play with me?
> So here I'm chatting with myself :)
>
> This is the next version with signal handling for resetting the expected
> signal number. I changed the behaviour of the timeout to skip all
> missing events at once and to proceed with the next event in the queue.
>
> So it's now possible to use the test script at any time, cause it resets
> the daemon, if real hotplug event coming in later all missing nimbers will
> be skipped after a timeout of 10 seconds and the queued events are applied.
Here is the next updated updated version to apply to the lastet udev.
I've added infrastructure for getting the state of the IPC queue in the
sender and set the program to exec by the daemon. Also the magic key id
is replaced by the usual key generation by path/nr.
It looks promising, I use it on my machine and my 4in1 USB-flash-reader
connect/disconnect emits the events "randomly" but udevd is able to
reorder it and calls our normal udev in the right order.
2004-01-23 11:28:57 +03:00
}