When re-execing, try with --test-config first, and revert if it fails.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Apr 2013 22:24:36 +0000 (00:24 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Apr 2013 22:24:36 +0000 (00:24 +0200)
main.cpp

index f220cfb..afc3edf 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -10,6 +10,8 @@
 #include <sys/ioctl.h>
 #include <sys/poll.h>
 #include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <signal.h>
 #include <errno.h>
 #include <ctype.h>
@@ -241,6 +243,45 @@ void create_streams(const Config &config,
                }
        }
 }
+       
+bool dry_run_config(const std::string &argv0, const std::string &config_filename)
+{
+       char *argv0_copy = strdup(argv0.c_str());
+       char *config_filename_copy = strdup(config_filename.c_str());
+
+       pid_t pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork()");
+               free(argv0_copy);
+               free(config_filename_copy);
+               return false;
+       case 0:
+               // Child.
+               execlp(argv0_copy, argv0_copy, "--test-config", config_filename_copy, NULL);
+               perror(argv0_copy);
+               _exit(1);
+       default:
+               // Parent.
+               break;
+       }
+               
+       free(argv0_copy);
+       free(config_filename_copy);
+
+       int status;
+       pid_t err;
+       do {
+               err = waitpid(pid, &status, 0);
+       } while (err == -1 && errno == EINTR);
+
+       if (err == -1) {
+               perror("waitpid()");
+               return false;
+       }       
+
+       return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
+}
 
 int main(int argc, char **argv)
 {
@@ -275,8 +316,6 @@ int main(int argc, char **argv)
                config_filename = argv[optind++];
        }
 
-       struct timeval serialize_start;
-
        Config config;
        if (!parse_config(config_filename, &config)) {
                exit(1);
@@ -285,10 +324,12 @@ int main(int argc, char **argv)
                exit(0);
        }
 
+start:
        fprintf(stderr, "\nCubemap " SERVER_VERSION " starting.\n");
        servers = new ServerPool(config.num_servers);
 
        CubemapStateProto loaded_state;
+       struct timeval serialize_start;
        set<string> deserialized_stream_ids;
        map<string, Input *> deserialized_inputs;
        map<int, Acceptor *> deserialized_acceptors;
@@ -384,6 +425,12 @@ int main(int argc, char **argv)
        state_fd = make_tempfile(collect_state(
                serialize_start, acceptors, inputs, servers));
        delete servers;
+
+       if (!dry_run_config(argv[0], config_filename)) {
+               fprintf(stderr, "ERROR: %s --test-config failed. Restarting old version instead of new.\n", argv[0]);
+               hupped = false;
+               goto start;
+       }
         
        char buf[16];
        sprintf(buf, "%d", state_fd);