On Thu, Jun 13, 2013 at 8:29 AM, Gurucharan Shetty <span dir="ltr"><<a href="mailto:shettyg@nicira.com" target="_blank">shettyg@nicira.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Wed, Jun 12, 2013 at 5:10 PM, Ben Pfaff <span dir="ltr"><<a href="mailto:blp@nicira.com" target="_blank">blp@nicira.com</a>></span> wrote:<br></div><div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
This is unpolished but it shows the approach I have in mind.<br>
Sending out for comments on the approach.<br></blockquote></div><div>I am fine with the approach. The two negatives I see with this:</div><div>* If /tmp is cleaned up routinely, we will loose the information. If we decide to put this in /etc/openvswitch, it may look a little dirty when program is abnormally terminated.</div>
</div></blockquote><div>This concern is probably invalid. I don't think there is a possibility that a second file with the same name will be created if the first one is deleted.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote">
<div>* If we have multiple run time data, (ex: add/remove databases) we may need multiple files.</div><div><br></div><div>If you are fine with this, I am fine with it.</div><div><div class="h5"><div><br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c<br>
index 20e1964..d87360a 100644<br>
--- a/ovsdb/ovsdb-server.c<br>
+++ b/ovsdb/ovsdb-server.c<br>
@@ -81,8 +81,14 @@ struct add_remote_aux {<br>
struct sset *remotes;<br>
struct db *dbs;<br>
size_t n_dbs;<br>
+ FILE *config_tmpfile;<br>
};<br>
static unixctl_cb_func ovsdb_server_add_remote;<br>
+<br>
+struct remove_remote_aux {<br>
+ struct sset *remotes;<br>
+ FILE *config_tmpfile;<br>
+};<br>
static unixctl_cb_func ovsdb_server_remove_remote;<br>
static unixctl_cb_func ovsdb_server_list_remotes;<br>
<br>
@@ -99,6 +105,9 @@ static void update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,<br>
const struct sset *remotes,<br>
struct db dbs[], size_t n_dbs);<br>
<br>
+static void save_config(FILE *config_file, const struct sset *);<br>
+static void load_config(FILE *config_file, struct sset *);<br>
+<br>
int<br>
main(int argc, char *argv[])<br>
{<br>
@@ -112,6 +121,8 @@ main(int argc, char *argv[])<br>
int retval;<br>
long long int status_timer = LLONG_MIN;<br>
struct add_remote_aux add_remote_aux;<br>
+ struct remove_remote_aux remove_remote_aux;<br>
+ FILE *config_tmpfile;<br>
<br>
struct db *dbs;<br>
int n_dbs;<br>
@@ -125,7 +136,14 @@ main(int argc, char *argv[])<br>
<br>
parse_options(&argc, &argv, &remotes, &unixctl_path, &run_command);<br>
<br>
+ config_tmpfile = tmpfile();<br>
+ if (!config_tmpfile) {<br>
+ ovs_fatal(errno, "failed to create temporary file");<br>
+ }<br>
+<br>
+ save_config(config_tmpfile, &remotes);<br>
daemonize_start();<br>
+ load_config(config_tmpfile, &remotes);<br>
<br>
n_dbs = MAX(1, argc);<br>
dbs = xcalloc(n_dbs + 1, sizeof *dbs);<br>
@@ -195,10 +213,13 @@ main(int argc, char *argv[])<br>
add_remote_aux.remotes = &remotes;<br>
add_remote_aux.dbs = dbs;<br>
add_remote_aux.n_dbs = n_dbs;<br>
+ add_remote_aux.config_tmpfile = config_tmpfile;<br>
unixctl_command_register("ovsdb-server/add-remote", "REMOTE", 1, 1,<br>
ovsdb_server_add_remote, &add_remote_aux);<br>
+ remove_remote_aux.remotes = &remotes;<br>
+ remove_remote_aux.config_tmpfile = config_tmpfile;<br>
unixctl_command_register("ovsdb-server/remove-remote", "REMOTE", 1, 1,<br>
- ovsdb_server_remove_remote, &remotes);<br>
+ ovsdb_server_remove_remote, &remove_remote_aux);<br>
unixctl_command_register("ovsdb-server/list-remotes", "", 0, 0,<br>
ovsdb_server_list_remotes, &remotes);<br>
<br>
@@ -922,7 +943,9 @@ ovsdb_server_add_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,<br>
: parse_db_column(aux->dbs, aux->n_dbs, remote,<br>
&db, &table, &column));<br>
if (!retval) {<br>
- sset_add(aux->remotes, remote);<br>
+ if (sset_add(aux->remotes, remote)) {<br>
+ save_config(aux->config_tmpfile, aux->remotes);<br>
+ }<br>
unixctl_command_reply(conn, NULL);<br>
} else {<br>
unixctl_command_reply_error(conn, retval);<br>
@@ -934,14 +957,15 @@ ovsdb_server_add_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,<br>
* that ovsdb-server services. */<br>
static void<br>
ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,<br>
- const char *argv[], void *remotes_)<br>
+ const char *argv[], void *aux_)<br>
{<br>
- struct sset *remotes = remotes_;<br>
+ struct remove_remote_aux *aux = aux_;<br>
struct sset_node *node;<br>
<br>
- node = sset_find(remotes, argv[1]);<br>
+ node = sset_find(aux->remotes, argv[1]);<br>
if (node) {<br>
- sset_delete(remotes, node);<br>
+ sset_delete(aux->remotes, node);<br>
+ save_config(aux->config_tmpfile, aux->remotes);<br>
unixctl_command_reply(conn, NULL);<br>
} else {<br>
unixctl_command_reply_error(conn, "no such remote");<br>
@@ -1092,3 +1116,48 @@ usage(void)<br>
leak_checker_usage();<br>
exit(EXIT_SUCCESS);<br>
}<br>
+<br>
+static void<br>
+save_config(FILE *config_file, const struct sset *remotes)<br>
+{<br>
+ const char *remote;<br>
+ struct json *json;<br>
+ char *s;<br>
+<br>
+ if (ftruncate(fileno(config_file), 0) == -1) {<br>
+ ovs_fatal(errno, "truncate failed");<br>
+ }<br>
+<br>
+ json = json_array_create_empty();<br>
+ SSET_FOR_EACH (remote, remotes) {<br>
+ json_array_add(json, json_string_create(remote));<br>
+ }<br>
+ s = json_to_string(json, 0);<br>
+ json_destroy(json);<br>
+<br>
+ if (fputs(s, config_file) == EOF || fflush(config_file) == EOF) {<br>
+ ovs_fatal(errno, "write failed");<br>
+ }<br>
+ free(s);<br>
+}<br>
+<br>
+static void<br>
+load_config(FILE *config_file, struct sset *remotes)<br>
+{<br>
+ struct json *json;<br>
+ size_t i;<br>
+<br>
+ sset_clear(remotes);<br>
+<br>
+ rewind(config_file);<br>
+ json = json_from_stream(config_file);<br>
+ if (json->type == JSON_STRING) {<br>
+ ovs_fatal(0, "reading json failed (%s)", json_string(json));<br>
+ }<br>
+ ovs_assert(json->type == JSON_ARRAY);<br>
+ for (i = 0; i < json->u.array.n; i++) {<br>
+ const struct json *remote = json->u.array.elems[i];<br>
+ sset_add(remotes, json_string(remote));<br>
+ }<br>
+ json_destroy(json);<br>
+}<br>
<span><font color="#888888">--<br>
1.7.2.5<br>
<br>
_______________________________________________<br>
dev mailing list<br>
<a href="mailto:dev@openvswitch.org" target="_blank">dev@openvswitch.org</a><br>
<a href="http://openvswitch.org/mailman/listinfo/dev" target="_blank">http://openvswitch.org/mailman/listinfo/dev</a><br>
</font></span></blockquote></div></div></div><br>
</blockquote></div><br>