DEFAULT_VSWITCHD_CONF = "@sysconfdir@/ovs-vswitchd.conf"
VSWITCHD_CONF = DEFAULT_VSWITCHD_CONF
-DEFAULT_VSWITCHD_TARGET = "@RUNDIR@/ovs-vswitchd.pid"
+DEFAULT_VSWITCHD_TARGET = "ovs-vswitchd"
VSWITCHD_TARGET = DEFAULT_VSWITCHD_TARGET
RELOAD_VSWITCHD = True
def cfg_reload():
target = VSWITCHD_TARGET
+ if not target.startswith('/'):
+ pid = read_first_line_of_file('%s/%s.pid' % ('@RUNDIR@', target))
+ target = '%s/%s.%s.ctl' % ('@RUNDIR@', target, pid)
s = os.stat(target)
- if stat.S_ISREG(s.st_mode):
- pid = read_first_line_of_file(target)
- target = "@RUNDIR@/ovs-vswitchd.%s.ctl" % pid
- s = os.stat(target)
if not stat.S_ISSOCK(s.st_mode):
raise Error("%s is not a Unix domain socket, cannot reload" % target)
skt = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
if fnmatch.fnmatch(key, 'bridge.*.port'):
cfg[key] = [s for s in cfg[key] if s != port]
+# Returns the name of the (real or fake) bridge in 'cfg' that contains
+# port 'port', or None if there is no such port.
+def port_to_bridge(cfg, port):
+ for bridge, parent, vlan in get_bridge_info(cfg):
+ if port != bridge and port in get_bridge_ports(cfg, parent, vlan):
+ return bridge
+ return None
+
def usage():
print """%(argv0)s: ovs-vswitchd management utility
usage: %(argv0)s [OPTIONS] COMMAND [ARG...]
list-ports BRIDGE print the names of all the ports on BRIDGE
add-port BRIDGE PORT add network device PORT to BRIDGE
add-bond BRIDGE PORT IFACE... add new bonded port PORT in BRIDGE from IFACES
- del-port BRIDGE PORT delete PORT (which may be bonded) from BRIDGE
+ del-port [BRIDGE] PORT delete PORT (which may be bonded) from BRIDGE
port-to-br PORT print name of bridge that contains PORT
A bond is considered to be a single port.
--no-syslog do not write mesages to syslog
-c, --config=FILE set configuration file
(default: %(config)s)
- -t, --target=PIDFILE|SOCKET set ovs-vswitchd target
+ -t, --target=PROGRAM|SOCKET set ovs-vswitchd target
(default: %(target)s)
--no-reload do not make ovs-vswitchd reload its configuration
-h, --help display this help message and exit
if name in get_bridge_ifaces(cfg, parent, vlan):
raise Error("%s because an interface named %s already exists on bridge %s" % (op, name, bridge))
-def cmd_add_br(bridge, parent=None, vlan=None):
- cfg = cfg_read(VSWITCHD_CONF, True)
-
+def cmd_add_br(cfg, bridge, parent=None, vlan=None):
check_conflicts(cfg, bridge, "cannot create a bridge named %s" % bridge)
if parent and vlan:
cfg['bridge.%s.port' % parent].append(bridge)
else:
cfg['bridge.%s.port' % bridge] = [bridge]
- cfg_save(cfg, VSWITCHD_CONF)
-def cmd_del_br(bridge):
- cfg = cfg_read(VSWITCHD_CONF, True)
+def cmd_del_br(cfg, bridge):
parent, vlan = find_bridge(cfg, bridge)
if vlan == 0:
vlan = -1
del_port(cfg, port)
if vlan < 0:
del_matching_keys(cfg, 'bridge.%s.[!0-9]*' % bridge)
- cfg_save(cfg, VSWITCHD_CONF)
-def cmd_list_br():
- cfg = cfg_read(VSWITCHD_CONF)
- for bridge in get_all_bridges(cfg):
- print bridge
+def cmd_list_br(cfg):
+ return get_all_bridges(cfg)
-def cmd_br_exists(bridge):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_br_exists(cfg, bridge):
if bridge not in get_all_bridges(cfg):
sys.exit(2)
-def cmd_list_ports(bridge):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_list_ports(cfg, bridge):
+ ports = []
parent, vlan = find_bridge(cfg, bridge)
for port in get_bridge_ports(cfg, parent, vlan):
if port != bridge:
- print port
+ ports.append(port)
+ return ports
def do_add_port(cfg, bridge, parent, port, vlan):
check_conflicts(cfg, port, "cannot create a port named %s" % port)
if vlan > 0:
cfg['vlan.%s.tag' % port] = [vlan]
-def cmd_add_port(bridge, port):
- cfg = cfg_read(VSWITCHD_CONF, True)
+def cmd_add_port(cfg, bridge, port):
parent, vlan = find_bridge(cfg, bridge)
do_add_port(cfg, bridge, parent, port, vlan)
- cfg_save(cfg, VSWITCHD_CONF)
-def cmd_add_bond(bridge, port, *slaves):
- cfg = cfg_read(VSWITCHD_CONF, True)
+def cmd_add_bond(cfg, bridge, port, *slaves):
parent, vlan = find_bridge(cfg, bridge)
do_add_port(cfg, bridge, parent, port, vlan)
cfg['bonding.%s.slave' % port] = list(slaves)
- cfg_save(cfg, VSWITCHD_CONF)
-def cmd_del_port(bridge, port):
- cfg = cfg_read(VSWITCHD_CONF, True)
- parent, vlan = find_bridge(cfg, bridge)
- if port not in get_bridge_ports(cfg, parent, vlan):
- if port in get_bridge_ports(cfg, parent, -1):
- raise Error("bridge %s does not have a port %s (although its parent bridge %s does)" % (bridge, port, parent))
- else:
- raise Error("bridge %s does not have a port %s" % (bridge, port))
+def cmd_del_port(cfg, *args):
+ if len(args) == 2:
+ bridge, port = args
+ parent, vlan = find_bridge(cfg, bridge)
+ if port not in get_bridge_ports(cfg, parent, vlan):
+ if port in get_bridge_ports(cfg, parent, -1):
+ raise Error("bridge %s does not have a port %s (although its parent bridge %s does)" % (bridge, port, parent))
+ else:
+ raise Error("bridge %s does not have a port %s" % (bridge, port))
+ else:
+ port, = args
+ if not port_to_bridge(cfg, port):
+ raise Error("no port %s on any bridge" % port)
del_port(cfg, port)
- cfg_save(cfg, VSWITCHD_CONF)
-def cmd_port_to_br(port):
- cfg = cfg_read(VSWITCHD_CONF)
- for bridge, parent, vlan in get_bridge_info(cfg):
- if port != bridge and port in get_bridge_ports(cfg, parent, vlan):
- print bridge
- return
- raise Error("no port named %s" % port)
+def cmd_port_to_br(cfg, port):
+ bridge = port_to_bridge(cfg, port)
+ if bridge:
+ return (bridge,)
+ else:
+ raise Error("no port named %s" % port)
-def cmd_list_ifaces(bridge):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_list_ifaces(cfg, bridge):
+ ifaces = []
parent, vlan = find_bridge(cfg, bridge)
for iface in get_bridge_ifaces(cfg, parent, vlan):
if iface != bridge:
- print iface
+ ifaces.append(iface)
+ return ifaces
-def cmd_iface_to_br(iface):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_iface_to_br(cfg, iface):
for bridge, parent, vlan in get_bridge_info(cfg):
if iface != bridge and iface in get_bridge_ifaces(cfg, parent, vlan):
- print bridge
- return
+ return (bridge,)
raise Error("no interface named %s" % iface)
-def cmd_br_to_vlan(bridge):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_br_to_vlan(cfg, bridge):
parent, vlan = find_bridge(cfg, bridge)
- print vlan
+ return (vlan,)
-def cmd_br_to_parent(bridge):
- cfg = cfg_read(VSWITCHD_CONF)
+def cmd_br_to_parent(cfg, bridge):
parent, vlan = find_bridge(cfg, bridge)
- print parent
+ return (parent,)
+cmdTable = {'add-br': (cmd_add_br, True, lambda n: n == 1 or n == 3),
+ 'del-br': (cmd_del_br, True, 1),
+ 'list-br': (cmd_list_br, False, 0),
+ 'br-exists': (cmd_br_exists, False, 1),
+ 'list-ports': (cmd_list_ports, False, 1),
+ 'add-port': (cmd_add_port, True, 2),
+ 'add-bond': (cmd_add_bond, True, lambda n: n >= 4),
+ 'del-port': (cmd_del_port, True, lambda n: n == 1 or n == 2),
+ 'port-to-br': (cmd_port_to_br, False, 1),
+ 'br-to-vlan': (cmd_br_to_vlan, False, 1),
+ 'br-to-parent': (cmd_br_to_parent, False, 1),
+ 'list-ifaces': (cmd_list_ifaces, False, 1),
+ 'iface-to-br': (cmd_iface_to_br, False, 1)}
+
+# Break up commands at -- boundaries.
+def split_commands(args):
+ commands = []
+ command = []
+ for arg in args:
+ if arg == '--':
+ if command:
+ commands.append(command)
+ command = []
+ else:
+ command.append(arg)
+ if command:
+ commands.append(command)
+ return commands
+
+def check_command(args):
+ command, args = args[0], args[1:]
+ if command not in cmdTable:
+ sys.stderr.write("%s: unknown command '%s' (use --help for help)\n"
+ % (argv0, command))
+ sys.exit(1)
+
+ function, is_mutator, nargs = cmdTable[command]
+ if callable(nargs) and not nargs(len(args)):
+ sys.stderr.write("%s: '%s' command does not accept %d arguments (use --help for help)\n" % (argv0, command, len(args)))
+ sys.exit(1)
+ elif not callable(nargs) and len(args) != nargs:
+ sys.stderr.write("%s: '%s' command takes %d arguments but %d were supplied (use --help for help)\n" % (argv0, command, nargs, len(args)))
+ sys.exit(1)
+
+def run_command(cfg, args):
+ command, args = args[0], args[1:]
+ function, need_lock, nargs = cmdTable[command]
+ return function(cfg, *args)
+
def main():
# Parse command line.
try:
- options, args = getopt.gnu_getopt(sys.argv[1:], "c:t:hV",
- ["config=",
- "target=",
- "no-reload",
- "no-syslog",
- "help",
- "version"])
+ options, args = getopt.getopt(sys.argv[1:], "c:t:hV",
+ ["config=",
+ "target=",
+ "no-reload",
+ "no-syslog",
+ "oneline",
+ "help",
+ "version"])
except getopt.GetoptError, msg:
sys.stderr.write("%s: %s (use --help for help)\n" % (argv0, msg))
sys.exit(1)
# Handle options.
+ oneline = False
for opt, optarg in options:
if opt == "-c" or opt == "--config":
global VSWITCHD_CONF
VSWITCHD_CONF = optarg
elif opt == "-t" or opt == "--target":
global VSWITCHD_TARGET
- if optarg[0] != '/':
- optarg = '@RUNDIR@/' + optarg
VSWITCHD_TARGET = optarg
elif opt == "--no-reload":
global RELOAD_VSWITCHD
elif opt == "--no-syslog":
global SYSLOG
SYSLOG = False
+ elif opt == "--oneline":
+ oneline = True
else:
raise RuntimeError("unhandled option %s" % opt)
syslog.openlog("ovs-vsctl")
log("Called as %s" % ' '.join(sys.argv[1:]))
- # Execute commands.
- if not args:
+ # Break arguments into a series of commands.
+ commands = split_commands(args)
+ if not commands:
sys.stderr.write("%s: missing command name (use --help for help)\n"
% argv0)
sys.exit(1)
- commands = {'add-br': (cmd_add_br, lambda n: n == 1 or n == 3),
- 'del-br': (cmd_del_br, 1),
- 'list-br': (cmd_list_br, 0),
- 'br-exists': (cmd_br_exists, 1),
- 'list-ports': (cmd_list_ports, 1),
- 'add-port': (cmd_add_port, 2),
- 'add-bond': (cmd_add_bond, lambda n: n >= 4),
- 'del-port': (cmd_del_port, 2),
- 'port-to-br': (cmd_port_to_br, 1),
- 'br-to-vlan': (cmd_br_to_vlan, 1),
- 'br-to-parent': (cmd_br_to_parent, 1),
- 'list-ifaces': (cmd_list_ifaces, 1),
- 'iface-to-br': (cmd_iface_to_br, 1)}
- command = args[0]
- args = args[1:]
- if command not in commands:
- sys.stderr.write("%s: unknown command '%s' (use --help for help)\n"
- % (argv0, command))
- sys.exit(1)
+ # Check command syntax.
+ need_lock = False
+ for command in commands:
+ check_command(command)
+ if cmdTable[command[0]][1]:
+ need_lock = True
- function, nargs = commands[command]
- if callable(nargs) and not nargs(len(args)):
- sys.stderr.write("%s: '%s' command does not accept %d arguments (use --help for help)\n" % (argv0, command, len(args)))
- sys.exit(1)
- elif not callable(nargs) and len(args) != nargs:
- sys.stderr.write("%s: '%s' command takes %d arguments but %d were supplied (use --help for help)\n" % (argv0, command, nargs, len(args)))
- sys.exit(1)
- else:
- function(*args)
- sys.exit(0)
+ # Execute commands.
+ cfg = cfg_read(VSWITCHD_CONF, need_lock)
+ for command in commands:
+ output = run_command(cfg, command)
+ if oneline:
+ if output == None:
+ output = ()
+ print '\\n'.join([str(s).replace('\\', '\\\\')
+ for s in output])
+ elif output != None:
+ for line in output:
+ print line
+ if need_lock:
+ cfg_save(cfg, VSWITCHD_CONF)
+ sys.exit(0)
if __name__ == "__main__":
try: