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 | } |
