summaryrefslogtreecommitdiffstats
path: root/src/Daemon
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-08-06 17:23:02 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-06 17:23:02 +0200
commit83a41775849cf6904bbd7f929d0bd1516759260f (patch)
treec5a203b7e1a747b24af7eda139d49dff934a17b0 /src/Daemon
parentd27b103044aac183fba6779c1defed4d145f3055 (diff)
downloadabrt-83a41775849cf6904bbd7f929d0bd1516759260f.tar.gz
abrt-83a41775849cf6904bbd7f929d0bd1516759260f.tar.xz
abrt-83a41775849cf6904bbd7f929d0bd1516759260f.zip
fix bug 54: make abrt (without -d) report initialization errors
Example (strace): 10053 17:18:58.384259 close(0) = 0 10053 17:18:58.384293 open("/dev/null", O_RDWR) = 0 child is created: 10053 17:18:58.384354 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f50eea1c880) = 10054 parent sleeps, child initializes: 10053 17:18:58.384678 nanosleep({0, 100000000}, <unfinished ...> 10054 17:18:58.384751 setsid() = 10054 10054 17:18:58.384794 close(1) = 0 10054 17:18:58.384828 close(2) = 0 10054 17:18:58.384870 dup(0) = 1 10054 17:18:58.384901 dup(0) = 2 10054 17:18:58.385099 open("/usr/app/abrt-TEST/var/etc/abrt/abrt.conf", O_RDONLY) = 3 ... 10054 17:18:58.449108 inotify_init() = 4 10054 17:18:58.449148 inotify_add_watch(4, "/usr/app/abrt-TEST/var/cache/abrt", IN_CREATE) = 1 10054 17:18:58.449228 fstat(4, {st_mode=S_IFDIR|0600, st_size=0, ...}) = 0 10054 17:18:58.449288 fcntl(4, F_GETFL) = 0 (flags O_RDONLY) child: initialization is done, it signals parent: 10054 17:18:58.449346 getppid() = 10053 10054 17:18:58.449380 kill(10053, SIGTERM) = 0 10054 17:18:58.449427 write(1, "Debug: Running...\n"..., 18 <unfinished ...> 10053 17:18:58.449447 <... nanosleep resumed> 0) = ? ERESTART_RESTARTBLOCK (To be restarted) 10054 17:18:58.449470 <... write resumed> ) = 18 10054 17:18:58.449494 open("/usr/app/abrt-TEST/var/run/abrt.lock", O_RDWR|O_CREAT, 0640 <unfinished ...> 10053 17:18:58.449517 --- SIGTERM (Terminated) @ 0 (0) --- 10054 17:18:58.449565 <... open resumed> ) = 5 10053 17:18:58.449583 rt_sigreturn(0xf <unfinished ...> 10054 17:18:58.449607 fcntl(5, F_SETLK, {type=F_WRLCK, whence=SEEK_CUR, start=0, len=0} <unfinished ...> sleep(100ms) is interrupted: 10053 17:18:58.449629 <... rt_sigreturn resumed> ) = -1 EINTR (Interrupted system call) 10054 17:18:58.449664 <... fcntl resumed> ) = 0 10054 17:18:58.449688 unlink("/usr/app/abrt-TEST/var/run/abrt.pid" <unfinished ...> parent exits 0 because it got TERM which means child is ok: 10053 17:18:58.449713 exit_group(0) = ? ... Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'src/Daemon')
-rw-r--r--src/Daemon/Daemon.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index dff8de6c..0b7393aa 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -56,25 +56,34 @@ int main(int argc, char** argv)
daemonize = 0;
}
}
- if(daemonize)
+ if (daemonize)
{
/* Open stdin to /dev/null. We do it before forking
* in order to emit useful exitcode to the parent
- * if open fails */
+ * if open fails */
close(STDIN_FILENO);
if (open("/dev/null", O_RDWR))
{
throw CABRTException(EXCEP_FATAL, "Can't open /dev/null");
}
- /* forking to background */
+ /* forking to background */
pid_t pid = fork();
if (pid < 0)
{
throw CABRTException(EXCEP_FATAL, "CCrashWatcher::Daemonize(): Fork error");
}
- /* parent exits */
- if (pid > 0) _exit(0);
- /* child (daemon) continues */
+ if (pid > 0)
+ {
+ /* Parent */
+ /* Wait for child to notify us via SIGTERM that it feels ok */
+ int i = 20; /* 2 sec */
+ while (sig_caught == 0 && --i)
+ {
+ usleep(100 * 1000);
+ }
+ _exit(sig_caught != SIGTERM); /* TERM:ok (0), anything else: bad (1) */
+ }
+ /* Child (daemon) continues */
pid_t sid = setsid();
if(sid == -1)
{
@@ -88,6 +97,11 @@ int main(int argc, char** argv)
dup(0);
}
g_pCrashWatcher = new CCrashWatcher(DEBUG_DUMPS_DIR);
+ if (daemonize)
+ {
+ /* Let parent know we initialized ok */
+ kill(getppid(), SIGTERM);
+ }
g_pCrashWatcher->Run();
}
catch(CABRTException& e)