chiark / gitweb /
[PATCH] udevsend fallback
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sat, 15 May 2004 06:18:41 +0000 (23:18 -0700)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:35:18 +0000 (21:35 -0700)
On Tue, May 11, 2004 at 04:54:44PM -0700, Greg KH wrote:
> On Tue, May 11, 2004 at 01:16:41PM +0200, Kay Sievers wrote:
> > Hi,
> > the execution of udev depends on the proper fuction of udevd, the
> > serializing daemon. If we can't connect to udevd within a 20 second we
> > give up and the request to create a node is lost. Hope this never happens,
> > but a broken udevd may prevent udev from working.
> >
> > What do you think? Should we call the udev binary directly from udevsend
> > instead of discarding the event? This way we would create the node, regardless
> > of the state of udevd. It would be 20 seconds later and maybe not in the right
> > sequence order - but the node will propably be there.
> >
> > Does it sound sane? What do you think?
>
> That sounds like a good "failsafe" thing to do.

Here we go:

Add a fallback udev call to udevsend. If udevsend is unable to send the
event to udevd, we call the udev binary instead of doing nothing and exiting.

udevsend.c

index f28e445433ab156caae58a7eb7b0a74d8f6bd482..a52d6ec1653c48150f436cd3b0c508ce464cbfce 100644 (file)
@@ -98,6 +98,26 @@ static int start_daemon(void)
        return 0;
 }
 
+static void run_udev(const char *subsystem)
+{
+       pid_t pid;
+
+       pid = fork();
+       switch (pid) {
+       case 0:
+               /* child */
+               execl(UDEV_BIN, "udev", subsystem, NULL);
+               dbg("exec of child failed");
+               exit(1);
+               break;
+       case -1:
+               dbg("fork of child failed");
+               break;
+       default:
+               wait(NULL);
+       }
+}
+
 int main(int argc, char* argv[])
 {
        struct hotplug_msg msg;
@@ -109,14 +129,12 @@ int main(int argc, char* argv[])
        int retval = 1;
        int loop;
        struct timespec tspec;
-       int sock;
+       int sock = -1;
        struct sockaddr_un saddr;
        socklen_t addrlen;
        int started_daemon = 0;
 
-#ifdef DEBUG
        init_logging("udevsend");
-#endif
        dbg("version %s", UDEV_VERSION);
 
        subsystem = get_subsystem(argv[1]);
@@ -150,7 +168,7 @@ int main(int argc, char* argv[])
        sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
        if (sock == -1) {
                dbg("error getting socket");
-               goto exit;
+               goto fallback;
        }
 
        memset(&saddr, 0x00, sizeof(struct sockaddr_un));
@@ -168,22 +186,21 @@ int main(int argc, char* argv[])
                                (struct sockaddr *)&saddr, addrlen);
                if (retval != -1) {
                        retval = 0;
-                       goto close_and_exit;
+                       goto exit;
                }
-               
+
                if (errno != ECONNREFUSED) {
                        dbg("error sending message");
-                       goto close_and_exit;
+                       goto fallback;
                }
-               
+
                if (!started_daemon) {
-                       dbg("connect failed, try starting daemon...");
+                       info("starting udevd daemon");
                        retval = start_daemon();
                        if (retval) {
-                               dbg("error starting daemon");
-                               goto exit;
+                               info("error starting daemon");
+                               goto fallback;
                        }
-                       
                        dbg("daemon started");
                        started_daemon = 1;
                } else {
@@ -193,9 +210,14 @@ int main(int argc, char* argv[])
                        nanosleep(&tspec, NULL);
                }
        }
-       
-close_and_exit:
-       close(sock);
+
+fallback:
+       info("unable to connect to event daemon, try to call udev directly");
+       run_udev(subsystem);
+
 exit:
+       if (sock != -1)
+               close(sock);
+
        return retval;
 }