aboutsummaryrefslogtreecommitdiff
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)
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 */
949static int 949static int
950wait_for_seqfile(const char *seq) 950wait_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 }