+ daemonize_start();
+ daemonize_complete();
+}
+
+static pid_t
+fork_and_wait_for_startup(int *fdp)
+{
+ int fds[2];
+ pid_t pid;
+
+ if (pipe(fds) < 0) {
+ ovs_fatal(errno, "pipe failed");
+ }
+
+ pid = fork();
+ if (pid > 0) {
+ /* Running in parent process. */
+ char c;
+
+ close(fds[1]);
+ fatal_signal_fork();
+ if (read(fds[0], &c, 1) != 1) {
+ int retval;
+ int status;
+
+ do {
+ retval = waitpid(pid, &status, 0);
+ } while (retval == -1 && errno == EINTR);
+
+ if (retval == pid
+ && WIFEXITED(status)
+ && WEXITSTATUS(status)) {
+ /* Child exited with an error. Convey the same error to
+ * our parent process as a courtesy. */
+ exit(WEXITSTATUS(status));
+ }
+
+ ovs_fatal(errno, "fork child failed to signal startup");
+ }
+ close(fds[0]);
+ *fdp = -1;
+ } else if (!pid) {
+ /* Running in child process. */
+ close(fds[0]);
+ time_postfork();
+ lockfile_postfork();
+ *fdp = fds[1];
+ } else {
+ ovs_fatal(errno, "could not fork");
+ }
+
+ return pid;
+}
+
+static void
+fork_notify_startup(int fd)
+{
+ if (fd != -1) {
+ size_t bytes_written;
+ int error;
+
+ error = write_fully(fd, "", 1, &bytes_written);
+ if (error) {
+ ovs_fatal(error, "could not write to pipe");