summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--util-linux/mdev.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 884e5de33..ca4b91510 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -947,7 +947,7 @@ static void open_mdev_log(const char *seq, unsigned my_pid)
* Active mdev pokes us with SIGCHLD to check the new file.
*/
static int
-wait_for_seqfile(const char *seq)
+wait_for_seqfile(unsigned expected_seq)
{
/* We time out after 2 sec */
static const struct timespec ts = { 0, 32*1000*1000 };
@@ -962,12 +962,14 @@ wait_for_seqfile(const char *seq)
for (;;) {
int seqlen;
- char seqbuf[sizeof(int)*3 + 2];
+ char seqbuf[sizeof(long)*3 + 2];
+ unsigned seqbufnum;
if (seq_fd < 0) {
seq_fd = open("mdev.seq", O_RDWR);
if (seq_fd < 0)
break;
+ close_on_exec_on(seq_fd);
}
seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0);
if (seqlen < 0) {
@@ -978,17 +980,25 @@ wait_for_seqfile(const char *seq)
seqbuf[seqlen] = '\0';
if (seqbuf[0] == '\n' || seqbuf[0] == '\0') {
/* seed file: write out seq ASAP */
- xwrite_str(seq_fd, seq);
+ xwrite_str(seq_fd, utoa(expected_seq));
xlseek(seq_fd, 0, SEEK_SET);
dbg2("first seq written");
break;
}
- if (strcmp(seq, seqbuf) == 0) {
+ seqbufnum = atoll(seqbuf);
+ if (seqbufnum == expected_seq) {
/* correct idx */
break;
}
+ if (seqbufnum > expected_seq) {
+ /* a later mdev runs already (this was seen by users to happen) */
+ /* do not overwrite seqfile on exit */
+ close(seq_fd);
+ seq_fd = -1;
+ break;
+ }
if (do_once) {
- dbg2("%s mdev.seq='%s', need '%s'", curtime(), seqbuf, seq);
+ dbg2("%s mdev.seq='%s', need '%u'", curtime(), seqbuf, expected_seq);
do_once = 0;
}
if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) {
@@ -1079,6 +1089,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
char *env_devname;
char *env_devpath;
unsigned my_pid;
+ unsigned seqnum = seqnum; /* for compiler */
int seq_fd;
smalluint op;
@@ -1100,7 +1111,11 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
my_pid = getpid();
open_mdev_log(seq, my_pid);
- seq_fd = seq ? wait_for_seqfile(seq) : -1;
+ seq_fd = -1;
+ if (seq) {
+ seqnum = atoll(seq);
+ seq_fd = wait_for_seqfile(seqnum);
+ }
dbg1("%s "
"ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s"
@@ -1128,7 +1143,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
dbg1("%s exiting", curtime());
if (seq_fd >= 0) {
- xwrite_str(seq_fd, utoa(xatou(seq) + 1));
+ xwrite_str(seq_fd, utoa(seqnum + 1));
signal_mdevs(my_pid);
}
}