]> git.ozlabs.org Git - ccan-lca-2011.git/commitdiff
lca2011: oserver_restore.
authorRusty Russell <rusty@rustcorp.com.au>
Sat, 22 Jan 2011 03:40:51 +0000 (14:10 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Sat, 22 Jan 2011 03:40:51 +0000 (14:10 +1030)
ccan/oserver/_info
ccan/oserver/oserver.c
ccan/oserver/oserver.h

index 9107e66323806facf8cdfde91320f9509ef68c27..7d05837c06f3fc3f45a9d6c5967e22e605446778 100644 (file)
@@ -52,6 +52,7 @@ int main(int argc, char *argv[])
                printf("ccan/array_size\n");
                printf("ccan/tevent\n");
                printf("ccan/cdump\n");
+               printf("ccan/grab_file\n");
                return 0;
        }
 
index 8a5fdceecf1a0c2c4f7ddf1ac278ad8c61f7e793..b65fe6b1f3069fd90dae4cda0895210bda37a649 100644 (file)
@@ -5,6 +5,7 @@
 #include <ccan/opt/opt.h>
 #include <ccan/tevent/tevent.h>
 #include <ccan/array_size/array_size.h>
+#include <ccan/grab_file/grab_file.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -306,6 +307,53 @@ static void dump(struct tevent_context *ev,
        talloc_free(str);
 }
 
+static bool load_file(struct oserver *oserver, const char *file)
+{
+       char *str;
+
+       if (!file)
+               return false;
+
+       str = grab_file(oserver, file, NULL);
+       if (!str)
+               return false;
+
+       if (!cdump_unbundle(oserver, cdump_struct_oserver, oserver, str)) {
+               talloc_free(str);
+               return false;
+       }
+       talloc_free(str);
+       return true;
+}
+
+static void complete_server(struct tevent_context *ev,
+                           struct oserver *oserver, const char *dumpfile)
+{
+       /* Re-set this even if restored from file, in case it changed. */
+       oserver->dumpfile = dumpfile;
+       if (oserver->dumpfile)
+               tevent_add_signal(ev, oserver, SIGHUP, SA_RESTART,
+                                 dump, oserver);
+
+       /* Don't kill us if client dies. */
+       signal(SIGPIPE, SIG_IGN);
+
+       /* Show talloc tree on SIGUSR1. */
+       tevent_add_signal(ev, oserver, SIGUSR1, SA_RESTART,
+                         talloc_dump, oserver);
+}
+
+struct oserver *oserver_restore(struct tevent_context *ev, const char *dumpfile)
+{
+       struct oserver *oserver = talloc(ev, struct oserver);
+       if (!load_file(oserver, dumpfile)) {
+               talloc_free(oserver);
+               return NULL;
+       }
+       complete_server(ev, oserver, dumpfile);
+       return oserver;
+}
+
 struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
                              const char *dumpfile)
 {
@@ -350,18 +398,6 @@ struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
                return NULL;
        }
 
-       oserver->dumpfile = dumpfile;
-       if (oserver->dumpfile) {
-               tevent_add_signal(ev, oserver, SIGHUP, SA_RESTART,
-                                 dump, oserver);
-       }
-
-       /* Don't kill us if client dies. */
-       signal(SIGPIPE, SIG_IGN);
-
-       /* Show talloc tree on SIGUSR1. */
-       tevent_add_signal(ev, oserver, SIGUSR1, SA_RESTART,
-                         talloc_dump, oserver);
-
+       complete_server(ev, oserver, dumpfile);
        return oserver;
 }
index 3342ba83e61850def0eb60109c068b501b2312f8..06a89b28344776035693136c9652fb110c1abe4d 100644 (file)
@@ -4,13 +4,12 @@
 #include <ccan/tevent/tevent.h>
 
 /**
- * oserver_setup - set up an oserver
+ * oserver_restore - restore an oserver from dump
  * @ev: tevent context to use.
- * @port: port to use (usually OSERVER_PORT)
- * @dumpfile: file to save state to on SIGHUP (if non-NULL).
+ * @dumpfile: file to with saved state.
  *
- * 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
+ * Tries to restore an oserver from the dump file.  Returns NULL on failure.
+ * talloc_free() the pointer returned to shut it down
  * (its parent is the tevent_context).
  *
  * Example:
  *     struct tevent_context *ev;
  *
  *     ev = tevent_context_init(NULL);
- *     oserver = oserver_setup(ev, OSERVER_PORT, "oserver.dump");
- *     if (!oserver)
- *             err(1, "Failed to set up server");
+ *     oserver = oserver_restore(ev, "oserver.dump");
+ *     if (oserver)
+ *             printf("Restored oserver!");
+ */
+struct oserver *oserver_restore(struct tevent_context *ev,
+                               const char *dumpfile);
+
+
+/**
+ * oserver_setup - set up an oserver
+ * @ev: tevent context to use.
+ * @port: port to use (usually OSERVER_PORT)
+ * @dumpfile: file to save state to 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
+ * (its parent is the tevent_context).
+ *
+ * Example:
+ *     ...
+ *     else {
+ *             oserver = oserver_setup(ev, OSERVER_PORT, "oserver.dump");
+ *             if (!oserver)
+ *                     err(1, "Failed to set up server");
+ *     }
  *     while (tevent_loop_wait(ev) == 0);
  *     err(1, "Event loop failed");
  */