On my raspberry pi 1, my daemons take a really long time to start, up to several minutes. I traced (with strace) the source of the delay to a seemingly endless loop of closing files at the start of the daemonization step. Upon examination of the library code, I found the function close_all_open_files() which seems to be the troublemaker.
Is this function really necessary? What files are open anyway, and does it really matter if they are closed? I'm assuming that the OS will close all open file descriptors anyway upon termination of the process.
I have tried to supply a large list (1024*1024) of file descriptors, in essence excluding all possible file descriptors from being closed, but the lookup and comparing process itself then seems to take a really long time also.
Would there be strong reasons not to make "the closing of the file descriptors in general" optional (i.e. to skip it altogether)?
Best regards,
Victor
Upon further examination, I see now that there are several pull requests and previous issues on this topic. But my question stands: is it really necessary?
On Mon, 2018-08-13 12:39 +0000, Victor Claessen pagure@pagure.io wrote:
Thank you for reporting this behaviour. As you have noticed, previous issues also discussed this, in particular issue#10 .
Your report doesn't specify which 'python-daemon' version you are using. There is an unreleased improvement (merge request #12, now merged into 'master') to use a system call to close many file descriptors at once.
Can you try with the current 'master' branch from this repository?
To implement a standard Unix daemon process, all open files need to be closed as part of detaching the program from its parent environment. See the manual page 'daemon(7)' on GNU+Linux, or read it online at .
-- \ `\ _o__) Ben Finney ben@benfinney.id.au
This bug should be addressed by the same fix (merge request #12) that resolved issue#10.
The changes are now released in 'python-daemon' version 2.2.0.
Metadata Update from @bignose: - Issue close_status updated to: Fixed - Issue status updated to: Closed (was: Open)
The version I tested it on was 2.1.2.
Thank you for releasing a new version. I've installed 2.2.0 on my raspberry pi. The behaviour is now different. There is now no more delay in closing file descriptors, which is great. However, now there seems to be a new delay that I didn't notice before. It takes about 20 seconds or so, and I believe that it occurs earlier in the code - i.e. before the location of close_all_open_files() - and has something to do with memory mapping? I'm not sure if you would like me to open a new issue; if so please let me know.
The part of the strace output I believe is relevant:
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb6f26068) = 28906 exit_group(0) = ? strace: Process 28906 attached [pid 28906] set_robust_list(0xb6f26070, 12) = 0 [pid 28906] getpid( [pid 28902] +++ exited with 0 +++ <... getpid resumed> ) = 28906 setsid() = 28906 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb6f26068) = 28907 exit_group(0) = ? +++ exited with 0 +++ strace: Process 28907 attached set_robust_list(0xb6f26070, 12) = 0 getpid() = 28907 rt_sigaction(SIGHUP, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, 8) = 0 rt_sigaction(SIGUSR1, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, 8) = 0 rt_sigaction(SIGUSR2, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, 8) = 0 rt_sigaction(SIGTERM, {sa_handler=0x11dc94, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6ce56b0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0 mremap(0xb5d11000, 4198400, 4722688, MREMAP_MAYMOVE) = 0xb5d11000 brk(0x19a9000) = 0x19a9000 mmap2(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb649d000 brk(0x1993000) = 0x1993000 mmap2(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb639c000 munmap(0xb649d000, 266240) = 0 mmap2(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb619b000 munmap(0xb639c000, 1052672) = 0 mmap2(NULL, 4198400, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb5910000 munmap(0xb619b000, 2101248) = 0 mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb510f000 munmap(0xb5910000, 4198400) = 0 mmap2(NULL, 16781312, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb410e000 munmap(0xb510f000, 8392704) = 0 prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=1024*1024}) = 0 mmap2(NULL, 4198400, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb5910000 brk(0x19b4000) = 0x19b4000 brk(0x19d5000) = 0x19d5000 brk(0x19f6000) = 0x19f6000 brk(0x1a17000) = 0x1a17000 brk(0x1a38000) = 0x1a38000 brk(0x1a59000) = 0x1a59000 brk(0x1a7a000) = 0x1a7a000 brk(0x1a9b000) = 0x1a9b000 brk(0x1abc000) = 0x1abc000 brk(0x1add000) = 0x1add000
It seems to stall on those munmap calls near the end (before all the brk's). I'm running Python 2.7.13 by the way.
The behaviour is now different. There is now no more delay in closing file descriptors, which is great. However, now there seems to be a new delay that I didn't notice before.
That sounds like you've found something new to report, separate from this bug. Can you open a new issue for that instead?