]> git.ozlabs.org Git - ccan-lca-2011.git/commitdiff
lca2011: dump, re-exec with --restore on restart.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 25 Jan 2011 00:32:12 +0000 (11:02 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 25 Jan 2011 00:32:12 +0000 (11:02 +1030)
ccan/oserver/_info
ccan/oserver/oserver.c
ccan/oserver/oserver.h
ccan/oserver/oserver_types.h
ccan/oserver/test/run-one-client-disconnect.c
ccan/oserver/test/run.c

index 7d05837c06f3fc3f45a9d6c5967e22e605446778..7bfaa3b129e6cbd101b9c9804d22ec903709fcd1 100644 (file)
  *     #include <err.h>
  *     #include <stdlib.h>
  *
+ *     #define STATE_FILE "/var/run/oserver/dump"
+ *
  *     int main(int argc, char *argv[])
  *     {
  *             struct tevent_context *ev = tevent_context_init(NULL);
  *             unsigned int port = OSERVER_PORT;
+ *             bool restore = false;
+ *             char **restore_argv;
+ *
+ *             // Save args before opt_parse mangles them.
+ *             restore_argv = talloc_array(NULL, char *, argc+2);
+ *             restore_argv[0] = argv[0];
+ *             restore_argv[1] = "--restore";
+ *             memcpy(restore_argv+2, argv+1, sizeof(argv[0])*argc);
  *
  *             opt_register_noarg("--help|--usage|-h", opt_usage_and_exit,
  *                                "\nA oserver program", "Usage information");
  *             opt_register_arg("--port", opt_set_uintval, opt_show_uintval,
  *                              &port, "Server port number");
+ *             opt_register_noarg("--restore", opt_set_bool,
+ *                                &restore, opt_hidden);
  *
  *             opt_parse(&argc, argv, opt_log_stderr_exit);
  *             if (argc != 1)
  *                     opt_log_stderr_exit("Unknown extra arguments");
  *
- *             if (!oserver_setup(ev, port, "/var/run/oserver/dump"))
+ *             if (restore) {
+ *                     if (!oserver_restore(ev, STATE_FILE))
+ *                             err(1, "Restoring server");
+ *             } else if (!oserver_setup(ev, port, STATE_FILE, restore_argv))
  *                     err(1, "Failed to set up server");
  *
  *             while (tevent_loop_wait(ev) == 0);
index 405a576c63d103003970e17c9b6e2fe477bf3c71..d4266eda1ef5ead9329ecd5e4136e307a8a162d4 100644 (file)
@@ -305,6 +305,8 @@ static void dump(struct tevent_context *ev,
        write(fd, str, strlen(str));
        close(fd);
        talloc_free(str);
+       if (oserver->argv)
+               execvp(oserver->argv[0], oserver->argv);
 }
 
 static bool load_file(struct oserver *oserver, const char *file)
@@ -385,7 +387,7 @@ struct oserver *oserver_restore(struct tevent_context *ev, const char *dumpfile)
 }
 
 struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
-                             const char *dumpfile)
+                             const char *dumpfile, char *argv[])
 {
        struct oserver *oserver;
        int one = 1;
@@ -395,6 +397,14 @@ struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
        } u;
 
        oserver = talloc(ev, struct oserver);
+       oserver->argv = argv;
+       if (argv) {
+               /* Count the terminal NULL in argv_len. */
+               for (oserver->argv_len = 1;
+                    argv[oserver->argv_len - 1];
+                    oserver->argv_len++);
+       } else
+               oserver->argv_len = 0;
        clear_clients(oserver);
        oserver->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (oserver->fd < 0) {
index 06a89b28344776035693136c9652fb110c1abe4d..597d7ee97887ab9346f99843c5dc41115df61cd3 100644 (file)
@@ -30,6 +30,7 @@ struct oserver *oserver_restore(struct tevent_context *ev,
  * @ev: tevent context to use.
  * @port: port to use (usually OSERVER_PORT)
  * @dumpfile: file to save state to on SIGHUP (if non-NULL).
+ * @argv: arguments to re-exec on SIGHUP (if non-NULL).
  *
  * Opens a socket and binds it to @port, then sets it up to listen
  * for connections.  talloc_free() the pointer returned to shut it down
@@ -38,7 +39,7 @@ struct oserver *oserver_restore(struct tevent_context *ev,
  * Example:
  *     ...
  *     else {
- *             oserver = oserver_setup(ev, OSERVER_PORT, "oserver.dump");
+ *             oserver = oserver_setup(ev, OSERVER_PORT, "oserver.dump", argv);
  *             if (!oserver)
  *                     err(1, "Failed to set up server");
  *     }
@@ -46,7 +47,7 @@ struct oserver *oserver_restore(struct tevent_context *ev,
  *     err(1, "Event loop failed");
  */
 struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
-                             const char *dumpfile);
+                             const char *dumpfile, char *argv[]);
 
 #define OSERVER_PORT 2828
 #endif /* CCAN_OSERVER_H */
index 8e998923314112a4c033768c2771d9ffd9cd041c..9943d090fd2f1c6443fb56149ec487266a727d59 100644 (file)
@@ -42,5 +42,7 @@ CDUMP_SAVED struct oserver {
        int fd;
        struct tevent_fd *fde CDUMP_IGNORE;
        const char *dumpfile;
+       int argv_len;
+       char **argv CDUMP_LEN(argv_len);
 };
 #endif /* CCAN_OSERVER_TYPES_H */
index 6023f784b17a2fd97e01fa3d513e9f05abe7751c..f26c6efa6523191912ef86bae14dcd3ca9cd2ca5 100644 (file)
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
        /* This is how many tests you plan to run */
        plan_tests(2);
 
-       oserver = oserver_setup(ev, OSERVER_PORT, NULL);
+       oserver = oserver_setup(ev, OSERVER_PORT, NULL, NULL);
        if (!oserver)
                err(1, "Failed to set up server");
 
index a8eb6f24391042b064cddaa243fe2c3ac80c2762..0513e72ca4e972ffeb5a5303dec1996cad35ebba 100644 (file)
@@ -20,7 +20,7 @@ static void run_server(int readyfd, int exitfd)
 {
        struct tevent_context *ev = tevent_context_init(NULL);
 
-       if (oserver_setup(ev, OSERVER_PORT, NULL) == NULL)
+       if (oserver_setup(ev, OSERVER_PORT, NULL, NULL) == NULL)
                exit(1);
 
        tevent_add_fd(ev, ev, exitfd, TEVENT_FD_READ, exit_quietly, NULL);