aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/xenmgr/lib/EventServer.py3
-rw-r--r--tools/xenmgr/lib/XendClient.py29
-rw-r--r--tools/xenmgr/lib/XendConsole.py2
-rw-r--r--tools/xenmgr/lib/XendDomain.py61
-rw-r--r--tools/xenmgr/lib/XendDomainInfo.py56
-rw-r--r--tools/xenmgr/lib/server/SrvConsoleServer.py50
-rwxr-xr-xtools/xenmgr/lib/server/blkif.py28
-rwxr-xr-xtools/xenmgr/lib/server/controller.py4
-rw-r--r--tools/xenmgr/lib/server/messages.py28
-rwxr-xr-xtools/xenmgr/lib/server/netif.py13
-rw-r--r--tools/xenmgr/lib/xm/create.py71
-rw-r--r--tools/xenmgr/lib/xm/main.py81
-rw-r--r--tools/xenmgr/lib/xm/opts.py1
-rw-r--r--tools/xenmgr/lib/xm/shutdown.py11
-rw-r--r--tools/xenmgr/netfix5
15 files changed, 262 insertions, 181 deletions
diff --git a/tools/xenmgr/lib/EventServer.py b/tools/xenmgr/lib/EventServer.py
index 9749e119fb..6fae2b9ccf 100644
--- a/tools/xenmgr/lib/EventServer.py
+++ b/tools/xenmgr/lib/EventServer.py
@@ -85,7 +85,8 @@ class EventServer:
hl = self.handlers.get(event)
if hl is None:
return
- hl.remove(handler)
+ if handler in hl:
+ hl.remove(handler)
def inject(self, event, val):
"""Inject an event. Handlers for it are called if runing, otherwise
diff --git a/tools/xenmgr/lib/XendClient.py b/tools/xenmgr/lib/XendClient.py
index 76f49f49bd..7eec62290f 100644
--- a/tools/xenmgr/lib/XendClient.py
+++ b/tools/xenmgr/lib/XendClient.py
@@ -244,29 +244,12 @@ class Xend:
return xend_get(self.domainurl(id),
{ 'op' : 'vifs' })
- def xend_domain_vif_stats(self, id, vif):
- return xend_get(self.domainurl(id),
- { 'op' : 'vif_stats',
- 'vif' : vif})
-
def xend_domain_vif_ip_add(self, id, vif, ipaddr):
return xend_call(self.domainurl(id),
{'op' : 'vif_ip_add',
'vif' : vif,
'ip' : ipaddr })
- def xend_domain_vif_scheduler_set(id, vif, bytes, usecs):
- return xend_call(self.domainurl(id),
- {'op' : 'vif_scheduler_set',
- 'vif' : vif,
- 'bytes' : bytes,
- 'usecs' : usecs })
-
- def xend_domain_vif_scheduler_get(id, vif):
- return xend_get(self.domainurl(id),
- {'op' : 'vif_scheduler_get',
- 'vif' : vif})
-
def xend_domain_vbds(self, id):
return xend_get(self.domainurl(id),
{'op' : 'vbds'})
@@ -276,18 +259,6 @@ class Xend:
{'op' : 'vbd',
'vbd' : vbd})
-## def xend_domain_vbd_add(self, id, uname, dev, mode):
-## return xend_call(self.domainurl(id),
-## {'op' : 'vbd_add',
-## 'uname' : uname,
-## 'dev' : dev,
-## 'mode' : mode})
-
-## def xend_domain_vbd_remove(self, id, dev):
-## return xend_call(self.domainurl(id),
-## {'op' : 'vbd_remove',
-## 'dev' : dev})
-
def xend_consoles(self):
return xend_get(self.consoleurl())
diff --git a/tools/xenmgr/lib/XendConsole.py b/tools/xenmgr/lib/XendConsole.py
index 041e6c4d44..19ad7eeae3 100644
--- a/tools/xenmgr/lib/XendConsole.py
+++ b/tools/xenmgr/lib/XendConsole.py
@@ -104,8 +104,10 @@ class XendConsole:
self._delete_console(c.id)
def onDomainDied(self, event, val):
+ print 'onDomainDied', "dom=", dom,
dom = int(val)
for c in self.consoles():
+ print 'onDomainDied', "dom=", dom, "dom1=", c.dom1, "dom2=", c.dom2
if (c.dom1 == dom) or (c.dom2 == dom):
self._delete_console(c.id)
diff --git a/tools/xenmgr/lib/XendDomain.py b/tools/xenmgr/lib/XendDomain.py
index 94afe3e87d..9ed3c6370d 100644
--- a/tools/xenmgr/lib/XendDomain.py
+++ b/tools/xenmgr/lib/XendDomain.py
@@ -18,6 +18,9 @@ import XendDomainInfo
import XendConsole
import EventServer
+from xenmgr.server import SrvConsoleServer
+xend = SrvConsoleServer.instance()
+
eserver = EventServer.instance()
__all__ = [ "XendDomain" ]
@@ -49,15 +52,16 @@ class XendDomain:
def initial_refresh(self):
"""Refresh initial domain info from domain_db.
"""
- print "initial_refresh> db=", self.domain_db.values()
+ print "initial_refresh>"
+ for d in self.domain_db.values(): print 'db dom=', d
domlist = xc.domain_getinfo()
- print "doms=", domlist
+ for d in domlist: print 'xc dom=', d
doms = {}
for d in domlist:
domid = str(d['dom'])
doms[domid] = d
for config in self.domain_db.values():
- domid = int(sxp.child_value(config, 'id'))
+ domid = str(sxp.child_value(config, 'id'))
print "dom=", domid, "config=", config
if domid in doms:
print "dom=", domid, "new"
@@ -141,7 +145,7 @@ class XendDomain:
config = None
image = None
newinfo = XendDomainInfo.XendDomainInfo(
- config, d['dom'], d['name'], d['mem_kb']/1024, image)
+ config, d['dom'], d['name'], d['mem_kb']/1024, image=image, info=d)
self._add_domain(newinfo.id, newinfo)
# Remove entries for domains that no longer exist.
for d in self.domain.values():
@@ -193,13 +197,13 @@ class XendDomain:
"""
dom = int(id)
eserver.inject('xend.domain.start', id)
- return xc.domain_start(dom=dom)
+ return xend.domain_start(dom)
def domain_stop(self, id):
"""Stop domain running.
"""
dom = int(id)
- return xc.domain_stop(dom=dom)
+ return xend.domain_stop(dom)
def domain_shutdown(self, id):
"""Shutdown domain (nicely).
@@ -208,7 +212,7 @@ class XendDomain:
if dom <= 0:
return 0
eserver.inject('xend.domain.shutdown', id)
- val = xc.domain_destroy(dom=dom, force=0)
+ val = xend.domain_destroy(dom, force=0)
self.refresh()
return val
@@ -219,7 +223,7 @@ class XendDomain:
if dom <= 0:
return 0
eserver.inject('xend.domain.halt', id)
- val = xc.domain_destroy(dom=dom, force=1)
+ val = xend.domain_destroy(dom, force=1)
self.refresh()
return val
@@ -247,21 +251,6 @@ class XendDomain:
self._add_domain(dominfo.id, dominfo)
return dominfo
- def domain_device_add(self, id, info):
- """Add a device to a domain.
- """
- pass
-
- def domain_device_remove(self, id, dev):
- """Delete a device from a domain.
- """
- pass
-
- def domain_device_configure(self, id, dev, info):
- """Configure a domain device.
- """
- pass
-
#============================================================================
# Backward compatibility stuff from here on.
@@ -297,23 +286,10 @@ class XendDomain:
if not dominfo: return None
return dominfo.get_device_by_index(vif)
- def domain_vif_stats(self, dom, vif):
- dom = int(dom)
- return xc.vif_stats_get(dom=dom, vif=vif)
-
def domain_vif_ip_add(self, dom, vif, ip):
dom = int(dom)
return xenctl.ip.setup_vfr_rules_for_vif(dom, vif, ip)
- def domain_vif_scheduler_set(self, dom, vif, bytes, usecs):
- dom = int(dom)
- return xc.xc_vif_scheduler_set(dom=dom, vif=vif,
- credit_bytes=bytes, credit_usecs=usecs)
-
- def domain_vif_scheduler_get(self, dom, vif):
- dom = int(dom)
- return xc.vif_scheduler_get(dom=dom, vif=vif)
-
def domain_vbd_ls(self, dom):
dominfo = self.domain_get(dom)
if not dominfo: return []
@@ -329,19 +305,6 @@ class XendDomain:
return v
return None
-## def domain_vbd_add(self, dom, uname, dev, mode):
-## dom = int(dom)
-## vbd = vm.make_disk(dom, uname, dev, mode)
-## return vbd
-
-## def domain_vbd_remove(self, dom, dev):
-## dom = int(dom)
-## vbd = xenctl.vdisk.blkdev_name_to_number(dev)
-## if vbd < 0: return vbd
-## err = xc.vbd_destroy(dom, vbd)
-## if err < 0: return err
-## return vbd
-
def domain_shadow_control(self, dom, op):
dom = int(dom)
return xc.shadow_control(dom, op)
diff --git a/tools/xenmgr/lib/XendDomainInfo.py b/tools/xenmgr/lib/XendDomainInfo.py
index 61a9b21c5a..f05397c169 100644
--- a/tools/xenmgr/lib/XendDomainInfo.py
+++ b/tools/xenmgr/lib/XendDomainInfo.py
@@ -28,6 +28,9 @@ xendConsole = XendConsole.instance()
import server.SrvConsoleServer
xend = server.SrvConsoleServer.instance()
+SIF_BLK_BE_DOMAIN = (1<<4)
+SIF_NET_BE_DOMAIN = (1<<5)
+
def readlines(fd):
"""Version of readlines safe against EINTR.
"""
@@ -59,7 +62,7 @@ class VmError(ValueError):
class XendDomainInfo:
"""Virtual machine object."""
- def __init__(self, config, dom, name, memory, image=None, console=None):
+ def __init__(self, config, dom, name, memory, image=None, console=None, info=None):
"""Construct a virtual machine object.
config configuration
@@ -78,8 +81,10 @@ class XendDomainInfo:
self.console = console
self.devices = {}
self.configs = []
- self.info = None
+ self.info = info
self.ipaddrs = []
+ self.block_controller = 0
+ self.net_controller = 0
#todo: state: running, suspended
self.state = 'running'
@@ -329,23 +334,28 @@ def xen_domain_create(config, ostype, name, memory, kernel, ramdisk, cmdline, vi
vifs_n number of network interfaces
returns vm
"""
+ flags = 0
if not os.path.isfile(kernel):
raise VmError('Kernel image does not exist: %s' % kernel)
if ramdisk and not os.path.isfile(ramdisk):
raise VMError('Kernel ramdisk does not exist: %s' % ramdisk)
cpu = int(sxp.child_value(config, 'cpu', '-1'))
+ print 'xen_domain_create> create ', memory, name, cpu
dom = xc.domain_create(mem_kb= memory * 1024, name= name, cpu= cpu)
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d kernel=%s'
% (name, memory, kernel))
console = xendConsole.console_create(dom)
buildfn = getattr(xc, '%s_build' % ostype)
+
+ print 'xen_domain_create> build ', ostype, dom, kernel, cmdline, ramdisk
err = buildfn(dom = dom,
image = kernel,
control_evtchn = console.port2,
cmdline = cmdline,
- ramdisk = ramdisk)
+ ramdisk = ramdisk,
+ flags = flags)
if err != 0:
raise VmError('Building domain failed: type=%s dom=%d err=%d'
% (ostype, dom, err))
@@ -528,6 +538,18 @@ def vm_create_devices(vm, config):
print '<vm_create_devices'
return deferred
+def config_controllers(vm, config):
+ for c in sxp.children(config, 'controller'):
+ name = sxp.name(c)
+ if name == 'block':
+ vm.block_controller = 1
+ xend.blkif_set_control_domain(vm.dom)
+ elif name == 'net':
+ vm.net_controller = 1
+ xend.netif_set_control_domain(vm.dom)
+ else:
+ raise VmError('invalid controller type:' + str(name))
+
def vm_configure(vm, config):
"""Configure a vm.
@@ -536,7 +558,12 @@ def vm_configure(vm, config):
returns Deferred - calls callback with vm
"""
- d = xend.blkif_create(vm.dom)
+ config_controllers(vm, config)
+ if vm.block_controller:
+ d = defer.Deferred()
+ d.callback(1)
+ else:
+ d = xend.blkif_create(vm.dom)
d.addCallback(_vm_configure1, vm, config)
return d
@@ -653,8 +680,11 @@ def vm_dev_vif(vm, val, index):
val vif config
index vif index
"""
+ if vm.net_controller:
+ raise VmError('vif: vif in control domain')
vif = index #todo
vmac = sxp.child_value(val, "mac")
+ bridge = sxp.child_value(val, "bridge") # todo
defer = make_vif(vm.dom, vif, vmac)
def fn(id):
dev = val + ['vif', vif]
@@ -671,6 +701,8 @@ def vm_dev_vbd(vm, val, index):
val vbd config
index vbd index
"""
+ if vm.block_controller:
+ raise VmError('vbd: vbd in control domain')
uname = sxp.child_value(val, 'uname')
if not uname:
raise VMError('vbd: Missing uname')
@@ -686,6 +718,16 @@ def vm_dev_vbd(vm, val, index):
defer.addCallback(fn)
return defer
+def parse_pci(val):
+ if isinstance(val, StringType):
+ radix = 10
+ if val.startswith('0x') or val.startswith('0X'):
+ radix = 16
+ v = int(val, radix)
+ else:
+ v = val
+ return v
+
def vm_dev_pci(vm, val, index):
bus = sxp.child_value(val, 'bus')
if not bus:
@@ -697,9 +739,9 @@ def vm_dev_pci(vm, val, index):
if not func:
raise VMError('pci: Missing func')
try:
- bus = int(bus, 16)
- dev = int(dev, 16)
- func = int(func, 16)
+ bus = parse_pci(bus)
+ dev = parse_pci(dev)
+ func = parse_pci(func)
except:
raise VMError('pci: invalid parameter')
rc = xc.physdev_pci_access_modify(dom=vm.dom, bus=bus, dev=dev, func=func, enable=1)
diff --git a/tools/xenmgr/lib/server/SrvConsoleServer.py b/tools/xenmgr/lib/server/SrvConsoleServer.py
index 88f3964811..6059ef2ebf 100644
--- a/tools/xenmgr/lib/server/SrvConsoleServer.py
+++ b/tools/xenmgr/lib/server/SrvConsoleServer.py
@@ -21,6 +21,8 @@ from twisted.internet import protocol
from twisted.internet import abstract
from twisted.internet import defer
+import Xc; xc = Xc.new()
+
import xend.utils
from xenmgr import sxp
@@ -289,6 +291,12 @@ class EventProtocol(protocol.Protocol):
else:
self.send_error()
+ def loseConnection(self):
+ if self.transport:
+ self.transport.loseConnection()
+ if self.connected:
+ reactor.callLater(0, self.connectionLost)
+
def connectionLost(self, reason=None):
self.unsubscribe()
@@ -559,6 +567,16 @@ class Daemon:
reactor.diconnectAll()
sys.exit(0)
+ def blkif_set_control_domain(self, dom):
+ """Set the block device backend control domain.
+ """
+ return self.blkifCF.setControlDomain(dom)
+
+ def blkif_get_control_domain(self, dom):
+ """Get the block device backend control domain.
+ """
+ return self.blkifCF.getControlDomain()
+
def blkif_create(self, dom):
"""Create a block device interface controller.
@@ -579,6 +597,16 @@ class Daemon:
d = ctrl.attach_device(vdev, mode, segment)
return d
+ def netif_set_control_domain(self, dom):
+ """Set the network interface backend control domain.
+ """
+ return self.netifCF.setControlDomain(dom)
+
+ def netif_get_control_domain(self, dom):
+ """Get the network interface backend control domain.
+ """
+ return self.netifCF.getControlDomain()
+
def netif_create(self, dom):
"""Create a network interface controller.
@@ -622,6 +650,28 @@ class Daemon:
if console.conn:
console.conn.loseConnection()
+ def domain_start(self, id):
+ """Start domain running.
+ """
+ dom = int(id)
+ if dom <= 0: return 0
+ return xc.domain_start(dom=dom)
+
+ def domain_stop(self, id):
+ """Stop domain running.
+ """
+ dom = int(id)
+ if dom <= 0: return 0
+ xc.domain_stop(dom=dom)
+
+ def domain_destroy(self, id, force=0):
+ """Destroy a domain. Shutdown if force=0, terminate immediately if force=1.
+ """
+ dom = int(id)
+ if dom <= 0: return 0
+ return xc.domain_destroy(dom=dom, force=force)
+
+
def instance():
global inst
try:
diff --git a/tools/xenmgr/lib/server/blkif.py b/tools/xenmgr/lib/server/blkif.py
index ae2736da43..7ffa35179d 100755
--- a/tools/xenmgr/lib/server/blkif.py
+++ b/tools/xenmgr/lib/server/blkif.py
@@ -34,9 +34,9 @@ class BlkifControllerFactory(controller.ControllerFactory):
return d
def setControlDomain(self, dom):
- if self.channel:
- self.deregisterChannel()
- self.attached = 0
+ if self.dom == dom: return
+ self.deregisterChannel()
+ self.attached = 0
self.dom = dom
self.registerChannel()
#
@@ -44,6 +44,9 @@ class BlkifControllerFactory(controller.ControllerFactory):
# xend.blkif.recovery = True
#xend.blkif.be_port = xend.main.port_from_dom(dom)
+ def getControlDomain(self):
+ return self.dom
+
def recv_be_create(self, msg, req):
#print 'recv_be_create>'
val = unpackMsg('blkif_be_create_t', msg)
@@ -81,15 +84,20 @@ class BlkifControllerFactory(controller.ControllerFactory):
blkif = self.getInstanceByDom(dom)
if blkif:
blkif.reattach_device(vdev)
+ self.attached = self.devices_attached()
+ if self.attached:
+ self.reattached()
+
+ def devices_attached(self):
+ """Check if all devices are attached.
+ """
attached = 1
for blkif in self.getInstances():
if not blkif.attached:
attached = 0
break
- self.attached = attached
- if self.attached:
- self.reattached()
-
+ return attached
+
def reattached(self):
for blkif in self.getInstances():
blkif.reattached()
@@ -149,12 +157,16 @@ class BlkifController(controller.Controller):
return self.factory.addDeferred()
def detach(self):
+ """Detach all devices, when the back-end control domain has changed.
+ """
self.attached = 0
for dev in self.devices.values():
dev.attached = 0
self.send_be_vbd_create(vdev)
def reattach_device(self, vdev):
+ """Reattach a device, when the back-end control domain has changed.
+ """
dev = self.devices[vdev]
dev.attached = 1
attached = 1
@@ -166,6 +178,8 @@ class BlkifController(controller.Controller):
return self.attached
def reattached(self):
+ """All devices have been reattached after the back-end control domain has changed.
+ """
msg = packMsg('blkif_fe_interface_status_changed_t',
{ 'handle' : 0,
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
diff --git a/tools/xenmgr/lib/server/controller.py b/tools/xenmgr/lib/server/controller.py
index 793ac85968..23b0f7fde1 100755
--- a/tools/xenmgr/lib/server/controller.py
+++ b/tools/xenmgr/lib/server/controller.py
@@ -37,9 +37,7 @@ class CtrlMsgRcvr:
def registerChannel(self):
self.channel = self.channelFactory.domChannel(self.dom)
- #print 'registerChannel> channel=', self.channel, self
self.idx = self.channel.getIndex()
- #print 'registerChannel> idx=', self.idx
if self.majorTypes:
self.channel.registerDevice(self.majorTypes, self)
@@ -90,7 +88,7 @@ class ControllerFactory(CtrlMsgRcvr):
return None
def delInstance(self, instance):
- if instance in self.instances:
+ if instance.idx in self.instances:
del self.instances[instance.idx]
def createInstance(self, dom):
diff --git a/tools/xenmgr/lib/server/messages.py b/tools/xenmgr/lib/server/messages.py
index f918e5d440..649629105c 100644
--- a/tools/xenmgr/lib/server/messages.py
+++ b/tools/xenmgr/lib/server/messages.py
@@ -142,6 +142,34 @@ netif_formats = {
msg_formats.update(netif_formats)
#============================================================================
+CMSG_SUSPEND = 5
+CMSG_SHUTDOWN = 6
+
+CMSG_SHUTDOWN_HALT = 0
+CMSG_SHUTDOWN_POWEROFF = 1
+CMSG_SHUTDOWN_REBOOT = 2
+
+STOPCODE_shutdown = 0
+STOPCODE_reboot = 1
+STOPCODE_suspend = 2
+
+ctrlif_formats = {
+ 'ctrlif_suspend_t':
+ (CMSG_SUSPEND, 0, "??"),
+
+ 'ctrlif_shutdown_halt_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_HALT, "??"),
+
+ 'ctrlif_shutdown_poweroff_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_POWEROFF, "??"),
+
+ 'ctrlif_shutdown_reboot_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_REBOOT, "??"),
+ }
+
+msg_formats.update(ctrlif_formats)
+
+#============================================================================
class Msg:
pass
diff --git a/tools/xenmgr/lib/server/netif.py b/tools/xenmgr/lib/server/netif.py
index 7403054409..13bdd96486 100755
--- a/tools/xenmgr/lib/server/netif.py
+++ b/tools/xenmgr/lib/server/netif.py
@@ -35,6 +35,7 @@ class NetifControllerFactory(controller.ControllerFactory):
def setControlDomain(self, dom):
"""Set the 'back-end' device driver domain.
"""
+ if self.dom == dom: return
self.deregisterChannel()
self.attached = 0
self.dom = dom
@@ -44,7 +45,9 @@ class NetifControllerFactory(controller.ControllerFactory):
# xend.netif.recovery = True
# xend.netif.be_port = xend.main.port_from_dom(dom)
#
- pass
+
+ def getControlDomain(self):
+ return self.dom
def recv_be_create(self, msg, req):
self.callDeferred(0)
@@ -64,6 +67,8 @@ class NetifControllerFactory(controller.ControllerFactory):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
status = val['status']
if status == NETIF_DRIVER_STATUS_UP and not self.attached:
+ # If we are not attached the driver domain was changed, and
+ # this signals the new driver domain is ready.
for netif in self.getInstances():
netif.reattach_devices()
self.attached = 1
@@ -149,6 +154,8 @@ class NetifController(controller.Controller):
return d
def reattach_devices(self):
+ """Reattach all devices when the back-end control domain has changed.
+ """
d = self.factory.addDeferred()
self.send_be_create(vif)
self.attach_fe_devices(0)
@@ -182,10 +189,6 @@ class NetifController(controller.Controller):
'rx_shmem_frame' : val['rx_shmem_frame'] })
self.factory.writeRequest(msg)
- #def recv_fe_interface_status_changed(self):
- # print 'recv_fe_interface_status_changed>'
- # pass
-
def send_interface_connected(self, vif):
dev = self.devices[vif]
msg = packMsg('netif_fe_interface_status_changed_t',
diff --git a/tools/xenmgr/lib/xm/create.py b/tools/xenmgr/lib/xm/create.py
index 863227ad4c..3843007a10 100644
--- a/tools/xenmgr/lib/xm/create.py
+++ b/tools/xenmgr/lib/xm/create.py
@@ -7,28 +7,28 @@ from xenmgr.XendClient import server
from xenmgr.xm.opts import *
-opts = Opts(use="""[options]
+gopts = Opts(use="""[options]
Create a domain.
""")
-opts.opt('help', short='h',
+gopts.opt('help', short='h',
fn=set_value, default=0,
use="Print this help.")
-opts.opt('quiet', short='q',
+gopts.opt('quiet', short='q',
fn=set_true, default=0,
use="Quiet.")
-opts.opt('path', val='PATH',
+gopts.opt('path', val='PATH',
fn=set_value, default='.:/etc/xc',
use="Search path for default scripts.")
-opts.opt('defaults', short='f', val='FILE',
+gopts.opt('defaults', short='f', val='FILE',
fn=set_value, default='xmdefaults',
use="Use the given default script.")
-opts.opt('config', short='F', val='FILE',
+gopts.opt('config', short='F', val='FILE',
fn=set_value, default=None,
use='Domain configuration to use.')
@@ -38,102 +38,103 @@ def set_var(opt, k, v):
(k, v) = string.split(d, '=')
opt.opts.setvar(k, v)
-opts.opt('define', short='D', val='VAR=VAL',
+gopts.opt('define', short='D', val='VAR=VAL',
fn=set_var, default=None,
use="""Set variables before loading defaults, e.g. '-D vmid=3;ip=1.2.3.4'
to set vmid and ip.""")
-opts.opt('dryrun', short='n',
+gopts.opt('dryrun', short='n',
fn=set_true, default=0,
use="Dry run - print the config but don't create the domain.")
-opts.opt('console', short='c',
+gopts.opt('console', short='c',
fn=set_true, default=0,
use="Connect to console after domain is created.")
-opts.opt('kernel', short='k', val='FILE',
+gopts.opt('kernel', short='k', val='FILE',
+ fn=set_value, default=None,
use="Path to kernel image.")
-opts.opt('ramdisk', short='r', val='FILE',
+gopts.opt('ramdisk', short='r', val='FILE',
fn=set_value, default='',
use="Path to ramdisk.")
-opts.opt('builder', short='b', val='FUNCTION',
+gopts.opt('builder', short='b', val='FUNCTION',
fn=set_value, default='linux',
use="Function to use to build the domain.")
-opts.opt('memory', short='m', val='MEMORY',
+gopts.opt('memory', short='m', val='MEMORY',
fn=set_value, default=128,
use="Domain memory in MB.")
-opts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
+gopts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
fn=append_value, default=[],
use="""Add a disk device to a domain. The physical device is DEV, which
is exported to the domain as VDEV. The disk is read-only if MODE is r,
read-write if mode is 'w'.""")
-opts.opt('pci', val='BUS,DEV,FUNC',
+gopts.opt('pci', val='BUS,DEV,FUNC',
fn=append_value, default=[],
- use="""Add a PCI device to a domain.""")
+ use="""Add a PCI device to a domain, using given params (in hex).""")
-opts.opt('ipaddr', short='i', val="IPADDR",
+gopts.opt('ipaddr', short='i', val="IPADDR",
fn=append_value, default=[],
use="Add an IP address to the domain.")
-opts.opt('mac', short='M', val="MAC",
+gopts.opt('mac', short='M', val="MAC",
fn=append_value, default=[],
use="""Add a network interface with the given mac address to the domain.
More than one interface may be specified. Interfaces with unspecified MAC addresses
are allocated a random address.""")
-opts.opt('nics', val="N",
+gopts.opt('nics', val="N",
fn=set_int, default=1,
use="Set the number of network interfaces.")
-opts.opt('vnet', val='VNET',
+gopts.opt('vnet', val='VNET',
fn=append_value, default=[],
use="""Define the vnets for the network interfaces.
More than one vnet may be given, they are used in order.
""")
-opts.opt('root', short='R', val='DEVICE',
+gopts.opt('root', short='R', val='DEVICE',
fn=set_value, default='',
use="""Set the root= parameter on the kernel command line.
Use a device, e.g. /dev/sda1, or /dev/nfs for NFS root.""")
-opts.opt('extra', short='E', val="ARGS",
+gopts.opt('extra', short='E', val="ARGS",
fn=set_value, default='',
use="Set extra arguments to append to the kernel command line.")
-opts.opt('ip', short='I', val='IPADDR',
+gopts.opt('ip', short='I', val='IPADDR',
fn=set_value, default='',
use="Set the kernel IP interface address.")
-opts.opt('gateway', val="IPADDR",
+gopts.opt('gateway', val="IPADDR",
fn=set_value, default='',
use="Set kernel IP gateway.")
-opts.opt('netmask', val="MASK",
+gopts.opt('netmask', val="MASK",
fn=set_value, default = '',
use="Set kernel IP netmask.")
-opts.opt('hostname', val="NAME",
+gopts.opt('hostname', val="NAME",
fn=set_value, default='',
use="Set kernel IP hostname.")
-opts.opt('interface', val="INTF",
+gopts.opt('interface', val="INTF",
fn=set_value, default="eth0",
use="Set the kernel IP interface name.")
-opts.opt('dhcp', val="off|dhcp",
+gopts.opt('dhcp', val="off|dhcp",
fn=set_value, default='off',
use="Set kernel dhcp option.")
-opts.opt('nfs_server', val="IPADDR",
+gopts.opt('nfs_server', val="IPADDR",
fn=set_value, default=None,
use="Set the address of the NFS server for NFS root.")
-opts.opt('nfs_root', val="PATH",
+gopts.opt('nfs_root', val="PATH",
fn=set_value, default=None,
use="Set the path of the root NFS directory.")
@@ -160,7 +161,7 @@ def make_config(opts):
config_image.append(['ip', cmdline_ip])
if opts.root:
cmdline_root = strip('root=', opts.root)
- config_image.append(['root', opts.root])
+ config_image.append(['root', cmdline_root])
if opts.extra:
config_image.append(['args', opts.extra])
config.append(['image', config_image ])
@@ -221,7 +222,9 @@ def preprocess_pci(opts):
d = v.split(',')
if len(d) != 3:
opts.err('Invalid pci specifier: ' + v)
- pci.append(d)
+ # Components are in hex: add hex specifier.
+ hexd = map(lambda v: '0x'+v, d)
+ pci.append(hexd)
opts.pci = pci
def preprocess_ip(opts):
@@ -247,6 +250,8 @@ def preprocess_nfs(opts):
opts.extra = nfs + ' ' + opts.extra
def preprocess(opts):
+ if not opts.kernel:
+ opts.err("No kernel specified")
preprocess_disk(opts)
preprocess_pci(opts)
preprocess_ip(opts)
@@ -278,6 +283,7 @@ def make_domain(opts, config):
return (dom, console_port)
def main(argv):
+ opts = gopts
args = opts.parse(argv)
if opts.config:
pass
@@ -285,6 +291,7 @@ def main(argv):
opts.load_defaults()
if opts.help:
opts.usage()
+ return
preprocess(opts)
config = make_config(opts)
if opts.dryrun:
diff --git a/tools/xenmgr/lib/xm/main.py b/tools/xenmgr/lib/xm/main.py
index 4c70717521..32a7be879b 100644
--- a/tools/xenmgr/lib/xm/main.py
+++ b/tools/xenmgr/lib/xm/main.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
-import string
import sys
+from xenmgr import PrettyPrint
from xenmgr import sxp
from xenmgr.XendClient import server
from xenmgr.xm import create, shutdown
@@ -39,7 +39,7 @@ class Xm:
def help(self, meth, args):
name = meth[3:]
f = getattr(self, meth)
- print "%s\t%s" % (name, f.__doc__ or '')
+ print "%-14s %s" % (name, f.__doc__ or '')
def xm_help(self, help, args):
"""Print help."""
@@ -69,12 +69,14 @@ class Xm:
print args[0], "FILE"
print "\nRestore a domain from FILE."
if len(args) < 2: self.err("%s: Missing file" % args[0])
- server.xend_domain_restore(dom, None, filename)
+ filename = args[1]
+ server.xend_domain_restore(None, filename)
- def xm_ls(self, help, args):
+ def xm_domains(self, help, args):
"""List domains."""
- if help: self.help('xm_' + args[0]); return
+ if help: self.help('xm_' + args[0], args); return
doms = server.xend_domains()
+ doms.sort()
print 'Dom Name Mem(MB) CPU State Time(s)'
for dom in doms:
info = server.xend_domain(dom)
@@ -85,7 +87,19 @@ class Xm:
d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
d['state'] = sxp.child_value(info, 'state', '??')
d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
- print ("%(dom)-4d %(name)-16s %(mem)4d %(cpu)3d %(state)5s %(cpu_time)10.2f" % d)
+ print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f" % d)
+
+ def xm_domain(self, help, args):
+ """Get information about a domain."""
+ if help:
+ print args[0], 'DOM'
+ print '\nGet information about domain DOM.'
+ return
+ if len(args) < 2: self.err("%s: Missing domain" % args[0])
+ dom = args[1]
+ info = server.xend_domain(dom)
+ PrettyPrint.prettyprint(info)
+ print
def xm_halt(self, help, args):
"""Terminate a domain immediately."""
@@ -101,8 +115,8 @@ class Xm:
"""Shutdown a domain."""
shutdown.main(args)
- def xm_stop(self, help, args):
- """Stop execution of a domain."""
+ def xm_pause(self, help, args):
+ """Pause execution of a domain."""
if help:
print args[0], 'DOM'
print '\nStop execution of domain DOM.'
@@ -111,11 +125,11 @@ class Xm:
dom = args[1]
server.xend_domain_stop(dom)
- def xm_start(self, help, args):
- """Start execution of a domain."""
+ def xm_unpause(self, help, args):
+ """Unpause a paused domain."""
if help:
print args[0], 'DOM'
- print '\nStart execution of domain DOM.'
+ print '\nUnpause execution of domain DOM.'
return
if len(args) < 2: self.err("%s: Missing domain" % args[0])
dom = args[1]
@@ -131,32 +145,6 @@ class Xm:
v = map(int, args[1:3])
server.xend_domain_pincpu(*v)
- def xm_vif_stats(self, help, args):
- """Get stats for a virtual interface."""
- if help:
- print args[0], 'DOM VIF'
- print '\nGet stats for interface VIF on domain DOM.'
- return
- if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
- v = map(int, args[1:3])
- print server.xend_domain_vif_stats(*v)
-
- def xm_vif_rate(self, help, args):
- """Set or get vif rate params."""
- if help:
- print args[0], "DOM VIF [BYTES USECS]"
- print '\nSet or get rate controls for interface VIF on domain DOM.'
- return
- n = len(args)
- if n == 3:
- v = map(int, args[1:n])
- print server.xend_domain_vif_scheduler_get(*v)
- elif n == 5:
- v = map(int, args[1:n])
- server.xend_domain_vif_scheduler_set(*v)
- else:
- self.err("%s: Invalid argument(s)" % args[0])
-
def xm_bvt(self, help, args):
"""Set BVT scheduler parameters."""
if help:
@@ -193,16 +181,29 @@ class Xm:
print "\nSet round robin scheduler slice."
return
if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
- slice = int(args[1])
- server.xend_node_rrobin_set(slice)
+ rrslice = int(args[1])
+ server.xend_node_rrobin_set(rrslice)
def xm_info(self, help, args):
"""Get information about the xen host."""
- if help: self.help('xm_info'); return
+ if help: self.help('xm_' + args[0], args); return
info = server.xend_node()
for x in info[1:]:
print "%-23s:" % x[0], x[1]
+ def xm_consoles(self, help, args):
+ """Get information about domain consoles."""
+ if help: self.help('xm_' + args[0], args); return
+ l = server.xend_consoles()
+ print "Dom Port Id"
+ for x in l:
+ info = server.xend_console(x)
+ d = {}
+ d['dom'] = sxp.child(info, 'dst', ['dst', '?', '?'])[1]
+ d['port'] = sxp.child_value(info, 'port', '?')
+ d['id'] = sxp.child_value(info, 'id', '?')
+ print "%(dom)3s %(port)4s %(id)3s" % d
+
def xm_console(self, help, args):
"""Open a console to a domain."""
if help:
diff --git a/tools/xenmgr/lib/xm/opts.py b/tools/xenmgr/lib/xm/opts.py
index 7b32daeae2..426a6d24d1 100644
--- a/tools/xenmgr/lib/xm/opts.py
+++ b/tools/xenmgr/lib/xm/opts.py
@@ -91,6 +91,7 @@ class Opts:
self._vals = {}
self._globals = {}
self._locals = {}
+ self.quiet = 0
def opt(self, name, **args):
x = Opt(self, name, **args)
diff --git a/tools/xenmgr/lib/xm/shutdown.py b/tools/xenmgr/lib/xm/shutdown.py
index 805af2929d..8c7a517e96 100644
--- a/tools/xenmgr/lib/xm/shutdown.py
+++ b/tools/xenmgr/lib/xm/shutdown.py
@@ -5,19 +5,19 @@ import time
from xenmgr.XendClient import server
from xenmgr.xm.opts import *
-opts = Opts(use="""[options] [DOM]
+gopts = Opts(use="""[options] [DOM]
Shutdown one or more domains gracefully.""")
-opts.opt('help', short='h',
+gopts.opt('help', short='h',
fn=set_value, default=0,
use="Print this help.")
-opts.opt('all', short='a',
+gopts.opt('all', short='a',
fn=set_true, default=0,
use="Shutdown all domains.")
-opts.opt('wait', short='w',
+gopts.opt('wait', short='w',
fn=set_true, default=0,
use='Wait for shutdown to complete.')
@@ -28,7 +28,7 @@ def shutdown(opts, doms, wait):
if 0 in doms:
doms.remove(0)
for d in doms:
- server.xend_domain_shutdown(dom)
+ server.xend_domain_shutdown(d)
if wait:
while doms:
alive = domains()
@@ -55,6 +55,7 @@ def main_dom(opts, args):
shutdown(opts, [ domid ], opts.wait)
def main(argv):
+ opts = gopts
args = opts.parse(argv)
if opts.help:
opts.usage()
diff --git a/tools/xenmgr/netfix b/tools/xenmgr/netfix
index 26c965260d..65c354490d 100644
--- a/tools/xenmgr/netfix
+++ b/tools/xenmgr/netfix
@@ -85,11 +85,10 @@ def reconfigure(interface, bridge):
if not intf_info['gateway']:
print 'Gateway not found: ', interface
return
- cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info)
cmd(CMD_IFCONFIG, '%(bridge)s %(address)s netmask %(mask)s broadcast %(broadcast)s up' % intf_info)
cmd(CMD_ROUTE, 'add default gateway %(gateway)s dev %(bridge)s' % intf_info)
- if os.path.exists(CMD_BRCTL):
- cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info)
+ cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info)
+ cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info)
defaults = {
'interface': 'eth0',