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); } }