runsvdir is missing service dir changes

Eric Lammerts busybox at lists.lammerts.org
Thu Dec 2 22:59:11 UTC 2010


Hi,
I've seen runsvdir missing updates to the service directory. What I do 
is create a /service/.whatever directory, populate it, and then 
rename it to /service/whatever.

I can trigger the problem with this script:

#!/bin/sh
# wait until time increments
t=`date +%s`
while [ `date +%s` == $t ]; do :; done
mkdir /service/.tmp
echo -e '#!/bin/sh\nsleep 666' >/service/.tmp/run
chmod +x /service/.tmp/run
sleep 0.75
mv /service/.tmp /service/tmp

If runsvdir happens to scan the service directory during the sleep, it 
records the mtime of the dir in the last_mtime variable. The 
subsequent mv doesn't change the directory mtime, because it's still 
within the same second.

There used to be a sleep to prevent this situation, but it was removed 
by Denis when he ripped out the tai stuff, in
http://git.busybox.net/busybox/commit/?id=45946f8b513d9c292613ac08c3ddf4a89b915752

I suggest something like this (using time(NULL), since "now" is a 
monotonic time).

diff --git a/runit/runsvdir.c b/runit/runsvdir.c
index e77eeff..f3ea785 100644
--- a/runit/runsvdir.c
+++ b/runit/runsvdir.c
@@ -312,8 +312,11 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
  						last_mtime = s.st_mtime;
  						last_dev = s.st_dev;
  						last_ino = s.st_ino;
-						//if (now <= mtime)
-						//	sleep(1);
+						/* if the svdir changed this very second, wait until the
+						 * next second, because we won't be able to detect more
+						 * changes within this second */
+						while(time(NULL) == last_mtime)
+							usleep(100000);
  						need_rescan = do_rescan();
  						while (fchdir(curdir) == -1) {
  							warn2_cannot("change directory, pausing", "");

cheers,

Eric



More information about the busybox mailing list