diff options
Diffstat (limited to 'util-linux/mdev.c')
-rw-r--r-- | util-linux/mdev.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index ccc00d365..ca4b91510 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -283,7 +283,7 @@ struct globals { | |||
283 | unsigned rule_idx; | 283 | unsigned rule_idx; |
284 | #endif | 284 | #endif |
285 | struct rule cur_rule; | 285 | struct rule cur_rule; |
286 | char timestr[sizeof("60.123456")]; | 286 | char timestr[sizeof("HH:MM:SS.123456")]; |
287 | } FIX_ALIASING; | 287 | } FIX_ALIASING; |
288 | #define G (*(struct globals*)&bb_common_bufsiz1) | 288 | #define G (*(struct globals*)&bb_common_bufsiz1) |
289 | #define INIT_G() do { \ | 289 | #define INIT_G() do { \ |
@@ -923,7 +923,11 @@ static char *curtime(void) | |||
923 | { | 923 | { |
924 | struct timeval tv; | 924 | struct timeval tv; |
925 | gettimeofday(&tv, NULL); | 925 | gettimeofday(&tv, NULL); |
926 | sprintf(G.timestr, "%u.%06u", (unsigned)tv.tv_sec % 60, (unsigned)tv.tv_usec); | 926 | sprintf( |
927 | strftime_HHMMSS(G.timestr, sizeof(G.timestr), &tv.tv_sec), | ||
928 | ".%06u", | ||
929 | (unsigned)tv.tv_usec | ||
930 | ); | ||
927 | return G.timestr; | 931 | return G.timestr; |
928 | } | 932 | } |
929 | 933 | ||
@@ -943,7 +947,7 @@ static void open_mdev_log(const char *seq, unsigned my_pid) | |||
943 | * Active mdev pokes us with SIGCHLD to check the new file. | 947 | * Active mdev pokes us with SIGCHLD to check the new file. |
944 | */ | 948 | */ |
945 | static int | 949 | static int |
946 | wait_for_seqfile(const char *seq) | 950 | wait_for_seqfile(unsigned expected_seq) |
947 | { | 951 | { |
948 | /* We time out after 2 sec */ | 952 | /* We time out after 2 sec */ |
949 | static const struct timespec ts = { 0, 32*1000*1000 }; | 953 | static const struct timespec ts = { 0, 32*1000*1000 }; |
@@ -958,12 +962,14 @@ wait_for_seqfile(const char *seq) | |||
958 | 962 | ||
959 | for (;;) { | 963 | for (;;) { |
960 | int seqlen; | 964 | int seqlen; |
961 | char seqbuf[sizeof(int)*3 + 2]; | 965 | char seqbuf[sizeof(long)*3 + 2]; |
966 | unsigned seqbufnum; | ||
962 | 967 | ||
963 | if (seq_fd < 0) { | 968 | if (seq_fd < 0) { |
964 | seq_fd = open("mdev.seq", O_RDWR); | 969 | seq_fd = open("mdev.seq", O_RDWR); |
965 | if (seq_fd < 0) | 970 | if (seq_fd < 0) |
966 | break; | 971 | break; |
972 | close_on_exec_on(seq_fd); | ||
967 | } | 973 | } |
968 | seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0); | 974 | seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0); |
969 | if (seqlen < 0) { | 975 | if (seqlen < 0) { |
@@ -974,17 +980,25 @@ wait_for_seqfile(const char *seq) | |||
974 | seqbuf[seqlen] = '\0'; | 980 | seqbuf[seqlen] = '\0'; |
975 | if (seqbuf[0] == '\n' || seqbuf[0] == '\0') { | 981 | if (seqbuf[0] == '\n' || seqbuf[0] == '\0') { |
976 | /* seed file: write out seq ASAP */ | 982 | /* seed file: write out seq ASAP */ |
977 | xwrite_str(seq_fd, seq); | 983 | xwrite_str(seq_fd, utoa(expected_seq)); |
978 | xlseek(seq_fd, 0, SEEK_SET); | 984 | xlseek(seq_fd, 0, SEEK_SET); |
979 | dbg2("first seq written"); | 985 | dbg2("first seq written"); |
980 | break; | 986 | break; |
981 | } | 987 | } |
982 | if (strcmp(seq, seqbuf) == 0) { | 988 | seqbufnum = atoll(seqbuf); |
989 | if (seqbufnum == expected_seq) { | ||
983 | /* correct idx */ | 990 | /* correct idx */ |
984 | break; | 991 | break; |
985 | } | 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 | } | ||
986 | if (do_once) { | 1000 | if (do_once) { |
987 | dbg2("%s waiting for '%s'", curtime(), seqbuf); | 1001 | dbg2("%s mdev.seq='%s', need '%u'", curtime(), seqbuf, expected_seq); |
988 | do_once = 0; | 1002 | do_once = 0; |
989 | } | 1003 | } |
990 | if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) { | 1004 | if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) { |
@@ -992,7 +1006,7 @@ wait_for_seqfile(const char *seq) | |||
992 | continue; /* don't decrement timeout! */ | 1006 | continue; /* don't decrement timeout! */ |
993 | } | 1007 | } |
994 | if (--timeout == 0) { | 1008 | if (--timeout == 0) { |
995 | dbg1("%s waiting for '%s'", "timed out", seqbuf); | 1009 | dbg1("%s mdev.seq='%s'", "timed out", seqbuf); |
996 | break; | 1010 | break; |
997 | } | 1011 | } |
998 | } | 1012 | } |
@@ -1075,6 +1089,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1075 | char *env_devname; | 1089 | char *env_devname; |
1076 | char *env_devpath; | 1090 | char *env_devpath; |
1077 | unsigned my_pid; | 1091 | unsigned my_pid; |
1092 | unsigned seqnum = seqnum; /* for compiler */ | ||
1078 | int seq_fd; | 1093 | int seq_fd; |
1079 | smalluint op; | 1094 | smalluint op; |
1080 | 1095 | ||
@@ -1096,7 +1111,11 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1096 | my_pid = getpid(); | 1111 | my_pid = getpid(); |
1097 | open_mdev_log(seq, my_pid); | 1112 | open_mdev_log(seq, my_pid); |
1098 | 1113 | ||
1099 | 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 | } | ||
1100 | 1119 | ||
1101 | dbg1("%s " | 1120 | dbg1("%s " |
1102 | "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" | 1121 | "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" |
@@ -1124,7 +1143,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
1124 | 1143 | ||
1125 | dbg1("%s exiting", curtime()); | 1144 | dbg1("%s exiting", curtime()); |
1126 | if (seq_fd >= 0) { | 1145 | if (seq_fd >= 0) { |
1127 | xwrite_str(seq_fd, utoa(xatou(seq) + 1)); | 1146 | xwrite_str(seq_fd, utoa(seqnum + 1)); |
1128 | signal_mdevs(my_pid); | 1147 | signal_mdevs(my_pid); |
1129 | } | 1148 | } |
1130 | } | 1149 | } |