From 3b7940ffef06b2080c6293f8020dd106ef48bb5f Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:24:32 +0000 Subject: [PATCH 01/12] Minor import tidy. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/SrvDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 29e4c21ef0..0a20752100 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -16,10 +16,10 @@ import traceback import xen.lowlevel.xc -from xen.xend.server import SrvServer from xen.xend.XendLogging import log import relocate +import SrvServer from params import * From 6efef1afab1daf899eb718d9a04e1d4b393ee313 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:32:19 +0000 Subject: [PATCH 02/12] Make from_string('') return []. This means that it is not necessary for our callers to special-case this value -- the [] is a valid sxp. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/sxp.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/xend/sxp.py b/tools/python/xen/xend/sxp.py index 88a81cdc8a..551a8d3ec2 100644 --- a/tools/python/xen/xend/sxp.py +++ b/tools/python/xen/xend/sxp.py @@ -696,13 +696,16 @@ def to_string(sxpr): io.close() return val -def from_string(str): +def from_string(s): """Create an sxpr by parsing a string. - str string + s string returns sxpr """ - io = StringIO(str) + if s == '': + return [] + + io = StringIO(s) vals = parse(io) if vals is []: return None @@ -710,13 +713,13 @@ def from_string(str): return vals[0] -def all_from_string(str): +def all_from_string(s): """Create an sxpr list by parsing a string. - str string + s string returns sxpr list """ - io = StringIO(str) + io = StringIO(s) vals = parse(io) return vals From 91da6b2f1cfbf6e8c96a47a9fe659dc698fe59d0 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:32:50 +0000 Subject: [PATCH 03/12] Minor tidy. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/SrvServer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 38a06be9e3..0b75f32271 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -40,6 +40,7 @@ # todo Support command-line args. import fcntl +import time from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer @@ -48,7 +49,6 @@ from xen.xend import XendRoot from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.web.SrvDir import SrvDir -import time from SrvRoot import SrvRoot From 03bbc8cec68eab2973ae491f44bab08dd039f939 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:43:48 +0000 Subject: [PATCH 04/12] Added a hosts-allow facility to TCP connections, which allows us to restrict the acceptable connections based upon a regular expression comparison with the FQDN or the IP address. Use the hosts-allow facility to restrict access to the relocation socket. This adds the configuration option xend-relocation-hosts-allow, which takes a space-separated sequence of regular expressions. Pass the protocol class instance through to SocketServerConnection, rather than a new instance of that class. This means that the new instance need not be passed through SocketListener.acceptConnection. Make the SocketServerConnection and SocketListener classes start their corresponding threads and open their sockets (in the case of SocketListener) automatically. This means that callers do not need to save an instance locally, just to call run() or listen() on it. This also means that listenTCP and listenUnix can go -- simply creating a TCPListener or UnixListener instance is sufficient. Signed-off-by: Ewan Mellor --- tools/python/xen/web/connection.py | 61 +++++++++--------------- tools/python/xen/web/tcp.py | 41 +++++++++++----- tools/python/xen/web/unix.py | 19 ++++---- tools/python/xen/xend/XendRoot.py | 6 +++ tools/python/xen/xend/server/relocate.py | 13 ++++- 5 files changed, 77 insertions(+), 63 deletions(-) diff --git a/tools/python/xen/web/connection.py b/tools/python/xen/web/connection.py index 342e6a6f59..cc3660d538 100644 --- a/tools/python/xen/web/connection.py +++ b/tools/python/xen/web/connection.py @@ -19,7 +19,6 @@ import sys import threading -import select import socket import fcntl @@ -31,21 +30,17 @@ for TCP and unix-domain sockets (see tcp.py and unix.py). """ BUFFER_SIZE = 1024 +BACKLOG = 5 class SocketServerConnection: """An accepted connection to a server. """ - def __init__(self, sock, protocol, addr, server): + def __init__(self, sock, protocol_class): self.sock = sock - self.protocol = protocol - self.addr = addr - self.server = server + self.protocol = protocol_class() self.protocol.setTransport(self) - - - def run(self): threading.Thread(target=self.main).start() @@ -68,6 +63,10 @@ class SocketServerConnection: pass + def close(self): + self.sock.close() + + def write(self, data): self.sock.send(data) @@ -77,52 +76,38 @@ class SocketListener: Accepts connections and runs a thread for each one. """ - def __init__(self, protocol_class, backlog=None): - if backlog is None: - backlog = 5 + def __init__(self, protocol_class, hosts_allow = ''): self.protocol_class = protocol_class - self.sock = None - self.backlog = backlog - self.thread = None + self.sock = self.createSocket() + threading.Thread(target=self.main).start() + + + def close(self): + try: + self.sock.close() + except: + pass def createSocket(self): raise NotImplementedError() - def setCloExec(self): - fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC) - - def acceptConnection(self, sock, protocol, addr): - return SocketServerConnection(sock, protocol, addr, self) - - - def listen(self): - if self.sock or self.thread: - raise IOError("already listening") - self.sock = self.createSocket() - self.sock.listen(self.backlog) - self.run() - - - def run(self): - self.thread = threading.Thread(target=self.main) - self.thread.start() + raise NotImplementedError() def main(self): try: + fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC) + self.sock.listen(BACKLOG) + while True: try: (sock, addr) = self.sock.accept() - self.acceptConnection(sock, self.protocol_class(), - addr).run() + self.acceptConnection(sock, addr) except socket.error, ex: if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): break finally: - try: - self.sock.close() - except: - pass + self.close() diff --git a/tools/python/xen/web/tcp.py b/tools/python/xen/web/tcp.py index f3d67a7de4..552bf4a5cc 100644 --- a/tools/python/xen/web/tcp.py +++ b/tools/python/xen/web/tcp.py @@ -17,20 +17,25 @@ #============================================================================ +import errno +import re import socket import time -import errno -from connection import * +import connection + +from xen.xend.XendLogging import log -class TCPListener(SocketListener): +class TCPListener(connection.SocketListener): - def __init__(self, port, protocol, backlog=None, interface=''): - SocketListener.__init__(self, protocol, backlog=backlog) + def __init__(self, protocol_class, port, interface, hosts_allow): self.port = port self.interface = interface - + self.hosts_allow = hosts_allow + connection.SocketListener.__init__(self, protocol_class) + + def createSocket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -49,11 +54,23 @@ class TCPListener(SocketListener): else: raise - def acceptConnection(self, sock, protocol, addr): - return SocketServerConnection(sock, protocol, addr, self) + def acceptConnection(self, sock, addrport): + addr = addrport[0] + if self.hosts_allow is None: + connection.SocketServerConnection(sock, self.protocol_class) + else: + fqdn = socket.getfqdn(addr) + for h in self.hosts_allow: + if h.match(fqdn) or h.match(addr): + log.debug("Match %s %s", fqdn, h.pattern) + connection.SocketServerConnection(sock, + self.protocol_class) + return -def listenTCP(port, protocol, interface='', backlog=None): - l = TCPListener(port, protocol, interface=interface, backlog=backlog) - l.listen() - l.setCloExec() + try: + log.warn("Rejected connection from %s:%d (%s) for port %d.", + addr, addrport[1], fqdn, self.port) + sock.close() + except: + pass diff --git a/tools/python/xen/web/unix.py b/tools/python/xen/web/unix.py index 64ae2fcf1b..174e7284bc 100644 --- a/tools/python/xen/web/unix.py +++ b/tools/python/xen/web/unix.py @@ -21,15 +21,15 @@ import socket import os import os.path -from connection import * +import connection -class UnixListener(SocketListener): - - def __init__(self, path, protocol, backlog=None): - SocketListener.__init__(self, protocol, backlog=backlog) +class UnixListener(connection.SocketListener): + def __init__(self, path, protocol_class): self.path = path - + connection.SocketListener.__init__(self, protocol_class) + + def createSocket(self): pathdir = os.path.dirname(self.path) if not os.path.exists(pathdir): @@ -45,9 +45,6 @@ class UnixListener(SocketListener): sock.bind(self.path) return sock - def acceptConnection(self, sock, protocol, addr): - return SocketServerConnection(sock, protocol, self.path, self) - -def listenUNIX(path, protocol, backlog=None): - UnixListener(path, protocol, backlog=backlog).listen() + def acceptConnection(self, sock, _): + connection.SocketServerConnection(sock, self.protocol_class) diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index b61532737a..c806f75e2f 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -75,6 +75,8 @@ class XendRoot: """Default port xend serves relocation at. """ xend_relocation_port_default = '8002' + xend_relocation_hosts_allow_default = '' + """Default for the flag indicating whether xend should run a unix-domain server.""" xend_unix_server_default = 'yes' @@ -194,6 +196,10 @@ class XendRoot: """ return self.get_config_int('xend-relocation-port', self.xend_relocation_port_default) + def get_xend_relocation_hosts_allow(self): + return self.get_config_value("xend-relocation-hosts-allow", + self.xend_relocation_hosts_allow_default) + def get_xend_address(self): """Get the address xend listens at for its HTTP port. This defaults to the empty string which allows all hosts to connect. diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py index c20d577156..1b7ed157e9 100644 --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -16,6 +16,7 @@ # Copyright (C) 2005 XenSource Ltd #============================================================================ +import re import sys import StringIO @@ -116,8 +117,16 @@ def listenRelocation(): xroot = XendRoot.instance() if xroot.get_xend_unix_server(): path = '/var/lib/xend/relocation-socket' - unix.listenUNIX(path, RelocationProtocol) + unix.UnixListener(path, RelocationProtocol) if xroot.get_xend_relocation_server(): port = xroot.get_xend_relocation_port() interface = xroot.get_xend_relocation_address() - tcp.listenTCP(port, RelocationProtocol, interface=interface) + + hosts_allow = xroot.get_xend_relocation_hosts_allow() + if hosts_allow == '': + hosts_allow = None + else: + hosts_allow = map(re.compile, hosts_allow.split(" ")) + + tcp.TCPListener(RelocationProtocol, port, interface = interface, + hosts_allow = hosts_allow) From 151c1bdf9c8c4e5948e6ce54e9a0e1e51d3bf638 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:44:27 +0000 Subject: [PATCH 05/12] Squelch error message from iptables (we log this later if necessary). Signed-off-by: Ewan Mellor --- tools/examples/vif-common.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/examples/vif-common.sh b/tools/examples/vif-common.sh index 105a843900..8c997f0d99 100644 --- a/tools/examples/vif-common.sh +++ b/tools/examples/vif-common.sh @@ -62,7 +62,8 @@ function frob_iptable() local c="-D" fi - iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT || + iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT \ + 2>/dev/null || [ "$c" == "-D" ] || log err \ "iptables $c FORWARD -m physdev --physdev-in $vif $@ -j ACCEPT failed. From 742b21299eab57a95b5f8bd1afbbdc648ede28ae Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 16:48:24 +0000 Subject: [PATCH 06/12] Added xend-relocation-hosts-allow option. Signed-off-by: Ewan Mellor --- tools/examples/xend-config.sxp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 67387f02df..4fd6907575 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -40,7 +40,20 @@ # xend-relocation-server is set. # Meaning and default as for xend-address above. #(xend-relocation-address '') -(xend-relocation-address localhost) + +# The hosts allowed to talk to the relocation port. If this is empty (the +# default), then all connections are allowed (assuming that the connection +# arrives on a port and interface on which we are listening; see +# xend-relocation-port and xend-relocation-address above). Otherwise, this +# should be a space-separated sequence of regular expressions. Any host with +# a fully-qualified domain name or an IP address that matches one of these +# regular expressions will be accepted. +# +# For example: +# (xend-relocation-hosts-allow '^localhost$ ^.*\.example\.org$') +# +#(xend-relocation-hosts-allow '') +(xend-relocation-hosts-allow '^localhost$') # The limit (in kilobytes) on the size of the console buffer #(console-limit 1024) From 17d0f5bf1664d386844dd54e59701de0a6913c9a Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 12 Dec 2005 17:13:38 +0000 Subject: [PATCH 07/12] Read the domid and vifid from the store, rather than horribly slicing up the store path. Signed-off-by: Ewan Mellor --- tools/examples/vif-nat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index 9ce79f0434..b9e353f103 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -42,8 +42,8 @@ then fi -domid=$(echo "$XENBUS_PATH" | sed -n 's#.*/\([0-9]*\)/[0-9]*$#\1#p') -vifid=$(echo "$XENBUS_PATH" | sed -n 's#.*/[0-9]*/\([0-9]*\)$#\1#p') +domid=$(xenstore_read "$XENBUS_PATH/frontend-id") +vifid=$(xenstore_read "$XENBUS_PATH/handle") vifid=$(( $vifid + 1 )) From d1bab24950a4a8de0303fc9639b75a3a9a1a115d Mon Sep 17 00:00:00 2001 From: "rread@ubuntu.eng.hq.xensource.com" Date: Mon, 12 Dec 2005 11:45:53 -0700 Subject: [PATCH 08/12] Increase the default ramdisk size to 16384 to support SLES initrds. --- linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 568121224a..1995399ec1 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.6-xen -# Mon Nov 28 11:04:51 2005 +# Mon Dec 12 10:42:00 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -417,7 +417,7 @@ CONFIG_BLK_DEV_SX8=m # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_LBD=y @@ -2726,8 +2726,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS_XATTR=y CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y From 296749cb10305ccb132b4cc5d5bdee9038362e83 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 13 Dec 2005 00:10:19 +0000 Subject: [PATCH 09/12] Don't try and close the pipe to the grandparent if it has already been closed (i.e. we have restarted Xend). Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/SrvDaemon.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 0a20752100..866990caf8 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -167,8 +167,9 @@ class Daemon: while True: pid = self.fork_pid() if pid: - os.close(w) - w = False + if w is not None: + os.close(w) + w = None (_, status) = os.waitpid(pid, 0) From bc8ed50e6c00293264a8f3a312edc69767efe46d Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 13 Dec 2005 00:15:53 +0000 Subject: [PATCH 10/12] Deprecate the nics option from the xm create configuration. Instead, we use the entries in vif to guide the configuration. This is much less confusing. Closes bug #440. Change the example configuration files to match. Also change them to use the XenSource OUI in the MAC addresses. Also change xm-test to match. Remove the obsolete ipaddr configuration entry, and the backend_mac vif config option. Remove the preprocess_vifs function, folding it into the configure_vifs function, and creating a simple comma_sep_kv_to_dict helper. Remove the configure_vfr method, as it is unused. Signed-off-by: Ewan Mellor --- docs/src/user.tex | 9 +- tools/examples/xmexample.nbd | 4 +- tools/examples/xmexample.vmx | 4 +- tools/examples/xmexample.vti | 5 +- tools/examples/xmexample1 | 18 ++- tools/examples/xmexample2 | 18 ++- tools/examples/xmexample3 | 3 - tools/python/xen/xm/create.py | 121 ++++++++---------- tools/xm-test/lib/XmTestLib/XenDomain.py | 2 - .../tests/create/13_create_multinic_pos.py | 3 +- .../network/02_network_local_ping_pos.py | 2 +- .../tests/network/05_network_dom0_ping_pos.py | 2 +- .../tests/network/11_network_domU_ping_pos.py | 2 +- .../restore/04_restore_withdevices_pos.py | 4 +- 14 files changed, 92 insertions(+), 105 deletions(-) diff --git a/docs/src/user.tex b/docs/src/user.tex index 84f5089001..6e958e6075 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -1087,16 +1087,17 @@ for concrete examples. \item[vcpus] The number of virtual CPUs. \item[console] Port to export the domain console on (default 9600 + domain ID). -\item[nics] Number of virtual network interfaces. -\item[vif] List of MAC addresses (random addresses are assigned if not - given) and bridges to use for the domain's network interfaces, e.g.\ +\item[vif] Network interface configuration. This may simply contain +an empty string for each desired interface, or may override various +settings, e.g.\ \begin{verbatim} vif = [ 'mac=00:16:3E:00:00:11, bridge=xen-br0', 'bridge=xen-br1' ] \end{verbatim} to assign a MAC address and bridge to the first interface and assign a different bridge to the second interface, leaving \xend\ to choose - the MAC address. + the MAC address. The settings that may be overridden in this way are + type, mac, bridge, ip, script, backend, and vifname. \item[disk] List of block devices to export to the domain e.g. \verb_disk = [ 'phy:hda1,sda1,r' ]_ exports physical device \path{/dev/hda1} to the domain as diff --git a/tools/examples/xmexample.nbd b/tools/examples/xmexample.nbd index 274be6eb06..90dadc294d 100644 --- a/tools/examples/xmexample.nbd +++ b/tools/examples/xmexample.nbd @@ -12,9 +12,7 @@ kernel = "/boot/vmlinuz-2.6.13-15b-xen" ramdisk = "/boot/initrd-2.6.13-15b-xen" memory = 128 name = "nbd4" -nics=1 -# Please change MAC -vif = [ 'mac=aa:cc:10:10:00:a0, bridge=xenbr0' ] +vif = [ '' ] # Please change PORT disk = [ 'nbd:134.100.233.115 20004,hda1,w' ] dhcp = "dhcp" diff --git a/tools/examples/xmexample.vmx b/tools/examples/xmexample.vmx index 8b694e32fe..9030b06117 100644 --- a/tools/examples/xmexample.vmx +++ b/tools/examples/xmexample.vmx @@ -37,9 +37,7 @@ vcpus=1 # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -# nics default is 1 -#vif = [ 'type=ioemu, mac=aa:00:00:00:00:11, bridge=xenbr0' ] -nics=1 +#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ] # type=ioemu specify the NIC is an ioemu device not netfront vif = [ 'type=ioemu, bridge=xenbr0' ] diff --git a/tools/examples/xmexample.vti b/tools/examples/xmexample.vti index 5722eb0699..2daa58ca39 100644 --- a/tools/examples/xmexample.vti +++ b/tools/examples/xmexample.vti @@ -28,12 +28,9 @@ name = "ExampleVMXDomain" #cpus = "0" # all vcpus run on CPU0 #cpus = "0-3,5,^1" # run on cpus 0,2,3,5 -# Disable vif for now -nics=0 - # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] +#vif = [ 'mac=00:16:3e:00:00:11, bridge=xen-br0' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmexample1 b/tools/examples/xmexample1 index 4e7fb4d72f..8985ff2582 100644 --- a/tools/examples/xmexample1 +++ b/tools/examples/xmexample1 @@ -33,12 +33,20 @@ name = "ExampleDomain" #---------------------------------------------------------------------------- # Define network interfaces. -# Number of network interfaces. Default is 1. -#nics=1 +# By default, no network interfaces are configured. You may have one created +# with sensible defaults using an empty vif clause: +# +# vif = [ '' ] +# +# or optionally override backend, bridge, ip, mac, script, type, or vifname: +# +# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ] +# +# or more than one interface may be configured: +# +# vif = [ '', 'bridge=xenbr1' ] -# Optionally define mac and/or bridge for the network interfaces. -# Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ] +vif = [ '' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmexample2 b/tools/examples/xmexample2 index 6a562a9609..ff39c4e7d9 100644 --- a/tools/examples/xmexample2 +++ b/tools/examples/xmexample2 @@ -64,12 +64,20 @@ vcpus = 4 # make your domain a 4-way #---------------------------------------------------------------------------- # Define network interfaces. -# Number of network interfaces. Default is 1. -#nics=1 +# By default, no network interfaces are configured. You may have one created +# with sensible defaults using an empty vif clause: +# +# vif = [ '' ] +# +# or optionally override backend, bridge, ip, mac, script, type, or vifname: +# +# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ] +# +# or more than one interface may be configured: +# +# vif = [ '', 'bridge=xenbr1' ] -# Optionally define mac and/or bridge for the network interfaces. -# Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ] +vif = [ '' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmexample3 b/tools/examples/xmexample3 index cdb993a2ff..bf20dd4862 100644 --- a/tools/examples/xmexample3 +++ b/tools/examples/xmexample3 @@ -60,9 +60,6 @@ cpus = "%s" % vmid # set based on vmid (mod number of CPUs) #---------------------------------------------------------------------------- # Define network interfaces. -# Number of network interfaces. Default is 1. -#nics=1 - # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 622bea9b18..e82ff6cc91 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -253,17 +253,12 @@ gopts.var('usb', val='PATH', use="""Add a physical USB port to a domain, as specified by the path to that port. This option may be repeated to add more than one port.""") -gopts.var('ipaddr', val="IPADDR", - fn=append_value, default=[], - use="Add an IP address to the domain.") - -gopts.var('vif', val="type=TYPE,mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM,vifname=NAME", +gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,backend=DOM,vifname=NAME", fn=append_value, default=[], use="""Add a network interface with the given MAC address and bridge. The vif is configured by calling the given configuration script. If type is not specified, default is netfront not ioemu device. If mac is not specified a random MAC address is used. - The MAC address of the backend interface can be selected with be_mac. If not specified then the network backend chooses it's own MAC address. If bridge is not specified the first bridge found is used. If script is not specified the default script is used. @@ -284,8 +279,10 @@ gopts.var('vtpm', val="instance=INSTANCE,backend=DOM", given domain.""") gopts.var('nics', val="NUM", - fn=set_int, default=1, - use="""Set the number of network interfaces. + fn=set_int, default=-1, + use="""DEPRECATED. Use empty vif entries instead. + + Set the number of network interfaces. Use the vif option to define interface parameters, otherwise defaults are used. Specifying vifs will increase the number of interfaces as needed.""") @@ -487,58 +484,38 @@ def configure_vtpm(config_devs, vals): config_vtpm.append(['backend', backend]) config_devs.append(['device', config_vtpm]) + def configure_vifs(config_devs, vals): """Create the config for virtual network interfaces. """ - vifs = vals.vif - vifs_n = max(vals.nics, len(vifs)) - for idx in range(0, vifs_n): - if idx < len(vifs): - d = vifs[idx] - mac = d.get('mac') - be_mac = d.get('be_mac') - bridge = d.get('bridge') - script = d.get('script') - backend = d.get('backend') - ip = d.get('ip') - vifname = d.get('vifname') - type = d.get('type') - else: - mac = None - be_mac = None - bridge = None - script = None - backend = None - ip = None - vifname = None - type = None + vifs = vals.vif + vifs_n = len(vifs) + + if hasattr(vals, 'nics'): + if vals.nics > 0: + warn("The nics option is deprecated. Please use an empty vif " + "entry instead:\n\n vif = [ '' ]\n") + for _ in range(vifs_n, vals.nics): + vifs.append('') + vifs_n = len(vifs) + elif vals.nics == 0: + warn("The nics option is deprecated. Please remove it.") + + for c in vifs: + d = comma_sep_kv_to_dict(c) config_vif = ['vif'] - if mac: - config_vif.append(['mac', mac]) - if vifname: - config_vif.append(['vifname', vifname]) - if be_mac: - config_vif.append(['be_mac', be_mac]) - if bridge: - config_vif.append(['bridge', bridge]) - if script: - config_vif.append(['script', script]) - if backend: - config_vif.append(['backend', backend]) - if ip: - config_vif.append(['ip', ip]) - if type: - config_vif.append(['type', type]) + + def f(k): + if k not in ['backend', 'bridge', 'ip', 'mac', 'script', 'type', + 'vifname']: + err('Invalid vif option: ' + k) + + config_vif.append([k, d[k]]) + + map(f, d.keys()) config_devs.append(['device', config_vif]) -def configure_vfr(config, vals): - if not vals.ipaddr: return - config_vfr = ['vfr'] - idx = 0 # No way of saying which IP is for which vif? - for ip in vals.ipaddr: - config_vfr.append(['vif', ['id', idx], ['ip', ip]]) - config.append(config_vfr) def configure_vmx(config_image, vals): """Create the config for VMX devices. @@ -649,22 +626,6 @@ def preprocess_ioports(vals): ioports.append(hexd) vals.ioports = ioports -def preprocess_vifs(vals): - if not vals.vif: return - vifs = [] - for vif in vals.vif: - d = {} - a = vif.split(',') - for b in a: - (k, v) = b.strip().split('=', 1) - k = k.strip() - v = v.strip() - if k not in ['type', 'mac', 'be_mac', 'bridge', 'script', 'backend', 'ip', 'vifname']: - err('Invalid vif specifier: ' + vif) - d[k] = v - vifs.append(d) - vals.vif = vifs - def preprocess_vtpm(vals): if not vals.vtpm: return vtpms = [] @@ -766,12 +727,30 @@ def preprocess(vals): preprocess_disk(vals) preprocess_pci(vals) preprocess_ioports(vals) - preprocess_vifs(vals) preprocess_ip(vals) preprocess_nfs(vals) preprocess_vnc(vals) preprocess_vtpm(vals) - + + +def comma_sep_kv_to_dict(c): + """Convert comma-separated, equals-separated key-value pairs into a + dictionary. + """ + d = {} + c = c.strip() + if len(c) > 0: + a = c.split(',') + for b in a: + if b.find('=') == -1: + err("%s should be a pair, separated by an equals sign." % b) + (k, v) = b.split('=', 1) + k = k.strip() + v = v.strip() + d[k] = v + return d + + def make_domain(opts, config): """Create, build and start a domain. diff --git a/tools/xm-test/lib/XmTestLib/XenDomain.py b/tools/xm-test/lib/XmTestLib/XenDomain.py index 4ea9c66f93..05ad6b36dc 100644 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py @@ -203,7 +203,6 @@ class XmTestVmxDomain(XenDomain): # Defaults self.defaults = {"memory" : 64, "vcpus" : 1, - "nics" : 0, "kernel" : "/usr/lib/xen/boot/vmxloader", "builder" : "\'vmx\'", "name" : name or self.getUniqueName() @@ -264,7 +263,6 @@ class XmTestPvDomain(XenDomain): # Defaults self.defaults = {"memory" : 64, "vcpus" : 1, - "nics" : 0, "kernel" : getDefaultKernel(), "root" : "/dev/ram0", "name" : name or self.getUniqueName(), diff --git a/tools/xm-test/tests/create/13_create_multinic_pos.py b/tools/xm-test/tests/create/13_create_multinic_pos.py index 810bf9829c..0c5c659469 100644 --- a/tools/xm-test/tests/create/13_create_multinic_pos.py +++ b/tools/xm-test/tests/create/13_create_multinic_pos.py @@ -6,7 +6,8 @@ from XmTestLib import * for i in range(0,10): - domain = XmTestDomain(extraOpts={"nics":"%i" % i}) + domain = XmTestDomain() + domain.configSetVar('vif', str(['' for _ in range(0, i)])) try: domain.start() diff --git a/tools/xm-test/tests/network/02_network_local_ping_pos.py b/tools/xm-test/tests/network/02_network_local_ping_pos.py index a904d49dd9..510711ae23 100644 --- a/tools/xm-test/tests/network/02_network_local_ping_pos.py +++ b/tools/xm-test/tests/network/02_network_local_ping_pos.py @@ -28,7 +28,7 @@ ip = Net.ip("dom1", "eth0") mask = Net.mask("dom1", "eth0") # Fire up a guest domain w/1 nic -domain = XmTestDomain(extraOpts={ 'nics' : 1 }) +domain = XmTestDomain() try: domain.configSetVar('vif', " [ 'ip=" + ip + "' ]") domain.start() diff --git a/tools/xm-test/tests/network/05_network_dom0_ping_pos.py b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py index b252c2d3ed..84e6be058a 100644 --- a/tools/xm-test/tests/network/05_network_dom0_ping_pos.py +++ b/tools/xm-test/tests/network/05_network_dom0_ping_pos.py @@ -31,7 +31,7 @@ except NetworkError, e: FAIL(str(e)) # Fire up a guest domain w/1 nic -domain = XmTestDomain(extraOpts={ 'nics' : 1 }) +domain = XmTestDomain() try: domain.configSetVar('vif', " [ 'ip=" + ip + "' ]") domain.start() diff --git a/tools/xm-test/tests/network/11_network_domU_ping_pos.py b/tools/xm-test/tests/network/11_network_domU_ping_pos.py index ca3fe35793..5ac8021562 100644 --- a/tools/xm-test/tests/network/11_network_domU_ping_pos.py +++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py @@ -21,7 +21,7 @@ from XmTestLib import * def netDomain(ip): - dom = XmTestDomain(extraOpts={ 'nics' : 1 }) + dom = XmTestDomain() try: dom.configSetVar('vif', " [ 'ip=" + ip + "' ]") dom.start() diff --git a/tools/xm-test/tests/restore/04_restore_withdevices_pos.py b/tools/xm-test/tests/restore/04_restore_withdevices_pos.py index 0b82943142..af290f4b8b 100644 --- a/tools/xm-test/tests/restore/04_restore_withdevices_pos.py +++ b/tools/xm-test/tests/restore/04_restore_withdevices_pos.py @@ -7,7 +7,9 @@ from XmTestLib import * import re -domain = XmTestDomain(extraOpts={"nics":2}) +domain = XmTestDomain() + +domain.configSetVar('vif', "[ '', '' ]") domain.configAddDisk("phy:/dev/ram0", "hda1", "w") domain.configAddDisk("phy:/dev/ram1", "hdb2", "w") From b57b530e0a709d9b2e37c7782c6a145aef68ee2e Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 13 Dec 2005 00:56:50 +0000 Subject: [PATCH 11/12] Match previous changeset removing nics option. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/tests/test_create.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/xm/tests/test_create.py b/tools/python/xen/xm/tests/test_create.py index cd10def073..d65666ad9f 100644 --- a/tools/python/xen/xm/tests/test_create.py +++ b/tools/python/xen/xm/tests/test_create.py @@ -36,7 +36,7 @@ class test_create(unittest.TestCase): (fd, fname) = tempfile.mkstemp() os.close(fd) self.t('-f %s kernel=/mykernel display=fakedisplay ' - 'macaddr=ab:cd:ef:ed nics=0' % fname, + 'macaddr=ab:cd:ef:ed' % fname, { 'name' : os.path.basename(fname), 'xm_file' : fname, 'defconfig' : fname, @@ -50,6 +50,7 @@ class test_create(unittest.TestCase): 'interface' : 'eth0', 'path' : '.:/etc/xen', 'builder' : 'linux', + 'nics' : -1, }) @@ -62,7 +63,6 @@ kernel = "/boot/vmlinuz-xenU-smp" memory = 768 name = "dom1" vcpus = 4 -nics = 1 disk = ['phy:/dev/virt-blkdev-backend/dom1,sda1,w', 'phy:/dev/virt-blkdev-backend/usr,sda2,r'] root = "/dev/sda1 ro" @@ -79,7 +79,7 @@ on_crash = 'destroy' 'memory' : 768, 'name' : 'dom1', 'vcpus' : 4, - 'nics' : 1, + 'nics' : -1, 'root' : '/dev/sda1 ro', 'extra' : ' profile=1 GATEWAY=10.0.1.254 NETMASK=255.255.0.0 IPADDR=10.0.134.1 HOSTNAME=dom1', 'on_poweroff' : 'destroy', @@ -118,7 +118,7 @@ cpu_weight = 0.75 finally: os.close(fd) - self.t('-f %s display=fakedisplay macaddr=ab:cd:ef:ed nics=0' % + self.t('-f %s display=fakedisplay macaddr=ab:cd:ef:ed' % fname, { 'name' : 'testname', 'xm_file' : fname, @@ -137,6 +137,7 @@ cpu_weight = 0.75 'interface' : 'eth0', 'path' : '.:/etc/xen', 'builder' : 'linux', + 'nics' : -1, }) From adec4de13140bc12f8820b0c092bee5f49b2638e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 13 Dec 2005 03:47:47 +0100 Subject: [PATCH 12/12] Fix rx buffer allocation in netfront. The final allocation size was ending up bigger than PAGE_SIZE. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 5fd59bc9f5..3115c5dafa 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -540,8 +540,8 @@ static void network_alloc_rx_buffers(struct net_device *dev) * tailroom then round down to SKB_DATA_ALIGN boundary. */ skb = alloc_xen_skb( - (PAGE_SIZE - 16 - sizeof(struct skb_shared_info)) & - (-SKB_DATA_ALIGN(1))); + ((PAGE_SIZE - sizeof(struct skb_shared_info)) & + (-SKB_DATA_ALIGN(1))) - 16); if (skb == NULL) break; __skb_queue_tail(&np->rx_batch, skb);