mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
cpacfstatsd: use a PIPE to notify the parent that the initialization is done
Use a PIPE to notify the parent that the initialization is complete and all external communication channels are established. See https://www.freedesktop.org/software/systemd/man/daemon.html for details. Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
10f8565e32
commit
94e0b644a7
@@ -252,14 +252,20 @@ static int do_print(int s, enum ctr_e ctr)
|
||||
}
|
||||
|
||||
|
||||
static int become_daemon(void)
|
||||
static int become_daemon(int *startup_pipe)
|
||||
{
|
||||
int child_initialized = 0, fd;
|
||||
int pipefds[2];
|
||||
FILE *f;
|
||||
int fd;
|
||||
|
||||
/* syslog */
|
||||
openlog("cpacfstatsd", 0, LOG_DAEMON);
|
||||
|
||||
if (pipe(pipefds) != 0) {
|
||||
eprint("pipe() failed, errno=%d [%s]\n", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* fork and terminate parent
|
||||
* Reasons:
|
||||
@@ -276,9 +282,23 @@ static int become_daemon(void)
|
||||
case 0: /* child */
|
||||
break;
|
||||
default: /* parent */
|
||||
(void)close(pipefds[1]);
|
||||
if (read(pipefds[0], &child_initialized, sizeof(child_initialized)) !=
|
||||
sizeof(child_initialized)) {
|
||||
eprint("Couldn't read from PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||
(void)close(pipefds[0]);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
(void)close(pipefds[0]);
|
||||
if (!child_initialized)
|
||||
_exit(EXIT_FAILURE);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* Executed within the child context only */
|
||||
(void)close(pipefds[0]);
|
||||
*startup_pipe = pipefds[1];
|
||||
|
||||
if (chdir("/") != 0) {
|
||||
eprint("Chdir('/') failed, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
@@ -418,7 +438,7 @@ int eprint(const char *format, ...)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sfd, foreground = 0;
|
||||
int rc, sfd, foreground = 0, startup_pipe = -1, initialized = 0;
|
||||
struct sigaction act;
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -459,22 +479,22 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
if (become_daemon() != 0) {
|
||||
if (become_daemon(&startup_pipe) != 0) {
|
||||
eprint("Couldn't daemonize\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_init() != 0) {
|
||||
eprint("Couldn't initialize perf lib\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
atexit(perf_close);
|
||||
|
||||
sfd = open_socket(SERVER);
|
||||
if (sfd < 0) {
|
||||
eprint("Couldn't initialize server socket\n");
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
atexit(remove_sock);
|
||||
|
||||
@@ -484,17 +504,27 @@ int main(int argc, char *argv[])
|
||||
if (sigaction(SIGINT, &act, 0) != 0) {
|
||||
eprint("Couldn't establish signal handler for SIGINT, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
if (sigaction(SIGTERM, &act, 0) != 0) {
|
||||
eprint("Couldn't establish signal handler for SIGTERM, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
/* Ignore SIGPIPE such that we see EPIPE as return from write. */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
eprint("Running\n");
|
||||
initialized = 1;
|
||||
/* `startup_pipe` has been initialized, so we know we are
|
||||
* running in daemon mode. Let's write to the pipe so that the
|
||||
* parent knows that the initialization is complete.
|
||||
*/
|
||||
if (startup_pipe != -1 &&
|
||||
write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||
goto error;
|
||||
(void)close(startup_pipe);
|
||||
startup_pipe = -1;
|
||||
|
||||
while (!stopsig) {
|
||||
enum ctr_e ctr;
|
||||
@@ -507,7 +537,7 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
eprint("Accept() failure, errno=%d [%s]\n",
|
||||
errno, strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = recv_query(s, &ctr, &cmd);
|
||||
@@ -542,4 +572,14 @@ int main(int argc, char *argv[])
|
||||
remove_pidfile();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (startup_pipe != -1) {
|
||||
/* Notify the parent process that there was an error */
|
||||
if (write(startup_pipe, &initialized, sizeof(initialized)) != sizeof(initialized))
|
||||
eprint("Couldn't write to PIPE, errno=%d [%s]\n", errno, strerror(errno));
|
||||
(void)close(startup_pipe);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user