mdev: if a "future" mdev.seq is seen, do not overwrite it with ours
This was seen to happen if two mdevs are run in parallel, mdev.seq is empty, and the "newer" one manages to write it first. function old new delta mdev_main 1366 1388 +22 atoll - 20 +20 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
bd77e9d609
commit
ad795510d9
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user