From 202725960bfb5037af8e9c3ede22072fc3742dab Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 6 Mar 2009 14:12:36 -0800 Subject: [PATCH] vswitch: Keep existing datapaths when starting up. Until now, vswitchd has deleted all existing datapaths when it started up, and then re-created the ones that are actually configured. This is a very "clean", conservative design, but it has undesirable effects in practice. In particular, if any datapath has a local port with an IP address configured on it, then deleting the datapath and recreating it will drop that IP address, which can mean that your machine just lost connectivity to the outside world. So, with this commit, now vswitchd only deletes datapaths at startup that don't have configured bridges, preserving local port IP addresses. --- vswitchd/bridge.c | 21 +++++++++++++++++++-- vswitchd/vswitchd.c | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 60ba9911..0d1aedba 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -246,6 +247,7 @@ static struct iface *iface_from_dp_ifidx(const struct bridge *, /* Public functions. */ +/* The caller must already have called cfg_read(). */ void bridge_init(void) { @@ -259,13 +261,19 @@ bridge_init(void) sprintf(devname, "dp%d", i); retval = dpif_open(devname, &dpif); if (!retval) { - dpif_delete(&dpif); + char dpif_name[IF_NAMESIZE]; + if (dpif_get_name(&dpif, dpif_name, sizeof dpif_name) + || !cfg_has("bridge.%s.port", dpif_name)) { + dpif_delete(&dpif); + } dpif_close(&dpif); } else if (retval != ENODEV) { VLOG_ERR("failed to delete datapath nl:%d: %s", i, strerror(retval)); } } + + bridge_reconfigure(); } static bool @@ -585,7 +593,16 @@ bridge_create(const char *name) br = xcalloc(1, sizeof *br); error = dpif_create(name, &br->dpif); - if (error) { + if (error == EEXIST) { + error = dpif_open(name, &br->dpif); + if (error) { + VLOG_ERR("datapath %s already exists but cannot be opened: %s", + name, strerror(error)); + free(br); + return NULL; + } + dpif_flow_flush(&br->dpif); + } else if (error) { VLOG_ERR("failed to create datapath %s: %s", name, strerror(error)); free(br); return NULL; diff --git a/vswitchd/vswitchd.c b/vswitchd/vswitchd.c index c83a22bf..1890b091 100644 --- a/vswitchd/vswitchd.c +++ b/vswitchd/vswitchd.c @@ -87,8 +87,8 @@ main(int argc, char *argv[]) ofp_fatal(retval, "could not listen for vlog connections"); } + cfg_read(); bridge_init(); - reconfigure(); for (;;) { if (signal_poll(sighup)) { -- 2.30.2