X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fjsonrpc.c;h=1ea5398b44068a53070f20de0a1064026f1fe4a7;hb=485e2766d816a18e1a51ddf5e12e55f38aeedf89;hp=0e1788cae2c37b28d29447af4d8e39a906d4a404;hpb=3a8d38c88e26f9f76f3c60efbcbead02240c26d0;p=sliver-openvswitch.git diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c index 0e1788cae..1ea5398b4 100644 --- a/lib/jsonrpc.c +++ b/lib/jsonrpc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ #include "jsonrpc.h" -#include #include #include "byteq.h" @@ -83,7 +82,7 @@ jsonrpc_open(struct stream *stream) { struct jsonrpc *rpc; - assert(stream != NULL); + ovs_assert(stream != NULL); rpc = xzalloc(sizeof *rpc); rpc->name = xstrdup(stream_get_name(stream)); @@ -473,7 +472,7 @@ jsonrpc_received(struct jsonrpc *rpc) static void jsonrpc_error(struct jsonrpc *rpc, int error) { - assert(error); + ovs_assert(error); if (!rpc->status) { rpc->status = error; jsonrpc_cleanup(rpc); @@ -745,6 +744,7 @@ struct jsonrpc_session { struct jsonrpc *rpc; struct stream *stream; struct pstream *pstream; + int last_error; unsigned int seqno; uint8_t dscp; }; @@ -753,14 +753,18 @@ struct jsonrpc_session { * acceptable to stream_open() or pstream_open(). * * If 'name' is an active connection method, e.g. "tcp:127.1.2.3", the new - * jsonrpc_session connects and reconnects, with back-off, to 'name'. + * jsonrpc_session connects to 'name'. If 'retry' is true, then the new + * session connects and reconnects to 'name', with backoff. If 'retry' is + * false, the new session will only try to connect once and after a connection + * failure or a disconnection jsonrpc_session_is_alive() will return false for + * the new session. * * If 'name' is a passive connection method, e.g. "ptcp:", the new * jsonrpc_session listens for connections to 'name'. It maintains at most one * connection at any given time. Any new connection causes the previous one * (if any) to be dropped. */ struct jsonrpc_session * -jsonrpc_session_open(const char *name) +jsonrpc_session_open(const char *name, bool retry) { struct jsonrpc_session *s; @@ -773,9 +777,13 @@ jsonrpc_session_open(const char *name) s->pstream = NULL; s->seqno = 0; s->dscp = 0; + s->last_error = 0; if (!pstream_verify_name(name)) { reconnect_set_passive(s->reconnect, true, time_msec()); + } else if (!retry) { + reconnect_set_max_tries(s->reconnect, 1); + reconnect_set_backoff(s->reconnect, INT_MAX, INT_MAX); } if (!stream_or_pstream_needs_probes(name)) { @@ -791,7 +799,7 @@ jsonrpc_session_open(const char *name) * On the assumption that such connections are likely to be short-lived * (e.g. from ovs-vsctl), informational logging for them is suppressed. */ struct jsonrpc_session * -jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc) +jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc, uint8_t dscp) { struct jsonrpc_session *s; @@ -801,7 +809,7 @@ jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc) reconnect_set_name(s->reconnect, jsonrpc_get_name(jsonrpc)); reconnect_set_max_tries(s->reconnect, 0); reconnect_connected(s->reconnect, time_msec()); - s->dscp = 0; + s->dscp = dscp; s->rpc = jsonrpc; s->stream = NULL; s->pstream = NULL; @@ -848,6 +856,8 @@ jsonrpc_session_connect(struct jsonrpc_session *s) error = jsonrpc_stream_open(name, &s->stream, s->dscp); if (!error) { reconnect_connecting(s->reconnect, time_msec()); + } else { + s->last_error = error; } } else { error = s->pstream ? 0 : jsonrpc_pstream_open(name, &s->pstream, @@ -909,6 +919,7 @@ jsonrpc_session_run(struct jsonrpc_session *s) if (error) { reconnect_disconnected(s->reconnect, time_msec(), error); jsonrpc_session_disconnect(s); + s->last_error = error; } } else if (s->stream) { int error; @@ -1062,6 +1073,12 @@ jsonrpc_session_get_status(const struct jsonrpc_session *s) return s && s->rpc ? jsonrpc_get_status(s->rpc) : 0; } +int +jsonrpc_session_get_last_error(const struct jsonrpc_session *s) +{ + return s->last_error; +} + void jsonrpc_session_get_reconnect_stats(const struct jsonrpc_session *s, struct reconnect_stats *stats) @@ -1093,6 +1110,20 @@ jsonrpc_session_set_dscp(struct jsonrpc_session *s, uint8_t dscp) { if (s->dscp != dscp) { + if (s->pstream) { + int error; + + error = pstream_set_dscp(s->pstream, dscp); + if (error) { + VLOG_ERR("%s: failed set_dscp %s", + reconnect_get_name(s->reconnect), strerror(error)); + } + /* + * XXX race window between setting dscp to listening socket + * and accepting socket. accepted socket may have old dscp value. + * Ignore this race window for now. + */ + } s->dscp = dscp; jsonrpc_session_force_reconnect(s); }