bitkeeper revision 1.946.1.3 (40c9c475sJLMEuc6TqUt-bX6hVFOpQ)

Add source tree for the management utils.
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-06-11 14:40:53 +00:00
1 parent 9eb865c540
commit 8b980d633c
57 files changed
+8896 -2

No files matched your search

+233
View File
@@ -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
+402
View File
@@ -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)
+157
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.