#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>
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)
{
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;
}
#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");
*/