hwclock: Tracking down uinterruptable sleep error
Bryan Evenson
bevenson at melinkcorp.com
Fri Mar 21 15:49:30 UTC 2014
All,
I'm on busybox-1.20.2 and I am tracking down an issue on hwclock. After my system is running for a long time, I will see a hwclock process in the process list that is stuck in an uninterruptable sleep. If that occurs, any command line calls to hwclock returns:
Can't open '/dev/misc/rtc': No such file or directory
And the command line hangs until I kill it with a CTRL+C. I took a look at the source code and I see that after opening the rtc dev interface with rtc_xopen(), hwclock doesn't verify the file opened successfully before trying to use it. I changed it so that all calls to rtc_xopen() verify the returned file descriptor is valid before trying to use it. I also enabled CONFIG_FEATURE_CLEAN_UP on my configuration so that the file descriptor is closed at the end of the fuction. Now at least if I get the above error message, the hwclock call exits back on the command line. However, I'm still getting the uninterruptable sleep on one instance of hwclock. Looking through the code I don't see an obvious place that could be causing a problem. Anyone else have any ideas?
Here's the script I'm using to reproduce the problem:
#!/bin/sh
while [ 1 ]; do
/sbin/hwclock -w -u
sleep 1
done
Run two copies of the above script in the background. On my system within seconds I will get the "Can't open '/dev/misc/rtc': No such file or directory'" error popping up in the console and there will be one instance of /sbin/hwclock -w -u that will be stuck in an uninterruptable sleep and cannot be killed.
If you're interested in my changes so far, below is a copy of my patch on busybox-1.20.2:
>From 0cdf61c5a7b56135e7809c01fea1ebe4fb201a50 Mon Sep 17 00:00:00 2001
From: Bryan Evenson <bevenson at melinkcorp.com>
Date: Fri, 21 Mar 2014 08:43:18 -0400
Subject: [PATCH 1/1] hwclock: Verify RTC file descriptor
If the RTC is in use by another process or if the RTC dev interface
is not properly established, calling rtc_xopen will fail. However,
hwclock does not check the result of rtc_xopen, causing hwclock
to hang indefinitely when it attempts to use the bad file
descriptor. This also prevents future calls to hwclock from
succeeding, thus making it impossible to read or set the RTC until
the system is rebooted.
Signed-off-by: Bryan Evenson <bevenson at melinkcorp.com>
---
util-linux/hwclock.c | 9 +++++++++
util-linux/rtcwake.c | 4 ++++
2 files changed, 13 insertions(+)
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 379eeb2..f959bc6 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -35,6 +35,10 @@ static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc)
fd = rtc_xopen(pp_rtcname, O_RDONLY);
+ /* Verify we can access the RTC before continuing */
+ if (fd < 0)
+ return 0;
+
rtc_read_tm(&tm_time, fd);
#if SHOW_HWCLOCK_DIFF
@@ -114,6 +118,11 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
int rtc;
rtc = rtc_xopen(pp_rtcname, O_WRONLY);
+
+ /* Verify we can access the RTC before continuing */
+ if (rtc < 0)
+ return;
+
gettimeofday(&tv, NULL);
/* Prepare tm_time */
if (sizeof(time_t) == sizeof(tv.tv_sec)) {
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c
index 735a298..e295885 100644
--- a/util-linux/rtcwake.c
+++ b/util-linux/rtcwake.c
@@ -177,6 +177,10 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
/* this RTC must exist and (if we'll sleep) be wakeup-enabled */
fd = rtc_xopen(&rtcname, O_RDONLY);
+ /* Verify we can access the RTC before continuing */
+ if (fd < 0)
+ return EXIT_FAILURE;
+
if (strcmp(suspend, "on") && !may_wakeup(rtcname))
bb_error_msg_and_die("%s not enabled for wakeup events", rtcname);
--
1.7.9.5
More information about the busybox
mailing list