direct-io.hg

changeset 1490:f32df7f04499

bitkeeper revision 1.972 (40d139b2Pih8HslUqkfo5Phz7g0NTg)

Merge ssh://xenbk@gandalf.hpl.hp.com//var/bk/xeno-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Thu Jun 17 06:26:58 2004 +0000 (2004-06-17)
parents 4f79516ed019 8f52e5e39641
children 50574defb9f7
files .rootkeys tools/Makefile tools/examples/Makefile tools/examples/xc_vd_tool.py tools/examples/xm_dom_control.py tools/examples/xm_vd_tool.py tools/examples/xmdefaults tools/xenctl/lib/vdisk.py tools/xenctl/setup.py tools/xenmgr/Makefile tools/xenmgr/lib/XendClient.py tools/xenmgr/lib/XendDomain.py tools/xenmgr/lib/XendDomainInfo.py tools/xenmgr/lib/XendNode.py tools/xenmgr/lib/XendVdisk.py tools/xenmgr/lib/server/SrvNode.py tools/xenmgr/lib/server/SrvRoot.py tools/xenmgr/lib/server/SrvVdisk.py tools/xenmgr/lib/server/SrvVdiskDir.py tools/xenmgr/lib/xm/__init__.py tools/xenmgr/lib/xm/create.py tools/xenmgr/lib/xm/main.py tools/xenmgr/lib/xm/opts.py tools/xenmgr/lib/xm/shutdown.py tools/xenmgr/netfix tools/xenmgr/setup.py tools/xenmgr/xend tools/xenmgr/xm
line diff
     1.1 --- a/.rootkeys	Wed Jun 16 21:29:21 2004 +0000
     1.2 +++ b/.rootkeys	Thu Jun 17 06:26:58 2004 +0000
     1.3 @@ -165,10 +165,9 @@ 40278d91ZjLhxdjjrGe8HEdwHLj5xQ tools/exa
     1.4  401d7e16NpnVrFSsR7lKKKfTwCYvWA tools/examples/xc_dom_control.py
     1.5  401d7e16RJj-lbtsVEjua6HYAIiKiA tools/examples/xc_dom_create.py
     1.6  403b7cf7J7FsSSoEPGhx6gXR4pIdZg tools/examples/xc_physinfo.py
     1.7 -401d7e16X4iojyKopo_j63AyzYZd2A tools/examples/xc_vd_tool.py
     1.8  40c9c4684Wfg8VgMKtRFa_ULi2e_tQ tools/examples/xm_dom_control.py
     1.9  40c9c468pXANclL7slGaoD0kSrIwoQ tools/examples/xm_dom_create.py
    1.10 -40c9c468QKoqBHjb5Qwrm60pNVcVng tools/examples/xm_vd_tool.py
    1.11 +40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmdefaults
    1.12  3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
    1.13  40ab2cfawIw8tsYo0dQKtp83h4qfTQ tools/misc/fakei386xen
    1.14  3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
    1.15 @@ -214,7 +213,6 @@ 4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/xen
    1.16  40c9c468IienauFHQ_xJIcqnPJ8giQ tools/xenctl/lib/ip.py
    1.17  4059c6a0pnxhG8hwSOivXybbGOwuXw tools/xenctl/lib/tempfile.py
    1.18  3fbd4bd6GtGwZGxYUJPOheYIR7bPaA tools/xenctl/lib/utils.py
    1.19 -40c9c468F36e06WH38kpYrD3JfXC0Q tools/xenctl/lib/vdisk.py
    1.20  4055ee44Bu6oP7U0WxxXypbUt4dNPQ tools/xenctl/setup.py
    1.21  40431ac64Hj4ixUnKmlugZKhXPFE_Q tools/xend/Makefile
    1.22  4055ad95Se-FqttgxollqOAAHB94zA tools/xend/lib/__init__.py
    1.23 @@ -241,7 +239,6 @@ 40c9c4685ykq87_n1kVUbMr9flx9fg tools/xen
    1.24  40c9c46854nsHmuxHQHncKk5rAs5NA tools/xenmgr/lib/XendMigrate.py
    1.25  40c9c468M96gA1EYDvNa5w5kQNYLFA tools/xenmgr/lib/XendNode.py
    1.26  40c9c4686jruMyZIqiaZRMiMoqMJtg tools/xenmgr/lib/XendRoot.py
    1.27 -40c9c468P75aHqyIE156JXwc-5W92A tools/xenmgr/lib/XendVdisk.py
    1.28  40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/xenmgr/lib/XendVnet.py
    1.29  40c9c468x191zetrVlMnExfsQWHxIQ tools/xenmgr/lib/__init__.py
    1.30  40c9c468S2YnCEKmk4ey8XQIST7INg tools/xenmgr/lib/encode.py
    1.31 @@ -257,8 +254,6 @@ 40c9c469-8mYEJJTAR6w_ClrJRAfwQ tools/xen
    1.32  40c9c4694eu5759Dehr4Uhakei0EMg tools/xenmgr/lib/server/SrvNode.py
    1.33  40c9c469TaZ83ypsrktmPSHLEZiP5w tools/xenmgr/lib/server/SrvRoot.py
    1.34  40c9c469W3sgDMbBJYQdz5wbQweL0Q tools/xenmgr/lib/server/SrvServer.py
    1.35 -40c9c469JlUVPkwGWZyVnqIsU8U6Bw tools/xenmgr/lib/server/SrvVdisk.py
    1.36 -40c9c469sG8iuyxjVH3zKw8XOAyxtQ tools/xenmgr/lib/server/SrvVdiskDir.py
    1.37  40c9c469aq7oXrE1Ngqf3_lBqL0RoQ tools/xenmgr/lib/server/SrvVnetDir.py
    1.38  40c9c469Y_aimoOFfUZoS-4eV8gEKg tools/xenmgr/lib/server/__init__.py
    1.39  40c9c4692hckPol_EK0EGB16ZyDsyQ tools/xenmgr/lib/server/blkif.py
    1.40 @@ -270,10 +265,16 @@ 40c9c469yrm31i60pGKslTi2Zgpotg tools/xen
    1.41  40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/xenmgr/lib/server/netif.py
    1.42  40c9c469ZqILEQ8x6yWy0_51jopiCg tools/xenmgr/lib/server/params.py
    1.43  40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/xenmgr/lib/sxp.py
    1.44 +40d05079aFRp6NQdo5wIh5Ly31c0cg tools/xenmgr/lib/xm/__init__.py
    1.45 +40cf2937gKQcATgXKGtNeWb1PDH5nA tools/xenmgr/lib/xm/create.py
    1.46 +40cf2937isyS250zyd0Q2GuEDoNXfQ tools/xenmgr/lib/xm/main.py
    1.47 +40cf2937PSslwBliN1g7ofDy2H_RhA tools/xenmgr/lib/xm/opts.py
    1.48 +40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/xenmgr/lib/xm/shutdown.py
    1.49  40c9c469kT0H9COWzA4XzPBjWK0WsA tools/xenmgr/netfix
    1.50  40c9c469n2RRwCmjWdjdyyVRWKmgWg tools/xenmgr/setup.py
    1.51  40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/xenmgr/xend
    1.52  40c9c469JkN47d1oXi-e0RjAP-C6uQ tools/xenmgr/xenmgrd
    1.53 +40cf2937dqM1jWW87O5OoOYND8leuA tools/xenmgr/xm
    1.54  403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile
    1.55  40a107afN60pFdURgBv9KwEzgRl5mQ tools/xentrace/formats
    1.56  4050c413PhhLNAYk3TEwP37i_iLw9Q tools/xentrace/xentrace.8
     3.1 --- a/tools/examples/Makefile	Wed Jun 16 21:29:21 2004 +0000
     3.2 +++ b/tools/examples/Makefile	Thu Jun 17 06:26:58 2004 +0000
     3.3 @@ -1,6 +1,6 @@
     3.4  
     3.5  INSTALL  = $(wildcard *.py)
     3.6 -ETC	 = defaults democd netbsd
     3.7 +ETC	 = defaults democd netbsd xmdefaults
     3.8  INITD    = init.d/xendomains init.d/xend
     3.9  
    3.10  all: 
     4.1 --- a/tools/examples/xc_vd_tool.py	Wed Jun 16 21:29:21 2004 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,153 +0,0 @@
     4.4 -#!/usr/bin/env python
     4.5 -
     4.6 -import xenctl.utils, sys, re, string
     4.7 -
     4.8 -def usage():
     4.9 -
    4.10 -    print >>sys.stderr,"""
    4.11 -Usage: %s command <params>
    4.12 -
    4.13 -  initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
    4.14 -  create [size] [[expiry]]      - allocate a vd of specified size (and expiry)
    4.15 -  enlarge [vdid] [extra_size]   - enlarge a specified vd by some amount
    4.16 -  delete [vdid]                 - delete a vd
    4.17 -  import [filename] [[expiry]]  - create a vd and populate w/ image from file
    4.18 -  export [vdid] [filename]      - copy vd's contents to a file
    4.19 -  setexpiry [vdid] [[expiry]]   - update the expiry time for a vd
    4.20 -  list                          - list all the unexpired virtual disks  
    4.21 -  undelete [vdid] [[expiry]]    - attempts to recover an expired vd
    4.22 -  freespace                     - print out the amount of space in free pool
    4.23 -
    4.24 -notes:
    4.25 -  vdid      - the virtual disk's identity string
    4.26 -  size      - measured in MB
    4.27 -  expiry    - is the expiry time of the virtual disk in seconds from now
    4.28 -               (0 = don't expire) 
    4.29 -  device    - physical partition to 'format' to hold vd's. e.g. hda4
    4.30 -  ext_size  - extent size (default 64MB)
    4.31 -""" % sys.argv[0]  
    4.32 -
    4.33 -if len(sys.argv) < 2: 
    4.34 -    usage()
    4.35 -    sys.exit(-1)
    4.36 -
    4.37 -rc=''
    4.38 -src=''
    4.39 -expiry_time = 0
    4.40 -cmd = sys.argv[1]
    4.41 -
    4.42 -if cmd == 'initialise':
    4.43 -
    4.44 -    dev = sys.argv[2]
    4.45 -
    4.46 -    if len(sys.argv) > 3:
    4.47 -	extent_size = int(sys.argv[3])
    4.48 -    else:
    4.49 -	print """No extent size specified - using default size of 64MB"""
    4.50 -	extent_size = 64
    4.51 -
    4.52 -    print "Formatting for virtual disks"
    4.53 -    print "Device: " + dev
    4.54 -    print "Extent size: " + str(extent_size) + "MB"
    4.55 -
    4.56 -    rc = xenctl.utils.vd_format(dev, extent_size)
    4.57 -
    4.58 -elif cmd == 'create':
    4.59 - 
    4.60 -    size = int(sys.argv[2])
    4.61 -    
    4.62 -    if len(sys.argv) > 3:
    4.63 -	expiry_time = int(sys.argv[3])
    4.64 -
    4.65 -    print "Creating a virtual disk"
    4.66 -    print "Size: %d" % size
    4.67 -    print "Expiry time (seconds from now): %d" % expiry_time
    4.68 -
    4.69 -    src = xenctl.utils.vd_create(size, expiry_time)
    4.70 -
    4.71 -elif cmd == 'enlarge':
    4.72 -
    4.73 -    id = sys.argv[2]
    4.74 -
    4.75 -    extra_size = int(sys.argv[3])
    4.76 -
    4.77 -    rc = xenctl.utils.vd_enlarge(id, extra_size)
    4.78 -
    4.79 -elif cmd == 'delete':
    4.80 -
    4.81 -    id = sys.argv[2]
    4.82 -
    4.83 -    print "Deleting a virtual disk with ID: " + id
    4.84 -
    4.85 -    rc = xenctl.utils.vd_delete(id)
    4.86 -
    4.87 -elif cmd == 'import':
    4.88 -
    4.89 -    file = sys.argv[2]
    4.90 -    
    4.91 -    if len(sys.argv) > 3:
    4.92 -	expiry_time = int(sys.argv[3])
    4.93 -
    4.94 -    print "Allocate new virtual disk and populate from file : %s" % file
    4.95 -
    4.96 -    print xenctl.utils.vd_read_from_file(file, expiry_time)
    4.97 -
    4.98 -elif cmd == 'export':
    4.99 -
   4.100 -    id = sys.argv[2]
   4.101 -    file = sys.argv[3]
   4.102 -
   4.103 -    print "Dump contents of virtual disk to file : %s" % file
   4.104 -
   4.105 -    rc = xenctl.utils.vd_cp_to_file(id, file )
   4.106 -
   4.107 -elif cmd == 'setexpiry':
   4.108 -
   4.109 -    id = sys.argv[2]
   4.110 -
   4.111 -    if len(sys.argv) > 3:
   4.112 -	expiry_time = int(sys.argv[3])
   4.113 -
   4.114 -    print "Refreshing a virtual disk"
   4.115 -    print "Id: " + id
   4.116 -    print "Expiry time (seconds from now [or 0]): " + str(expiry_time)
   4.117 -
   4.118 -    rc = xenctl.utils.vd_refresh(id, expiry_time)
   4.119 -
   4.120 -elif cmd == 'list':
   4.121 -    print 'ID    Size(MB)      Expiry'
   4.122 -
   4.123 -    for vbd in xenctl.utils.vd_list():
   4.124 -        vbd['size_mb'] = vbd['size'] / 2048
   4.125 -        vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never'
   4.126 -        print '%(vdisk_id)-4s  %(size_mb)-12d  %(expiry)s' % vbd
   4.127 -
   4.128 -elif cmd == 'freespace':
   4.129 -
   4.130 -    print xenctl.utils.vd_freespace()
   4.131 -
   4.132 -elif cmd == 'undelete':
   4.133 -
   4.134 -    id = sys.argv[2]
   4.135 -
   4.136 -    if len(sys.argv) > 3:
   4.137 -	expiry_time = int(sys.argv[3])
   4.138 -   
   4.139 -    if xenctl.utils.vd_undelete(id, expiry_time):
   4.140 -	print "Undelete operation failed for virtual disk: " + id
   4.141 -    else:
   4.142 -	print "Undelete operation succeeded for virtual disk: " + id
   4.143 -
   4.144 -else:
   4.145 -    usage()
   4.146 -    sys.exit(-1)
   4.147 -
   4.148 -
   4.149 -if src != '':  
   4.150 -    print "Returned virtual disk id is : %s" % src
   4.151 -
   4.152 -if rc != '':
   4.153 -    print "return code %d" % rc
   4.154 -
   4.155 -
   4.156 -
     5.1 --- a/tools/examples/xm_dom_control.py	Wed Jun 16 21:29:21 2004 +0000
     5.2 +++ b/tools/examples/xm_dom_control.py	Thu Jun 17 06:26:58 2004 +0000
     5.3 @@ -8,6 +8,7 @@ import os
     5.4  import os.path
     5.5  import signal
     5.6  
     5.7 +from xenmgr import sxp
     5.8  from xenmgr.XendClient import server
     5.9  
    5.10  # usage: xc_dom_control [command] <params>
    5.11 @@ -131,13 +132,13 @@ elif cmd == 'list':
    5.12      for dom in server.xend_domains():
    5.13          info = server.xend_domain(dom)
    5.14          d = {}
    5.15 -        d['dom'] = dom
    5.16 -        d['name'] = sxp.get_child_value(info, 'name', '??')
    5.17 -        d['mem'] = int(sxp.get_child_value(info, 'memory', '0'))
    5.18 -        d['cpu'] = int(sxp.get_child_value(info, 'cpu', '0'))
    5.19 -        d['state'] = sxp.get_child_value(info, 'state', '??')
    5.20 -        d['cpu_time'] = sxp.get_child_value(info, 'cpu_time', '0')
    5.21 -        print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)8d"
    5.22 +        d['dom'] = int(dom)
    5.23 +        d['name'] = sxp.child_value(info, 'name', '??')
    5.24 +        d['mem'] = int(sxp.child_value(info, 'memory', '0'))
    5.25 +        d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
    5.26 +        d['state'] = sxp.child_value(info, 'state', '??')
    5.27 +        d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0')
    5.28 +        print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)8.2f"
    5.29                 % d)
    5.30  
    5.31  elif cmd == 'unwatch':
     6.1 --- a/tools/examples/xm_vd_tool.py	Wed Jun 16 21:29:21 2004 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,157 +0,0 @@
     6.4 -#!/usr/bin/env python
     6.5 -
     6.6 -import sys
     6.7 -import re
     6.8 -import string
     6.9 -
    6.10 -from xenctl import vdisk
    6.11 -
    6.12 -def usage():
    6.13 -
    6.14 -    print >>sys.stderr,"""
    6.15 -Usage: %s command <params>
    6.16 -
    6.17 -  initialise [dev] [[ext_size]] - init. a physcial partition to store vd's
    6.18 -  create [size] [[expiry]]      - allocate a vd of specified size (and expiry)
    6.19 -  enlarge [vdid] [extra_size]   - enlarge a specified vd by some amount
    6.20 -  delete [vdid]                 - delete a vd
    6.21 -  import [filename] [[expiry]]  - create a vd and populate w/ image from file
    6.22 -  export [vdid] [filename]      - copy vd's contents to a file
    6.23 -  setexpiry [vdid] [[expiry]]   - update the expiry time for a vd
    6.24 -  list                          - list all the unexpired virtual disks  
    6.25 -  undelete [vdid] [[expiry]]    - attempts to recover an expired vd
    6.26 -  freespace                     - print out the amount of space in free pool
    6.27 -
    6.28 -notes:
    6.29 -  vdid      - the virtual disk's identity string
    6.30 -  size      - measured in MB
    6.31 -  expiry    - is the expiry time of the virtual disk in seconds from now
    6.32 -               (0 = don't expire) 
    6.33 -  device    - physical partition to 'format' to hold vd's. e.g. hda4
    6.34 -  ext_size  - extent size (default 64MB)
    6.35 -""" % sys.argv[0]  
    6.36 -
    6.37 -if len(sys.argv) < 2: 
    6.38 -    usage()
    6.39 -    sys.exit(-1)
    6.40 -
    6.41 -rc=''
    6.42 -src=''
    6.43 -expiry_time = 0
    6.44 -cmd = sys.argv[1]
    6.45 -
    6.46 -if cmd == 'initialise':
    6.47 -
    6.48 -    dev = sys.argv[2]
    6.49 -
    6.50 -    if len(sys.argv) > 3:
    6.51 -	extent_size = int(sys.argv[3])
    6.52 -    else:
    6.53 -	print """No extent size specified - using default size of 64MB"""
    6.54 -	extent_size = 64
    6.55 -
    6.56 -    print "Formatting for virtual disks"
    6.57 -    print "Device: " + dev
    6.58 -    print "Extent size: " + str(extent_size) + "MB"
    6.59 -
    6.60 -    rc = vdisk.vd_format(dev, extent_size)
    6.61 -
    6.62 -elif cmd == 'create':
    6.63 - 
    6.64 -    size = int(sys.argv[2])
    6.65 -    
    6.66 -    if len(sys.argv) > 3:
    6.67 -	expiry_time = int(sys.argv[3])
    6.68 -
    6.69 -    print "Creating a virtual disk"
    6.70 -    print "Size: %d" % size
    6.71 -    print "Expiry time (seconds from now): %d" % expiry_time
    6.72 -
    6.73 -    src = vdisk.vd_create(size, expiry_time)
    6.74 -
    6.75 -elif cmd == 'enlarge':
    6.76 -
    6.77 -    id = sys.argv[2]
    6.78 -
    6.79 -    extra_size = int(sys.argv[3])
    6.80 -
    6.81 -    rc = vdisk.vd_enlarge(id, extra_size)
    6.82 -
    6.83 -elif cmd == 'delete':
    6.84 -
    6.85 -    id = sys.argv[2]
    6.86 -
    6.87 -    print "Deleting a virtual disk with ID: " + id
    6.88 -
    6.89 -    rc = vdisk.vd_delete(id)
    6.90 -
    6.91 -elif cmd == 'import':
    6.92 -
    6.93 -    file = sys.argv[2]
    6.94 -    
    6.95 -    if len(sys.argv) > 3:
    6.96 -	expiry_time = int(sys.argv[3])
    6.97 -
    6.98 -    print "Allocate new virtual disk and populate from file : %s" % file
    6.99 -
   6.100 -    print vdisk.vd_read_from_file(file, expiry_time)
   6.101 -
   6.102 -elif cmd == 'export':
   6.103 -
   6.104 -    id = sys.argv[2]
   6.105 -    file = sys.argv[3]
   6.106 -
   6.107 -    print "Dump contents of virtual disk to file : %s" % file
   6.108 -
   6.109 -    rc = vdisk.vd_cp_to_file(id, file )
   6.110 -
   6.111 -elif cmd == 'setexpiry':
   6.112 -
   6.113 -    id = sys.argv[2]
   6.114 -
   6.115 -    if len(sys.argv) > 3:
   6.116 -	expiry_time = int(sys.argv[3])
   6.117 -
   6.118 -    print "Refreshing a virtual disk"
   6.119 -    print "Id: " + id
   6.120 -    print "Expiry time (seconds from now [or 0]): " + str(expiry_time)
   6.121 -
   6.122 -    rc = vdisk.vd_refresh(id, expiry_time)
   6.123 -
   6.124 -elif cmd == 'list':
   6.125 -    print 'ID    Size(MB)      Expiry'
   6.126 -
   6.127 -    for vbd in vdisk.vd_list():
   6.128 -        vbd['size_mb'] = vbd['size'] / vdisk.VBD_SECTORS_PER_MB
   6.129 -        vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never'
   6.130 -        print '%(vdisk_id)-4s  %(size_mb)-12d  %(expiry)s' % vbd
   6.131 -
   6.132 -elif cmd == 'freespace':
   6.133 -
   6.134 -    print vdisk.vd_freespace()
   6.135 -
   6.136 -elif cmd == 'undelete':
   6.137 -
   6.138 -    id = sys.argv[2]
   6.139 -
   6.140 -    if len(sys.argv) > 3:
   6.141 -	expiry_time = int(sys.argv[3])
   6.142 -   
   6.143 -    if vdisk.vd_undelete(id, expiry_time):
   6.144 -	print "Undelete operation failed for virtual disk: " + id
   6.145 -    else:
   6.146 -	print "Undelete operation succeeded for virtual disk: " + id
   6.147 -
   6.148 -else:
   6.149 -    usage()
   6.150 -    sys.exit(-1)
   6.151 -
   6.152 -
   6.153 -if src != '':  
   6.154 -    print "Returned virtual disk id is : %s" % src
   6.155 -
   6.156 -if rc != '':
   6.157 -    print "return code %d" % rc
   6.158 -
   6.159 -
   6.160 -
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/examples/xmdefaults	Thu Jun 17 06:26:58 2004 +0000
     7.3 @@ -0,0 +1,96 @@
     7.4 +#  -*- mode: python; -*-
     7.5 +#============================================================================
     7.6 +# Python defaults setup for 'xm create'.
     7.7 +# Edit this file to reflect the configuration of your system.
     7.8 +# This file expects the variable 'vmid' to be set.
     7.9 +#============================================================================
    7.10 +
    7.11 +import sys
    7.12 +import xenctl.ip
    7.13 +
    7.14 +try:
    7.15 +    vmid = int(vmid) # convert to integer
    7.16 +except:
    7.17 +    raise ValueError, "Variable 'vmid' must be an integer"
    7.18 +
    7.19 +if vmid <= 0:
    7.20 +    raise ValueError, "Variable 'vmid' must be greater than 0" 
    7.21 +
    7.22 +
    7.23 +#----------------------------------------------------------------------------
    7.24 +# Kernel image file.
    7.25 +kernel = "../../../install/boot/vmlinuz-2.4.26-xen"
    7.26 +
    7.27 +# Optional ramdisk.
    7.28 +#ramdisk = "/boot/initrd.gz"
    7.29 +
    7.30 +# The domain build function. Default is 'linux'.
    7.31 +#builder='linux'
    7.32 +#builder='netbsd'
    7.33 +
    7.34 +# Initial memory allocation (in megabytes) for the new domain.
    7.35 +memory = 64
    7.36 +
    7.37 +# A handy name for your new domain.
    7.38 +name = "This is VM %d" % vmid
    7.39 +
    7.40 +# Which CPU to start domain on? 
    7.41 +#cpu = -1   # leave to Xen to pick
    7.42 +cpu = vmid  # set based on vmid (mod number of CPUs)
    7.43 +
    7.44 +#----------------------------------------------------------------------------
    7.45 +# Define network interfaces.
    7.46 +
    7.47 +# Number of network interfaces. Default is 1.
    7.48 +#nics=1
    7.49 +
    7.50 +# List of MAC addresses for the network interfaces.
    7.51 +# If there aren't enough addresses for all the interfaces
    7.52 +# the rest get random MACs.
    7.53 +#mac = [ "aa:00:00:00:00:11" ]
    7.54 +
    7.55 +#----------------------------------------------------------------------------
    7.56 +# Define the disk devices you want the domain to have access to, and
    7.57 +# what you want them accessible as.
    7.58 +# Each disk entry is of the form phy:DEV,VDEV,MODE
    7.59 +# where DEV is the device, VDEV is the device name the domain will see,
    7.60 +# and MODE is r for read-only, w for read-write.
    7.61 +
    7.62 +disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
    7.63 +         'phy:sda6,sda6,r' ]
    7.64 +
    7.65 +#----------------------------------------------------------------------------
    7.66 +# Set the kernel command line for the new domain.
    7.67 +# You only need to define the IP parameters and hostname if the domain's
    7.68 +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    7.69 +# You can use 'extra' to set the runlevel and custom environment
    7.70 +# variables used by custom rc scripts (e.g. VMID=, usr= ).
    7.71 +
    7.72 +# Set if you want dhcp to allocate the IP address.
    7.73 +#dhcp="dhcp"
    7.74 +# Set netmask.
    7.75 +#netmask=
    7.76 +# Set default gateway.
    7.77 +#gateway=
    7.78 +# Set the hostname.
    7.79 +#hostname= "vm%d" % vmid
    7.80 +
    7.81 +# Set root device.
    7.82 +root = "/dev/sda1 ro"
    7.83 +
    7.84 +# Root device for nfs.
    7.85 +#root = "/dev/nfs"
    7.86 +# The nfs server.
    7.87 +#nfs_server = '169.254.1.0'  
    7.88 +# Root directory on the nfs server.
    7.89 +#nfs_root   = '/full/path/to/root/directory'
    7.90 +
    7.91 +# Sets runlevel 4 and the device for /usr.
    7.92 +extra = "4 VMID=%d usr=/dev/sda6" % vmid
    7.93 +
    7.94 +#----------------------------------------------------------------------------
    7.95 +# Set according to whether you want the domain  restarted when it exits.
    7.96 +# The default is False.
    7.97 +#restart = True
    7.98 +
    7.99 +#============================================================================
     8.1 --- a/tools/xenctl/lib/vdisk.py	Wed Jun 16 21:29:21 2004 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,944 +0,0 @@
     8.4 -import os
     8.5 -import re
     8.6 -import socket
     8.7 -import string
     8.8 -import sys
     8.9 -import tempfile
    8.10 -import struct
    8.11 -
    8.12 -##### Module variables
    8.13 -
    8.14 -"""Location of the Virtual Disk management database.
    8.15 -   defaults to /var/db/xen_vdisks.sqlite
    8.16 -"""
    8.17 -VD_DB_FILE = "/var/db/xen_vdisks.sqlite"
    8.18 -
    8.19 -"""VBD expertise level - determines the strictness of the sanity checking.
    8.20 -  This mode determines the level of complaints when disk sharing occurs
    8.21 -  through the current VBD mappings.
    8.22 -   0 - only allow shared mappings if both domains have r/o access (always OK)
    8.23 -   1 - also allow sharing with one dom r/w and the other r/o
    8.24 -   2 - allow sharing with both doms r/w
    8.25 -"""
    8.26 -VBD_SAFETY_RR = 0
    8.27 -VBD_SAFETY_RW = 1
    8.28 -VBD_SAFETY_WW = 2
    8.29 -
    8.30 -VBD_SECTORS_PER_MB = 2048
    8.31 -
    8.32 -##### Module initialisation
    8.33 -
    8.34 -try:
    8.35 -    # try to import sqlite (not everyone will have it installed)
    8.36 -    import sqlite
    8.37 -except ImportError:
    8.38 -    # on failure, just catch the error, don't do anything
    8.39 -    pass
    8.40 -
    8.41 -
    8.42 -
    8.43 -##### VBD-related Functions
    8.44 -
    8.45 -def blkdev_name_to_number(name):
    8.46 -    """Take the given textual block-device name (e.g., '/dev/sda1',
    8.47 -    'hda') and return the device number used by the OS. """
    8.48 -
    8.49 -    if not re.match( '/dev/', name ):
    8.50 -        name = '/dev/' + name
    8.51 -        
    8.52 -    return os.stat(name).st_rdev
    8.53 -
    8.54 -# lookup_blkdev_partn_info( '/dev/sda3' )
    8.55 -def lookup_raw_partn(partition):
    8.56 -    """Take the given block-device name (e.g., '/dev/sda1', 'hda')
    8.57 -    and return a dictionary { device, start_sector,
    8.58 -    nr_sectors, type }
    8.59 -        device:       Device number of the given partition
    8.60 -        start_sector: Index of first sector of the partition
    8.61 -        nr_sectors:   Number of sectors comprising this partition
    8.62 -        type:         'Disk' or identifying name for partition type
    8.63 -    """
    8.64 -
    8.65 -    if not re.match( '/dev/', partition ):
    8.66 -        partition = '/dev/' + partition
    8.67 -
    8.68 -    drive = re.split( '[0-9]', partition )[0]
    8.69 -
    8.70 -    if drive == partition:
    8.71 -        fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
    8.72 -        line = readline(fd)
    8.73 -        if line:
    8.74 -            return [ { 'device' : blkdev_name_to_number(drive),
    8.75 -                       'start_sector' : long(0),
    8.76 -                       'nr_sectors' : long(line) * 2,
    8.77 -                       'type' : 'Disk' } ]
    8.78 -        return None
    8.79 -
    8.80 -    # determine position on disk
    8.81 -    fd = os.popen( '/sbin/sfdisk -d ' + drive + ' 2>/dev/null' )
    8.82 -
    8.83 -    #['/dev/sda3 : start= 16948575, size=16836120, Id=83, bootable\012']
    8.84 -    lines = readlines(fd)
    8.85 -    for line in lines:
    8.86 -        m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' +
    8.87 -                       'size=\s*([0-9]+), Id=\s*(\S+).*$', line)
    8.88 -        if m:
    8.89 -            return [ { 'device' : blkdev_name_to_number(drive),
    8.90 -                       'start_sector' : long(m.group(1)),
    8.91 -                       'nr_sectors' : long(m.group(2)),
    8.92 -                       'type' : m.group(3) } ]
    8.93 -    
    8.94 -    return None
    8.95 -
    8.96 -def lookup_disk_uname( uname ):
    8.97 -    """Lookup a list of segments for either a physical or a virtual device.
    8.98 -    uname [string]:  name of the device in the format \'vd:id\' for a virtual
    8.99 -                     disk, or \'phy:dev\' for a physical device
   8.100 -    returns [list of dicts]: list of extents that make up the named device
   8.101 -    """
   8.102 -    ( type, d_name ) = string.split( uname, ':' )
   8.103 -
   8.104 -    if type == "phy":
   8.105 -        segments = lookup_raw_partn( d_name )
   8.106 -    elif type == "vd":
   8.107 -	segments = vd_lookup( d_name )
   8.108 -
   8.109 -    return segments
   8.110 -
   8.111 -
   8.112 -##### VD Management-related functions
   8.113 -
   8.114 -##### By Mark Williamson, <mark.a.williamson@intel.com>
   8.115 -##### (C) Intel Research Cambridge
   8.116 -
   8.117 -# TODO:
   8.118 -#
   8.119 -# Plenty of room for enhancement to this functionality (contributions
   8.120 -# welcome - and then you get to have your name in the source ;-)...
   8.121 -#
   8.122 -# vd_unformat() : want facilities to unallocate virtual disk
   8.123 -# partitions, possibly migrating virtual disks of them, with checks to see if
   8.124 -# it's safe and options to force it anyway
   8.125 -#
   8.126 -# vd_create() : should have an optional argument specifying a physical
   8.127 -# disk preference - useful to allocate for guest doms to do RAID
   8.128 -#
   8.129 -# vd_undelete() : add ability to "best effort" undelete as much of a
   8.130 -# vdisk as is left in the case that some of it has already been
   8.131 -# reallocated.  Some people might still be able to recover some of
   8.132 -# their data this way, even if some of the disk has disappeared.
   8.133 -#
   8.134 -# It'd be nice if we could wipe virtual disks for security purposes -
   8.135 -# should be easy to do this using dev if=/dev/{zero,random} on each
   8.136 -# extent in turn.  There could be another optional flag to vd_create
   8.137 -# in order to allow this.
   8.138 -#
   8.139 -# Error codes could be more expressive - i.e. actually tell why the
   8.140 -# error occurred rather than "it broke".  Currently the code avoids
   8.141 -# using exceptions to make control scripting simpler and more
   8.142 -# accessible to beginners - therefore probably should just use more
   8.143 -# return codes.
   8.144 -#
   8.145 -# Enhancements / additions to the example scripts are also welcome:
   8.146 -# some people will interact with this code mostly through those
   8.147 -# scripts.
   8.148 -#
   8.149 -# More documentation of how this stuff should be used is always nice -
   8.150 -# if you have a novel configuration that you feel isn't discussed
   8.151 -# enough in the HOWTO (which is currently a work in progress), feel
   8.152 -# free to contribute a walkthrough, or something more substantial.
   8.153 -#
   8.154 -
   8.155 -
   8.156 -def __vd_no_database():
   8.157 -    """Called when no database found - exits with an error
   8.158 -    """
   8.159 -    print >> sys.stderr, "ERROR: Could not locate the database file at " + VD_DB_FILE
   8.160 -    sys.exit(1)
   8.161 -
   8.162 -def readlines(fd):
   8.163 -    """Version of readlines safe against EINTR.
   8.164 -    """
   8.165 -    import errno
   8.166 -    
   8.167 -    lines = []
   8.168 -    while 1:
   8.169 -        try:
   8.170 -            line = fd.readline()
   8.171 -        except IOError, ex:
   8.172 -            if ex.errno == errno.EINTR:
   8.173 -                continue
   8.174 -            else:
   8.175 -                raise
   8.176 -        if line == '': break
   8.177 -        lines.append(line)
   8.178 -    return lines
   8.179 -
   8.180 -def readline(fd):
   8.181 -    """Version of readline safe against EINTR.
   8.182 -    """
   8.183 -    while 1:
   8.184 -        try:
   8.185 -            return fd.readline()
   8.186 -        except IOError, ex:
   8.187 -            if ex.errno == errno.EINTR:
   8.188 -                continue
   8.189 -            else:
   8.190 -                raise
   8.191 -        
   8.192 -
   8.193 -def vd_format(partition, extent_size_mb):
   8.194 -    """Format a partition or drive for use a virtual disk storage.
   8.195 -    partition [string]: device file representing the partition
   8.196 -    extent_size_mb [string]: extent size in megabytes to use on this disk
   8.197 -    """
   8.198 -
   8.199 -    if not os.path.isfile(VD_DB_FILE):
   8.200 -        vd_init_db(VD_DB_FILE)
   8.201 -    
   8.202 -    if not re.match( '/dev/', partition ):
   8.203 -        partition = '/dev/' + partition
   8.204 -
   8.205 -    cx = sqlite.connect(VD_DB_FILE)
   8.206 -    cu = cx.cursor()
   8.207 -
   8.208 -    cu.execute("select * from vdisk_part where partition = \'"
   8.209 -               + partition + "\'")
   8.210 -    row = cu.fetchone()
   8.211 -
   8.212 -    extent_size = extent_size_mb * VBD_SECTORS_PER_MB # convert megabytes to sectors
   8.213 -    
   8.214 -    if not row:
   8.215 -        part_info = lookup_raw_partn(partition)[0]
   8.216 -        
   8.217 -        cu.execute("INSERT INTO vdisk_part(partition, part_id, extent_size) " +
   8.218 -                   "VALUES ( \'" + partition + "\', "
   8.219 -                   + str(blkdev_name_to_number(partition))
   8.220 -                   + ", " + str(extent_size) + ")")
   8.221 -
   8.222 -
   8.223 -        cu.execute("SELECT max(vdisk_extent_no) FROM vdisk_extents "
   8.224 -                   + "WHERE vdisk_id = 0")
   8.225 -        
   8.226 -        max_id, = cu.fetchone()
   8.227 -
   8.228 -        if max_id != None:
   8.229 -            new_id = max_id + 1
   8.230 -        else:
   8.231 -            new_id = 0
   8.232 -
   8.233 -        num_extents = part_info['nr_sectors'] / extent_size
   8.234 -
   8.235 -        for i in range(num_extents):
   8.236 -            sql ="""INSERT INTO vdisk_extents(vdisk_extent_no, vdisk_id,
   8.237 -                                              part_id, part_extent_no)
   8.238 -                    VALUES ("""+ str(new_id + i) + ", 0, "\
   8.239 -                               + str(blkdev_name_to_number(partition))\
   8.240 -                               + ", " + str(num_extents - (i + 1)) + ")"
   8.241 -            cu.execute(sql)
   8.242 -
   8.243 -    cx.commit()
   8.244 -    cx.close()
   8.245 -    return 0
   8.246 -
   8.247 -
   8.248 -def vd_create(size_mb, expiry):
   8.249 -    """Create a new virtual disk.
   8.250 -    size_mb [int]: size in megabytes for the new virtual disk
   8.251 -    expiry [int]: expiry time in seconds from now
   8.252 -    """
   8.253 -
   8.254 -    if not os.path.isfile(VD_DB_FILE):
   8.255 -        __vd_no_database()
   8.256 -
   8.257 -    cx = sqlite.connect(VD_DB_FILE)
   8.258 -    cu = cx.cursor()
   8.259 -
   8.260 -    size = size_mb * VBD_SECTORS_PER_MB
   8.261 -
   8.262 -    cu.execute("SELECT max(vdisk_id) FROM vdisks")
   8.263 -    max_id, = cu.fetchone()
   8.264 -    new_id = int(max_id) + 1
   8.265 -
   8.266 -    # fetch a list of extents from the expired disks, along with information
   8.267 -    # about their size
   8.268 -    cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
   8.269 -                         vdisk_extents.part_id, extent_size
   8.270 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.271 -                                                  NATURAL JOIN vdisk_part
   8.272 -                  WHERE expires AND expiry_time <= datetime('now')
   8.273 -                  ORDER BY expiry_time ASC, vdisk_extent_no DESC
   8.274 -               """)  # aims to reuse the last extents
   8.275 -                     # from the longest-expired disks first
   8.276 -
   8.277 -    allocated = 0
   8.278 -
   8.279 -    if expiry:
   8.280 -        expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
   8.281 -        expires = 1
   8.282 -    else:
   8.283 -        expiry_ts = "NULL"
   8.284 -        expires = 0
   8.285 -
   8.286 -    # we'll use this to build the SQL statement we want
   8.287 -    building_sql = "INSERT INTO vdisks(vdisk_id, size, expires, expiry_time)" \
   8.288 -                   +" VALUES ("+str(new_id)+", "+str(size)+ ", "              \
   8.289 -                   + str(expires) + ", " + expiry_ts + "); "
   8.290 -
   8.291 -    counter = 0
   8.292 -
   8.293 -    while allocated < size:
   8.294 -        row = cu.fetchone()
   8.295 -        if not row:
   8.296 -            print "ran out of space, having allocated %d meg of %d" % (allocated, size)
   8.297 -            cx.close()
   8.298 -            return -1
   8.299 -        
   8.300 -
   8.301 -        (vdisk_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
   8.302 -        allocated += extent_size
   8.303 -        building_sql += "UPDATE vdisk_extents SET vdisk_id = " + str(new_id) \
   8.304 -                        + ", " + "vdisk_extent_no = " + str(counter)         \
   8.305 -                        + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
   8.306 -                        + " AND vdisk_id = " + str(vdisk_id) + "; "
   8.307 -
   8.308 -        counter += 1
   8.309 -        
   8.310 -
   8.311 -    # this will execute the SQL query we build to store details of the new
   8.312 -    # virtual disk and allocate space to it print building_sql
   8.313 -    cu.execute(building_sql)
   8.314 -    
   8.315 -    cx.commit()
   8.316 -    cx.close()
   8.317 -    return str(new_id)
   8.318 -
   8.319 -
   8.320 -def vd_lookup(id):
   8.321 -    """Lookup a Virtual Disk by ID.
   8.322 -    id [string]: a virtual disk identifier
   8.323 -    Returns [list of dicts]: a list of extents as dicts, containing fields:
   8.324 -                             device : Linux device number of host disk
   8.325 -                             start_sector : within the device
   8.326 -                             nr_sectors : size of this extent
   8.327 -                             type : set to \'VD Extent\'
   8.328 -                             
   8.329 -                             part_device : Linux device no of host partition
   8.330 -                             part_start_sector : within the partition
   8.331 -    """
   8.332 -
   8.333 -    if not os.path.isfile(VD_DB_FILE):
   8.334 -        __vd_no_database()
   8.335 -
   8.336 -    cx = sqlite.connect(VD_DB_FILE)
   8.337 -    cu = cx.cursor()
   8.338 -
   8.339 -    cu.execute("-- types int")
   8.340 -    cu.execute("""SELECT COUNT(*)
   8.341 -                  FROM vdisks
   8.342 -                  WHERE (expiry_time > datetime('now') OR NOT expires)
   8.343 -                              AND vdisk_id = """ + id)
   8.344 -    count, = cu.fetchone()
   8.345 -
   8.346 -    if not count:
   8.347 -        cx.close()
   8.348 -        return None
   8.349 -
   8.350 -    cu.execute("SELECT size from vdisks WHERE vdisk_id = " + id)
   8.351 -    real_size, = cu.fetchone()
   8.352 -  
   8.353 -    # This query tells PySQLite how to convert the data returned from the
   8.354 -    # following query - the use of the multiplication confuses it otherwise ;-)
   8.355 -    # This row is significant to PySQLite but is syntactically an SQL comment.
   8.356 -
   8.357 -    cu.execute("-- types str, int, int, int")
   8.358 -
   8.359 -    # This SQL statement is designed so that when the results are fetched they
   8.360 -    # will be in the right format to return immediately.
   8.361 -    cu.execute("""SELECT partition, vdisk_part.part_id,
   8.362 -                         round(part_extent_no * extent_size) as start,
   8.363 -                         extent_size
   8.364 -                         
   8.365 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.366 -                                             NATURAL JOIN vdisk_part
   8.367 -                                                
   8.368 -                  WHERE vdisk_extents.vdisk_id = """ + id
   8.369 -               + " ORDER BY vdisk_extents.vdisk_extent_no ASC"
   8.370 -               )
   8.371 -
   8.372 -    extent_tuples = cu.fetchall()
   8.373 -
   8.374 -    # use this function to map the results from the database into a dict
   8.375 -    # list of extents, for consistency with the rest of the code
   8.376 -    def transform ((partition, part_device, part_offset, nr_sectors)):
   8.377 -        return {
   8.378 -                 # the disk device this extent is on - for passing to Xen
   8.379 -                 'device' : lookup_raw_partn(partition)[0]['device'],
   8.380 -                 # the offset of this extent within the disk - for passing to Xen
   8.381 -                 'start_sector' : long(part_offset + lookup_raw_partn(partition)[0]['start_sector']),
   8.382 -                 # extent size, in sectors
   8.383 -                 'nr_sectors' : nr_sectors,
   8.384 -                 # partition device this extent is on (useful to know for xenctl.utils fns)
   8.385 -                 'part_device' : part_device,
   8.386 -                 # start sector within this partition (useful to know for xenctl.utils fns)
   8.387 -                 'part_start_sector' : part_offset,
   8.388 -                 # type of this extent - handy to know
   8.389 -                 'type' : 'VD Extent' }
   8.390 -
   8.391 -    cx.commit()
   8.392 -    cx.close()
   8.393 -
   8.394 -    extent_dicts = map(transform, extent_tuples)
   8.395 -
   8.396 -    # calculate the over-allocation in sectors (happens because
   8.397 -    # we allocate whole extents)
   8.398 -    allocated_size = 0
   8.399 -    for i in extent_dicts:
   8.400 -        allocated_size += i['nr_sectors']
   8.401 -
   8.402 -    over_allocation = allocated_size - real_size
   8.403 -
   8.404 -    # trim down the last extent's length so the resulting VBD will be the
   8.405 -    # size requested, rather than being rounded up to the nearest extent
   8.406 -    extent_dicts[len(extent_dicts) - 1]['nr_sectors'] -= over_allocation
   8.407 -
   8.408 -    return extent_dicts
   8.409 -
   8.410 -
   8.411 -def vd_enlarge(vdisk_id, extra_size_mb):
   8.412 -    """Create a new virtual disk.
   8.413 -    vdisk_id [string]   :    ID of the virtual disk to enlarge
   8.414 -    extra_size_mb  [int]:    size in megabytes to increase the allocation by
   8.415 -    returns  [int]      :    0 on success, otherwise non-zero
   8.416 -    """
   8.417 -
   8.418 -    if not os.path.isfile(VD_DB_FILE):
   8.419 -        __vd_no_database()
   8.420 -
   8.421 -    cx = sqlite.connect(VD_DB_FILE)
   8.422 -    cu = cx.cursor()
   8.423 -
   8.424 -    extra_size = extra_size_mb * VBD_SECTORS_PER_MB
   8.425 -
   8.426 -    cu.execute("-- types int")
   8.427 -    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id
   8.428 -               + " AND (expiry_time > datetime('now') OR NOT expires)")
   8.429 -    count, = cu.fetchone()
   8.430 -
   8.431 -    if not count: # no such vdisk
   8.432 -        cx.close()
   8.433 -        return -1
   8.434 -
   8.435 -    cu.execute("-- types int")
   8.436 -    cu.execute("""SELECT SUM(extent_size)
   8.437 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.438 -                                         NATURAL JOIN vdisk_part
   8.439 -                  WHERE vdisks.vdisk_id = """ + vdisk_id)
   8.440 -
   8.441 -    real_size, = cu.fetchone() # get the true allocated size
   8.442 -
   8.443 -    cu.execute("-- types int")
   8.444 -    cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
   8.445 -
   8.446 -    old_size, = cu.fetchone()
   8.447 -
   8.448 -
   8.449 -    cu.execute("--- types int")
   8.450 -    cu.execute("""SELECT MAX(vdisk_extent_no)
   8.451 -                  FROM vdisk_extents
   8.452 -                  WHERE vdisk_id = """ + vdisk_id)
   8.453 -
   8.454 -    counter = cu.fetchone()[0] + 1 # this stores the extent numbers
   8.455 -
   8.456 -
   8.457 -    # because of the extent-based allocation, the VD may already have more
   8.458 -    # allocated space than they asked for.  Find out how much we really
   8.459 -    # need to add.
   8.460 -    add_size = extra_size + old_size - real_size
   8.461 -
   8.462 -    # fetch a list of extents from the expired disks, along with information
   8.463 -    # about their size
   8.464 -    cu.execute("""SELECT vdisks.vdisk_id, vdisk_extent_no, part_extent_no,
   8.465 -                         vdisk_extents.part_id, extent_size
   8.466 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.467 -                                                  NATURAL JOIN vdisk_part
   8.468 -                  WHERE expires AND expiry_time <= datetime('now')
   8.469 -                  ORDER BY expiry_time ASC, vdisk_extent_no DESC
   8.470 -               """)  # aims to reuse the last extents
   8.471 -                     # from the longest-expired disks first
   8.472 -
   8.473 -    allocated = 0
   8.474 -
   8.475 -    building_sql = "UPDATE vdisks SET size = " + str(old_size + extra_size)\
   8.476 -                   + " WHERE vdisk_id = " + vdisk_id + "; "
   8.477 -
   8.478 -    while allocated < add_size:
   8.479 -        row = cu.fetchone()
   8.480 -        if not row:
   8.481 -            cx.close()
   8.482 -            return -1
   8.483 -
   8.484 -        (dead_vd_id, vdisk_extent_no, part_extent_no, part_id, extent_size) = row
   8.485 -        allocated += extent_size
   8.486 -        building_sql += "UPDATE vdisk_extents SET vdisk_id = " + vdisk_id    \
   8.487 -                        + ", " + "vdisk_extent_no = " + str(counter)         \
   8.488 -                        + " WHERE vdisk_extent_no = " + str(vdisk_extent_no) \
   8.489 -                        + " AND vdisk_id = " + str(dead_vd_id) + "; "
   8.490 -
   8.491 -        counter += 1
   8.492 -        
   8.493 -
   8.494 -    # this will execute the SQL query we build to store details of the new
   8.495 -    # virtual disk and allocate space to it print building_sql
   8.496 -    cu.execute(building_sql)
   8.497 -    
   8.498 -    cx.commit()
   8.499 -    cx.close()
   8.500 -    return 0
   8.501 -
   8.502 -
   8.503 -def vd_undelete(vdisk_id, expiry_time):
   8.504 -    """Create a new virtual disk.
   8.505 -    vdisk_id      [int]: size in megabytes for the new virtual disk
   8.506 -    expiry_time   [int]: expiry time, in seconds from now
   8.507 -    returns       [int]: zero on success, non-zero on failure
   8.508 -    """
   8.509 -
   8.510 -    if not os.path.isfile(VD_DB_FILE):
   8.511 -        __vd_no_database()
   8.512 -
   8.513 -    if vdisk_id == '0': #  undeleting vdisk 0 isn't sane!
   8.514 -        return -1
   8.515 -
   8.516 -    cx = sqlite.connect(VD_DB_FILE)
   8.517 -    cu = cx.cursor()
   8.518 -
   8.519 -    cu.execute("-- types int")
   8.520 -    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + vdisk_id)
   8.521 -    count, = cu.fetchone()
   8.522 -
   8.523 -    if not count:
   8.524 -        cx.close()
   8.525 -        return -1
   8.526 -
   8.527 -    cu.execute("-- types int")
   8.528 -    cu.execute("""SELECT SUM(extent_size)
   8.529 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.530 -                                         NATURAL JOIN vdisk_part
   8.531 -                  WHERE vdisks.vdisk_id = """ + vdisk_id)
   8.532 -
   8.533 -    real_size, = cu.fetchone() # get the true allocated size
   8.534 -
   8.535 -
   8.536 -    cu.execute("-- types int")
   8.537 -    cu.execute("SELECT size FROM vdisks WHERE vdisk_id = " + vdisk_id)
   8.538 -
   8.539 -    old_size, = cu.fetchone()
   8.540 -
   8.541 -    if real_size < old_size:
   8.542 -        cx.close()
   8.543 -        return -1
   8.544 -
   8.545 -    if expiry_time == 0:
   8.546 -        expires = '0'
   8.547 -    else:
   8.548 -        expires = '1'
   8.549 -
   8.550 -    # this will execute the SQL query we build to store details of the new
   8.551 -    # virtual disk and allocate space to it print building_sql
   8.552 -    cu.execute("UPDATE vdisks SET expiry_time = datetime('now','"
   8.553 -               + str(expiry_time) + " seconds'), expires = " + expires
   8.554 -               + " WHERE vdisk_id = " + vdisk_id)
   8.555 -    
   8.556 -    cx.commit()
   8.557 -    cx.close()
   8.558 -    return 0
   8.559 -
   8.560 -
   8.561 -
   8.562 -
   8.563 -def vd_list():
   8.564 -    """Lists all the virtual disks registered in the system.
   8.565 -    returns [list of dicts]
   8.566 -    """
   8.567 -    
   8.568 -    if not os.path.isfile(VD_DB_FILE):
   8.569 -        __vd_no_database()
   8.570 -
   8.571 -    cx = sqlite.connect(VD_DB_FILE)
   8.572 -    cu = cx.cursor()
   8.573 -
   8.574 -    cu.execute("""SELECT vdisk_id, size, expires, expiry_time
   8.575 -                  FROM vdisks
   8.576 -                  WHERE (NOT expires) OR expiry_time > datetime('now')
   8.577 -               """)
   8.578 -
   8.579 -    ret = cu.fetchall()
   8.580 -
   8.581 -    cx.close()
   8.582 -
   8.583 -    def makedicts((vdisk_id, size, expires, expiry_time)):
   8.584 -        return { 'vdisk_id' : str(vdisk_id), 'size': size,
   8.585 -                 'expires' : expires, 'expiry_time' : expiry_time }
   8.586 -
   8.587 -    return map(makedicts, ret)
   8.588 -
   8.589 -
   8.590 -def vd_refresh(id, expiry):
   8.591 -    """Change the expiry time of a virtual disk.
   8.592 -    id [string]  : a virtual disk identifier
   8.593 -    expiry [int] : expiry time in seconds from now (0 = never expire)
   8.594 -    returns [int]: zero on success, non-zero on failure
   8.595 -    """
   8.596 -
   8.597 -    if not os.path.isfile(VD_DB_FILE):
   8.598 -        __vd_no_database()
   8.599 -    
   8.600 -    cx = sqlite.connect(VD_DB_FILE)
   8.601 -    cu = cx.cursor()
   8.602 -
   8.603 -    cu.execute("-- types int")
   8.604 -    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
   8.605 -               + " AND (expiry_time > datetime('now') OR NOT expires)")
   8.606 -    count, = cu.fetchone()
   8.607 -
   8.608 -    if not count:
   8.609 -        cx.close()
   8.610 -        return -1
   8.611 -
   8.612 -    if expiry:
   8.613 -        expires = 1
   8.614 -        expiry_ts = "datetime('now', '" + str(expiry) + " seconds')"
   8.615 -    else:
   8.616 -        expires = 0
   8.617 -        expiry_ts = "NULL"
   8.618 -
   8.619 -    cu.execute("UPDATE vdisks SET expires = " + str(expires)
   8.620 -               + ", expiry_time = " + expiry_ts
   8.621 -               + " WHERE (expiry_time > datetime('now') OR NOT expires)"
   8.622 -               + " AND vdisk_id = " + id)
   8.623 -
   8.624 -    cx.commit()
   8.625 -    cx.close()
   8.626 -    
   8.627 -    return 0
   8.628 -
   8.629 -
   8.630 -def vd_delete(id):
   8.631 -    """Deletes a Virtual Disk, making its extents available for future VDs.
   8.632 -       id [string]   : identifier for the virtual disk to delete
   8.633 -       returns [int] : 0 on success, -1 on failure (VD not found
   8.634 -                       or already deleted)
   8.635 -    """
   8.636 -
   8.637 -    if not os.path.isfile(VD_DB_FILE):
   8.638 -        __vd_no_database()
   8.639 -    
   8.640 -    cx = sqlite.connect(VD_DB_FILE)
   8.641 -    cu = cx.cursor()
   8.642 -
   8.643 -    cu.execute("-- types int")
   8.644 -    cu.execute("SELECT COUNT(*) FROM vdisks WHERE vdisk_id = " + id
   8.645 -               + " AND (expiry_time > datetime('now') OR NOT expires)")
   8.646 -    count, = cu.fetchone()
   8.647 -
   8.648 -    if not count:
   8.649 -        cx.close()
   8.650 -        return -1
   8.651 -
   8.652 -    cu.execute("UPDATE vdisks SET expires = 1, expiry_time = datetime('now')"
   8.653 -               + " WHERE vdisk_id = " + id)
   8.654 -
   8.655 -    cx.commit()
   8.656 -    cx.close()
   8.657 -    
   8.658 -    return 0
   8.659 -
   8.660 -
   8.661 -def vd_freespace():
   8.662 -    """Returns the amount of free space available for new virtual disks, in MB
   8.663 -    returns [int] : free space for VDs in MB
   8.664 -    """
   8.665 -
   8.666 -    if not os.path.isfile(VD_DB_FILE):
   8.667 -        __vd_no_database()
   8.668 - 
   8.669 -    cx = sqlite.connect(VD_DB_FILE)
   8.670 -    cu = cx.cursor()
   8.671 -
   8.672 -    cu.execute("-- types int")
   8.673 -
   8.674 -    cu.execute("""SELECT SUM(extent_size)
   8.675 -                  FROM vdisks NATURAL JOIN vdisk_extents
   8.676 -                                           NATURAL JOIN vdisk_part
   8.677 -                  WHERE expiry_time <= datetime('now') AND expires""")
   8.678 -
   8.679 -    sum, = cu.fetchone()
   8.680 -
   8.681 -    cx.close()
   8.682 -
   8.683 -    return sum / VBD_SECTORS_PER_MB
   8.684 -
   8.685 -
   8.686 -def vd_init_db(path):
   8.687 -    """Initialise the VD SQLite database
   8.688 -    path [string]: path to the SQLite database file
   8.689 -    """
   8.690 -
   8.691 -    cx = sqlite.connect(path)
   8.692 -    cu = cx.cursor()
   8.693 -
   8.694 -    cu.execute(
   8.695 -        """CREATE TABLE vdisk_extents
   8.696 -                           ( vdisk_extent_no INT,
   8.697 -                             vdisk_id INT,
   8.698 -                             part_id INT,
   8.699 -                             part_extent_no INT )
   8.700 -        """)
   8.701 -
   8.702 -    cu.execute(
   8.703 -        """CREATE TABLE vdisk_part
   8.704 -                           ( part_id INT,
   8.705 -                             partition VARCHAR,
   8.706 -                             extent_size INT )
   8.707 -        """)
   8.708 -
   8.709 -    cu.execute(
   8.710 -        """CREATE TABLE vdisks
   8.711 -                           ( vdisk_id INT,
   8.712 -                             size INT,
   8.713 -                             expires BOOLEAN,
   8.714 -                             expiry_time TIMESTAMP )
   8.715 -        """)
   8.716 -
   8.717 -
   8.718 -    cu.execute(
   8.719 -        """INSERT INTO vdisks ( vdisk_id, size, expires, expiry_time )
   8.720 -                       VALUES ( 0,        0,    1,       datetime('now') )
   8.721 -        """)
   8.722 -
   8.723 -    cx.commit()
   8.724 -    cx.close()
   8.725 -
   8.726 -    VD_DB_FILE = path
   8.727 -
   8.728 -
   8.729 -
   8.730 -def vd_cp_to_file(vdisk_id,filename):
   8.731 -    """Writes the contents of a specified vdisk out into a disk file, leaving
   8.732 -    the original copy in the virtual disk pool."""
   8.733 -
   8.734 -    cx = sqlite.connect(VD_DB_FILE)
   8.735 -    cu = cx.cursor()
   8.736 -
   8.737 -    extents = vd_lookup(vdisk_id)
   8.738 -
   8.739 -    if not extents:
   8.740 -        return -1
   8.741 -    
   8.742 -    file_idx = 0 # index into source file, in sectors
   8.743 -
   8.744 -    for i in extents:
   8.745 -        cu.execute("""SELECT partition, extent_size FROM vdisk_part
   8.746 -                      WHERE part_id =  """ + str(i['part_device']))
   8.747 -
   8.748 -        (partition, extent_size) = cu.fetchone()
   8.749 -
   8.750 -        os.system("dd bs=1b if=" + partition + " of=" + filename
   8.751 -                  + " skip=" + str(i['part_start_sector'])
   8.752 -                  + " seek=" + str(file_idx)
   8.753 -                  + " count=" + str(i['nr_sectors'])
   8.754 -                  + " > /dev/null")
   8.755 -
   8.756 -        file_idx += i['nr_sectors']
   8.757 -
   8.758 -    cx.close()
   8.759 -
   8.760 -    return 0 # should return -1 if something breaks
   8.761 -    
   8.762 -
   8.763 -def vd_mv_to_file(vdisk_id,filename):
   8.764 -    """Writes a vdisk out into a disk file and frees the space originally
   8.765 -    taken within the virtual disk pool.
   8.766 -    vdisk_id [string]: ID of the vdisk to write out
   8.767 -    filename [string]: file to write vdisk contents out to
   8.768 -    returns [int]: zero on success, nonzero on failure
   8.769 -    """
   8.770 -
   8.771 -    if vd_cp_to_file(vdisk_id,filename):
   8.772 -        return -1
   8.773 -
   8.774 -    if vd_delete(vdisk_id):
   8.775 -        return -1
   8.776 -
   8.777 -    return 0
   8.778 -
   8.779 -
   8.780 -def vd_read_from_file(filename,expiry):
   8.781 -    """Reads the contents of a file directly into a vdisk, which is
   8.782 -    automatically allocated to fit.
   8.783 -    filename [string]: file to read disk contents from
   8.784 -    returns [string] : vdisk ID for the destination vdisk
   8.785 -    """
   8.786 -
   8.787 -    size_bytes = os.stat(filename).st_size
   8.788 -
   8.789 -    (size_mb,leftover) =  divmod(size_bytes,1048580) # size in megabytes
   8.790 -    if leftover > 0: size_mb += 1 # round up if not an exact number of MB
   8.791 -
   8.792 -    vdisk_id = vd_create(size_mb, expiry)
   8.793 -
   8.794 -    if vdisk_id < 0:
   8.795 -        return -1
   8.796 -
   8.797 -    cx = sqlite.connect(VD_DB_FILE)
   8.798 -    cu = cx.cursor()
   8.799 -
   8.800 -    cu.execute("""SELECT partition, extent_size, part_extent_no
   8.801 -                  FROM vdisk_part NATURAL JOIN vdisk_extents
   8.802 -                  WHERE vdisk_id =  """ + vdisk_id + """
   8.803 -                  ORDER BY vdisk_extent_no ASC""")
   8.804 -
   8.805 -    extents = cu.fetchall()
   8.806 -
   8.807 -    size_sectors = size_mb * VBD_SECTORS_PER_MB # for feeding to dd
   8.808 -
   8.809 -    file_idx = 0 # index into source file, in sectors
   8.810 -
   8.811 -    def write_extent_to_vd((partition, extent_size, part_extent_no),
   8.812 -                           file_idx, filename):
   8.813 -        """Write an extent out to disk and update file_idx"""
   8.814 -
   8.815 -        os.system("dd bs=512 if=" + filename + " of=" + partition
   8.816 -                  + " skip=" + str(file_idx)
   8.817 -                  + " seek=" + str(part_extent_no * extent_size)
   8.818 -                  + " count=" + str(min(extent_size, size_sectors - file_idx))
   8.819 -                  + " > /dev/null")
   8.820 -
   8.821 -        return extent_size
   8.822 -
   8.823 -    for i in extents:
   8.824 -        file_idx += write_extent_to_vd(i, file_idx, filename)
   8.825 -
   8.826 -    cx.close()
   8.827 -
   8.828 -    return vdisk_id
   8.829 -    
   8.830 -
   8.831 -
   8.832 -
   8.833 -def vd_extents_validate(new_extents, new_writeable, safety=VBD_SAFETY_RR):
   8.834 -    """Validate the extents against the existing extents.
   8.835 -    Complains if the list supplied clashes against the extents that
   8.836 -    are already in use in the system.
   8.837 -    new_extents [list of dicts]: list of new extents, as dicts
   8.838 -    new_writeable [int]: 1 if they are to be writeable, 0 otherwise
   8.839 -    returns [int]: either the expertise level of the mapping if it doesn't
   8.840 -                   exceed VBD_EXPERT_MODE or -1 if it does (error)
   8.841 -    """
   8.842 -
   8.843 -    import Xc # this is only needed in this function
   8.844 -
   8.845 -    xc = Xc.new()
   8.846 -
   8.847 -    ##### Probe for explicitly created virtual disks and build a list
   8.848 -    ##### of extents for comparison with the ones that are being added
   8.849 -
   8.850 -    probe = xc.vbd_probe()
   8.851 -
   8.852 -    old_extents = [] # this will hold a list of all existing extents and
   8.853 -                     # their writeable status, as a list of (device,
   8.854 -                     # start, size, writeable?) tuples
   8.855 -
   8.856 -    for vbd in probe:
   8.857 -        this_vbd_extents = xc.vbd_getextents(vbd['dom'],vbd['vbd'])
   8.858 -        for vbd_ext in this_vbd_extents:
   8.859 -            vbd_ext['writeable'] = vbd['writeable']
   8.860 -            old_extents.append(vbd_ext)
   8.861 -            
   8.862 -    ##### Now scan /proc/mounts for compile a list of extents corresponding to
   8.863 -    ##### any devices mounted in DOM0.  This list is added on to old_extents
   8.864 -
   8.865 -    regexp = re.compile("/dev/(\S*) \S* \S* (..).*")
   8.866 -    fd = open('/proc/mounts', "r")
   8.867 -
   8.868 -    while True:
   8.869 -        line = readline(fd)
   8.870 -        if not line: # if we've run out of lines then stop reading
   8.871 -            break
   8.872 -        
   8.873 -        m = regexp.match(line)
   8.874 -
   8.875 -        # if the regexp didn't match then it's probably a line we don't
   8.876 -        # care about - skip to next line
   8.877 -        if not m:
   8.878 -            continue
   8.879 -
   8.880 -        # lookup the device
   8.881 -        ext_list = lookup_raw_partn(m.group(1))
   8.882 -
   8.883 -        # if lookup failed, skip to next mounted device
   8.884 -        if not ext_list:
   8.885 -            continue
   8.886 -
   8.887 -        # set a writeable flag as appropriate
   8.888 -        for ext in ext_list:
   8.889 -            ext['writeable'] = m.group(2) == 'rw'
   8.890 -
   8.891 -        # now we've got here, the contents of ext_list are in a
   8.892 -        # suitable format to be added onto the old_extents list, ready
   8.893 -        # for checking against the new extents
   8.894 -
   8.895 -        old_extents.extend(ext_list)
   8.896 -
   8.897 -    fd.close() # close /proc/mounts
   8.898 -
   8.899 -    ##### By this point, old_extents contains a list of extents, in
   8.900 -    ##### dictionary format corresponding to every extent of physical
   8.901 -    ##### disk that's either part of an explicitly created VBD, or is
   8.902 -    ##### mounted under DOM0.  We now check these extents against the
   8.903 -    ##### proposed additions in new_extents, to see if a conflict will
   8.904 -    ##### happen if they are added with write status new_writeable
   8.905 -
   8.906 -    level = 0 # this'll accumulate the max warning level
   8.907 -
   8.908 -    # Search for clashes between the new extents and the old ones
   8.909 -    # Takes time O(len(new_extents) * len(old_extents))
   8.910 -    for new_ext in new_extents:
   8.911 -        for old_ext in old_extents:
   8.912 -            if(new_ext['device'] == old_ext['device']):
   8.913 -
   8.914 -                new_ext_start = new_ext['start_sector']
   8.915 -                new_ext_end = new_ext_start + new_ext['nr_sectors'] - 1
   8.916 -                
   8.917 -                old_ext_start = old_ext['start_sector']
   8.918 -                old_ext_end = old_ext_start + old_ext['nr_sectors'] - 1
   8.919 -                
   8.920 -                if((old_ext_start <= new_ext_start <= old_ext_end) or
   8.921 -                   (old_ext_start <= new_ext_end <= old_ext_end)):
   8.922 -                    if (not old_ext['writeable']) and new_writeable:
   8.923 -                        level = max(1,level)
   8.924 -                    elif old_ext['writeable'] and (not new_writeable):
   8.925 -                        level = max(1,level)
   8.926 -                    elif old_ext['writeable'] and new_writeable:
   8.927 -                        level = max(2,level)
   8.928 -
   8.929 -
   8.930 -    ##### level now holds the warning level incurred by the current
   8.931 -    ##### VBD setup and we complain appropriately to the user
   8.932 -
   8.933 -
   8.934 -    if level == 1:
   8.935 -        print >> sys.stderr, """Warning: one or more hard disk extents
   8.936 -         writeable by one domain are also readable by another."""
   8.937 -    elif level == 2:
   8.938 -        print >> sys.stderr, """Warning: one or more hard disk extents are
   8.939 -         writeable by two or more domains simultaneously."""
   8.940 -
   8.941 -    if level > safety:
   8.942 -        print >> sys.stderr, """ERROR: This kind of disk sharing is not allowed
   8.943 -        at the current safety level (%d).""" % safety
   8.944 -        level = -1
   8.945 -
   8.946 -    return level
   8.947 -
     9.1 --- a/tools/xenctl/setup.py	Wed Jun 16 21:29:21 2004 +0000
     9.2 +++ b/tools/xenctl/setup.py	Thu Jun 17 06:26:58 2004 +0000
     9.3 @@ -2,7 +2,7 @@
     9.4  from distutils.core import setup, Extension
     9.5  import sys
     9.6  
     9.7 -modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' , 'xenctl.vdisk' ]
     9.8 +modules = [ 'xenctl.console_client', 'xenctl.utils', 'xenctl.ip' ]
     9.9  
    9.10  # We need the 'tempfile' module from Python 2.3. We install this ourselves
    9.11  # if the installed Python is older than 2.3.
    10.1 --- a/tools/xenmgr/Makefile	Wed Jun 16 21:29:21 2004 +0000
    10.2 +++ b/tools/xenmgr/Makefile	Thu Jun 17 06:26:58 2004 +0000
    10.3 @@ -11,9 +11,9 @@ install: all
    10.4  	    python setup.py install --root="$(prefix)"; \
    10.5  	fi
    10.6  	mkdir -p $(prefix)/usr/sbin
    10.7 -	install -m0755 xenmgrd $(prefix)/usr/sbin
    10.8  	install -m0755 xend $(prefix)/usr/sbin
    10.9  	install -m0755 netfix $(prefix)/usr/sbin
   10.10 +	install -m0755 xm $(prefix)/usr/sbin
   10.11  
   10.12  clean:
   10.13  	rm -rf build *.pyc *.pyo *.o *.a *~
    11.1 --- a/tools/xenmgr/lib/XendClient.py	Wed Jun 16 21:29:21 2004 +0000
    11.2 +++ b/tools/xenmgr/lib/XendClient.py	Thu Jun 17 06:26:58 2004 +0000
    11.3 @@ -97,7 +97,7 @@ def xend_request(url, method, data=None)
    11.4      #hdr['Accept'] = 'text/html,text/plain'
    11.5      conn = httplib.HTTPConnection(ulocation)
    11.6      #conn.response_class = Foo
    11.7 -    conn.set_debuglevel(1)
    11.8 +    if DEBUG: conn.set_debuglevel(1)
    11.9      conn.request(method, upath, args, hdr)
   11.10      resp = conn.getresponse()
   11.11      if DEBUG: print resp.status, resp.reason
   11.12 @@ -118,10 +118,7 @@ def xend_request(url, method, data=None)
   11.13      #    val = val[1]
   11.14      if isinstance(val, types.ListType) and sxp.name(val) == 'err':
   11.15          raise RuntimeError(val[1])
   11.16 -    if DEBUG: print '**val='
   11.17 -    #sxp.show(val); print
   11.18 -    PrettyPrint.prettyprint(val)
   11.19 -    if DEBUG: print '**'
   11.20 +    if DEBUG: print '**val='; sxp.show(val); print
   11.21      return val
   11.22  
   11.23  def xend_get(url, args=None):
   11.24 @@ -334,7 +331,9 @@ def main(argv):
   11.25      if not fn.startswith('xend'):
   11.26          fn = 'xend_' + fn
   11.27      args = argv[2:]
   11.28 -    getattr(server, fn)(*args)
   11.29 +    val = getattr(server, fn)(*args)
   11.30 +    PrettyPrint.prettyprint(val)
   11.31 +    print
   11.32  
   11.33  if __name__ == "__main__":
   11.34      main(sys.argv)
    12.1 --- a/tools/xenmgr/lib/XendDomain.py	Wed Jun 16 21:29:21 2004 +0000
    12.2 +++ b/tools/xenmgr/lib/XendDomain.py	Thu Jun 17 06:26:58 2004 +0000
    12.3 @@ -49,18 +49,28 @@ class XendDomain:
    12.4      def initial_refresh(self):
    12.5          """Refresh initial domain info from domain_db.
    12.6          """
    12.7 +        print "initial_refresh> db=", self.domain_db.values()
    12.8          domlist = xc.domain_getinfo()
    12.9 +        print "doms=", domlist
   12.10          doms = {}
   12.11          for d in domlist:
   12.12              domid = str(d['dom'])
   12.13              doms[domid] = d
   12.14          for config in self.domain_db.values():
   12.15              domid = int(sxp.child_value(config, 'id'))
   12.16 +            print "dom=", domid, "config=", config
   12.17              if domid in doms:
   12.18 +                print "dom=", domid, "new"
   12.19                  self._new_domain(config)
   12.20              else:
   12.21 +                print "dom=", domid, "del"
   12.22                  self._delete_domain(domid)
   12.23 +        print "doms:"
   12.24 +        for d in self.domain.values(): print 'dom', d
   12.25 +        print "refresh..."
   12.26          self.refresh()
   12.27 +        print "doms:"
   12.28 +        for d in self.domain.values(): print 'dom', d
   12.29  
   12.30      def sync(self):
   12.31          """Sync domain db to disk.
   12.32 @@ -132,7 +142,7 @@ class XendDomain:
   12.33                  image = None
   12.34                  newinfo = XendDomainInfo.XendDomainInfo(
   12.35                      config, d['dom'], d['name'], d['mem_kb']/1024, image)
   12.36 -                self._add_domain(id, newinfo)
   12.37 +                self._add_domain(newinfo.id, newinfo)
   12.38          # Remove entries for domains that no longer exist.
   12.39          for d in self.domain.values():
   12.40              dominfo = doms.get(d.id)
   12.41 @@ -152,7 +162,7 @@ class XendDomain:
   12.42          else:
   12.43              d = self.domain.get(id)
   12.44              if d:
   12.45 -                d.update(dominfo)
   12.46 +                d.update(dominfo[0])
   12.47  
   12.48      def domain_ls(self):
   12.49          # List domains.
   12.50 @@ -319,18 +329,18 @@ class XendDomain:
   12.51                  return v
   12.52          return None
   12.53  
   12.54 -    def domain_vbd_add(self, dom, uname, dev, mode):
   12.55 -        dom = int(dom)
   12.56 -        vbd = vm.make_disk(dom, uname, dev, mode)
   12.57 -        return vbd
   12.58 +##     def domain_vbd_add(self, dom, uname, dev, mode):
   12.59 +##         dom = int(dom)
   12.60 +##         vbd = vm.make_disk(dom, uname, dev, mode)
   12.61 +##         return vbd
   12.62  
   12.63 -    def domain_vbd_remove(self, dom, dev):
   12.64 -        dom = int(dom)
   12.65 -        vbd = xenctl.vdisk.blkdev_name_to_number(dev)
   12.66 -        if vbd < 0: return vbd
   12.67 -        err = xc.vbd_destroy(dom, vbd)
   12.68 -        if err < 0: return err
   12.69 -        return vbd
   12.70 +##     def domain_vbd_remove(self, dom, dev):
   12.71 +##         dom = int(dom)
   12.72 +##         vbd = xenctl.vdisk.blkdev_name_to_number(dev)
   12.73 +##         if vbd < 0: return vbd
   12.74 +##         err = xc.vbd_destroy(dom, vbd)
   12.75 +##         if err < 0: return err
   12.76 +##         return vbd
   12.77  
   12.78      def domain_shadow_control(self, dom, op):
   12.79          dom = int(dom)
    13.1 --- a/tools/xenmgr/lib/XendDomainInfo.py	Wed Jun 16 21:29:21 2004 +0000
    13.2 +++ b/tools/xenmgr/lib/XendDomainInfo.py	Thu Jun 17 06:26:58 2004 +0000
    13.3 @@ -9,6 +9,8 @@ Author: Mike Wray <mike.wray@hpl.hp.com>
    13.4  
    13.5  """
    13.6  
    13.7 +import string
    13.8 +import re
    13.9  import sys
   13.10  import os
   13.11  
   13.12 @@ -17,7 +19,6 @@ from twisted.internet import defer
   13.13  import Xc; xc = Xc.new()
   13.14  
   13.15  import xenctl.ip
   13.16 -import xenctl.vdisk
   13.17  
   13.18  import sxp
   13.19  
   13.20 @@ -27,6 +28,24 @@ xendConsole = XendConsole.instance()
   13.21  import server.SrvConsoleServer
   13.22  xend = server.SrvConsoleServer.instance()
   13.23  
   13.24 +def readlines(fd):
   13.25 +    """Version of readlines safe against EINTR.
   13.26 +    """
   13.27 +    import errno
   13.28 +    
   13.29 +    lines = []
   13.30 +    while 1:
   13.31 +        try:
   13.32 +            line = fd.readline()
   13.33 +        except IOError, ex:
   13.34 +            if ex.errno == errno.EINTR:
   13.35 +                continue
   13.36 +            else:
   13.37 +                raise
   13.38 +        if line == '': break
   13.39 +        lines.append(line)
   13.40 +    return lines
   13.41 +
   13.42  class VmError(ValueError):
   13.43      """Vm construction error."""
   13.44  
   13.45 @@ -60,6 +79,7 @@ class XendDomainInfo:
   13.46          self.devices = {}
   13.47          self.configs = []
   13.48          self.info = None
   13.49 +        self.ipaddrs = []
   13.50  
   13.51          #todo: state: running, suspended
   13.52          self.state = 'running'
   13.53 @@ -93,7 +113,7 @@ class XendDomainInfo:
   13.54          if self.info:
   13.55              run = (self.info['running'] and 'r') or '-'
   13.56              stop = (self.info['stopped'] and 's') or '-'
   13.57 -            state = run + state
   13.58 +            state = run + stop
   13.59              sxpr.append(['cpu', self.info['cpu']])
   13.60              sxpr.append(['state', state])
   13.61              sxpr.append(['cpu_time', self.info['cpu_time']/1e8])
   13.62 @@ -127,6 +147,12 @@ class XendDomainInfo:
   13.63          return sxp.child_with_id(self.get_devices(type), id)
   13.64  
   13.65      def get_device_by_index(self, type, idx):
   13.66 +        """Get the device with the given index.
   13.67 +
   13.68 +        idx       device index
   13.69 +
   13.70 +        returns  device or None
   13.71 +        """
   13.72          dl = self.get_devices(type)
   13.73          if 0 <= idx < len(dl):
   13.74              return dl[idx]
   13.75 @@ -163,48 +189,81 @@ class XendDomainInfo:
   13.76              print
   13.77          print "]"
   13.78  
   13.79 -def safety_level(sharing):
   13.80 -    if sharing == 'rw':
   13.81 -        return xenctl.vdisk.VBD_SAFETY_RW
   13.82 -    if sharing == 'ww':
   13.83 -        return xenctl.vdisk.VBD_SAFETY_WW
   13.84 -    return xenctl.vdisk.VBD_SAFETY_RR
   13.85 +def blkdev_name_to_number(name):
   13.86 +    """Take the given textual block-device name (e.g., '/dev/sda1',
   13.87 +    'hda') and return the device number used by the OS. """
   13.88 +
   13.89 +    if not re.match( '/dev/', name ):
   13.90 +        name = '/dev/' + name
   13.91 +        
   13.92 +    return os.stat(name).st_rdev
   13.93  
   13.94 +def lookup_raw_partn(partition):
   13.95 +    """Take the given block-device name (e.g., '/dev/sda1', 'hda')
   13.96 +    and return a dictionary { device, start_sector,
   13.97 +    nr_sectors, type }
   13.98 +        device:       Device number of the given partition
   13.99 +        start_sector: Index of first sector of the partition
  13.100 +        nr_sectors:   Number of sectors comprising this partition
  13.101 +        type:         'Disk' or identifying name for partition type
  13.102 +    """
  13.103 +
  13.104 +    if not re.match( '/dev/', partition ):
  13.105 +        partition = '/dev/' + partition
  13.106 +
  13.107 +    drive = re.split( '[0-9]', partition )[0]
  13.108  
  13.109 -def make_disk_old(dom, uname, dev, mode, sharing):
  13.110 -    writeable = ('w' in mode)
  13.111 -    safety = safety_level(sharing)
  13.112 -    vbd = xenctl.vdisk.blkdev_name_to_number(dev)
  13.113 -    extents = xenctl.vdisk.lookup_disk_uname(uname)
  13.114 -    if not extents:
  13.115 -        raise VmError("vbd: Extents not found: uname=%s" % uname)
  13.116 +    if drive == partition:
  13.117 +        fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
  13.118 +        line = readline(fd)
  13.119 +        if line:
  13.120 +            return [ { 'device' : blkdev_name_to_number(drive),
  13.121 +                       'start_sector' : long(0),
  13.122 +                       'nr_sectors' : long(line) * 2,
  13.123 +                       'type' : 'Disk' } ]
  13.124 +        return None
  13.125 +
  13.126 +    # determine position on disk
  13.127 +    fd = os.popen( '/sbin/sfdisk -d ' + drive + ' 2>/dev/null' )
  13.128  
  13.129 -    # check that setting up this VBD won't violate the sharing
  13.130 -    # allowed by the current VBD expertise level
  13.131 -    if xenctl.vdisk.vd_extents_validate(extents, writeable, safety=safety) < 0:
  13.132 -        raise VmError("vbd: Extents invalid: uname=%s" % uname)
  13.133 -            
  13.134 -    if xc.vbd_create(dom=dom, vbd=vbd, writeable=writeable):
  13.135 -        raise VmError("vbd: Creating device failed: dom=%d uname=%s vbd=%d mode=%s"
  13.136 -                      % (dom, uname, vbdmode))
  13.137 +    #['/dev/sda3 : start= 16948575, size=16836120, Id=83, bootable\012']
  13.138 +    lines = readlines(fd)
  13.139 +    for line in lines:
  13.140 +        m = re.search( '^' + partition + '\s*: start=\s*([0-9]+), ' +
  13.141 +                       'size=\s*([0-9]+), Id=\s*(\S+).*$', line)
  13.142 +        if m:
  13.143 +            return [ { 'device' : blkdev_name_to_number(drive),
  13.144 +                       'start_sector' : long(m.group(1)),
  13.145 +                       'nr_sectors' : long(m.group(2)),
  13.146 +                       'type' : m.group(3) } ]
  13.147 +    
  13.148 +    return None
  13.149  
  13.150 -    if xc.vbd_setextents(dom=dom, vbd=vbd, extents=extents):
  13.151 -        raise VMError("vbd: Setting extents failed: dom=%d uname=%s vbd=%d"
  13.152 -                      % (dom, uname, vbd))
  13.153 -    return vbd
  13.154 +def lookup_disk_uname( uname ):
  13.155 +    """Lookup a list of segments for a physical device.
  13.156 +    uname [string]:  name of the device in the format \'phy:dev\' for a physical device
  13.157 +    returns [list of dicts]: list of extents that make up the named device
  13.158 +    """
  13.159 +    ( type, d_name ) = string.split( uname, ':' )
  13.160 +
  13.161 +    if type == "phy":
  13.162 +        segments = lookup_raw_partn( d_name )
  13.163 +    else:
  13.164 +        segments = None
  13.165 +    return segments
  13.166  
  13.167  def make_disk(dom, uname, dev, mode, sharing):
  13.168      """Create a virtual disk device for a domain.
  13.169  
  13.170      @returns Deferred
  13.171      """
  13.172 -    segments = xenctl.vdisk.lookup_disk_uname(uname)
  13.173 +    segments = lookup_disk_uname(uname)
  13.174      if not segments:
  13.175          raise VmError("vbd: Segments not found: uname=%s" % uname)
  13.176      if len(segments) > 1:
  13.177          raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
  13.178      segment = segments[0]
  13.179 -    vdev = xenctl.vdisk.blkdev_name_to_number(dev)
  13.180 +    vdev = blkdev_name_to_number(dev)
  13.181      ctrl = xend.blkif_create(dom)
  13.182      
  13.183      def fn(ctrl):
  13.184 @@ -212,13 +271,6 @@ def make_disk(dom, uname, dev, mode, sha
  13.185      ctrl.addCallback(fn)
  13.186      return ctrl
  13.187          
  13.188 -def make_vif_old(dom, vif, vmac, vnet):
  13.189 -    return # todo: Not supported yet.
  13.190 -    err = xc.vif_setinfo(dom=dom, vif=vif, vmac=vmac, vnet=vnet)
  13.191 -    if err < 0:
  13.192 -        raise VmError('vnet: Error %d setting vif mac dom=%d vif=%d vmac=%s vnet=%d' %
  13.193 -                        (err, dom, vif, vmac, vnet))
  13.194 -
  13.195  def make_vif(dom, vif, vmac):
  13.196      """Create a virtual network device for a domain.
  13.197  
  13.198 @@ -230,8 +282,10 @@ def make_vif(dom, vif, vmac):
  13.199      return d
  13.200  
  13.201  def vif_up(iplist):
  13.202 -    #todo: Need a better way.
  13.203 -    # send an unsolicited ARP reply for all non link-local IPs
  13.204 +    """send an unsolicited ARP reply for all non link-local IP addresses.
  13.205 +
  13.206 +    iplist IP addresses
  13.207 +    """
  13.208  
  13.209      IP_NONLOCAL_BIND = '/proc/sys/net/ipv4/ip_nonlocal_bind'
  13.210      
  13.211 @@ -260,6 +314,18 @@ def vif_up(iplist):
  13.212          if not nlb: set_ip_nonlocal_bind(0)
  13.213  
  13.214  def xen_domain_create(config, ostype, name, memory, kernel, ramdisk, cmdline, vifs_n):
  13.215 +    """Create a domain. Builds the image but does not configure it.
  13.216 +
  13.217 +    config  configuration
  13.218 +    ostype  OS type
  13.219 +    name    domain name
  13.220 +    memory  domain memory (MB)
  13.221 +    kernel  kernel image
  13.222 +    ramdisk kernel ramdisk
  13.223 +    cmdline kernel commandline
  13.224 +    vifs_n  number of network interfaces
  13.225 +    returns vm
  13.226 +    """
  13.227      if not os.path.isfile(kernel):
  13.228          raise VmError('Kernel image does not exist: %s' % kernel)
  13.229      if ramdisk and not os.path.isfile(ramdisk):
  13.230 @@ -380,11 +446,22 @@ def vm_create(config):
  13.231      return deferred
  13.232  
  13.233  def vm_restore(src, config, progress=0):
  13.234 +    """Restore a VM.
  13.235 +
  13.236 +    src      saved state to restore
  13.237 +    config   configuration
  13.238 +    progress progress reporting flag
  13.239 +    returns  deferred
  13.240 +    raises   VmError for invalid configuration
  13.241 +    """
  13.242      ostype = "linux" #todo set from config
  13.243      restorefn = getattr(xc, "%s_restore" % ostype)
  13.244      dom = restorefn(state_file=src, progress=progress)
  13.245      if dom < 0: return dom
  13.246      deferred = dom_configure(dom, config)
  13.247 +    def vifs_cb(val, vm):
  13.248 +        vif_up(vm.ipaddrs)
  13.249 +    deferred.addCallback(vifs_cb, vm)
  13.250      return deferred
  13.251      
  13.252  def dom_get(dom):
  13.253 @@ -394,6 +471,12 @@ def dom_get(dom):
  13.254      return None
  13.255      
  13.256  def dom_configure(dom, config):
  13.257 +    """Configure a domain.
  13.258 +
  13.259 +    dom    domain id
  13.260 +    config configuration
  13.261 +    returns deferred
  13.262 +    """
  13.263      d = dom_get(dom)
  13.264      if not d:
  13.265          raise VMError("Domain not found: %d" % dom)
  13.266 @@ -610,6 +693,12 @@ def vm_dev_pci(vm, val, index):
  13.267      func = sxp.child_value(val, 'func')
  13.268      if not func:
  13.269          raise VMError('pci: Missing func')
  13.270 +    try:
  13.271 +        bus = int(bus, 16)
  13.272 +        dev = int(dev, 16)
  13.273 +        func = int(func, 16)
  13.274 +    except:
  13.275 +        raise VMError('pci: invalid parameter')
  13.276      rc = xc.physdev_pci_access_modify(dom=vm.dom, bus=bus, dev=dev, func=func, enable=1)
  13.277      if rc < 0:
  13.278          #todo non-fatal
  13.279 @@ -628,6 +717,7 @@ def vm_field_vfr(vm, config, val, index)
  13.280      # Get the rules and add them.
  13.281      # (vfr (vif (id foo) (ip x.x.x.x)) ... ) 
  13.282      list = sxp.children(val, 'vif')
  13.283 +    ipaddrs = []
  13.284      for v in list:
  13.285          id = sxp.child_value(v, 'id')
  13.286          if id is None:
  13.287 @@ -640,9 +730,11 @@ def vm_field_vfr(vm, config, val, index)
  13.288          ip = sxp.child_value(v, 'ip')
  13.289          if not ip:
  13.290              raise VmError('vfr: missing ip address')
  13.291 +        ipaddrs.append(ip);
  13.292          #Don't do this in new i/o model.
  13.293          #print 'vm_field_vfr> add rule', 'dom=', vm.dom, 'vif=', vif, 'ip=', ip
  13.294          #xenctl.ip.setup_vfr_rules_for_vif(vm.dom, vif, ip)
  13.295 +    vm.ipaddrs = ipaddrs
  13.296  
  13.297  def vnet_bridge(vnet, vmac, dom, idx):
  13.298      """Add the device for the vif to the bridge for its vnet.
    14.1 --- a/tools/xenmgr/lib/XendNode.py	Wed Jun 16 21:29:21 2004 +0000
    14.2 +++ b/tools/xenmgr/lib/XendNode.py	Thu Jun 17 06:26:58 2004 +0000
    14.3 @@ -7,15 +7,9 @@
    14.4  
    14.5  """
    14.6  
    14.7 +import os
    14.8  import Xc
    14.9  
   14.10 -class XendNodeInfo:
   14.11 -    """Node information record.
   14.12 -    """
   14.13 -
   14.14 -    def __init__(self):
   14.15 -        pass
   14.16 -
   14.17  class XendNode:
   14.18  
   14.19      def __init__(self):
   14.20 @@ -45,6 +39,28 @@ class XendNode:
   14.21          #ret = self.xc.rrobin_global_set(slice)
   14.22          return ret
   14.23  
   14.24 +    def info(self):
   14.25 +        return self.nodeinfo() + self.physinfo()
   14.26 +
   14.27 +    def nodeinfo(self):
   14.28 +        (sys, host, rel, ver, mch) = os.uname()
   14.29 +        return [['system',  sys],
   14.30 +                ['host',    host],
   14.31 +                ['release', rel],
   14.32 +                ['version', ver],
   14.33 +                ['machine', mch]]
   14.34 +
   14.35 +    def physinfo(self):
   14.36 +        pinfo = self.xc.physinfo()
   14.37 +        info = [['cores', pinfo['cores']],
   14.38 +                ['hyperthreads_per_core', pinfo['ht_per_core']],
   14.39 +                ['cpu_mhz', pinfo['cpu_khz']/1000],
   14.40 +                ['memory', pinfo['total_pages']/256],
   14.41 +                ['free_memory', pinfo['free_pages']/256]]
   14.42 +        return info
   14.43 +        
   14.44 +        
   14.45 +
   14.46  def instance():
   14.47      global inst
   14.48      try:
    15.1 --- a/tools/xenmgr/lib/XendVdisk.py	Wed Jun 16 21:29:21 2004 +0000
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,111 +0,0 @@
    15.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    15.5 -
    15.6 -"""Handler for vdisk operations.
    15.7 -
    15.8 -"""
    15.9 -
   15.10 -import os
   15.11 -import os.path
   15.12 -
   15.13 -from xenctl import vdisk
   15.14 -    
   15.15 -import sxp
   15.16 -
   15.17 -class XendVdiskInfo:
   15.18 -
   15.19 -    def __init__(self, info):
   15.20 -        self.info = info
   15.21 -        self.id = info['vdisk_id']
   15.22 -
   15.23 -    def __str__(self):
   15.24 -        return ("vdisk id=%(vdisk_id)s size=%(size)d expires=%(expires)d expiry_time=%(expiry_time)d"
   15.25 -                % self.info)
   15.26 -
   15.27 -    def sxpr(self):
   15.28 -        val = ['vdisk']
   15.29 -        for (k,v) in self.info.items():
   15.30 -            val.append([k, str(v)])
   15.31 -        return val     
   15.32 -
   15.33 -class XendVdisk:
   15.34 -    """Index of all vdisks. Singleton.
   15.35 -    """
   15.36 -
   15.37 -    dbpath = "vdisk"
   15.38 -
   15.39 -    def __init__(self):
   15.40 -        # Table of vdisk info indexed by vdisk id.
   15.41 -        self.vdisk = {}
   15.42 -        if not os.path.isfile(vdisk.VD_DB_FILE):
   15.43 -            vdisk.vd_init_db(vdisk.VD_DB_FILE)
   15.44 -        self.vdisk_refresh()
   15.45 -
   15.46 -    def vdisk_refresh(self):
   15.47 -        # vdisk = {vdisk_id, size, expires, expiry_time}
   15.48 -        try:
   15.49 -            vdisks = vdisk.vd_list()
   15.50 -        except:
   15.51 -            vdisks = []
   15.52 -        for vdisk in vdisks:
   15.53 -            vdiskinfo = XendVdiskInfo(vdisk)
   15.54 -            self.vdisk[vdiskinfo.id] = vdiskinfo
   15.55 -
   15.56 -    def vdisk_ls(self):
   15.57 -        """List all vdisk ids.
   15.58 -        """
   15.59 -        return self.vdisk.keys()
   15.60 -
   15.61 -    def vdisks(self):
   15.62 -        return self.vdisk.values()
   15.63 -    
   15.64 -    def vdisk_get(self, id):
   15.65 -        """Get a vdisk.
   15.66 -
   15.67 -        id	vdisk id
   15.68 -        """
   15.69 -        return self.vdisk.get(id)
   15.70 -
   15.71 -    def vdisk_create(self, info):
   15.72 -        """Create a vdisk.
   15.73 -
   15.74 -        info	config
   15.75 -        """
   15.76 -        # Need to configure for real.
   15.77 -        # vdisk.vd_create(size, expiry)
   15.78 -
   15.79 -    def vdisk_configure(self, info):
   15.80 -        """Configure a vdisk.
   15.81 -        id	vdisk id
   15.82 -        info	config
   15.83 -        """
   15.84 -        # Need to configure for real.
   15.85 -        # Make bigger: vdisk.vd_enlarge(id, extra_size)
   15.86 -        # Update expiry time: vdisk.vd_refresh(id, expiry)
   15.87 -        # Try to recover an expired vdisk : vdisk.vd_undelete(id, expiry)
   15.88 -        
   15.89 -
   15.90 -    def vdisk_delete(self, id):
   15.91 -        """Delete a vdisk.
   15.92 -
   15.93 -        id	vdisk id
   15.94 -        """
   15.95 -        # Need to delete vdisk for real. What if fails?
   15.96 -        del self.vdisk[id]
   15.97 -        vdisk.vd_delete(id)
   15.98 -
   15.99 -    # def vdisk_copy: copy contents to file, vdisk still exists
  15.100 -    # def vdisk_export: copy contents to file then delete the vdisk 
  15.101 -    # def vdisk_import: create a vdisk from a file
  15.102 -    # def vdisk_space: space left for new vdisks
  15.103 -
  15.104 -    # def vdisk_recover: recover an expired vdisk
  15.105 -
  15.106 -    # def vdisk_init_partition: setup a physical partition for vdisks
  15.107 -
  15.108 -def instance():
  15.109 -    global inst
  15.110 -    try:
  15.111 -        inst
  15.112 -    except:
  15.113 -        inst = XendVdisk()
  15.114 -    return inst
    16.1 --- a/tools/xenmgr/lib/server/SrvNode.py	Wed Jun 16 21:29:21 2004 +0000
    16.2 +++ b/tools/xenmgr/lib/server/SrvNode.py	Thu Jun 17 06:26:58 2004 +0000
    16.3 @@ -45,15 +45,10 @@ class SrvNode(SrvDir):
    16.4              self.print_path(req)
    16.5              req.write('<ul>')
    16.6              for d in self.info():
    16.7 -                req.write('<li> %10s: %s' % (d[0], d[1]))
    16.8 +                req.write('<li> %10s: %s' % (d[0], str(d[1])))
    16.9              req.write('</ul>')
   16.10              req.write('</body></html>')
   16.11          return ''
   16.12              
   16.13      def info(self):
   16.14 -        (sys, host, rel, ver, mch) = os.uname()
   16.15 -        return [['system',  sys],
   16.16 -                ['host',    host],
   16.17 -                ['release', rel],
   16.18 -                ['version', ver],
   16.19 -                ['machine', mch]]
   16.20 +        return self.xn.info()
    17.1 --- a/tools/xenmgr/lib/server/SrvRoot.py	Wed Jun 16 21:29:21 2004 +0000
    17.2 +++ b/tools/xenmgr/lib/server/SrvRoot.py	Thu Jun 17 06:26:58 2004 +0000
    17.3 @@ -17,7 +17,6 @@ class SrvRoot(SrvDir):
    17.4          ('domain',  'SrvDomainDir'  ),
    17.5          ('console', 'SrvConsoleDir' ),
    17.6          ('event',   'SrvEventDir'   ),
    17.7 -        ('vdisk',   'SrvVdiskDir'   ),
    17.8          ('device',  'SrvDeviceDir'  ),
    17.9          ('vnet',    'SrvVnetDir'    ),
   17.10          ]
    18.1 --- a/tools/xenmgr/lib/server/SrvVdisk.py	Wed Jun 16 21:29:21 2004 +0000
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,12 +0,0 @@
    18.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    18.5 -
    18.6 -from xenmgr import XendVdisk
    18.7 -from SrvVdiskDir import SrvVdiskDir
    18.8 -
    18.9 -class SrvVdisk(SrvDir):
   18.10 -    """A virtual disk.
   18.11 -    """
   18.12 -
   18.13 -    def __init__(self):
   18.14 -        SrvDir.__init__(self)
   18.15 -        self.xvdisk = XendVdisk.instance()
    19.1 --- a/tools/xenmgr/lib/server/SrvVdiskDir.py	Wed Jun 16 21:29:21 2004 +0000
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,28 +0,0 @@
    19.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    19.5 -
    19.6 -from xenmgr import XendVdisk
    19.7 -from SrvDir import SrvDir
    19.8 -
    19.9 -class SrvVdiskDir(SrvDir):
   19.10 -    """Virtual disk directory.
   19.11 -    """
   19.12 -
   19.13 -    def __init__(self):
   19.14 -        SrvDir.__init__(self)
   19.15 -        #self.xvdisk = XendVdisk.instance()
   19.16 -
   19.17 -    def vdisk(self, x):
   19.18 -        val = None
   19.19 -        try:
   19.20 -            dom = self.xvdisk.vdisk_get(x)
   19.21 -            val = SrvVdisk(dom)
   19.22 -        except KeyError:
   19.23 -            pass
   19.24 -        return val
   19.25 -
   19.26 -    def get(self, x):
   19.27 -        v = SrvDir.get(self, x)
   19.28 -        if v is not None:
   19.29 -            return v
   19.30 -        v = self.vdisk(x)
   19.31 -        return v
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/xenmgr/lib/xm/create.py	Thu Jun 17 06:26:58 2004 +0000
    21.3 @@ -0,0 +1,296 @@
    21.4 +import string
    21.5 +import sys
    21.6 +
    21.7 +from xenmgr import sxp
    21.8 +from xenmgr import PrettyPrint
    21.9 +from xenmgr.XendClient import server
   21.10 +
   21.11 +from xenmgr.xm.opts import *
   21.12 +
   21.13 +opts = Opts(use="""[options]
   21.14 +
   21.15 +Create a domain.
   21.16 +""")
   21.17 +
   21.18 +opts.opt('help', short='h',
   21.19 +         fn=set_value, default=0,
   21.20 +         use="Print this help.")
   21.21 +
   21.22 +opts.opt('quiet', short='q',
   21.23 +         fn=set_true, default=0,
   21.24 +         use="Quiet.")
   21.25 +
   21.26 +opts.opt('path', val='PATH',
   21.27 +         fn=set_value, default='.:/etc/xc',
   21.28 +         use="Search path for default scripts.")
   21.29 +
   21.30 +opts.opt('defaults', short='f', val='FILE',
   21.31 +         fn=set_value, default='xmdefaults',
   21.32 +         use="Use the given default script.")
   21.33 +
   21.34 +opts.opt('config', short='F', val='FILE',
   21.35 +         fn=set_value, default=None,
   21.36 +         use='Domain configuration to use.')
   21.37 +
   21.38 +def set_var(opt, k, v):
   21.39 +    opt.set(v)
   21.40 +    for d in string.split(v, ';' ):
   21.41 +        (k, v) = string.split(d, '=')
   21.42 +        opt.opts.setvar(k, v)
   21.43 +
   21.44 +opts.opt('define', short='D', val='VAR=VAL',
   21.45 +         fn=set_var, default=None,
   21.46 +         use="""Set variables before loading defaults, e.g. '-D vmid=3;ip=1.2.3.4'
   21.47 +         to set vmid and ip.""")
   21.48 +
   21.49 +opts.opt('dryrun', short='n',
   21.50 +         fn=set_true, default=0,
   21.51 +         use="Dry run - print the config but don't create the domain.")
   21.52 +
   21.53 +opts.opt('console', short='c',
   21.54 +         fn=set_true, default=0,
   21.55 +         use="Connect to console after domain is created.")
   21.56 +
   21.57 +opts.opt('kernel', short='k', val='FILE',
   21.58 +         use="Path to kernel image.")
   21.59 +
   21.60 +opts.opt('ramdisk', short='r', val='FILE',
   21.61 +         fn=set_value, default='',
   21.62 +         use="Path to ramdisk.")
   21.63 +
   21.64 +opts.opt('builder', short='b', val='FUNCTION',
   21.65 +         fn=set_value, default='linux',
   21.66 +         use="Function to use to build the domain.")
   21.67 +
   21.68 +opts.opt('memory', short='m', val='MEMORY',
   21.69 +         fn=set_value, default=128,
   21.70 +         use="Domain memory in MB.")
   21.71 +
   21.72 +opts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
   21.73 +         fn=append_value, default=[],
   21.74 +         use="""Add a disk device to a domain. The physical device is DEV, which
   21.75 +         is exported to the domain as VDEV. The disk is read-only if MODE is r,
   21.76 +         read-write if mode is 'w'.""")
   21.77 +
   21.78 +opts.opt('pci', val='BUS,DEV,FUNC',
   21.79 +         fn=append_value, default=[],
   21.80 +         use="""Add a PCI device to a domain.""")
   21.81 +
   21.82 +opts.opt('ipaddr', short='i', val="IPADDR",
   21.83 +         fn=append_value, default=[],
   21.84 +         use="Add an IP address to the domain.")
   21.85 +
   21.86 +opts.opt('mac', short='M', val="MAC",
   21.87 +         fn=append_value, default=[],
   21.88 +         use="""Add a network interface with the given mac address to the domain.
   21.89 +         More than one interface may be specified. Interfaces with unspecified MAC addresses
   21.90 +         are allocated a random address.""")
   21.91 +
   21.92 +opts.opt('nics', val="N",
   21.93 +         fn=set_int, default=1,
   21.94 +         use="Set the number of network interfaces.")
   21.95 +
   21.96 +opts.opt('vnet', val='VNET',
   21.97 +         fn=append_value, default=[],
   21.98 +         use="""Define the vnets for the network interfaces.
   21.99 +         More than one vnet may be given, they are used in order.
  21.100 +         """)
  21.101 +
  21.102 +opts.opt('root', short='R', val='DEVICE',
  21.103 +         fn=set_value, default='',
  21.104 +         use="""Set the root= parameter on the kernel command line.
  21.105 +         Use a device, e.g. /dev/sda1, or /dev/nfs for NFS root.""")
  21.106 +
  21.107 +opts.opt('extra', short='E', val="ARGS",
  21.108 +         fn=set_value, default='',
  21.109 +         use="Set extra arguments to append to the kernel command line.")
  21.110 +
  21.111 +opts.opt('ip', short='I', val='IPADDR',
  21.112 +         fn=set_value, default='',
  21.113 +         use="Set the kernel IP interface address.")
  21.114 +
  21.115 +opts.opt('gateway', val="IPADDR",
  21.116 +         fn=set_value, default='',
  21.117 +         use="Set kernel IP gateway.")
  21.118 +
  21.119 +opts.opt('netmask', val="MASK",
  21.120 +         fn=set_value, default = '',
  21.121 +         use="Set kernel IP netmask.")
  21.122 +
  21.123 +opts.opt('hostname', val="NAME",
  21.124 +         fn=set_value, default='',
  21.125 +         use="Set kernel IP hostname.")
  21.126 +
  21.127 +opts.opt('interface', val="INTF",
  21.128 +         fn=set_value, default="eth0",
  21.129 +         use="Set the kernel IP interface name.")
  21.130 +
  21.131 +opts.opt('dhcp', val="off|dhcp",
  21.132 +         fn=set_value, default='off',
  21.133 +         use="Set kernel dhcp option.")
  21.134 +
  21.135 +opts.opt('nfs_server', val="IPADDR",
  21.136 +         fn=set_value, default=None,
  21.137 +         use="Set the address of the NFS server for NFS root.")
  21.138 +
  21.139 +opts.opt('nfs_root', val="PATH",
  21.140 +         fn=set_value, default=None,
  21.141 +         use="Set the path of the root NFS directory.")
  21.142 +
  21.143 +def strip(pre, s):
  21.144 +    if s.startswith(pre):
  21.145 +        return s[len(pre):]
  21.146 +    else:
  21.147 +        return s
  21.148 +
  21.149 +def make_config(opts):
  21.150 +    
  21.151 +    config = ['config',
  21.152 +              ['name', opts.name ],
  21.153 +              ['memory', opts.memory ] ]
  21.154 +    if opts.cpu:
  21.155 +        config.append(['cpu', opts.cpu])
  21.156 +    
  21.157 +    config_image = [ opts.builder ]
  21.158 +    config_image.append([ 'kernel', os.path.abspath(opts.kernel) ])
  21.159 +    if opts.ramdisk:
  21.160 +        config_image.append([ 'ramdisk', os.path.abspath(opts.ramdisk) ])
  21.161 +    if opts.cmdline_ip:
  21.162 +        cmdline_ip = strip('ip=', opts.cmdline_ip)
  21.163 +        config_image.append(['ip', cmdline_ip])
  21.164 +    if opts.root:
  21.165 +        cmdline_root = strip('root=', opts.root)
  21.166 +        config_image.append(['root', opts.root])
  21.167 +    if opts.extra:
  21.168 +        config_image.append(['args', opts.extra])
  21.169 +    config.append(['image', config_image ])
  21.170 +    	
  21.171 +    config_devs = []
  21.172 +    for (uname, dev, mode) in opts.disk:
  21.173 +        config_vbd = ['vbd',
  21.174 +                      ['uname', uname],
  21.175 +                      ['dev', dev ],
  21.176 +                      ['mode', mode ] ]
  21.177 +        config_devs.append(['device', config_vbd])
  21.178 +
  21.179 +    for (bus, dev, func) in opts.pci:
  21.180 +        config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
  21.181 +        config_devs.append(['device', config_pci])
  21.182 +
  21.183 +    for idx in range(0, opts.nics):
  21.184 +        config_vif = ['vif', ['@', ['id', 'vif%d' % idx]]]
  21.185 +        if idx < len(opts.mac):
  21.186 +            config_vif.append(['mac', opts.mac[idx]])
  21.187 +        config_devs.append(['device', config_vif])
  21.188 +
  21.189 +    config += config_devs
  21.190 +
  21.191 +##     if vfr_ipaddr:
  21.192 +##         config_vfr = ['vfr']
  21.193 +##         idx = 0 # No way of saying which IP is for which vif?
  21.194 +##         for ip in vfr_ipaddr:
  21.195 +##             config_vfr.append(['vif', ['id', idx], ['ip', ip]])
  21.196 +##         config.append(config_vfr)
  21.197 +
  21.198 +    if opts.vnet:
  21.199 +        config_vnet = ['vnet']
  21.200 +        idx = 0
  21.201 +        for vnet in opts.vnet:
  21.202 +            config_vif = ['vif', ['id', 'vif%d' % idx], ['vnet', vnet]]
  21.203 +            config_vnet.append(config_vif)
  21.204 +            idx += 1
  21.205 +        config.append(config_vnet)
  21.206 +            
  21.207 +    return config
  21.208 +
  21.209 +def preprocess_disk(opts):
  21.210 +    if not opts.disk: return
  21.211 +    disk = []
  21.212 +    for v in opts.disk:
  21.213 +        d = v.split(',')
  21.214 +        print 'disk', v, d
  21.215 +        if len(d) != 3:
  21.216 +            opts.err('Invalid disk specifier: ' + v)
  21.217 +        disk.append(d)
  21.218 +    opts.disk = disk
  21.219 +
  21.220 +def preprocess_pci(opts):
  21.221 +    if not opts.pci: return
  21.222 +    pci = []
  21.223 +    for v in opts.pci:
  21.224 +        d = v.split(',')
  21.225 +        if len(d) != 3:
  21.226 +            opts.err('Invalid pci specifier: ' + v)
  21.227 +        pci.append(d)
  21.228 +    opts.pci = pci
  21.229 +
  21.230 +def preprocess_ip(opts):
  21.231 +    setip = (opts.hostname or opts.netmask
  21.232 +             or opts.gateway or opts.dhcp or opts.interface)
  21.233 +    if not setip: return
  21.234 +    ip = (opts.ip
  21.235 +          + ':'
  21.236 +          + ':' + opts.gateway
  21.237 +          + ':' + opts.netmask
  21.238 +          + ':' + opts.hostname
  21.239 +          + ':' + opts.interface
  21.240 +          + ':' + opts.dhcp)
  21.241 +    opts.cmdline_ip = ip
  21.242 +
  21.243 +def preprocess_nfs(opts):
  21.244 +    if (opts.nfs_root or opts.nfs_server):
  21.245 +        if (not opts.nfs_root) or (not opts.nfs_server):
  21.246 +            opts.err('Must set nfs root and nfs server')
  21.247 +    else:
  21.248 +        return
  21.249 +    nfs = 'nfsroot=' + opts.nfs_server + ':' + opts.nfs_root
  21.250 +    opts.extra = nfs + ' ' + opts.extra
  21.251 +    
  21.252 +def preprocess(opts):
  21.253 +    preprocess_disk(opts)
  21.254 +    preprocess_pci(opts)
  21.255 +    preprocess_ip(opts)
  21.256 +    preprocess_nfs(opts)
  21.257 +         
  21.258 +def make_domain(opts, config):
  21.259 +    """Create, build and start a domain.
  21.260 +    Returns: [int] the ID of the new domain.
  21.261 +    """
  21.262 +    restore = 0 #todo
  21.263 +
  21.264 +    if restore:
  21.265 +        dominfo = server.xend_domain_restore(state_file, config)
  21.266 +    else:
  21.267 +        dominfo = server.xend_domain_create(config)
  21.268 +
  21.269 +    dom = int(sxp.child_value(dominfo, 'id'))
  21.270 +    console_info = sxp.child(dominfo, 'console')
  21.271 +    if console_info:
  21.272 +        console_port = int(sxp.child_value(console_info, 'port'))
  21.273 +    else:
  21.274 +        console_port = None
  21.275 +    
  21.276 +    if server.xend_domain_start(dom) < 0:
  21.277 +        server.xend_domain_halt(dom)
  21.278 +        opts.err("Failed to start domain %d" % dom)
  21.279 +    opts.info("Started domain %d, console on port %d"
  21.280 +              % (dom, console_port))
  21.281 +    return (dom, console_port)
  21.282 +
  21.283 +def main(argv):
  21.284 +    args = opts.parse(argv)
  21.285 +    if opts.config:
  21.286 +        pass
  21.287 +    else:
  21.288 +        opts.load_defaults()
  21.289 +    if opts.help:
  21.290 +        opts.usage()
  21.291 +    preprocess(opts)
  21.292 +    config = make_config(opts)
  21.293 +    if opts.dryrun:
  21.294 +        PrettyPrint.prettyprint(config)
  21.295 +    else:
  21.296 +        make_domain(opts, config)
  21.297 +        
  21.298 +if __name__ == '__main__':
  21.299 +    main(sys.argv)
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/xenmgr/lib/xm/main.py	Thu Jun 17 06:26:58 2004 +0000
    22.3 @@ -0,0 +1,224 @@
    22.4 +#!/usr/bin/python
    22.5 +import string
    22.6 +import sys
    22.7 +
    22.8 +from xenmgr import sxp
    22.9 +from xenmgr.XendClient import server
   22.10 +from xenmgr.xm import create, shutdown
   22.11 +
   22.12 +class Xm:
   22.13 +
   22.14 +    def __init__(self):
   22.15 +        self.prog = 'xm'
   22.16 +        pass
   22.17 +
   22.18 +    def err(self, msg):
   22.19 +        print >>sys.stderr, "Error:", msg
   22.20 +        sys.exit(1)
   22.21 +
   22.22 +    def main(self, args):
   22.23 +        self.prog = args[0]
   22.24 +        if len(args) < 2:
   22.25 +            self.err("Missing command\nTry '%s help' for more information."
   22.26 +                     % self.prog)
   22.27 +        prog = 'xm_' + args[1]
   22.28 +        help = self.helparg(args)
   22.29 +        fn = getattr(self, prog, self.unknown)
   22.30 +        fn(help, args[1:])
   22.31 +
   22.32 +    def helparg(self, args):
   22.33 +        for a in args:
   22.34 +            if a in ['-h', '--help']:
   22.35 +                return 1
   22.36 +        return 0
   22.37 +
   22.38 +    def unknown(self, help, args):
   22.39 +        self.err("Unknown command: %s\nTry '%s help' for more information."
   22.40 +                 % (args[0], self.prog))
   22.41 +
   22.42 +    def help(self, meth, args):
   22.43 +        name = meth[3:]
   22.44 +        f = getattr(self, meth)
   22.45 +        print "%s\t%s" % (name, f.__doc__ or '')
   22.46 +
   22.47 +    def xm_help(self, help, args):
   22.48 +        """Print help."""
   22.49 +        for k in dir(self):
   22.50 +            if not k.startswith('xm_'): continue
   22.51 +            self.help(k, args)
   22.52 +        print "\nTry '%s CMD -h' for help on CMD" % self.prog
   22.53 +                
   22.54 +    def xm_create(self, help, args):
   22.55 +        """Create a domain."""
   22.56 +        create.main(args)
   22.57 +
   22.58 +    def xm_save(self, help, args):
   22.59 +        """Save domain state to file."""
   22.60 +        if help:
   22.61 +            print args[0], "DOM FILE"
   22.62 +            print "\nSave domain with id DOM to FILE."
   22.63 +            return
   22.64 +        if len(args) < 3: self.err("%s: Missing arguments" % args[0])
   22.65 +        dom = args[1]
   22.66 +        filename = args[2]
   22.67 +        server.xend_domain_save(dom, filename)
   22.68 +
   22.69 +    def xm_restore(self, help, args):
   22.70 +        """Create a domain from a saved state."""
   22.71 +        if help:
   22.72 +            print args[0], "FILE"
   22.73 +            print "\nRestore a domain from FILE."
   22.74 +        if len(args) < 2: self.err("%s: Missing file" % args[0])
   22.75 +        server.xend_domain_restore(dom, None, filename)
   22.76 +
   22.77 +    def xm_ls(self, help, args):
   22.78 +        """List domains."""
   22.79 +        if help: self.help('xm_' + args[0]); return
   22.80 +        doms = server.xend_domains()
   22.81 +        print 'Dom  Name             Mem(MB)  CPU  State  Time(s)'
   22.82 +        for dom in doms:
   22.83 +            info = server.xend_domain(dom)
   22.84 +            d = {}
   22.85 +            d['dom'] = int(dom)
   22.86 +            d['name'] = sxp.child_value(info, 'name', '??')
   22.87 +            d['mem'] = int(sxp.child_value(info, 'memory', '0'))
   22.88 +            d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
   22.89 +            d['state'] = sxp.child_value(info, 'state', '??')
   22.90 +            d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
   22.91 +            print ("%(dom)-4d %(name)-16s %(mem)4d     %(cpu)3d %(state)5s %(cpu_time)10.2f" % d)
   22.92 +
   22.93 +    def xm_halt(self, help, args):
   22.94 +        """Terminate a domain immediately."""
   22.95 +        if help:
   22.96 +            print args[0], 'DOM'
   22.97 +            print '\nTerminate domain DOM immediately.'
   22.98 +            return
   22.99 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
  22.100 +        dom = args[1]
  22.101 +        server.xend_domain_halt(dom)
  22.102 +
  22.103 +    def xm_shutdown(self, help, args):
  22.104 +        """Shutdown a domain."""
  22.105 +        shutdown.main(args)
  22.106 +
  22.107 +    def xm_stop(self, help, args):
  22.108 +        """Stop execution of a domain."""
  22.109 +        if help:
  22.110 +            print args[0], 'DOM'
  22.111 +            print '\nStop execution of domain DOM.'
  22.112 +            return
  22.113 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
  22.114 +        dom = args[1]
  22.115 +        server.xend_domain_stop(dom)
  22.116 +
  22.117 +    def xm_start(self, help, args):
  22.118 +        """Start execution of a domain."""
  22.119 +        if help:
  22.120 +            print args[0], 'DOM'
  22.121 +            print '\nStart execution of domain DOM.'
  22.122 +            return
  22.123 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
  22.124 +        dom = args[1]
  22.125 +        server.xend_domain_start(dom)
  22.126 +
  22.127 +    def xm_pincpu(self, help, args):
  22.128 +        """Pin a domain to a cpu. """
  22.129 +        if help:
  22.130 +            print args[0],'DOM CPU'
  22.131 +            print '\nPin domain DOM to cpu CPU.'
  22.132 +            return
  22.133 +        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
  22.134 +        v = map(int, args[1:3])
  22.135 +        server.xend_domain_pincpu(*v)
  22.136 +
  22.137 +    def xm_vif_stats(self, help, args):
  22.138 +        """Get stats for a virtual interface."""
  22.139 +        if help:
  22.140 +            print args[0], 'DOM VIF'
  22.141 +            print '\nGet stats for interface VIF on domain DOM.'
  22.142 +            return
  22.143 +        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
  22.144 +        v = map(int, args[1:3])
  22.145 +        print server.xend_domain_vif_stats(*v)
  22.146 +
  22.147 +    def xm_vif_rate(self, help, args):
  22.148 +        """Set or get vif rate params."""
  22.149 +        if help:
  22.150 +            print args[0], "DOM VIF [BYTES USECS]"
  22.151 +            print '\nSet or get rate controls for interface VIF on domain DOM.'
  22.152 +            return
  22.153 +        n = len(args)
  22.154 +        if n == 3:
  22.155 +            v = map(int, args[1:n])
  22.156 +            print server.xend_domain_vif_scheduler_get(*v)
  22.157 +        elif n == 5:
  22.158 +            v = map(int, args[1:n])
  22.159 +            server.xend_domain_vif_scheduler_set(*v)
  22.160 +        else:
  22.161 +            self.err("%s: Invalid argument(s)" % args[0])
  22.162 +
  22.163 +    def xm_bvt(self, help, args):
  22.164 +        """Set BVT scheduler parameters."""
  22.165 +        if help:
  22.166 +            print args[0], "DOM MCUADV WARP WARPL WARPU"
  22.167 +            print '\nSet Borrowed Virtual Time scheduler parameters.'
  22.168 +            return
  22.169 +        if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
  22.170 +        v = map(int, args[1:6])
  22.171 +        server.xend_domain_cpu_bvt_set(*v)
  22.172 +
  22.173 +    def xm_bvtslice(self, help, args):
  22.174 +        """Set the BVT scheduler slice."""
  22.175 +        if help:
  22.176 +            print args[0], 'SLICE'
  22.177 +            print '\nSet Borrowed Virtual Time scheduler slice.'
  22.178 +            return
  22.179 +        if len(args) < 2: self.err('%s: Missing slice' % args[0])
  22.180 +        server.xend_node_cpu_bvt_slice_set(slice)
  22.181 +
  22.182 +    def xm_atropos(self, help, args):
  22.183 +        """Set atropos parameters."""
  22.184 +        if help:
  22.185 +            print args[0], "DOM PERIOD SLICE LATENCY XTRATIME"
  22.186 +            print "\nSet atropos parameters."
  22.187 +            return
  22.188 +        if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
  22.189 +        v = map(int, args[1:5])
  22.190 +        server.xend_domain_cpu_atropos_set(*v)
  22.191 +
  22.192 +    def xm_rrobin(self, help, args):
  22.193 +        """Set round robin slice."""
  22.194 +        if help:
  22.195 +            print args[0], "SLICE"
  22.196 +            print "\nSet round robin scheduler slice."
  22.197 +            return
  22.198 +        if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
  22.199 +        slice = int(args[1])
  22.200 +        server.xend_node_rrobin_set(slice)
  22.201 +
  22.202 +    def xm_info(self, help, args):
  22.203 +        """Get information about the xen host."""
  22.204 +        if help: self.help('xm_info'); return
  22.205 +        info = server.xend_node()
  22.206 +        for x in info[1:]:
  22.207 +            print "%-23s:" % x[0], x[1]
  22.208 +
  22.209 +    def xm_console(self, help, args):
  22.210 +        """Open a console to a domain."""
  22.211 +        if help:
  22.212 +            print "console DOM"
  22.213 +            print "\nOpen a console to domain DOM."
  22.214 +            return
  22.215 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
  22.216 +        dom = args[1]
  22.217 +        info = server.xend_domain(dom)
  22.218 +        console = sxp.child(info, "console")
  22.219 +        if not console:
  22.220 +            self.err("No console information")
  22.221 +        port = sxp.child_value(console, "port")
  22.222 +        from xenctl import console_client
  22.223 +        console_client.connect("localhost", int(port))
  22.224 +
  22.225 +def main(args):
  22.226 +    xm = Xm()
  22.227 +    xm.main(args)
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/xenmgr/lib/xm/opts.py	Thu Jun 17 06:26:58 2004 +0000
    23.3 @@ -0,0 +1,199 @@
    23.4 +from getopt import getopt
    23.5 +import os
    23.6 +import os.path
    23.7 +import sys
    23.8 +import types
    23.9 +
   23.10 +class Opt:
   23.11 +    def __init__(self, opts, name, short=None, long=None,
   23.12 +                 val=None, fn=None, use=None, default=None):
   23.13 +        self.opts = opts
   23.14 +        self.name = name
   23.15 +        self.short = short
   23.16 +        if long is None:
   23.17 +            long = name
   23.18 +        self.long = long
   23.19 +        self.val = val
   23.20 +        self.use = use
   23.21 +        self.default = default
   23.22 +        self.optkeys = []
   23.23 +        if self.short:
   23.24 +            self.optkeys.append('-' + self.short)
   23.25 +        if self.long:
   23.26 +            self.optkeys.append('--' + self.long)
   23.27 +        self.fn = fn
   23.28 +        self.specified_opt = None
   23.29 +        self.specified_val = None
   23.30 +        self.set(default)
   23.31 +
   23.32 +    def set(self, value):
   23.33 +        setattr(self.opts, self.name, value)
   23.34 +
   23.35 +    def get(self):
   23.36 +        return getattr(self.opts, self.name)
   23.37 +
   23.38 +    def append(self, value):
   23.39 +        self.set(self.get().append(value))
   23.40 +
   23.41 +    def short_opt(self):
   23.42 +        if self.short:
   23.43 +            if self.val:
   23.44 +                return self.short + ':'
   23.45 +            else:
   23.46 +                return self.short
   23.47 +        else:
   23.48 +            return None
   23.49 +
   23.50 +    def long_opt(self):
   23.51 +        if self.long:
   23.52 +            if self.val:
   23.53 +                return self.long + '='
   23.54 +            else:
   23.55 +                return self.long
   23.56 +        else:
   23.57 +            return None
   23.58 +
   23.59 +    def show(self):
   23.60 +        sep = ''
   23.61 +        for x in self.optkeys:
   23.62 +            print sep, x,
   23.63 +            sep = ','
   23.64 +        if self.val:
   23.65 +            print self.val,
   23.66 +        print
   23.67 +        if self.use:
   23.68 +            print '\t',
   23.69 +            print self.use
   23.70 +        if self.val:
   23.71 +            print '\tDefault', self.default or 'None'
   23.72 +
   23.73 +    def specify(self, k, v):
   23.74 +        if k in self.optkeys:
   23.75 +            if self.val is None and v:
   23.76 +                self.opts.err("Option '%s' does not take a value" % k)
   23.77 +            self.specified_opt = k
   23.78 +            self.specified_val = v
   23.79 +            if self.fn:
   23.80 +                self.fn(self, k, v)
   23.81 +            return 1
   23.82 +        else:
   23.83 +            return 0
   23.84 +
   23.85 +    def specified(self):
   23.86 +        return self.specified_opt
   23.87 +
   23.88 +class Opts:
   23.89 +    def __init__(self, use=None):
   23.90 +        self._usage = use
   23.91 +        self._options = []
   23.92 +        self._options_map = {}
   23.93 +        self._argv = []
   23.94 +        self._vals = {}
   23.95 +        self._globals = {}
   23.96 +        self._locals = {}
   23.97 +
   23.98 +    def opt(self, name, **args):
   23.99 +        x = Opt(self, name, **args)
  23.100 +        self._options.append(x)
  23.101 +        self._options_map[name] = x
  23.102 +        return x
  23.103 +
  23.104 +    def getopt(self, name):
  23.105 +        return self._options_map.get(name)
  23.106 +
  23.107 +    def specified(self, name):
  23.108 +        opt = self.getopt(name)
  23.109 +        return opt and opt.specified()
  23.110 +
  23.111 +    def setvar(self, name, val):
  23.112 +        self._globals[name] = val
  23.113 +
  23.114 +    def err(self, msg):
  23.115 +        print >>sys.stderr, "Error:", msg
  23.116 +        sys.exit(1)
  23.117 +
  23.118 +    def info(self, msg):
  23.119 +        if self.quiet: return
  23.120 +        print msg
  23.121 +
  23.122 +    def warn(self, msg):
  23.123 +        print >>sys.stderr, "Warning:", msg
  23.124 +
  23.125 +    def parse(self, argv):
  23.126 +        self._argv = argv
  23.127 +        (vals, args) = getopt(argv[1:], self.short_opts(), self.long_opts())
  23.128 +        self._args = args
  23.129 +        for (k, v) in vals:
  23.130 +            for opt in self._options:
  23.131 +                if opt.specify(k, v): break
  23.132 +            else:
  23.133 +                print >>sys.stderr, "Error: Unknown option:", k
  23.134 +                self.usage()
  23.135 +        return args
  23.136 +
  23.137 +    def short_opts(self):
  23.138 +        l = []
  23.139 +        for x in self._options:
  23.140 +            y = x.short_opt()
  23.141 +            if not y: continue
  23.142 +            l.append(y)
  23.143 +        return ''.join(l)
  23.144 +
  23.145 +    def long_opts(self):
  23.146 +        l = []
  23.147 +        for x in self._options:
  23.148 +            y = x.long_opt()
  23.149 +            if not y: continue
  23.150 +            l.append(y)
  23.151 +        return ''.join(l)
  23.152 +
  23.153 +    def usage(self):
  23.154 +        print 'Usage: ', self._argv[0], self._usage or 'OPTIONS'
  23.155 +        for opt in self._options:
  23.156 +            opt.show()
  23.157 +
  23.158 +    def load_defaults(self):
  23.159 +        for x in [ '' ] + self.path.split(':'):
  23.160 +            if x:
  23.161 +                p = os.path.join(x, self.defaults)
  23.162 +            else:
  23.163 +                p = self.defaults
  23.164 +            if os.path.exists(p):
  23.165 +                self.load(p)
  23.166 +                break
  23.167 +        else:
  23.168 +            self.err("Cannot open defaults file %s" % self.defaults)
  23.169 +
  23.170 +    def load(self, defaults):
  23.171 +        self._globals['sys'] = sys
  23.172 +        self._globals['config_file'] = defaults
  23.173 +        execfile(defaults, self._globals, self._locals)
  23.174 +        vtypes = [ types.StringType,
  23.175 +                   types.ListType,
  23.176 +                   types.IntType,
  23.177 +                   types.FloatType
  23.178 +                   ]
  23.179 +        for (k, v) in self._locals.items():
  23.180 +            if self.specified(k): continue
  23.181 +            if not(type(v) in vtypes): continue
  23.182 +            print 'SET ', k, v
  23.183 +            setattr(self, k, v)
  23.184 +
  23.185 +def set_true(opt, k, v):
  23.186 +    opt.set(1)
  23.187 +
  23.188 +def set_false(opt, k, v):
  23.189 +    opt.set(0)
  23.190 +
  23.191 +def set_value(opt, k, v):
  23.192 +    opt.set(v)
  23.193 +
  23.194 +def set_int(opt, k, v):
  23.195 +    try:
  23.196 +        v = int(v)
  23.197 +    except:
  23.198 +        opt.opts.err('Invalid value: ' + str(v))
  23.199 +    opt.set(v)
  23.200 +
  23.201 +def append_value(opt, k, v):
  23.202 +    opt.append(v)
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/xenmgr/lib/xm/shutdown.py	Thu Jun 17 06:26:58 2004 +0000
    24.3 @@ -0,0 +1,65 @@
    24.4 +import string
    24.5 +import sys
    24.6 +import time
    24.7 +
    24.8 +from xenmgr.XendClient import server
    24.9 +from xenmgr.xm.opts import *
   24.10 +
   24.11 +opts = Opts(use="""[options] [DOM]
   24.12 +
   24.13 +Shutdown one or more domains gracefully.""")
   24.14 +
   24.15 +opts.opt('help', short='h',
   24.16 +         fn=set_value, default=0,
   24.17 +         use="Print this help.")
   24.18 +
   24.19 +opts.opt('all', short='a',
   24.20 +         fn=set_true, default=0,
   24.21 +         use="Shutdown all domains.")
   24.22 +
   24.23 +opts.opt('wait', short='w',
   24.24 +         fn=set_true, default=0,
   24.25 +         use='Wait for shutdown to complete.')
   24.26 +
   24.27 +def shutdown(opts, doms, wait):
   24.28 +    def domains():
   24.29 +        return [ int(a) for a in server.xend_domains() ]
   24.30 +    if doms == None: doms = domains()
   24.31 +    if 0 in doms:
   24.32 +        doms.remove(0)
   24.33 +    for d in doms:
   24.34 +        server.xend_domain_shutdown(dom)
   24.35 +    if wait:
   24.36 +        while doms:
   24.37 +            alive = domains()
   24.38 +            dead = []
   24.39 +            for d in doms:
   24.40 +                if d in alive: continue
   24.41 +                dead.append(d)
   24.42 +            for d in dead:
   24.43 +                opts.info("Domain %d terminated" % d)
   24.44 +                doms.remove(d)
   24.45 +            time.sleep(1)
   24.46 +        opts.info("All domains terminated")
   24.47 +
   24.48 +def main_all(opts, args):
   24.49 +    shutdown(opts, None, opts.wait)
   24.50 +
   24.51 +def main_dom(opts, args):
   24.52 +    if len(args) < 2: opts.err('Missing domain')
   24.53 +    dom = argv[1]
   24.54 +    try:
   24.55 +        domid = int(dom)
   24.56 +    except:
   24.57 +        opts.err('Invalid domain: ' + dom)
   24.58 +    shutdown(opts, [ domid ], opts.wait)
   24.59 +    
   24.60 +def main(argv):
   24.61 +    args = opts.parse(argv)
   24.62 +    if opts.help:
   24.63 +        opts.usage()
   24.64 +    if opts.all:
   24.65 +        main_all(opts, args)
   24.66 +    else:
   24.67 +        main_dom(opts, args)
   24.68 +        
    25.1 --- a/tools/xenmgr/netfix	Wed Jun 16 21:29:21 2004 +0000
    25.2 +++ b/tools/xenmgr/netfix	Thu Jun 17 06:26:58 2004 +0000
    25.3 @@ -1,4 +1,5 @@
    25.4  #!/usr/bin/python
    25.5 +#  -*- mode: python; -*-
    25.6  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    25.7  #============================================================================
    25.8  # Move the IP address from eth0 onto the Xen bridge (nbe-br).
    26.1 --- a/tools/xenmgr/setup.py	Wed Jun 16 21:29:21 2004 +0000
    26.2 +++ b/tools/xenmgr/setup.py	Thu Jun 17 06:26:58 2004 +0000
    26.3 @@ -9,6 +9,6 @@ setup(name            = PACKAGE,
    26.4        description     = 'Xen Management API',
    26.5        author          = 'Mike Wray',
    26.6        author_email    = 'mike.wray@hp.com',
    26.7 -      packages        = [ PACKAGE, PACKAGE + '.server' ],
    26.8 +      packages        = [ PACKAGE, PACKAGE + '.server', PACKAGE + '.xm' ],
    26.9        package_dir     = { PACKAGE: 'lib' },
   26.10        )
    27.1 --- a/tools/xenmgr/xend	Wed Jun 16 21:29:21 2004 +0000
    27.2 +++ b/tools/xenmgr/xend	Thu Jun 17 06:26:58 2004 +0000
    27.3 @@ -1,4 +1,5 @@
    27.4  #!/usr/bin/python
    27.5 +#  -*- mode: python; -*-
    27.6  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    27.7  
    27.8  """Xen management daemon. Lives in /usr/sbin.
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tools/xenmgr/xm	Thu Jun 17 06:26:58 2004 +0000
    28.3 @@ -0,0 +1,6 @@
    28.4 +#!/usr/bin/python
    28.5 +#  -*- mode: python; -*-
    28.6 +import sys
    28.7 +from xenmgr.xm import main
    28.8 +
    28.9 +main.main(sys.argv)