From: kay.sievers@vrfy.org Date: Sat, 15 May 2004 06:18:41 +0000 (-0700) Subject: [PATCH] udevsend fallback X-Git-Tag: 026~8 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=28e169f067aa96b406342677922e34e7361a7d1b [PATCH] udevsend fallback 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. --- diff --git a/udevsend.c b/udevsend.c index f28e44543..a52d6ec16 100644 --- a/udevsend.c +++ b/udevsend.c @@ -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; }