]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/Preforker.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #ifndef CEPH_COMMON_PREFORKER_H
4 #define CEPH_COMMON_PREFORKER_H
6 #include <sys/socket.h>
11 #include "include/assert.h"
12 #include "common/errno.h"
13 #include "common/safe_io.h"
14 #include "include/compat.h"
15 #include "include/sock_compat.h"
18 * pre-fork fork/daemonize helper class
20 * Hide the details of letting a process fork early, do a bunch of
21 * initialization work that may spam stdout or exit with an error, and
22 * then daemonize. The exit() method will either exit directly (if we
23 * haven't forked) or pass a message to the parent with the error if
29 int fd
[2]; // parent's, child's
37 int prefork(std::string
&err
) {
39 std::ostringstream oss
;
40 int r
= socketpair_cloexec(AF_UNIX
, SOCK_STREAM
, 0, fd
);
43 oss
<< "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(e
);
45 return (errno
= e
, -1);
53 oss
<< "[" << getpid() << "]: unable to fork: " << cpp_strerror(e
);
55 return (errno
= e
, -1);
65 int get_signal_fd() const {
66 return forked
? fd
[1] : 0;
77 int parent_wait(std::string
&err_msg
) {
81 std::ostringstream oss
;
82 int err
= safe_read_exact(fd
[0], &r
, sizeof(r
));
83 if (err
== 0 && r
== -1) {
90 oss
<< "[" << getpid() << "]: " << cpp_strerror(err
);
92 // wait for child to exit
94 err
= waitpid(childpid
, &status
, 0);
96 oss
<< "[" << getpid() << "]" << " waitpid error: " << cpp_strerror(err
);
97 } else if (WIFSIGNALED(status
)) {
98 oss
<< "[" << getpid() << "]" << " exited with a signal";
99 } else if (!WIFEXITED(status
)) {
100 oss
<< "[" << getpid() << "]" << " did not exit normally";
102 err
= WEXITSTATUS(status
);
104 oss
<< "[" << getpid() << "]" << " returned exit_status " << cpp_strerror(err
);
111 int signal_exit(int r
) {
113 /* If we get an error here, it's too late to do anything reasonable about it. */
114 (void)safe_write(fd
[1], &r
, sizeof(r
));
127 int r2
= ::write(fd
[1], &r
, sizeof(r
));
128 r
+= r2
; // make the compiler shut up about the unused return code from ::write(2).