aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-04-19 18:55:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-04-19 18:55:12 +0200
commitad795510d9fd6f4290be170c84c0d30eb1af7245 (patch)
treed9fdc1a48404e9d26b016adbfe3e58e7a0e279e9
parentbd77e9d6093dc8632788a3c3efffd53ac8ba3233 (diff)
downloadbusybox-w32-ad795510d9fd6f4290be170c84c0d30eb1af7245.tar.gz
busybox-w32-ad795510d9fd6f4290be170c84c0d30eb1af7245.tar.bz2
busybox-w32-ad795510d9fd6f4290be170c84c0d30eb1af7245.zip
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>
-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 }