Comment to task #5647 in hc-cron: hc-cron czasami odpala dwukrotnie
zadania
Flyspray - The bug killer!
btsadmin at pld-linux.org
Wed May 25 15:57:59 CEST 2005
Project: PLD 2.x (Ac)
Package: hc-cron
Summary: hc-cron czasami odpala dwukrotnie zadania
Commented by: Marcin Kaminski (maxiu)
Comment: Kolejny strace, tym razem z timestampami:
1117028160.621671 stat64("cron", {st_mode=S_IFDIR|S_ISVTX|0730,
st_size=6, ...}) = 0
[...]
1117028160.622872 time(NULL) = 1117028160
1117028160.622911 time(NULL) = 1117028160
1117028160.622951 clone(child_stack=0,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x40138708) = 5062
1117028160.623176 clone(child_stack=0,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x40138708) = 5063
1117028160.623440 time(NULL) = 1117028160
1117028160.623772 nanosleep({60, 0}, 0xbfffd844) = ?
ERESTART_RESTARTBLOCK (To be restarted)
1117028160.629052 --- SIGCHLD (Child exited) @ 0 (0) ---
1117028160.629102 waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}],
WNOHANG) = 5062
1117028160.629179 waitpid(-1, 0xbfffd524, WNOHANG) = 0
1117028160.629230 sigreturn() = ? (mask now [])
1117028160.629533 nanosleep({60, 0}, 0xbfffd844) = ?
ERESTART_RESTARTBLOCK (To be restarted)
1117028161.135012 --- SIGCHLD (Child exited) @ 0 (0) ---
1117028161.135060 waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}],
WNOHANG) = 5063
1117028161.135134 waitpid(-1, 0xbfffd524, WNOHANG) = 0
1117028161.135182 sigreturn() = ? (mask now [])
1117028161.135547 nanosleep({59, 0},{59, 0}) = 0
1117028220.136696 stat64("cron", {st_mode=S_IFDIR|S_ISVTX|0730,
st_size=6, ...}) = 0
[...]
1117028220.138375 time(NULL) = 1117028220
1117028220.138426 time(NULL) = 1117028220
1117028220.138477 clone(child_stack=0,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x40138708) = 5462
1117028220.138912 clone(child_stack=0,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x40138708) = 5464
1117028220.139269 time(NULL) = 1117028220
1117028220.139535 nanosleep({60, 0}, 0xbfffd844) = ?
ERESTART_RESTARTBLOCK (To be restarted)
1117028220.146077 --- SIGCHLD (Child exited) @ 0 (0) ---
1117028220.146166 waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}],
WNOHANG) = 5462
1117028220.146361 waitpid(-1, 0xbfffd524, WNOHANG) = 0
1117028220.146575 sigreturn() = ? (mask now [])
1117028220.147538 nanosleep({60, 0}, 0xbfffd844) = ?
ERESTART_RESTARTBLOCK (To be restarted)
1117028220.650707 --- SIGCHLD (Child exited) @ 0 (0) ---
1117028220.650750 waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}],
WNOHANG) = 5464
1117028220.650811 waitpid(-1, 0xbfffd524, WNOHANG) = 0
1117028220.650845 sigreturn() = ? (mask now [])
1117028220.651079 nanosleep({59, 0}, {59, 0}) = 0
1117028279.651581 stat64("cron", {st_mode=S_IFDIR|S_ISVTX|0730,
st_size=6, ...}) = 0
Pierwsza seria pokazuje prawidłowe zachowanie. W sekundzie 1117028161
został puszczony sleep na 59 sekund.
Druga seria pokazuje złe zachowane. W sekundzie 1117028220 został
puszczony sleep na 59 sekund, a więc za krótko!
Kod to obsługujący wygląda następująco:
while (seconds_to_wait > 0) {
Debug(DSCH, ("[%d] sleeping for %d secondsn",
getpid(), seconds_to_wait))
seconds_to_wait = (int) sleep((unsigned int)
seconds_to_wait);
}
A więc parametr do kolejnego sleepa jest pobierany z wyniku
poprzedniego. Powinna to być ilość sekund jaka pozostała do
wykonania pełnego sleepa. Niestety wychodzi na to że sleep wywołany
w momencie 1117028220.147538 zwrócił 59 w momencie 1117028220.650707,
a powinien zwrócić 60 (poprzedni wywołany w 1117028220.139535 tak
zrobił).
Tak na oko:
1117028220.146077 - 1117028220.139535 = 0.006542
1117028220.650707 - 1117028220.147538 = 0.503169
Wygląda na to że funkcja sleep() zaokrągla wynik i jeśli minęło
troche więcej niż półsekundy to w wyniku już pomija całą tą
sekundę.
W przypadku crona to jest zachowanie nieodpowiednie, gdyż on tylko
zmniejsza pozostały czas, więc zabrane pół sekundy już nie wróci
(chyba że wykonywanie kodu zajmie pół sekundy).
Muszę sprawdzić w specyfikacji funkcji sleep() jak ona ma się
zachowywać. Niestety zdanie z mana:
Zero if the requested time has elapsed, or the number of seconds left
to sleep.
Nic nie mówi o dokładności. Jeśli to jest ostateczna specyfikacja
to znaczy że błąd jest w hc-cron, gdyż powinien on uwzględniać te
błędy zaokrągleń.
Pytanie do operatorów bugs: czy kontynuować to na bugd.pld-linux.org,
czy skoro błąd występuje w orginalnym hc-cron to PLD się nim nie
zajmuje? Jeśli ostatecznym winowajcom okaże się hc-cron to mogę
stworzyć łatę i ją przesłać.
For more further see:
http://bugs.pld-linux.org/index.php?do=details&id=5647&area=comments#tabs}
------------------------------------------------------------------------
THIS IS AN AUTOMATICALLY GENERATED MESSAGE, DO NOT REPLY
More information about the pld-bugs
mailing list