linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Integrate udevsettle with udevtrigger?
@ 2006-04-17 23:16 Bryan Kadzban
  2006-04-18  2:30 ` Alexander E. Patrakov
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Bryan Kadzban @ 2006-04-17 23:16 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 2048 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

It seems to me that udevtrigger and udevsettle are strongly related
(generate all the uevents, then wait for them to finish -- this seems
like it's is all part of the same "task").  Therefore I don't really see
any reason to run udevtrigger without udevsettle.  I doubt any distro's
bootscripts are going to run the one without the other, for instance,
but even running udevtrigger manually should (IMO) wait for events to
settle out.

Would it make sense to anyone else to integrate the two programs, by
adding an option to udevtrigger that would tell it to wait?

If so, I've attached one possible patch to do that, against udev-090.
It adds support in udevtrigger (and documentation) for a --wait option,
which when specified will cause udevtrigger to call a new do_uevent_wait
function.  do_uevent_wait is basically the guts out of udevsettle.
- --wait will also take an argument: the number of seconds to wait (this
is the same option that udevsettle took).

(I basically cut-and-pasted udevsettle's code into the function; it's
possible that something got screwed up there.  The code compiles OK for
me, though, and it hasn't leaked any more uevents than "udevtrigger &&
udevsettle" over ~6-8 bootups.  To check for leaks, I'm doing what
Alexander did[1]: putting an ACTION=="add" RUN+="bug" rule last,
clearing out the /dev/bug file after the udevtrigger --wait call,
sleeping 6 seconds, and looking for anything in /dev/bug.  Both setups
leak events in the presence of usb-storage devices, but I think that's a
known issue.  If I have only USB-HID devices plugged in, that works OK
whether I use "udevtrigger --wait" or "udevtrigger && udevsettle".)

Comments?

[1] http://sourceforge.net/mailarchive/message.php?msg_id=15413263

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFERCHJi5mq6LtIi44RA6erAJ9DcSoVaSgSIhvWrpXdLXNu9j+MnwCfX6iE
ZGwFpzNryvZsou+xW5W1jj4=
=K4JV
-----END PGP SIGNATURE-----

[-- Attachment #2: udev-090-integrate-settle-with-trigger.patch --]
[-- Type: text/plain, Size: 13364 bytes --]

diff -Naur udev-090/udevsettle.8 udev-090-patched/udevsettle.8
--- udev-090/udevsettle.8	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevsettle.8	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-.\" ** You probably do not want to edit this file directly **
-.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1).
-.\" Instead of manually editing it, you probably should edit the DocBook XML
-.\" source for it and then use the DocBook XSL Stylesheets to regenerate it.
-.TH "UDEVSETTLE" "8" "March 2006" "udev" "udevsettle"
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.SH "NAME"
-udevsettle \- wait until queued kernel/udev events are handled
-.SH "SYNOPSIS"
-.HP 11
-\fBudevsettle\fR [\fB\-\-timeout=\fR\fB\fIseconds\fR\fR]
-.SH "DESCRIPTION"
-.PP
-Waits watching the udev event queue and exits if all current events are handled.
-.SH "OPTIONS"
-.TP
-\fB\-\-timeout=\fR\fB\fIseconds\fR\fR
-maximum seconds to wait for the queue to become empty.
-.SH "ENVIRONMENT"
-.TP
-\fBUDEV_LOG\fR
-Overrides the syslog priority specified in the config file.
-.SH "AUTHOR"
-.PP
-Written by Kay Sievers
-<kay.sievers@vrfy.org>.
-.SH "SEE ALSO"
-.PP
-\fBudev\fR(7)
diff -Naur udev-090/udevsettle.c udev-090-patched/udevsettle.c
--- udev-090/udevsettle.c	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevsettle.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,156 +0,0 @@
-/*
- * udevsettle.c
- *
- * Copyright (C) 2006 Kay Sievers <kay@vrfy.org>
- *
- *	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 version 2 of the License.
- * 
- *	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.
- * 
- *	You should have received a copy of the GNU General Public License along
- *	with this program; if not, write to the Free Software Foundation, Inc.,
- *	675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "udev.h"
-#include "udevd.h"
-
-#define DEFAULT_TIMEOUT			180
-#define LOOP_PER_SECOND			20
-
-static const char *udev_log_str;
-
-#ifdef USE_LOG
-void log_message(int priority, const char *format, ...)
-{
-	va_list args;
-
-	if (priority > udev_log_priority)
-		return;
-
-	va_start(args, format);
-	vsyslog(priority, format, args);
-	va_end(args);
-}
-#endif
-
-int main(int argc, char *argv[], char *envp[])
-{
-	char queuename[PATH_SIZE];
-	char filename[PATH_SIZE];
-	unsigned long long seq_kernel;
-	unsigned long long seq_udev;
-	char seqnum[32];
-	int fd;
-	ssize_t len;
-	int timeout = DEFAULT_TIMEOUT;
-	int loop;
-	int i;
-	int rc = 1;
-
-	logging_init("udevsettle");
-	udev_config_init();
-	dbg("version %s", UDEV_VERSION);
-
-	udev_log_str = getenv("UDEV_LOG");
-
-	for (i = 1 ; i < argc; i++) {
-		char *arg = argv[i];
-
-		if (strncmp(arg, "--timeout=", 10) == 0) {
-			char *str = &arg[10];
-
-			timeout = atoi(str);
-			dbg("timeout=%i", timeout);
-			if (timeout <= 0) {
-				fprintf(stderr, "Invalid timeout value.\n");
-				goto exit;
-			}
-		} else {
-			fprintf(stderr, "Usage: udevsettle [--timeout=<seconds>]\n");
-			goto exit;
-		}
-	}
-
-	sysfs_init();
-	strlcpy(queuename, udev_root, sizeof(queuename));
-	strlcat(queuename, "/" EVENT_QUEUE_DIR, sizeof(queuename));
-
-	loop = timeout * LOOP_PER_SECOND;
-	while (loop--) {
-		/* wait for events in queue to finish */
-		while (loop--) {
-			struct stat statbuf;
-
-			if (stat(queuename, &statbuf) < 0) {
-				info("queue is empty");
-				break;
-			}
-			usleep(1000 * 1000 / LOOP_PER_SECOND);
-		}
-		if (loop <= 0) {
-			info("timeout waiting for queue");
-			goto exit;
-		}
-
-		/* read current kernel seqnum */
-		strlcpy(filename, sysfs_path, sizeof(filename));
-		strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename));
-		fd = open(filename, O_RDONLY);
-		if (fd < 0)
-			goto exit;
-		len = read(fd, seqnum, sizeof(seqnum)-1);
-		close(fd);
-		if (len <= 0)
-			goto exit;
-		seqnum[len] = '\0';
-		seq_kernel = strtoull(seqnum, NULL, 10);
-		info("kernel seqnum = %llu", seq_kernel);
-
-		/* read current udev seqnum */
-		strlcpy(filename, udev_root, sizeof(filename));
-		strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename));
-		fd = open(filename, O_RDONLY);
-		if (fd < 0)
-			goto exit;
-		len = read(fd, seqnum, sizeof(seqnum)-1);
-		close(fd);
-		if (len <= 0)
-			goto exit;
-		seqnum[len] = '\0';
-		seq_udev = strtoull(seqnum, NULL, 10);
-		info("udev seqnum = %llu", seq_udev);
-
-		/* make sure all kernel events have arrived in the queue */
-		if (seq_udev >= seq_kernel) {
-			info("queue is empty and no pending events left");
-			rc = 0;
-			goto exit;
-		}
-		usleep(1000 * 1000 / LOOP_PER_SECOND);
-		info("queue is empty, but events still pending");
-	}
-
-exit:
-	sysfs_cleanup();
-	logging_close();
-	return rc;
-}
diff -Naur udev-090/udevsettle.xml udev-090-patched/udevsettle.xml
--- udev-090/udevsettle.xml	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevsettle.xml	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<article>
-  <articleinfo>
-    <title>xmlto</title>
-    <author>
-      <firstname>Kay</firstname>
-      <surname>Sievers</surname>
-      <email>kay.sievers@vrfy.org</email>
-    </author>
-    <copyright>
-      <year>2006</year>
-      <holder>Kay Sievers</holder>
-    </copyright>
-  </articleinfo>
-
-  <section>
-    <title>udevsettle</title>
-    <refentry>
-      <refentryinfo>
-        <title>udevsettle</title>
-        <date>March 2006</date>
-        <productname>udev</productname>
-      </refentryinfo>
-
-      <refmeta>
-        <refentrytitle>udevsettle</refentrytitle>
-        <manvolnum>8</manvolnum>
-      </refmeta>
-
-      <refnamediv>
-        <refname>udevsettle</refname><refpurpose>wait until queued kernel/udev events are handled</refpurpose>
-      </refnamediv>
-
-      <refsynopsisdiv>
-        <cmdsynopsis>
-          <command>udevsettle</command>
-          <arg><option>--timeout=<replaceable>seconds</replaceable></option></arg>
-        </cmdsynopsis>
-      </refsynopsisdiv>
-
-      <refsect1><title>DESCRIPTION</title>
-        <para>Waits watching the udev event queue and exits if all current events are handled.</para>
-      </refsect1>
-
-      <refsect1><title>OPTIONS</title>
-        <variablelist>
-          <varlistentry>
-            <term><option>--timeout=<replaceable>seconds</replaceable></option></term>
-            <listitem>
-              <para>maximum seconds to wait for the queue to become empty.</para>
-            </listitem>
-          </varlistentry>
-        </variablelist>
-      </refsect1>
-
-      <refsect1><title>ENVIRONMENT</title>
-        <variablelist>
-          <varlistentry>
-            <term><option>UDEV_LOG</option></term>
-            <listitem>
-              <para>Overrides the syslog priority specified in the config file.</para>
-            </listitem>
-          </varlistentry>
-        </variablelist>
-     </refsect1>
-
-      <refsect1><title>AUTHOR</title>
-        <para>Written by Kay Sievers <email>kay.sievers@vrfy.org</email>.</para>
-      </refsect1>
-
-      <refsect1>
-        <title>SEE ALSO</title>
-        <para><citerefentry>
-            <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
-        </citerefentry></para>
-      </refsect1>
-    </refentry>
-  </section>
-</article>
diff -Naur udev-090/udevtrigger.8 udev-090-patched/udevtrigger.8
--- udev-090/udevtrigger.8	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevtrigger.8	2006-04-17 18:43:17.000000000 -0400
@@ -11,7 +11,7 @@
 udevtrigger \- request kernel devices events for coldplug
 .SH "SYNOPSIS"
 .HP 12
-\fBudevtrigger\fR [\fB\-\-verbose\fR] [\fB\-\-dry\-run\fR]
+\fBudevtrigger\fR [\fB\-\-verbose\fR] [\fB\-\-dry\-run\fR] [\fB\-\-wait\fR\fB[=\fIseconds\fR]\fR]
 .SH "DESCRIPTION"
 .PP
 Trigger kernel device uevents to replay missing events at system coldplug.
@@ -22,6 +22,11 @@
 .TP
 \fB\-\-dry\-run\fR
 don't actually trigger the event.
+.TP
+\fB\-\-wait\fR\fB[=\fIseconds\fR]\fR
+Whether to wait for the uevent queue to empty. If specified,
+\fIseconds\fR
+determines how long to wait. Default is 180.
 .SH "ENVIRONMENT"
 .TP
 \fBUDEV_LOG\fR
diff -Naur udev-090/udevtrigger.c udev-090-patched/udevtrigger.c
--- udev-090/udevtrigger.c	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevtrigger.c	2006-04-17 18:40:08.000000000 -0400
@@ -32,6 +32,10 @@
 #include <sys/types.h>
 
 #include "udev.h"
+#include "udevd.h"
+
+#define DEFAULT_TIMEOUT			180
+#define LOOP_PER_SECOND			20
 
 static const char *udev_log_str;
 static int verbose;
@@ -318,9 +322,85 @@
 	}
 }
 
+static int do_uevent_wait(int timeout)
+{
+	char queuename[PATH_SIZE];
+	char filename[PATH_SIZE];
+	unsigned long long seq_kernel;
+	unsigned long long seq_udev;
+	char seqnum[32];
+	int fd;
+	ssize_t len;
+	int loop;
+	int rc = 1;
+
+	strlcpy(queuename, udev_root, sizeof(queuename));
+	strlcat(queuename, "/" EVENT_QUEUE_DIR, sizeof(queuename));
+
+	loop = timeout * LOOP_PER_SECOND;
+	while (loop--) {
+		/* wait for events in queue to finish */
+		while (loop--) {
+			struct stat statbuf;
+
+			if (stat(queuename, &statbuf) < 0) {
+				info("queue is empty");
+				break;
+			}
+			usleep(1000 * 1000 / LOOP_PER_SECOND);
+		}
+		if (loop <= 0) {
+			info("timeout waiting for queue");
+			goto exit;
+		}
+
+		/* read current kernel seqnum */
+		strlcpy(filename, sysfs_path, sizeof(filename));
+		strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename));
+		fd = open(filename, O_RDONLY);
+		if (fd < 0)
+			goto exit;
+		len = read(fd, seqnum, sizeof(seqnum)-1);
+		close(fd);
+		if (len <= 0)
+			goto exit;
+		seqnum[len] = '\0';
+		seq_kernel = strtoull(seqnum, NULL, 10);
+		info("kernel seqnum = %llu", seq_kernel);
+
+		/* read current udev seqnum */
+		strlcpy(filename, udev_root, sizeof(filename));
+		strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename));
+		fd = open(filename, O_RDONLY);
+		if (fd < 0)
+			goto exit;
+		len = read(fd, seqnum, sizeof(seqnum)-1);
+		close(fd);
+		if (len <= 0)
+			goto exit;
+		seqnum[len] = '\0';
+		seq_udev = strtoull(seqnum, NULL, 10);
+		info("udev seqnum = %llu", seq_udev);
+
+		/* make sure all kernel events have arrived in the queue */
+		if (seq_udev >= seq_kernel) {
+			info("queue is empty and no pending events left");
+			rc = 0;
+			goto exit;
+		}
+		usleep(1000 * 1000 / LOOP_PER_SECOND);
+		info("queue is empty, but events still pending");
+	}
+
+exit:
+	return rc;
+}
+
 int main(int argc, char *argv[], char *envp[])
 {
 	int i;
+	int wait_for_uevents = 0, uevent_wait_timeout = DEFAULT_TIMEOUT;
+	int rc = 0;
 
 	logging_init("udevtrigger");
 	udev_config_init();
@@ -335,8 +415,23 @@
 			verbose = 1;
 		else if (strcmp(arg, "--dry-run") == 0 || strcmp(arg, "-n") == 0)
 			dry_run = 1;
+		else if (strncmp(arg, "--wait", 6) == 0) {
+			wait_for_uevents = 1;
+
+			if (arg[6] == '=') {
+				char *str = &arg[7];
+
+				uevent_wait_timeout = atoi(str);
+				dbg("timeout=%i", uevent_wait_timeout);
+				if(uevent_wait_timeout <= 0) {
+					fprintf(stderr, "Invalid timeout value.\n");
+					goto exit;
+				}
+			}
+		}
 		else {
-			fprintf(stderr, "Usage: udevtrigger [--verbose] [--dry-run]\n");
+			fprintf(stderr, "Usage: udevtrigger [--verbose] [--dry-run] [--wait[=<seconds>]]\n");
+			fprintf(stderr, "Default is to not wait.  If no <seconds> timeout is provided, default is to wait %d seconds.\n", DEFAULT_TIMEOUT);
 			goto exit;
 		}
 	}
@@ -348,8 +443,11 @@
 	udev_scan_block();
 	exec_lists();
 
+	if(wait_for_uevents)
+		rc = do_uevent_wait(uevent_wait_timeout);
+
 	sysfs_cleanup();
 exit:
 	logging_close();
-	return 0;
+	return rc;
 }
diff -Naur udev-090/udevtrigger.xml udev-090-patched/udevtrigger.xml
--- udev-090/udevtrigger.xml	2006-04-15 13:32:38.000000000 -0400
+++ udev-090-patched/udevtrigger.xml	2006-04-17 18:43:11.000000000 -0400
@@ -39,6 +39,7 @@
           <command>udevtrigger</command>
           <arg><option>--verbose</option></arg>
           <arg><option>--dry-run</option></arg>
+          <arg><option>--wait<optional>=<replaceable>seconds</replaceable></optional></option></arg>
         </cmdsynopsis>
       </refsynopsisdiv>
 
@@ -60,6 +61,12 @@
               <para>don't actually trigger the event.</para>
             </listitem>
           </varlistentry>
+          <varlistentry>
+            <term><option>--wait<optional>=<replaceable>seconds</replaceable></optional></option></term>
+            <listitem>
+              <para>Whether to wait for the uevent queue to empty. If specified, <replaceable>seconds</replaceable> determines how long to wait. Default is 180.</para>
+            </listitem>
+          </varlistentry>
         </variablelist>
       </refsect1>
 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-04-18 23:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-17 23:16 Integrate udevsettle with udevtrigger? Bryan Kadzban
2006-04-18  2:30 ` Alexander E. Patrakov
2006-04-18  3:02 ` Alexander E. Patrakov
2006-04-18  3:14 ` Bryan Kadzban
2006-04-18  6:35 ` Marco d'Itri
2006-04-18  8:03 ` Kay Sievers
2006-04-18 16:00 ` Andrey Borzenkov
2006-04-18 23:39 ` Bryan Kadzban

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).