2 * Copyright (C) 2017 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 #include <sys/types.h>
45 #ifdef HAVE_SYS_WAIT_H
51 static char pidpath
[] = "/tmp/nbdkitpidXXXXXX";
53 static void run_test (void);
56 main (int argc
, char *argv
[])
58 if (system ("nbdkit --exit-with-parent --version") != 0) {
59 printf ("%s: --exit-with-parent is not implemented on this platform, "
79 fd
= mkstemp (pidpath
);
87 /* We're going to create:
89 * monitoring process (this)
91 * `--- parent of nbdkit: waits for nbdkit to start then exits (ppid)
93 * `--- exec nbdkit --exit-with-parent (pidpath)
95 * We can read the nbdkit PID in the monitoring process using
99 if (ppid
== 0) { /* parent of nbdkit */
101 if (nbdpid
== 0) { /* exec nbdkit process */
102 const char *argv
[] = {
103 "nbdkit", "-U", "-", "-P", pidpath
, "-fv", "--exit-with-parent",
108 execvp ("nbdkit", (char **) argv
);
109 perror ("exec: nbdkit");
110 _exit (EXIT_FAILURE
);
113 printf ("parent of nbdkit: "
114 "monitoring process (test) = %d, "
115 "parent of nbdkit = %d, "
117 (int) getppid (), (int) getpid (), nbdpid
);
120 /* Wait for the pidfile to turn up, which indicates that nbdkit has
121 * started up successfully and is ready to serve requests. However
122 * if 'nbdpid' exits in this time it indicates a failure to start up.
123 * Also there is a timeout in case nbdkit hangs.
125 for (i
= 0; i
< NBDKIT_START_TIMEOUT
; ++i
) {
126 if (waitpid (nbdpid
, NULL
, WNOHANG
) == nbdpid
)
129 if (kill (nbdpid
, 0) == -1) {
130 if (errno
== ESRCH
) {
133 "%s FAILED: nbdkit exited before starting to serve files\n",
141 if (access (pidpath
, F_OK
) == 0)
147 printf ("parent of nbdkit: exiting\n");
150 /* nbdkit is now running, check that --exit-with-parent works
151 * by exiting abruptly here.
153 _exit (EXIT_SUCCESS
);
156 /* Monitoring process. */
157 printf ("monitor: waiting for parent of nbdkit to finish and exit\n");
160 if (waitpid (ppid
, &status
, 0) == -1) {
161 perror ("waitpid (ppid)");
164 if (WIFEXITED (status
) && WEXITSTATUS (status
) != 0) {
165 fprintf (stderr
, "child exited unexpectedly with non-zero exit code %d\n",
166 WEXITSTATUS (status
));
167 exit (WEXITSTATUS (status
));
169 if (WIFSIGNALED (status
)) {
170 fprintf (stderr
, "child terminated by signal %d\n", WTERMSIG (status
));
173 if (WIFSTOPPED (status
)) {
174 fprintf (stderr
, "child stopped by signal %d\n", WSTOPSIG (status
));
178 /* Get the PID of nbdkit from the pidpath file. */
179 fp
= fopen (pidpath
, "r");
184 r
= getline (&pidstr
, &n
, fp
);
189 if (sscanf (pidstr
, "%d", &nbdpid
) != 1) {
190 fprintf (stderr
, "could not read nbdkit PID from -P pidfile (%s)\n",
198 printf ("monitor: found PID of nbdkit = %d\n", nbdpid
);
201 /* We expect PID to go away, but it might take a few seconds. */
202 for (i
= 0; i
< NBDKIT_START_TIMEOUT
; ++i
) {
203 if (kill (nbdpid
, 0) == -1) {
204 if (errno
== ESRCH
) goto done
; /* good - gone away */
212 fprintf (stderr
, "--exit-with-parent does not appear to work\n");
216 printf ("monitor: success: nbdkit exited with parent\n");