mirror of
https://github.com/systemd/systemd.git
synced 2025-01-12 13:18:14 +03:00
udevd: export current seqnum and add udevsettle
This commit is contained in:
parent
2b3f8e93ca
commit
7baada47be
6
Makefile
6
Makefile
@ -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
15
udevd.c
@ -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 */
|
||||
|
1
udevd.h
1
udevd.h
@ -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
32
udevsettle.8
Normal 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
155
udevsettle.c
Normal 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
82
udevsettle.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user