vswitchd can gracefully shutdown after receiving the 'appctl exit' command. But the datapath resources vswitchd created can linger on. This is not a problem, and in fact desireable when the shutdown is transient in nature. Since restarted vswitchd usually sees a similar configuration. By keeping the datapath resources minimize the perturbation to the running data traffic.
However, when vswitchd shutdown is permanent, there should be a way to release the all datapath resources, so that they won't be linger on forever. Add 'appctl quit' command for such purpose. Signed-off-by: Andy Zhou <az...@ovn.org> --- NEWS | 1 + ofproto/ofproto-dpif.c | 11 +++++++---- ofproto/ofproto-provider.h | 2 +- ofproto/ofproto.c | 2 +- vswitchd/bridge.c | 4 ++-- vswitchd/bridge.h | 4 +++- vswitchd/ovs-vswitchd.8.in | 3 +++ vswitchd/ovs-vswitchd.c | 7 ++++--- 8 files changed, 22 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index ea97d84a2dea..3f65654f5124 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,7 @@ Post-v2.7.0 * Bundles now support hashing by just nw_src or nw_dst. * The "learn" action now supports a "limit" option (see ovs-ofctl(8)). * The port status bit OFPPS_LIVE now reflects link aliveness. + - Add the command 'ovs-appctl quit' (see ovs-vswitchd(8)). v2.7.0 - 21 Feb 2017 --------------------- diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c73c2738c91c..bd2eaa60d36b 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -645,7 +645,7 @@ dealloc(struct ofproto *ofproto_) } static void -close_dpif_backer(struct dpif_backer *backer) +close_dpif_backer(struct dpif_backer *backer, bool del) { ovs_assert(backer->refcount > 0); @@ -661,6 +661,9 @@ close_dpif_backer(struct dpif_backer *backer) shash_find_and_delete(&all_dpif_backers, backer->type); free(backer->type); free(backer->dp_version_string); + if (del) { + dpif_delete(backer->dpif); + } dpif_close(backer->dpif); free(backer); } @@ -772,7 +775,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp) if (error) { VLOG_ERR("failed to listen on datapath of type %s: %s", type, ovs_strerror(error)); - close_dpif_backer(backer); + close_dpif_backer(backer, false); return error; } @@ -1452,7 +1455,7 @@ add_internal_flows(struct ofproto_dpif *ofproto) } static void -destruct(struct ofproto *ofproto_) +destruct(struct ofproto *ofproto_, bool del) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct ofproto_async_msg *am; @@ -1505,7 +1508,7 @@ destruct(struct ofproto *ofproto_) seq_destroy(ofproto->ams_seq); - close_dpif_backer(ofproto->backer); + close_dpif_backer(ofproto->backer, del); } static int diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index b7b12cdfd5f4..ef993d0afc4d 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -828,7 +828,7 @@ struct ofproto_class { */ struct ofproto *(*alloc)(void); int (*construct)(struct ofproto *ofproto); - void (*destruct)(struct ofproto *ofproto); + void (*destruct)(struct ofproto *ofproto, bool del); void (*dealloc)(struct ofproto *ofproto); /* Performs any periodic activity required by 'ofproto'. It should: diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index ca0f3e49bd67..7bc7b7f99d0d 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1651,7 +1651,7 @@ ofproto_destroy(struct ofproto *p, bool del) free(usage); } - p->ofproto_class->destruct(p); + p->ofproto_class->destruct(p, del); /* We should not postpone this because it involves deleting a listening * socket which we may want to reopen soon. 'connmgr' may be used by other diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index ebb6249416fa..e741f34f19ec 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -496,14 +496,14 @@ bridge_init(const char *remote) } void -bridge_exit(void) +bridge_exit(bool delete_datpath) { struct bridge *br, *next_br; if_notifier_destroy(ifnotifier); seq_destroy(ifaces_changed); HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) { - bridge_destroy(br, false); + bridge_destroy(br, delete_datpath); } ovsdb_idl_destroy(idl); } diff --git a/vswitchd/bridge.h b/vswitchd/bridge.h index 3783a21e3b4c..7835611568cf 100644 --- a/vswitchd/bridge.h +++ b/vswitchd/bridge.h @@ -16,10 +16,12 @@ #ifndef VSWITCHD_BRIDGE_H #define VSWITCHD_BRIDGE_H 1 +#include <stdbool.h> + struct simap; void bridge_init(const char *remote); -void bridge_exit(void); +void bridge_exit(bool delete_datpath); void bridge_run(void); void bridge_wait(void); diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index 8496aa68af97..bb855861992b 100644 --- a/vswitchd/ovs-vswitchd.8.in +++ b/vswitchd/ovs-vswitchd.8.in @@ -111,6 +111,9 @@ how to configure Open vSwitch. .SS "GENERAL COMMANDS" .IP "\fBexit\fR" Causes \fBovs\-vswitchd\fR to gracefully terminate. +.IP "\fBquit\fR" +Similar to "\fBexit\fR", but also release datapath resources. +. .IP "\fBqos/show-types\fR \fIinterface\fR" Queries the interface for a list of Quality of Service types that are configurable via Open vSwitch for the given \fIinterface\fR. diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c index bed3fb5c374d..10953bb1bd47 100644 --- a/vswitchd/ovs-vswitchd.c +++ b/vswitchd/ovs-vswitchd.c @@ -66,7 +66,7 @@ main(int argc, char *argv[]) char *unixctl_path = NULL; struct unixctl_server *unixctl; char *remote; - bool exiting; + bool exiting, quiting; int retval; set_program_name(argv[0]); @@ -93,6 +93,7 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } unixctl_command_register("exit", "", 0, 0, ovs_vswitchd_exit, &exiting); + unixctl_command_register("quit", "", 0, 0, ovs_vswitchd_exit, &quiting); bridge_init(remote); free(remote); @@ -120,11 +121,11 @@ main(int argc, char *argv[]) poll_immediate_wake(); } poll_block(); - if (should_service_stop()) { + if (quiting || should_service_stop()) { exiting = true; } } - bridge_exit(); + bridge_exit(quiting); unixctl_server_destroy(unixctl); service_stop(); -- 1.8.3.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev