aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-05-02 09:05:03 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-05-02 09:05:03 +0200
commit528808fa7b0778931fb624e95c38cf8cbc2fff90 (patch)
treed66730c8a6cdbff37c69bd88a511bb486ed55d71
parentfe33683c8bad841a1b5e947fcc6a502b85ca53cf (diff)
downloadbusybox-w32-528808fa7b0778931fb624e95c38cf8cbc2fff90.tar.gz
busybox-w32-528808fa7b0778931fb624e95c38cf8cbc2fff90.tar.bz2
busybox-w32-528808fa7b0778931fb624e95c38cf8cbc2fff90.zip
libbb: make rtc_xopen try harder on EBUSY
function old new delta rtc_xopen 77 139 +62 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/rtc.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/libbb/rtc.c b/libbb/rtc.c
index 97455e86a..f84da09bb 100644
--- a/libbb/rtc.c
+++ b/libbb/rtc.c
@@ -33,23 +33,55 @@ int FAST_FUNC rtc_adjtime_is_utc(void)
33 return utc; 33 return utc;
34} 34}
35 35
36/* rtc opens are exclusive.
37 * Try to run two "hwclock -w" at the same time to see it.
38 * Users wouldn't expect that to fail merely because /dev/rtc
39 * was momentarily busy, let's try a bit harder on errno == EBUSY.
40 */
41static int open_loop_on_busy(const char *name, int flags)
42{
43 int rtc;
44 /*
45 * Tested with two parallel "hwclock -w" loops.
46 * With try = 10, no failures with 2x1000000 loop iterations.
47 */
48 int try = 1000 / 20;
49 again:
50 errno = 0;
51 rtc = open(name, flags);
52 if (errno == EBUSY) {
53 usleep(20 * 1000);
54 if (--try != 0)
55 goto again;
56 /* EBUSY. Last try, exit on error instead of returning -1 */
57 return xopen(name, flags);
58 }
59 return rtc;
60}
61
62/* Never fails */
36int FAST_FUNC rtc_xopen(const char **default_rtc, int flags) 63int FAST_FUNC rtc_xopen(const char **default_rtc, int flags)
37{ 64{
38 int rtc; 65 int rtc;
66 const char *name =
67 "/dev/rtc""\0"
68 "/dev/rtc0""\0"
69 "/dev/misc/rtc""\0";
39 70
40 if (!*default_rtc) { 71 if (!*default_rtc)
41 *default_rtc = "/dev/rtc"; 72 goto try_name;
42 rtc = open(*default_rtc, flags); 73 name = ""; /*else: we have rtc name, don't try other names */
43 if (rtc >= 0) 74
44 return rtc; 75 for (;;) {
45 *default_rtc = "/dev/rtc0"; 76 rtc = open_loop_on_busy(*default_rtc, flags);
46 rtc = open(*default_rtc, flags);
47 if (rtc >= 0) 77 if (rtc >= 0)
48 return rtc; 78 return rtc;
49 *default_rtc = "/dev/misc/rtc"; 79 name += strlen(name) + 1;
80 if (!name[0])
81 return xopen(*default_rtc, flags);
82 try_name:
83 *default_rtc = name;
50 } 84 }
51
52 return xopen(*default_rtc, flags);
53} 85}
54 86
55void FAST_FUNC rtc_read_tm(struct tm *ptm, int fd) 87void FAST_FUNC rtc_read_tm(struct tm *ptm, int fd)