udevd: export current seqnum and add udevsettle

This commit is contained in:
Kay Sievers 2006-04-05 00:08:10 +02:00
parent 2b3f8e93ca
commit 7baada47be
6 changed files with 291 additions and 0 deletions

View file

@ -50,6 +50,7 @@ PROGRAMS = \
udev \
udevd \
udevtrigger \
udevsettle \
udevsend \
udevcontrol \
udevmonitor \
@ -86,6 +87,7 @@ MAN_PAGES = \
udevmonitor.8 \
udevd.8 \
udevtrigger.8 \
udevsettle.8 \
udevsend.8 \
udevtest.8 \
udevinfo.8 \
@ -261,6 +263,7 @@ install-man:
$(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8
$(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8
$(INSTALL_DATA) -D udevtrigger.8 $(DESTDIR)$(mandir)/man8/udevtrigger.8
$(INSTALL_DATA) -D udevsettle.8 $(DESTDIR)$(mandir)/man8/udevsettle.8
$(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8
- ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8
@extras="$(EXTRAS)"; for target in $$extras; do \
@ -274,6 +277,7 @@ uninstall-man:
- rm -f $(DESTDIR)$(mandir)/man8/udevtest.8
- rm -f $(DESTDIR)$(mandir)/man8/udevd.8
- rm -f $(DESTDIR)$(mandir)/man8/udevtrigger.8
- rm -f $(DESTDIR)$(mandir)/man8/udevsettle.8
- rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8
- rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8
@ extras="$(EXTRAS)"; for target in $$extras; do \
@ -285,6 +289,7 @@ install-bin:
$(INSTALL) -d $(DESTDIR)$(udevdir)
$(INSTALL_PROGRAM) -D udevd $(DESTDIR)$(sbindir)/udevd
$(INSTALL_PROGRAM) -D udevtrigger $(DESTDIR)$(sbindir)/udevtrigger
$(INSTALL_PROGRAM) -D udevsettle $(DESTDIR)$(sbindir)/udevsettle
$(INSTALL_PROGRAM) -D udevcontrol $(DESTDIR)$(sbindir)/udevcontrol
$(INSTALL_PROGRAM) -D udevmonitor $(DESTDIR)$(usrsbindir)/udevmonitor
$(INSTALL_PROGRAM) -D udevinfo $(DESTDIR)$(usrbindir)/udevinfo
@ -302,6 +307,7 @@ endif
uninstall-bin:
- rm -f $(DESTDIR)$(sbindir)/udevd
- rm -f $(DESTDIR)$(sbindir)/udevtrigger
- rm -f $(DESTDIR)$(sbindir)/udevsettle
- rm -f $(DESTDIR)$(sbindir)/udevcontrol
- rm -f $(DESTDIR)$(usrsbindir)/udevmonitor
- rm -f $(DESTDIR)$(usrbindir)/udevinfo

15
udevd.c
View file

@ -279,8 +279,23 @@ static void udev_event_run(struct uevent_msg *msg)
static void msg_queue_insert(struct uevent_msg *msg)
{
char filename[PATH_SIZE];
int fd;
msg->queue_time = time(NULL);
strlcpy(filename, udev_root, sizeof(filename));
strlcat(filename, "/" EVENT_SEQNUM, sizeof(filename));
fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd > 0) {
char str[32];
int len;
len = sprintf(str, "%llu\n", msg->seqnum);
write(fd, str, len);
close(fd);
}
export_event_state(msg, EVENT_QUEUED);
/* run all events with a timeout set immediately */

View file

@ -31,6 +31,7 @@
#define EVENT_QUEUE_DIR ".udev/queue"
#define EVENT_FAILED_DIR ".udev/failed"
#define EVENT_SEQNUM ".udev/uevent_seqnum"
/* maximum limit of forked childs */
#define UDEVD_MAX_CHILDS 64

32
udevsettle.8 Normal file
View file

@ -0,0 +1,32 @@
.\" ** 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)

155
udevsettle.c Normal file
View file

@ -0,0 +1,155 @@
/*
* 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 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 = 30;
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;
}

82
udevsettle.xml Normal file
View file

@ -0,0 +1,82 @@
<?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>