mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.946.1.3 (40c9c475sJLMEuc6TqUt-bX6hVFOpQ)
Add source tree for the management utils.
This commit is contained in:
1 parent
9eb865c540
commit
8b980d633c
57 files changed
+8896
-2
No files matched your search
Executable
+233
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
import os
|
||||
import os.path
|
||||
import signal
|
||||
|
||||
from xenmgr.XendClient import server
|
||||
|
||||
# usage: xc_dom_control [command] <params>
|
||||
#
|
||||
# this script isn't very smart, but it'll do for now.
|
||||
#
|
||||
|
||||
def usage (rc=0):
|
||||
if rc:
|
||||
out = sys.stderr
|
||||
else:
|
||||
out = sys.stdout
|
||||
print >> out, """
|
||||
Usage: %s [command] <params>
|
||||
|
||||
help -- print usage
|
||||
stop [dom] -- pause a domain
|
||||
start [dom] -- un-pause a domain
|
||||
shutdown [dom] [[-w]] -- request a domain to shutdown (can specify 'all')
|
||||
(optionally wait for complete shutdown)
|
||||
destroy [dom] -- immediately terminate a domain
|
||||
pincpu [dom] [cpu] -- pin a domain to the specified CPU
|
||||
suspend [dom] [file] -- write domain's memory to a file and terminate
|
||||
(resume by re-running xc_dom_create with -L option)
|
||||
unwatch [dom] -- kill the auto-restart daemon for a domain
|
||||
list -- print info about all domains
|
||||
listvbds -- print info about all virtual block devs
|
||||
cpu_bvtset [dom] [mcuadv] [warp] [warpl] [warpu]
|
||||
-- set BVT scheduling parameters for domain
|
||||
cpu_bvtslice [slice] -- set default BVT scheduler slice
|
||||
cpu_atropos_set [dom] [period] [slice] [latency] [xtratime]
|
||||
-- set Atropos scheduling parameters for domain
|
||||
cpu_rrobin_slice [slice] -- set Round Robin scheduler slice
|
||||
vif_stats [dom] [vif] -- get stats for a given network vif
|
||||
vif_addip [dom] [vif] [ip] -- add an IP address to a given vif
|
||||
vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth
|
||||
vif_getsched [dom] [vif] -- print vif's scheduling parameters
|
||||
vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to
|
||||
domain as dev e.g. 'vbd_add 2 phy:sda3 hda1 w'
|
||||
vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev'
|
||||
""" % sys.argv[0]
|
||||
if rc: sys.exit(rc)
|
||||
|
||||
if len(sys.argv) < 2: usage(1)
|
||||
cmd = sys.argv[1]
|
||||
|
||||
#todo: replace all uses of xc with the new api.
|
||||
import Xc; xc = Xc.new()
|
||||
|
||||
rc = ''
|
||||
dom = None
|
||||
|
||||
|
||||
def auto_restart_pid_file(dom):
|
||||
# The auto-restart daemon's pid file.
|
||||
return '/var/run/xendomains/%d.pid' % dom
|
||||
|
||||
def auto_restart_pid(dom):
|
||||
watcher = auto_restart_pid_file(dom)
|
||||
if os.path.isfile(watcher):
|
||||
fd = open(watcher,'r')
|
||||
pid = int(fd.readline())
|
||||
else:
|
||||
pid = None
|
||||
return pid
|
||||
|
||||
def auto_restart_kill(dom):
|
||||
#todo: replace this - tell xend not to restart any more.
|
||||
# Kill a domain's auto restart daemon.
|
||||
pid = auto_restart_pid(dom)
|
||||
if pid:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
|
||||
|
||||
if len( sys.argv ) > 2 and re.match('\d+$', sys.argv[2]):
|
||||
dom = long(sys.argv[2])
|
||||
|
||||
if cmd == "help":
|
||||
usage()
|
||||
|
||||
elif cmd == 'stop':
|
||||
rc = server.xend_domain_stop(dom)
|
||||
|
||||
elif cmd == 'start':
|
||||
rc = server.xend_domain_start(dom)
|
||||
|
||||
elif cmd == 'shutdown':
|
||||
doms = []
|
||||
shutdown = []
|
||||
if dom != None:
|
||||
doms = [ dom ]
|
||||
elif sys.argv[2] == 'all':
|
||||
doms = server.xend_domains()
|
||||
doms.remove('0')
|
||||
for d in doms:
|
||||
ret = server.xend_domain_shutdown(d)
|
||||
if ret == 0:
|
||||
shutdown.append(d)
|
||||
else:
|
||||
rc = ret
|
||||
|
||||
wait = (len(sys.argv) == 4 and sys.argv[3] == "-w")
|
||||
if wait:
|
||||
# wait for all domains we shut down to terminate
|
||||
for dom in shutdown:
|
||||
while True:
|
||||
info = server.xend_domain(dom)
|
||||
if not info: break
|
||||
time.sleep(1)
|
||||
|
||||
elif cmd == 'destroy':
|
||||
rc = server.xend_domain_halt(dom)
|
||||
|
||||
elif cmd == 'pincpu':
|
||||
if len(sys.argv) < 4: usage(1)
|
||||
cpu = int(sys.argv[3])
|
||||
rc = server.xend_domain_pincpu(dom, cpu)
|
||||
|
||||
elif cmd == 'list':
|
||||
print 'Dom Name Mem(MB) CPU State Time(s)'
|
||||
for dom in server.xend_domains():
|
||||
info = server.xend_domain(dom)
|
||||
d = {}
|
||||
d['dom'] = dom
|
||||
d['name'] = sxp.get_child_value(info, 'name', '??')
|
||||
d['mem'] = int(sxp.get_child_value(info, 'memory', '0'))
|
||||
d['cpu'] = int(sxp.get_child_value(info, 'cpu', '0'))
|
||||
d['state'] = sxp.get_child_value(info, 'state', '??')
|
||||
d['cpu_time'] = sxp.get_child_value(info, 'cpu_time', '0')
|
||||
print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)8d"
|
||||
% d)
|
||||
|
||||
elif cmd == 'unwatch':
|
||||
auto_restart_kill(dom)
|
||||
|
||||
elif cmd == 'listvbds':
|
||||
print 'Dom Dev Mode Size(MB)'
|
||||
for dom in server.xend_domains():
|
||||
for vbd in server.xend_domain_vbds(dom):
|
||||
info = server.xend_domain_vbd(vbd)
|
||||
v['vbd'] = vbd
|
||||
v['size'] = int(sxp.get_child_value(info, 'size', '0'))
|
||||
v['mode'] = sxp.get_child_value(info, 'mode', '??')
|
||||
vbd['size_mb'] = vbd['nr_sectors'] / 2048
|
||||
print ('%(dom)-4d %(vbd)04x %(mode)-2s %(size)d' % v)
|
||||
|
||||
elif cmd == 'suspend':
|
||||
if len(sys.argv) < 4: usage(1)
|
||||
file = os.path.abspath(sys.argv[3])
|
||||
auto_restart_kill(dom)
|
||||
rc = server.xend_domain_save(dom, file, progress=1)
|
||||
|
||||
elif cmd == 'cpu_bvtslice':
|
||||
if len(sys.argv) < 3: usage(1)
|
||||
slice = sys.argv[2]
|
||||
rc = server.xend_node_cpu_bvt_slice_set(slice)
|
||||
|
||||
elif cmd == 'cpu_bvtset':
|
||||
if len(sys.argv) < 7: usage(1)
|
||||
(mcuadv, warp, warpl, warpu) = map(int, sys.argv[3:7])
|
||||
|
||||
rc = server.xend_domain_cpu_bvt_set(dom, mcuadv, warp, warpl, warpu)
|
||||
|
||||
elif cmd == 'vif_stats':
|
||||
if len(sys.argv) < 4: usage(1)
|
||||
vif = int(sys.argv[3])
|
||||
|
||||
print server.xend_domain_vif_stats(dom, vif)
|
||||
|
||||
elif cmd == 'vif_addip':
|
||||
if len(sys.argv) < 5: usage(1)
|
||||
vif = int(sys.argv[3])
|
||||
ip = sys.argv[4]
|
||||
rc = server.xend_domain_vif_addip(dom, vif, ip)
|
||||
|
||||
elif cmd == 'vif_setsched':
|
||||
if len(sys.argv) < 6: usage(1)
|
||||
(vif, bytes, usecs) = map(int, sys.argv[3:6])
|
||||
rc = server.xend_domain_vif_scheduler_set(dom, vif, bytes, usecs)
|
||||
|
||||
elif cmd == 'vif_getsched':
|
||||
if len(sys.argv) < 4: usage(1)
|
||||
vif = int(sys.argv[3])
|
||||
print server.xend_domain_vif_scheduler_get(dom, vif)
|
||||
|
||||
elif cmd == 'vbd_add':
|
||||
if len(sys.argv) < 6: usage(1)
|
||||
uname = sys.argv[3]
|
||||
dev = sys.argv[4]
|
||||
mode = sys.argv[5]
|
||||
try:
|
||||
vbd = server.xend_domain_vbd_add(dom, uname, dev, mode)
|
||||
except StandardError, ex:
|
||||
print "Error:", ex
|
||||
sys.exit(1)
|
||||
print "Added disk/partition %s to domain %d as device %s (%x)" % (uname, dom, dev, vbd)
|
||||
|
||||
elif cmd == 'vbd_remove':
|
||||
if len(sys.argv) < 4: usage(1)
|
||||
dev = sys.argv[3]
|
||||
vbd = server.xend_domain_vbd_remove(dom, dev)
|
||||
if vbd < 0:
|
||||
print "Failed"
|
||||
sys.exit(1)
|
||||
else:
|
||||
print "Removed disk/partition attached as device %s (%x) in domain %d" % (dev, vbd, dom)
|
||||
|
||||
elif cmd == 'cpu_atropos_set': # args: dom period slice latency xtratime
|
||||
if len(sys.argv) < 6: usage(1)
|
||||
(period, slice, latency, xtratime) = map(int, sys.argv[3:7])
|
||||
rc = server.xend_domain_cpu_atropos_set(
|
||||
dom, period, slice, latency, xtratime)
|
||||
|
||||
elif cmd == 'cpu_rrobin_slice':
|
||||
if len(sys.argv) < 3: usage(1)
|
||||
slice = int(sys.argv[2])
|
||||
rc = server.xend_node_rrobin_set(slice=slice)
|
||||
|
||||
else:
|
||||
usage(1)
|
||||
|
||||
if rc != '':
|
||||
print "return code %d" % rc
|
||||
Executable
+402
@@ -0,0 +1,402 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import string
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import time
|
||||
import socket
|
||||
import getopt
|
||||
import signal
|
||||
import syslog
|
||||
|
||||
import xenctl.console_client
|
||||
|
||||
from xenmgr import sxp
|
||||
from xenmgr import PrettyPrint
|
||||
from xenmgr.XendClient import server
|
||||
|
||||
config_dir = '/etc/xc/'
|
||||
config_file = xc_config_file = config_dir + 'defaults'
|
||||
|
||||
def main_usage ():
|
||||
print >>sys.stderr,"""
|
||||
Usage: %s <args>
|
||||
|
||||
This tool is used to create and start new domains. It reads defaults
|
||||
from a file written in Python, having allowed variables to be set and
|
||||
passed into the file. Further command line arguments allow the
|
||||
defaults to be overridden. The defaults for each parameter are listed
|
||||
in [] brackets. Arguments are as follows:
|
||||
|
||||
Arguments to control the parsing of the defaults file:
|
||||
-f config_file -- Use the specified defaults script.
|
||||
Default: ['%s']
|
||||
-L state_file -- Load virtual machine memory state from state_file
|
||||
-D foo=bar -- Set variable foo=bar before parsing config
|
||||
E.g. '-D vmid=3;ip=1.2.3.4'
|
||||
-h -- Print extended help message, including all arguments
|
||||
-n -- Dry run only, don't actually create domain
|
||||
Prints the config, suitable for -F.
|
||||
-q -- Quiet - write output only to the system log
|
||||
-F domain_config -- Build domain using the config in the file.
|
||||
Suitable files can be made using '-n' to output a config.
|
||||
""" % (sys.argv[0], xc_config_file)
|
||||
|
||||
def extra_usage ():
|
||||
print >>sys.stderr,"""
|
||||
Arguments to override current config read from '%s':
|
||||
-c -- Turn into console terminal after domain is created
|
||||
-k image -- Path to kernel image ['%s']
|
||||
-r ramdisk -- Path to ramdisk (or empty) ['%s']
|
||||
-b builder_fn -- Function to use to build domain ['%s']
|
||||
-m mem_size -- Initial memory allocation in MB [%dMB]
|
||||
-N domain_name -- Set textual name of domain ['%s']
|
||||
-a auto_restart -- Restart domain on exit, yes/no ['%d']
|
||||
-e vbd_expert -- Safety catch to avoid some disk accidents ['%s']
|
||||
-d udisk,dev,rw -- Add disk, partition, or virtual disk to domain. E.g. to
|
||||
make partion sda4 available to the domain as hda1 with
|
||||
read-write access: '-d phy:sda4,hda1,rw' To add
|
||||
multiple disks use multiple -d flags or seperate with ';'
|
||||
Default: ['%s']
|
||||
-i vfr_ipaddr -- Add IP address to the list which Xen will route to
|
||||
the domain. Use multiple times to add more IP addrs.
|
||||
Default: ['%s']
|
||||
|
||||
Args to override the kernel command line, which is concatenated from these:
|
||||
-I cmdline_ip -- Override 'ip=ipaddr:nfsserv:gateway:netmask::eth0:off'
|
||||
Default: ['%s']
|
||||
-R cmdline_root -- Override root device parameters.
|
||||
Default: ['%s']
|
||||
-E cmdline_extra -- Override extra kernel args and rc script env vars.
|
||||
Default: ['%s']
|
||||
|
||||
""" % (config_file,
|
||||
image, ramdisk, builder_fn, mem_size, domain_name, auto_restart,
|
||||
vbd_expert,
|
||||
printvbds( vbd_list ),
|
||||
reduce ( (lambda a,b: a+':'+b), vfr_ipaddr,'' )[1:],
|
||||
cmdline_ip, cmdline_root, cmdline_extra)
|
||||
|
||||
def config_usage (): pass
|
||||
|
||||
def answer ( s ):
|
||||
s = string.lower(s)
|
||||
if s == 'yes' or s == 'true' or s == '1': return 1
|
||||
return 0
|
||||
|
||||
def printvbds ( v ):
|
||||
s=''
|
||||
for (a,b,c) in v:
|
||||
s = s + '; %s,%s,%s' % (a,b,c)
|
||||
return s[2:]
|
||||
|
||||
def output(string):
|
||||
global quiet
|
||||
syslog.syslog(string)
|
||||
if not quiet:
|
||||
print string
|
||||
return
|
||||
|
||||
bail=False; dryrun=False; extrahelp=False; quiet = False
|
||||
image=''; ramdisk=''; builder_fn='linux'; restore=0; state_file=''
|
||||
mem_size=0; domain_name=''; vfr_ipaddr=[];
|
||||
vbd_expert='rr'; auto_restart=False;
|
||||
vbd_list = []; cmdline_ip = ''; cmdline_root=''; cmdline_extra=''
|
||||
pci_device_list = []; console_port = -1
|
||||
auto_console = False
|
||||
config_from_file = False
|
||||
|
||||
##### Determine location of defaults file
|
||||
#####
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "h?nqcf:F:D:k:r:b:m:N:a:e:d:i:I:R:E:L:" )
|
||||
|
||||
for opt in opts:
|
||||
if opt[0] == '-f': config_file= opt[1]
|
||||
if opt[0] == '-h' or opt[0] == '-?' : bail=True; extrahelp=True
|
||||
if opt[0] == '-n': dryrun=True
|
||||
if opt[0] == '-D':
|
||||
for o in string.split( opt[1], ';' ):
|
||||
(l,r) = string.split( o, '=' )
|
||||
exec "%s='%s'" % (l,r)
|
||||
if opt[0] == '-q': quiet = True
|
||||
if opt[0] == '-L': restore = True; state_file = opt[1]
|
||||
if opt[0] == '-F': config_from_file = True; domain_config = opt[1]
|
||||
|
||||
|
||||
except getopt.GetoptError:
|
||||
bail=True
|
||||
|
||||
if not config_from_file:
|
||||
try:
|
||||
os.stat( config_file )
|
||||
except:
|
||||
try:
|
||||
d = config_dir + config_file
|
||||
os.stat( d )
|
||||
config_file = d
|
||||
except:
|
||||
print >> sys.stderr, "Unable to open config file '%s'" % config_file
|
||||
bail = True
|
||||
|
||||
|
||||
##### Parse the config file
|
||||
#####
|
||||
|
||||
if not config_from_file:
|
||||
if not quiet:
|
||||
print "Parsing config file '%s'" % config_file
|
||||
|
||||
try:
|
||||
execfile ( config_file )
|
||||
except (AssertionError,IOError):
|
||||
print >>sys.stderr,"Exiting %s" % sys.argv[0]
|
||||
bail = True
|
||||
|
||||
##### Print out config if necessary
|
||||
#####
|
||||
|
||||
def bailout():
|
||||
global extrahelp
|
||||
main_usage()
|
||||
config_usage()
|
||||
if extrahelp: extra_usage()
|
||||
sys.exit(1)
|
||||
|
||||
if bail:
|
||||
bailout()
|
||||
|
||||
##### Parse any command line overrides
|
||||
#####
|
||||
|
||||
x_vbd_list = []
|
||||
x_vfr_ipaddr = []
|
||||
|
||||
for opt in opts:
|
||||
if opt[0] == '-k': image = opt[1]
|
||||
if opt[0] == '-r': ramdisk = opt[1]
|
||||
if opt[0] == '-b': builder_fn = opt[1]
|
||||
if opt[0] == '-m': mem_size = int(opt[1])
|
||||
if opt[0] == '-C': cpu = int(opt[1])
|
||||
if opt[0] == '-N': domain_name = opt[1]
|
||||
if opt[0] == '-a': auto_restart = answer(opt[1])
|
||||
if opt[0] == '-e': vbd_expert = opt[1]
|
||||
if opt[0] == '-I': cmdline_ip = opt[1]
|
||||
if opt[0] == '-R': cmdline_root = opt[1]
|
||||
if opt[0] == '-E': cmdline_extra = opt[1]
|
||||
if opt[0] == '-i': x_vfr_ipaddr.append(opt[1])
|
||||
if opt[0] == '-c': auto_console = True
|
||||
if opt[0] == '-d':
|
||||
try:
|
||||
vv = string.split(opt[1],';')
|
||||
for v in vv:
|
||||
(udisk,dev,mode) = string.split(v,',')
|
||||
x_vbd_list.append( (udisk,dev,mode) )
|
||||
except:
|
||||
print >>sys.stderr, "Invalid block device specification : %s" % opt[1]
|
||||
sys.exit(1)
|
||||
|
||||
if x_vbd_list: vbd_list = x_vbd_list
|
||||
if x_vfr_ipaddr: vfr_ipaddr = x_vfr_ipaddr
|
||||
|
||||
syslog.openlog('xc_dom_create.py %s' % config_file, 0, syslog.LOG_DAEMON)
|
||||
|
||||
def strip(pre, s):
|
||||
if s.startswith(pre):
|
||||
return s[len(pre):]
|
||||
else:
|
||||
return s
|
||||
|
||||
def make_domain_config():
|
||||
global builder_fn, image, ramdisk, mem_size, domain_name
|
||||
global cpu
|
||||
global cmdline, cmdline_ip, cmdline_root
|
||||
global vfr_ipaddr, vbd_list, vbd_expert
|
||||
|
||||
config = ['config',
|
||||
['name', domain_name ],
|
||||
['memory', mem_size ],
|
||||
]
|
||||
if cpu:
|
||||
config.append(['cpu', cpu])
|
||||
|
||||
config_image = [ builder_fn ]
|
||||
config_image.append([ 'kernel', os.path.abspath(image) ])
|
||||
if ramdisk:
|
||||
config_image.append([ 'ramdisk', os.path.abspath(ramdisk) ])
|
||||
if cmdline_ip:
|
||||
cmdline_ip = strip("ip=", cmdline_ip)
|
||||
config_image.append(['ip', cmdline_ip])
|
||||
if cmdline_root:
|
||||
cmdline_root = strip("root=", cmdline_root)
|
||||
config_image.append(['root', cmdline_root])
|
||||
if cmdline_extra:
|
||||
config_image.append(['args', cmdline_extra])
|
||||
config.append(['image', config_image ])
|
||||
|
||||
config_devs = []
|
||||
for (uname, dev, mode) in vbd_list:
|
||||
config_vbd = ['vbd',
|
||||
['uname', uname],
|
||||
['dev', dev ],
|
||||
['mode', mode ] ]
|
||||
if vbd_expert != 'rr':
|
||||
config_vbd.append(['sharing', vbd_expert])
|
||||
config_devs.append(['device', config_vbd])
|
||||
|
||||
for (bus, dev, func) in pci_device_list:
|
||||
config_pci = ['pci',
|
||||
['bus', bus ],
|
||||
['dev', dev ],
|
||||
['func', func] ]
|
||||
config_devs.append(['device', config_pci])
|
||||
|
||||
config += config_devs
|
||||
|
||||
config_vfr = ['vfr']
|
||||
idx = 0 # No way of saying which IP is for which vif?
|
||||
for ip in vfr_ipaddr:
|
||||
config_vfr.append(['vif', ['id', idx], ['ip', ip]])
|
||||
|
||||
config.append(config_vfr)
|
||||
return config
|
||||
|
||||
def parse_config_file(domain_file):
|
||||
config = None
|
||||
fin = None
|
||||
try:
|
||||
fin = file(domain_file, "rb")
|
||||
config = sxp.parse(fin)
|
||||
if len(config) >= 1:
|
||||
config = config[0]
|
||||
else:
|
||||
raise StandardError("Invalid configuration")
|
||||
except StandardError, ex:
|
||||
print >> sys.stderr, "Error :", ex
|
||||
sys.exit(1)
|
||||
#finally:
|
||||
if fin: fin.close()
|
||||
return config
|
||||
|
||||
# This function creates, builds and starts a domain, using the values
|
||||
# in the global variables, set above. It is used in the subsequent
|
||||
# code for starting the new domain and rebooting it if appropriate.
|
||||
def make_domain(config):
|
||||
"""Create, build and start a domain.
|
||||
Returns: [int] the ID of the new domain.
|
||||
"""
|
||||
global restore
|
||||
|
||||
if restore:
|
||||
dominfo = server.xend_domain_restore(state_file, config)
|
||||
else:
|
||||
dominfo = server.xend_domain_create(config)
|
||||
|
||||
dom = int(sxp.child_value(dominfo, 'id'))
|
||||
console_info = sxp.child(dominfo, 'console')
|
||||
if console_info:
|
||||
console_port = int(sxp.child_value(console_info, 'port'))
|
||||
else:
|
||||
console_port = None
|
||||
|
||||
if server.xend_domain_start(dom) < 0:
|
||||
print "Error starting domain"
|
||||
server.xend_domain_halt(dom)
|
||||
sys.exit()
|
||||
|
||||
return (dom, console_port)
|
||||
|
||||
PID_DIR = '/var/run/xendomains/'
|
||||
|
||||
def pidfile(dom):
|
||||
return PID_DIR + '%d.pid' % dom
|
||||
|
||||
def mkpidfile():
|
||||
global current_id
|
||||
if not os.path.isdir(PID_DIR):
|
||||
os.mkdir(PID_DIR)
|
||||
|
||||
fd = open(pidfile(current_id), 'w')
|
||||
print >> fd, str(os.getpid())
|
||||
fd.close()
|
||||
return
|
||||
|
||||
def rmpidfile():
|
||||
global current_id
|
||||
os.unlink(pidfile(current_id))
|
||||
|
||||
def death_handler(dummy1,dummy2):
|
||||
global current_id
|
||||
os.unlink(pidfile(current_id))
|
||||
output('Auto-restart daemon: daemon PID = %d for domain %d is now exiting'
|
||||
% (os.getpid(), current_id))
|
||||
sys.exit(0)
|
||||
return
|
||||
|
||||
#============================================================================
|
||||
# The starting / monitoring of the domain actually happens here...
|
||||
|
||||
if config_from_file:
|
||||
config = parse_config_file(domain_config)
|
||||
else:
|
||||
config = make_domain_config()
|
||||
|
||||
if dryrun:
|
||||
print "# %s" % ' '.join(sys.argv)
|
||||
PrettyPrint.prettyprint(config)
|
||||
sys.exit(0)
|
||||
elif quiet:
|
||||
pass
|
||||
else:
|
||||
PrettyPrint.prettyprint(config)
|
||||
|
||||
# start the domain and record its ID number
|
||||
(current_id, current_port) = make_domain(config)
|
||||
|
||||
def start_msg(prefix, dom, port):
|
||||
output(prefix + "VM started in domain %d" % dom)
|
||||
if port:
|
||||
output(prefix + "Console I/O available on TCP port %d." % port)
|
||||
|
||||
start_msg('', current_id, current_port)
|
||||
|
||||
if current_port and auto_console:
|
||||
xenctl.console_client.connect('127.0.0.1', current_port)
|
||||
|
||||
# if the auto_restart flag is set then keep polling to see if the domain is
|
||||
# alive - restart if it is not by calling make_domain() again (it's necessary
|
||||
# to update the id variable, since the new domain may have a new ID)
|
||||
|
||||
#todo: Replace this - get xend to watch them.
|
||||
if auto_restart:
|
||||
ARD = "Auto-restart daemon: "
|
||||
# turn ourselves into a background daemon
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
sys.exit(0)
|
||||
os.setsid()
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
output(ARD + 'PID = %d' % pid)
|
||||
sys.exit(0)
|
||||
signal.signal(signal.SIGTERM,death_handler)
|
||||
except OSError:
|
||||
print >> sys.stderr, ARD+'Startup failed'
|
||||
sys.exit(1)
|
||||
|
||||
mkpidfile()
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
# todo: use new interface
|
||||
info = xc.domain_getinfo(current_id, 1)
|
||||
if info == [] or info[0]['dom'] != current_id:
|
||||
output(ARD + "Domain %d terminated, restarting VM in new domain"
|
||||
% current_id)
|
||||
rmpidfile()
|
||||
(current_id, current_port) = make_domain()
|
||||
mkpidfile()
|
||||
start_msg(ARD, current_id, current_port)
|
||||
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import re
|
||||
import string
|
||||
|
||||
from xenctl import vdisk
|
||||
|
||||
def usage():
|
||||
|
||||
print >>sys.stderr,"""
|
||||
Usage: %s command <params>
|
||||
|
||||
initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
|
||||
create [size] [[expiry]] - allocate a vd of specified size (and expiry)
|
||||
enlarge [vdid] [extra_size] - enlarge a specified vd by some amount
|
||||
delete [vdid] - delete a vd
|
||||
import [filename] [[expiry]] - create a vd and populate w/ image from file
|
||||
export [vdid] [filename] - copy vd's contents to a file
|
||||
setexpiry [vdid] [[expiry]] - update the expiry time for a vd
|
||||
list - list all the unexpired virtual disks
|
||||
undelete [vdid] [[expiry]] - attempts to recover an expired vd
|
||||
freespace - print out the amount of space in free pool
|
||||
|
||||
notes:
|
||||
vdid - the virtual disk's identity string
|
||||
size - measured in MB
|
||||
expiry - is the expiry time of the virtual disk in seconds from now
|
||||
(0 = don't expire)
|
||||
device - physical partition to 'format' to hold vd's. e.g. hda4
|
||||
ext_size - extent size (default 64MB)
|
||||
""" % sys.argv[0]
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
usage()
|
||||
sys.exit(-1)
|
||||
|
||||
rc=''
|
||||
src=''
|
||||
expiry_time = 0
|
||||
cmd = sys.argv[1]
|
||||
|
||||
if cmd == 'initialise':
|
||||
|
||||
dev = sys.argv[2]
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
extent_size = int(sys.argv[3])
|
||||
else:
|
||||
print """No extent size specified - using default size of 64MB"""
|
||||
extent_size = 64
|
||||
|
||||
print "Formatting for virtual disks"
|
||||
print "Device: " + dev
|
||||
print "Extent size: " + str(extent_size) + "MB"
|
||||
|
||||
rc = vdisk.vd_format(dev, extent_size)
|
||||
|
||||
elif cmd == 'create':
|
||||
|
||||
size = int(sys.argv[2])
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
expiry_time = int(sys.argv[3])
|
||||
|
||||
print "Creating a virtual disk"
|
||||
print "Size: %d" % size
|
||||
print "Expiry time (seconds from now): %d" % expiry_time
|
||||
|
||||
src = vdisk.vd_create(size, expiry_time)
|
||||
|
||||
elif cmd == 'enlarge':
|
||||
|
||||
id = sys.argv[2]
|
||||
|
||||
extra_size = int(sys.argv[3])
|
||||
|
||||
rc = vdisk.vd_enlarge(id, extra_size)
|
||||
|
||||
elif cmd == 'delete':
|
||||
|
||||
id = sys.argv[2]
|
||||
|
||||
print "Deleting a virtual disk with ID: " + id
|
||||
|
||||
rc = vdisk.vd_delete(id)
|
||||
|
||||
elif cmd == 'import':
|
||||
|
||||
file = sys.argv[2]
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
expiry_time = int(sys.argv[3])
|
||||
|
||||
print "Allocate new virtual disk and populate from file : %s" % file
|
||||
|
||||
print vdisk.vd_read_from_file(file, expiry_time)
|
||||
|
||||
elif cmd == 'export':
|
||||
|
||||
id = sys.argv[2]
|
||||
file = sys.argv[3]
|
||||
|
||||
print "Dump contents of virtual disk to file : %s" % file
|
||||
|
||||
rc = vdisk.vd_cp_to_file(id, file )
|
||||
|
||||
elif cmd == 'setexpiry':
|
||||
|
||||
id = sys.argv[2]
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
expiry_time = int(sys.argv[3])
|
||||
|
||||
print "Refreshing a virtual disk"
|
||||
print "Id: " + id
|
||||
print "Expiry time (seconds from now [or 0]): " + str(expiry_time)
|
||||
|
||||
rc = vdisk.vd_refresh(id, expiry_time)
|
||||
|
||||
elif cmd == 'list':
|
||||
print 'ID Size(MB) Expiry'
|
||||
|
||||
for vbd in vdisk.vd_list():
|
||||
vbd['size_mb'] = vbd['size'] / vdisk.VBD_SECTORS_PER_MB
|
||||
vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never'
|
||||
print '%(vdisk_id)-4s %(size_mb)-12d %(expiry)s' % vbd
|
||||
|
||||
elif cmd == 'freespace':
|
||||
|
||||
print vdisk.vd_freespace()
|
||||
|
||||
elif cmd == 'undelete':
|
||||
|
||||
id = sys.argv[2]
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
expiry_time = int(sys.argv[3])
|
||||
|
||||
if vdisk.vd_undelete(id, expiry_time):
|
||||
print "Undelete operation failed for virtual disk: " + id
|
||||
else:
|
||||
print "Undelete operation succeeded for virtual disk: " + id
|
||||
|
||||
else:
|
||||
usage()
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if src != '':
|
||||
print "Returned virtual disk id is : %s" % src
|
||||
|
||||
if rc != '':
|
||||
print "return code %d" % rc
|
||||
|
||||
|
||||
|
||||