diff options
-rw-r--r-- | util-linux/mdev.c | 29 |
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) | |||
947 | * Active mdev pokes us with SIGCHLD to check the new file. | 947 | * Active mdev pokes us with SIGCHLD to check the new file. |
948 | */ | 948 | */ |
949 | static int | 949 | static int |
950 | wait_for_seqfile(const char *seq) | 950 | wait_for_seqfile(unsigned expected_seq) |
951 | { | 951 | { |
952 | /* We time out after 2 sec */ | 952 | /* We time out after 2 sec */ |
953 | static const struct timespec ts = { 0, 32*1000*1000 }; | 953 | static const struct timespec ts = { 0, 32*1000*1000 }; |
@@ -962,12 +962,14 @@ wait_for_seqfile(const char *seq) | |||
962 | 962 | ||
963 | for (;;) { | 963 | for (;;) { |
964 | int seqlen; | 964 | int seqlen; |
965 | char seqbuf[sizeof(int)*3 + 2]; | 965 | char seqbuf[sizeof(long)*3 + 2]; |
966 | unsigned seqbufnum; | ||
966 | 967 | ||
967 | if (seq_fd < 0) { | 968 | if (seq_fd < 0) { |
968 | seq_fd = open("mdev.seq", O_RDWR); | 969 | seq_fd = open("mdev.seq", O_RDWR); |
969 | if (seq_fd < 0) | 970 | if (seq_fd < 0) |
970 | break; | 971 | break; |
972 | close_on_exec_on(seq_fd); | ||
971 | } | 973 | } |
972 | seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0); | 974 | seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0); |
973 | if (seqlen < 0) { | 975 | if (seqlen < 0) { |
@@ -978,17 +980,25 @@ wait_for_seqfile(const char *seq) | |||
978 | seqbuf[seqlen] = '\0'; | 980 | seqbuf[seqlen] = '\0'; |
979 | if (seqbuf[0] == '\n' || seqbuf[0] == '\0') { | 981 | if (seqbuf[0] == '\n' || seqbuf[0] == '\0') { |
980 | /* seed file: write out seq ASAP */ | 982 | /* seed file: write out seq ASAP */ |
981 | xwrite_str(seq_fd, seq); | 983 | xwrite_str(seq_fd, utoa(expected_seq)); |
982 | xlseek(seq_fd, 0, SEEK_SET); | 984 | xlseek(seq_fd, 0, SEEK_SET); |
983 | dbg2("first seq written"); | 985 | dbg2("first seq written"); |
984 | break; | 986 | break; |
985 | } | 987 | } |
986 | if (strcmp(seq, seqbuf) == 0) { | 988 | seqbufnum = atoll(seqbuf); |
989 | if (seqbufnum == expected_seq) { | ||
987 | /* correct idx */ | 990 | /* correct idx */ |
988 | break; | 991 | break; |
989 | } | 992 | } |
993 | if (seqbufnum > expected_seq) { | ||
994 | /* a later mdev runs already (this was seen by users to happen) */ | ||
995 | /* do not overwrite seqfile on exit */ | ||
996 | close(seq_fd); | ||
997 | seq_fd = -1; | ||
998 | break; | ||
999 | } | ||
990 | if (do_once) { | 1000 | if (do_once) { |
991 | dbg2("%s mdev.seq='%s', need '%s'", curtime(), seqbuf, seq); | 1001 | dbg2("%s mdev.seq='%s', need '%u'", curtime(), seqbuf, expected_seq); |
992 | do_once = 0; | 1002 | do_once = 0; |
993 | } | 1003 | } |
994 | if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) { | 1004 | if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) { |
@@ -1079,6 +1089,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1079 | char *env_devname; | 1089 | char *env_devname; |
1080 | char *env_devpath; | 1090 | char *env_devpath; |
1081 | unsigned my_pid; | 1091 | unsigned my_pid; |
1092 | unsigned seqnum = seqnum; /* for compiler */ | ||
1082 | int seq_fd; | 1093 | int seq_fd; |
1083 | smalluint op; | 1094 | smalluint op; |
1084 | 1095 | ||
@@ -1100,7 +1111,11 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1100 | my_pid = getpid(); | 1111 | my_pid = getpid(); |
1101 | open_mdev_log(seq, my_pid); | 1112 | open_mdev_log(seq, my_pid); |
1102 | 1113 | ||
1103 | seq_fd = seq ? wait_for_seqfile(seq) : -1; | 1114 | seq_fd = -1; |
1115 | if (seq) { | ||
1116 | seqnum = atoll(seq); | ||
1117 | seq_fd = wait_for_seqfile(seqnum); | ||
1118 | } | ||
1104 | 1119 | ||
1105 | dbg1("%s " | 1120 | dbg1("%s " |
1106 | "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" | 1121 | "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" |
@@ -1128,7 +1143,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1128 | 1143 | ||
1129 | dbg1("%s exiting", curtime()); | 1144 | dbg1("%s exiting", curtime()); |
1130 | if (seq_fd >= 0) { | 1145 | if (seq_fd >= 0) { |
1131 | xwrite_str(seq_fd, utoa(xatou(seq) + 1)); | 1146 | xwrite_str(seq_fd, utoa(seqnum + 1)); |
1132 | signal_mdevs(my_pid); | 1147 | signal_mdevs(my_pid); |
1133 | } | 1148 | } |
1134 | } | 1149 | } |