mdev: if a "future" mdev.seq is seen, do not overwrite it with ours
No binary (build failed)
—
(log yok)
| @@ -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); | |
| } | |
| } | |