From: Rusty Russell Date: Sat, 22 Jan 2011 03:40:51 +0000 (+1030) Subject: lca2011: oserver_restore. X-Git-Url: http://git.ozlabs.org/?a=commitdiff_plain;h=33b799969447a818cd99749aa937a59c88e4f83f;p=ccan-lca-2011.git lca2011: oserver_restore. --- diff --git a/ccan/oserver/_info b/ccan/oserver/_info index 9107e66..7d05837 100644 --- a/ccan/oserver/_info +++ b/ccan/oserver/_info @@ -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; } diff --git a/ccan/oserver/oserver.c b/ccan/oserver/oserver.c index 8a5fdce..b65fe6b 100644 --- a/ccan/oserver/oserver.c +++ b/ccan/oserver/oserver.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/ccan/oserver/oserver.h b/ccan/oserver/oserver.h index 3342ba8..06a89b2 100644 --- a/ccan/oserver/oserver.h +++ b/ccan/oserver/oserver.h @@ -4,13 +4,12 @@ #include /** - * 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: @@ -18,10 +17,31 @@ * 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"); */