This allows lttng to work across fork(2) and related calls, including
daemon(3). Without these calls, LD_PRELOAD would need to include
liblttng-ust-fork.so, which wraps fork and daemon.
If these calls or the liblttng-ust-fork wrappers are not used, the
atexit(3) handlers registered by lttng may cause a crash when the
process exits. This does not happen with upstart, since it runs
ceph-osd and other daemons in the foreground.
Backport: hammer
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
+#ifdef WITH_LTTNG
+#include <lttng/ust.h>
+#endif
#include "common/safe_io.h"
#include "common/errno.h"
pid_t childpid;
bool forked;
int fd[2]; // parent's, child's
+#ifdef WITH_LTTNG
+ sigset_t sigset;
+#endif
public:
Preforker()
exit(errno);
}
+#ifdef WITH_LTTNG
+ ust_before_fork(&sigset);
+#endif
+
forked = true;
childpid = fork();
if (childpid == 0) {
- ::close(fd[0]);
+ child_after_fork();
} else {
- ::close(fd[1]);
+ parent_after_fork();
}
}
r += r2; // make the compiler shut up about the unused return code from ::write(2).
}
+private:
+ void child_after_fork() {
+#ifdef WITH_LTTNG
+ ust_after_fork_child(&sigset);
+#endif
+ ::close(fd[0]);
+ }
+
+ void parent_after_fork() {
+#ifdef WITH_LTTNG
+ ust_after_fork_parent(&sigset);
+#endif
+ ::close(fd[1]);
+ }
};
#endif
global/pidfile.cc \
global/signal_handler.cc
libglobal_la_LIBADD = $(LIBCOMMON)
+if WITH_LTTNG
+libglobal_la_LIBADD += -llttng-ust -ldl
+endif
noinst_LTLIBRARIES += libglobal.la
noinst_HEADERS += \
#include <errno.h>
#include <deque>
+#ifdef WITH_LTTNG
+#include <lttng/ust.h>
+#endif
+
#define dout_subsys ceph_subsys_
if (global_init_prefork(cct, flags) < 0)
return;
+#ifdef WITH_LTTNG
+ sigset_t sigset;
+ ust_before_fork(&sigset);
+#endif
+
int ret = daemon(1, 1);
if (ret) {
ret = errno;
exit(1);
}
+#ifdef WITH_LTTNG
+ ust_after_fork_child(&sigset);
+#endif
global_init_postfork_start(cct);
global_init_postfork_finish(cct, flags);
}