2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-29 05:18:13 +00:00

ofproto: Do not delete datapath flows on exit by default.

Commit e96a5c24e853 ("upcall: Remove datapath flows when setting
n-threads.") caused OVS to delete datapath flows when it exits through
any graceful means.  This is not necessarily desirable, especially when
OVS is being stopped as part of an upgrade.  This commit changes OVS so
that it only removes datapath flows when requested, via "ovs-appctl
exit --cleanup".

Acked-by: Numan Siddique <numans@ovn.org>
Tested-by: Numan Siddique <numans@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Ben Pfaff 2020-01-09 12:49:44 -08:00
parent 586cd3101e
commit 79eadafeb1
4 changed files with 28 additions and 20 deletions

1
NEWS
View File

@ -1,5 +1,6 @@
Post-v2.13.0 Post-v2.13.0
--------------------- ---------------------
- ovs-vswitchd no longer deletes datapath flows on exit by default.
v2.13.0 - xx xxx xxxx v2.13.0 - xx xxx xxxx

View File

@ -332,7 +332,7 @@ static size_t recv_upcalls(struct handler *);
static int process_upcall(struct udpif *, struct upcall *, static int process_upcall(struct udpif *, struct upcall *,
struct ofpbuf *odp_actions, struct flow_wildcards *); struct ofpbuf *odp_actions, struct flow_wildcards *);
static void handle_upcalls(struct udpif *, struct upcall *, size_t n_upcalls); static void handle_upcalls(struct udpif *, struct upcall *, size_t n_upcalls);
static void udpif_stop_threads(struct udpif *); static void udpif_stop_threads(struct udpif *, bool delete_flows);
static void udpif_start_threads(struct udpif *, size_t n_handlers, static void udpif_start_threads(struct udpif *, size_t n_handlers,
size_t n_revalidators); size_t n_revalidators);
static void udpif_pause_revalidators(struct udpif *); static void udpif_pause_revalidators(struct udpif *);
@ -483,7 +483,7 @@ udpif_run(struct udpif *udpif)
void void
udpif_destroy(struct udpif *udpif) udpif_destroy(struct udpif *udpif)
{ {
udpif_stop_threads(udpif); udpif_stop_threads(udpif, false);
dpif_register_dp_purge_cb(udpif->dpif, NULL, udpif); dpif_register_dp_purge_cb(udpif->dpif, NULL, udpif);
dpif_register_upcall_cb(udpif->dpif, NULL, udpif); dpif_register_upcall_cb(udpif->dpif, NULL, udpif);
@ -504,9 +504,15 @@ udpif_destroy(struct udpif *udpif)
free(udpif); free(udpif);
} }
/* Stops the handler and revalidator threads. */ /* Stops the handler and revalidator threads.
*
* If 'delete_flows' is true, we delete ukeys and delete all flows from the
* datapath. Otherwise, we end up double-counting stats for flows that remain
* in the datapath. If 'delete_flows' is false, we skip this step. This is
* appropriate if OVS is about to exit anyway and it is desirable to let
* existing network connections continue being forwarded afterward. */
static void static void
udpif_stop_threads(struct udpif *udpif) udpif_stop_threads(struct udpif *udpif, bool delete_flows)
{ {
if (udpif && (udpif->n_handlers != 0 || udpif->n_revalidators != 0)) { if (udpif && (udpif->n_handlers != 0 || udpif->n_revalidators != 0)) {
size_t i; size_t i;
@ -526,10 +532,10 @@ udpif_stop_threads(struct udpif *udpif)
dpif_disable_upcall(udpif->dpif); dpif_disable_upcall(udpif->dpif);
ovsrcu_quiesce_end(); ovsrcu_quiesce_end();
/* Delete ukeys, and delete all flows from the datapath to prevent if (delete_flows) {
* double-counting stats. */ for (i = 0; i < udpif->n_revalidators; i++) {
for (i = 0; i < udpif->n_revalidators; i++) { revalidator_purge(&udpif->revalidators[i]);
revalidator_purge(&udpif->revalidators[i]); }
} }
latch_poll(&udpif->exit_latch); latch_poll(&udpif->exit_latch);
@ -627,7 +633,7 @@ udpif_set_threads(struct udpif *udpif, size_t n_handlers_,
if (udpif->n_handlers != n_handlers_ if (udpif->n_handlers != n_handlers_
|| udpif->n_revalidators != n_revalidators_) { || udpif->n_revalidators != n_revalidators_) {
udpif_stop_threads(udpif); udpif_stop_threads(udpif, true);
} }
if (!udpif->handlers && !udpif->revalidators) { if (!udpif->handlers && !udpif->revalidators) {
@ -681,7 +687,7 @@ udpif_flush(struct udpif *udpif)
size_t n_handlers_ = udpif->n_handlers; size_t n_handlers_ = udpif->n_handlers;
size_t n_revalidators_ = udpif->n_revalidators; size_t n_revalidators_ = udpif->n_revalidators;
udpif_stop_threads(udpif); udpif_stop_threads(udpif, true);
dpif_flow_flush(udpif->dpif); dpif_flow_flush(udpif->dpif);
udpif_start_threads(udpif, n_handlers_, n_revalidators_); udpif_start_threads(udpif, n_handlers_, n_revalidators_);
} }

View File

@ -1601,13 +1601,13 @@ ofproto_rule_delete(struct ofproto *ofproto, struct rule *rule)
} }
static void static void
ofproto_flush__(struct ofproto *ofproto) ofproto_flush__(struct ofproto *ofproto, bool del)
OVS_EXCLUDED(ofproto_mutex) OVS_EXCLUDED(ofproto_mutex)
{ {
struct oftable *table; struct oftable *table;
/* This will flush all datapath flows. */ /* This will flush all datapath flows. */
if (ofproto->ofproto_class->flush) { if (del && ofproto->ofproto_class->flush) {
ofproto->ofproto_class->flush(ofproto); ofproto->ofproto_class->flush(ofproto);
} }
@ -1710,7 +1710,7 @@ ofproto_destroy(struct ofproto *p, bool del)
return; return;
} }
ofproto_flush__(p); ofproto_flush__(p, del);
HMAP_FOR_EACH_SAFE (ofport, next_ofport, hmap_node, &p->ports) { HMAP_FOR_EACH_SAFE (ofport, next_ofport, hmap_node, &p->ports) {
ofport_destroy(ofport, del); ofport_destroy(ofport, del);
} }
@ -2288,7 +2288,7 @@ void
ofproto_flush_flows(struct ofproto *ofproto) ofproto_flush_flows(struct ofproto *ofproto)
{ {
COVERAGE_INC(ofproto_flush); COVERAGE_INC(ofproto_flush);
ofproto_flush__(ofproto); ofproto_flush__(ofproto, false);
connmgr_flushed(ofproto->connmgr); connmgr_flushed(ofproto->connmgr);
} }

View File

@ -107,12 +107,13 @@ how to configure Open vSwitch.
.SS "GENERAL COMMANDS" .SS "GENERAL COMMANDS"
.IP "\fBexit\fR \fI--cleanup\fR" .IP "\fBexit\fR \fI--cleanup\fR"
Causes \fBovs\-vswitchd\fR to gracefully terminate. If \fI--cleanup\fR Causes \fBovs\-vswitchd\fR to gracefully terminate. If \fI--cleanup\fR
is specified, release datapath resources configured by \fBovs\-vswitchd\fR. is specified, deletes flows from datpaths and releases other datapath
Otherwise, datapath flows and other resources remains undeleted. resources configured by \fBovs\-vswitchd\fR. Otherwise, datapath
Resources of datapaths that are integrated into \fBovs\-vswitchd\fR (e.g. flows and other resources remains undeleted. Resources of datapaths
the \fBnetdev\fR datapath type) are always released regardless of that are integrated into \fBovs\-vswitchd\fR (e.g. the \fBnetdev\fR
\fI--cleanup\fR except for ports with \fBinternal\fR type. Use \fI--cleanup\fR datapath type) are always released regardless of \fI--cleanup\fR
to release \fBinternal\fR ports too. except for ports with \fBinternal\fR type. Use \fI--cleanup\fR to
release \fBinternal\fR ports too.
. .
.IP "\fBqos/show-types\fR \fIinterface\fR" .IP "\fBqos/show-types\fR \fIinterface\fR"
Queries the interface for a list of Quality of Service types that are Queries the interface for a list of Quality of Service types that are