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.
+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;
int main(int argc, char* argv[])
{
struct hotplug_msg msg;
int retval = 1;
int loop;
struct timespec tspec;
int retval = 1;
int loop;
struct timespec tspec;
struct sockaddr_un saddr;
socklen_t addrlen;
int started_daemon = 0;
struct sockaddr_un saddr;
socklen_t addrlen;
int started_daemon = 0;
init_logging("udevsend");
init_logging("udevsend");
dbg("version %s", UDEV_VERSION);
subsystem = get_subsystem(argv[1]);
dbg("version %s", UDEV_VERSION);
subsystem = get_subsystem(argv[1]);
sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (sock == -1) {
dbg("error getting socket");
sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (sock == -1) {
dbg("error getting socket");
}
memset(&saddr, 0x00, sizeof(struct sockaddr_un));
}
memset(&saddr, 0x00, sizeof(struct sockaddr_un));
(struct sockaddr *)&saddr, addrlen);
if (retval != -1) {
retval = 0;
(struct sockaddr *)&saddr, addrlen);
if (retval != -1) {
retval = 0;
if (errno != ECONNREFUSED) {
dbg("error sending message");
if (errno != ECONNREFUSED) {
dbg("error sending message");
- dbg("connect failed, try starting daemon...");
+ info("starting udevd daemon");
retval = start_daemon();
if (retval) {
retval = start_daemon();
if (retval) {
- dbg("error starting daemon");
- goto exit;
+ info("error starting daemon");
+ goto fallback;
dbg("daemon started");
started_daemon = 1;
} else {
dbg("daemon started");
started_daemon = 1;
} else {
nanosleep(&tspec, NULL);
}
}
nanosleep(&tspec, NULL);
}
}
-
-close_and_exit:
- close(sock);
+
+fallback:
+ info("unable to connect to event daemon, try to call udev directly");
+ run_udev(subsystem);
+
+ if (sock != -1)
+ close(sock);
+