xenserver: Fix use of VLAN as primary management interface.
authorBen Pfaff <blp@nicira.com>
Wed, 20 May 2009 21:57:06 +0000 (14:57 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 21 May 2009 16:42:54 +0000 (09:42 -0700)
xapi insists that the device that carries the IP address for a VLAN is
the bridge that it thinks the VLAN is on.  This commit makes it so.

xapi also will do the ioctl equivalent of "brctl addbr xapi#" if that
bridge appears to be missing when it reconfigures the interface.  If we
return EEXIST or any other error, then it gives up at that point.  So we
have to return "success" to that attempt regardless of whether we really
want to do so.

vswitchd/brcompatd.c
xenserver/etc_init.d_vswitch
xenserver/opt_xensource_libexec_interface-reconfigure

index 08151f88aeceb38325588167c70c12959a9d610f..fbd063d843b1c09105d27ef4c2054206bfaea987 100644 (file)
@@ -309,9 +309,16 @@ add_bridge(const char *br_name)
         VLOG_WARN("addbr %s: bridge %s exists", br_name, br_name);
         return EEXIST;
     } else if (netdev_exists(br_name)) {
-        VLOG_WARN("addbr %s: cannot create bridge %s because a network device "
-                  "named %s already exists", br_name, br_name, br_name);
-        return EEXIST;
+        if (cfg_get_bool(0, "iface.%s.fake-bridge", br_name)) {
+            VLOG_WARN("addbr %s: %s exists as a fake bridge",
+                      br_name, br_name);
+            return 0;
+        } else {
+            VLOG_WARN("addbr %s: cannot create bridge %s because a network "
+                      "device named %s already exists",
+                      br_name, br_name, br_name);
+            return EEXIST;
+        }
     }
 
     cfg_add_entry("bridge.%s.port=%s", br_name, br_name);
@@ -669,11 +676,11 @@ parse_options(int argc, char *argv[])
     char *short_options = long_options_to_short_options(long_options);
     int error;
 
-    reload_command = xasprintf("ovs-appctl "
+    reload_command = xasprintf("%s/ovs-appctl "
                                "-t %s/vswitchd.`cat %s/vswitchd.pid`.ctl "
                                "-e vswitchd/reload 2>&1 "
                                "| /usr/bin/logger -t brcompatd-reload",
-                               ovs_rundir, ovs_rundir);
+                               ovs_bindir, ovs_rundir, ovs_rundir);
     for (;;) {
         int c;
 
index 27e582f55b325f50e339838828e937b6ddf511c3..bf52c921f06160a96215cb7b25b23cb4d807a9cc 100755 (executable)
@@ -242,12 +242,13 @@ function start_brcompatd {
         valgrind_opt="valgrind --log-file=$BRCOMPATD_VALGRIND_LOG $BRCOMPATD_VALGRIND_OPT"
         daemonize="n"
     fi
+    reload_cmd='/root/vswitch/bin/ovs-appctl -t /var/run/vswitchd.`cat /var/run/vswitchd.pid`.ctl -e vswitchd/reload 2>&1 | /usr/bin/logger -t brcompatd-reload'
     if [ "$daemonize" != "y" ]; then
         # Start in background and force a "success" message
         action "Starting brcompatd ($strace_opt$valgrind_opt)" true
-        (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE --vswitchd-pidfile=$VSWITCHD_PIDFILE -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
+        (nice -n "$VSWITCHD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" --reload-command="$reload_cmd" -P$BRCOMPATD_PIDFILE -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF") &
     else
-        action "Starting brcompatd" nice -n "$BRCOMPATD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" -P$BRCOMPATD_PIDFILE -D -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
+        action "Starting brcompatd" nice -n "$BRCOMPATD_PRIORITY" $strace_opt $valgrind_opt "$brcompatd" --reload-command="$reload_cmd" -P$BRCOMPATD_PIDFILE -D -vANY:CONSOLE:EMER $syslog_opt $logfile_level_opt $logfile_file_opt $leak_opt "$VSWITCHD_CONF"
     fi
 }
 
index 46ff2b88327fa607b7c820c7b7159eabbd5d442f..27c8f502642a6d4f4875be23b1f1763600849480 100755 (executable)
@@ -418,16 +418,11 @@ use it.)
 def ipdev_name(pif):
     """Return the the name of the network device that carries the
 IP configuration (if any) associated with pif.
-For a non-VLAN PIF, the ipdev name is the bridge name.
-For a VLAN PIF, the ipdev name is the interface name.
+The ipdev name is the same as the bridge name.
 """
 
     pifrec = db.get_pif_record(pif)
-
-    if pifrec['VLAN'] == '-1':
-        return bridge_name(pif)
-    else:
-        return interface_name(pif)
+    return bridge_name(pif)
 
 def physdev_names(pif):
     """Return the name(s) of the physical network device(s) associated with pif.
@@ -533,7 +528,6 @@ def interface_deconfigure_commands(interface):
 
 def run_command(command):
     log("Running command: " + ' '.join(command))
-    #return
     if os.spawnl(os.P_WAIT, command[0], *command) != 0:
         log("Command failed: " + ' '.join(command))
         return False
@@ -825,6 +819,16 @@ def action_up(pif):
     if vlan_slave:
         argv += ['--add=vlan.%s.tag=%s' % (ipdev, pifrec['VLAN'])]
         argv += ['--add=iface.%s.internal=true' % (ipdev)]
+
+        # xapi creates a bridge by the name of the ipdev and requires
+        # that the IP address will be on it.  We need to delete this
+        # bridge because we need that device to be a member of our
+        # datapath.
+        argv += ['--del-match=bridge.%s.[!0-9]*' % ipdev]
+
+        # xapi insists that its attempts to create the bridge succeed,
+        # so force that to happen.
+        argv += ['--add=iface.%s.fake-bridge=true' % (ipdev)]
     if bond_master:
         argv += configure_bond(bond_master)
     modify_config(argv)