ia64/xen-unstable
changeset 11390:e01441c9a607
[POWERPC] merge with xen-unstable.hg
author | Hollis Blanchard <hollisb@us.ibm.com> |
---|---|
date | Wed Aug 30 14:09:31 2006 -0500 (2006-08-30) |
parents | 18ce855ff594 a39ad4c78850 |
children | 50aea0ec406b |
files |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Tue Aug 29 17:53:57 2006 -0500 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Aug 30 14:09:31 2006 -0500 1.3 @@ -114,8 +114,8 @@ typedef struct domid_translate { 1.4 } domid_translate_t ; 1.5 1.6 1.7 -domid_translate_t translate_domid[MAX_TAP_DEV]; 1.8 -tap_blkif_t *tapfds[MAX_TAP_DEV]; 1.9 +static domid_translate_t translate_domid[MAX_TAP_DEV]; 1.10 +static tap_blkif_t *tapfds[MAX_TAP_DEV]; 1.11 1.12 static int __init set_blkif_reqs(char *str) 1.13 { 1.14 @@ -1118,7 +1118,7 @@ static int do_block_io_op(blkif_t *blkif 1.15 "ring does not exist!\n"); 1.16 print_dbug = 0; /*We only print this message once*/ 1.17 } 1.18 - return 1; 1.19 + return 0; 1.20 } 1.21 1.22 info = tapfds[blkif->dev_num]; 1.23 @@ -1127,7 +1127,7 @@ static int do_block_io_op(blkif_t *blkif 1.24 WPRINTK("Can't get UE info!\n"); 1.25 print_dbug = 0; 1.26 } 1.27 - return 1; 1.28 + return 0; 1.29 } 1.30 1.31 while (rc != rp) {
2.1 --- a/tools/blktap/drivers/block-aio.c Tue Aug 29 17:53:57 2006 -0500 2.2 +++ b/tools/blktap/drivers/block-aio.c Wed Aug 30 14:09:31 2006 -0500 2.3 @@ -52,7 +52,7 @@ 2.4 */ 2.5 #define REQUEST_ASYNC_FD 1 2.6 2.7 -#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ * 8) 2.8 +#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ) 2.9 2.10 struct pending_aio { 2.11 td_callback_t cb; 2.12 @@ -146,7 +146,7 @@ int tdaio_open (struct td_state *s, cons 2.13 struct tdaio_state *prv = (struct tdaio_state *)s->private; 2.14 s->private = prv; 2.15 2.16 - DPRINTF("XXX: block-aio open('%s')", name); 2.17 + DPRINTF("block-aio open('%s')", name); 2.18 /* Initialize AIO */ 2.19 prv->iocb_free_count = MAX_AIO_REQS; 2.20 prv->iocb_queued = 0; 2.21 @@ -156,9 +156,18 @@ int tdaio_open (struct td_state *s, cons 2.22 2.23 if (prv->poll_fd < 0) { 2.24 ret = prv->poll_fd; 2.25 - DPRINTF("Couldn't get fd for AIO poll support. This is " 2.26 - "probably because your kernel does not have the " 2.27 - "aio-poll patch applied.\n"); 2.28 + if (ret == -EAGAIN) { 2.29 + DPRINTF("Couldn't setup AIO context. If you are " 2.30 + "trying to concurrently use a large number " 2.31 + "of blktap-based disks, you may need to " 2.32 + "increase the system-wide aio request limit. " 2.33 + "(e.g. 'echo echo 1048576 > /proc/sys/fs/" 2.34 + "aio-max-nr')\n"); 2.35 + } else { 2.36 + DPRINTF("Couldn't get fd for AIO poll support. This " 2.37 + "is probably because your kernel does not " 2.38 + "have the aio-poll patch applied.\n"); 2.39 + } 2.40 goto done; 2.41 } 2.42
3.1 --- a/tools/blktap/drivers/block-qcow.c Tue Aug 29 17:53:57 2006 -0500 3.2 +++ b/tools/blktap/drivers/block-qcow.c Wed Aug 30 14:09:31 2006 -0500 3.3 @@ -51,7 +51,7 @@ 3.4 /******AIO DEFINES******/ 3.5 #define REQUEST_ASYNC_FD 1 3.6 #define MAX_QCOW_IDS 0xFFFF 3.7 -#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ * 8) 3.8 +#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ) 3.9 3.10 struct pending_aio { 3.11 td_callback_t cb; 3.12 @@ -176,10 +176,21 @@ static int init_aio_state(struct td_stat 3.13 s->aio_ctx = (io_context_t) REQUEST_ASYNC_FD; 3.14 s->poll_fd = io_setup(MAX_AIO_REQS, &s->aio_ctx); 3.15 3.16 - if (s->poll_fd < 0) { 3.17 - DPRINTF("Retrieving Async poll fd failed\n"); 3.18 + if (s->poll_fd < 0) { 3.19 + if (s->poll_fd == -EAGAIN) { 3.20 + DPRINTF("Couldn't setup AIO context. If you are " 3.21 + "trying to concurrently use a large number " 3.22 + "of blktap-based disks, you may need to " 3.23 + "increase the system-wide aio request limit. " 3.24 + "(e.g. 'echo echo 1048576 > /proc/sys/fs/" 3.25 + "aio-max-nr')\n"); 3.26 + } else { 3.27 + DPRINTF("Couldn't get fd for AIO poll support. This " 3.28 + "is probably because your kernel does not " 3.29 + "have the aio-poll patch applied.\n"); 3.30 + } 3.31 goto fail; 3.32 - } 3.33 + } 3.34 3.35 for (i=0;i<MAX_AIO_REQS;i++) 3.36 s->iocb_free[i] = &s->iocb_list[i];
4.1 --- a/tools/blktap/drivers/tapdisk.c Tue Aug 29 17:53:57 2006 -0500 4.2 +++ b/tools/blktap/drivers/tapdisk.c Wed Aug 30 14:09:31 2006 -0500 4.3 @@ -110,6 +110,7 @@ static void unmap_disk(struct td_state * 4.4 free(s->fd_entry); 4.5 free(s->blkif); 4.6 free(s->ring_info); 4.7 + free(s->private); 4.8 free(s); 4.9 4.10 return;
5.1 --- a/tools/blktap/lib/xs_api.c Tue Aug 29 17:53:57 2006 -0500 5.2 +++ b/tools/blktap/lib/xs_api.c Wed Aug 30 14:09:31 2006 -0500 5.3 @@ -204,7 +204,7 @@ char *get_dom_domid(struct xs_handle *h, 5.4 int convert_dev_name_to_num(char *name) { 5.5 char *p_sd, *p_hd, *p_xvd, *p_plx, *p, *alpha,*ptr; 5.6 int majors[10] = {3,22,33,34,56,57,88,89,90,91}; 5.7 - int maj,i; 5.8 + int maj,i,ret = 0; 5.9 5.10 asprintf(&p_sd,"/dev/sd"); 5.11 asprintf(&p_hd,"/dev/hd"); 5.12 @@ -221,7 +221,7 @@ int convert_dev_name_to_num(char *name) 5.13 *ptr++; 5.14 } 5.15 *p++; 5.16 - return BASE_DEV_VAL + (16*i) + atoi(p); 5.17 + ret = BASE_DEV_VAL + (16*i) + atoi(p); 5.18 } else if (strstr(name, p_hd) != NULL) { 5.19 p = name + strlen(p_hd); 5.20 for (i = 0, ptr = alpha; i < strlen(alpha); i++) { 5.21 @@ -229,7 +229,7 @@ int convert_dev_name_to_num(char *name) 5.22 *ptr++; 5.23 } 5.24 *p++; 5.25 - return (majors[i/2]*256) + atoi(p); 5.26 + ret = (majors[i/2]*256) + atoi(p); 5.27 5.28 } else if (strstr(name, p_xvd) != NULL) { 5.29 p = name + strlen(p_xvd); 5.30 @@ -238,17 +238,24 @@ int convert_dev_name_to_num(char *name) 5.31 *ptr++; 5.32 } 5.33 *p++; 5.34 - return (202*256) + (16*i) + atoi(p); 5.35 + ret = (202*256) + (16*i) + atoi(p); 5.36 5.37 } else if (strstr(name, p_plx) != NULL) { 5.38 p = name + strlen(p_plx); 5.39 - return atoi(p); 5.40 + ret = atoi(p); 5.41 5.42 } else { 5.43 DPRINTF("Unknown device type, setting to default.\n"); 5.44 - return BASE_DEV_VAL; 5.45 + ret = BASE_DEV_VAL; 5.46 } 5.47 - return 0; 5.48 + 5.49 + free(p_sd); 5.50 + free(p_hd); 5.51 + free(p_xvd); 5.52 + free(p_plx); 5.53 + free(alpha); 5.54 + 5.55 + return ret; 5.56 } 5.57 5.58 /**
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/tools/python/xen/xend/FlatDeviceTree.py Wed Aug 30 14:09:31 2006 -0500 6.3 @@ -0,0 +1,323 @@ 6.4 +#!/usr/bin/env python 6.5 +# 6.6 +# This library is free software; you can redistribute it and/or 6.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 6.8 +# License as published by the Free Software Foundation. 6.9 +# 6.10 +# This library is distributed in the hope that it will be useful, 6.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 6.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 6.13 +# Lesser General Public License for more details. 6.14 +# 6.15 +# You should have received a copy of the GNU Lesser General Public 6.16 +# License along with this library; if not, write to the Free Software 6.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6.18 +# 6.19 +# Copyright (C) IBM Corp. 2006 6.20 +# 6.21 +# Authors: Hollis Blanchard <hollisb@us.ibm.com> 6.22 + 6.23 +import os 6.24 +import sys 6.25 +import struct 6.26 +import stat 6.27 +import re 6.28 + 6.29 +_OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning 6.30 +_OF_DT_BEGIN_NODE = 0x1 6.31 +_OF_DT_END_NODE = 0x2 6.32 +_OF_DT_PROP = 0x3 6.33 +_OF_DT_END = 0x9 6.34 + 6.35 +def _bincat(seq, separator=''): 6.36 + '''Concatenate the contents of seq into a bytestream.''' 6.37 + strs = [] 6.38 + for item in seq: 6.39 + if type(item) == type(0): 6.40 + strs.append(struct.pack(">I", item)) 6.41 + else: 6.42 + try: 6.43 + strs.append(item.to_bin()) 6.44 + except AttributeError, e: 6.45 + strs.append(item) 6.46 + return separator.join(strs) 6.47 + 6.48 +def _alignup(val, alignment): 6.49 + return (val + alignment - 1) & ~(alignment - 1) 6.50 + 6.51 +def _pad(buf, alignment): 6.52 + '''Pad bytestream with NULLs to specified alignment.''' 6.53 + padlen = _alignup(len(buf), alignment) 6.54 + return buf + '\0' * (padlen - len(buf)) 6.55 + # not present in Python 2.3: 6.56 + #return buf.ljust(_padlen, '\0') 6.57 + 6.58 +def _indent(item): 6.59 + indented = [] 6.60 + for line in str(item).splitlines(True): 6.61 + indented.append(' ' + line) 6.62 + return ''.join(indented) 6.63 + 6.64 +class _Property: 6.65 + _nonprint = re.compile('[\000-\037\200-\377]') 6.66 + def __init__(self, node, name, value): 6.67 + self.node = node 6.68 + self.value = value 6.69 + self.name = name 6.70 + self.node.tree.stradd(name) 6.71 + 6.72 + def __str__(self): 6.73 + result = self.name 6.74 + if self.value: 6.75 + searchtext = self.value 6.76 + # it's ok for a string to end in NULL 6.77 + if searchtext.find('\000') == len(searchtext)-1: 6.78 + searchtext = searchtext[:-1] 6.79 + m = self._nonprint.search(searchtext) 6.80 + if m: 6.81 + bytes = struct.unpack("B" * len(self.value), self.value) 6.82 + hexbytes = [ '%02x' % b for b in bytes ] 6.83 + words = [] 6.84 + for i in range(0, len(self.value), 4): 6.85 + words.append(''.join(hexbytes[i:i+4])) 6.86 + v = '<' + ' '.join(words) + '>' 6.87 + else: 6.88 + v = '"%s"' % self.value 6.89 + result += ': ' + v 6.90 + return result 6.91 + 6.92 + def to_bin(self): 6.93 + offset = self.node.tree.stroffset(self.name) 6.94 + return struct.pack('>III', _OF_DT_PROP, len(self.value), offset) \ 6.95 + + _pad(self.value, 4) 6.96 + 6.97 +class _Node: 6.98 + def __init__(self, tree, name): 6.99 + self.tree = tree 6.100 + self.name = name 6.101 + self.props = {} 6.102 + self.children = {} 6.103 + self.phandle = 0 6.104 + 6.105 + def __str__(self): 6.106 + propstrs = [ _indent(prop) for prop in self.props.values() ] 6.107 + childstrs = [ _indent(child) for child in self.children.values() ] 6.108 + return '%s:\n%s\n%s' % (self.name, '\n'.join(propstrs), 6.109 + '\n'.join(childstrs)) 6.110 + 6.111 + def to_bin(self): 6.112 + name = _pad(self.name + '\0', 4) 6.113 + return struct.pack('>I', _OF_DT_BEGIN_NODE) + \ 6.114 + name + \ 6.115 + _bincat(self.props.values()) + \ 6.116 + _bincat(self.children.values()) + \ 6.117 + struct.pack('>I', _OF_DT_END_NODE) 6.118 + 6.119 + def addprop(self, propname, *cells): 6.120 + '''setprop with duplicate error-checking.''' 6.121 + if propname in self.props: 6.122 + raise AttributeError('%s/%s already exists' % (self.name, propname)) 6.123 + self.setprop(propname, *cells) 6.124 + 6.125 + def setprop(self, propname, *cells): 6.126 + self.props[propname] = _Property(self, propname, _bincat(cells)) 6.127 + 6.128 + def addnode(self, nodename): 6.129 + '''newnode with duplicate error-checking.''' 6.130 + if nodename in self.children: 6.131 + raise AttributeError('%s/%s already exists' % (self.name, nodename)) 6.132 + return self.newnode(nodename) 6.133 + 6.134 + def newnode(self, nodename): 6.135 + node = _Node(self.tree, nodename) 6.136 + self.children[nodename] = node 6.137 + return node 6.138 + 6.139 + def getprop(self, propname): 6.140 + return self.props[propname] 6.141 + 6.142 + def getchild(self, nodename): 6.143 + return self.children[nodename] 6.144 + 6.145 + def get_phandle(self): 6.146 + if self.phandle: 6.147 + return self.phandle 6.148 + self.phandle = self.tree.alloc_phandle() 6.149 + self.addprop('linux,phandle', self.phandle) 6.150 + return self.phandle 6.151 + 6.152 +class _Header: 6.153 + def __init__(self): 6.154 + self.magic = 0 6.155 + self.totalsize = 0 6.156 + self.off_dt_struct = 0 6.157 + self.off_dt_strings = 0 6.158 + self.off_mem_rsvmap = 0 6.159 + self.version = 0 6.160 + self.last_comp_version = 0 6.161 + self.boot_cpuid_phys = 0 6.162 + self.size_dt_strings = 0 6.163 + def to_bin(self): 6.164 + return struct.pack('>9I', 6.165 + self.magic, 6.166 + self.totalsize, 6.167 + self.off_dt_struct, 6.168 + self.off_dt_strings, 6.169 + self.off_mem_rsvmap, 6.170 + self.version, 6.171 + self.last_comp_version, 6.172 + self.boot_cpuid_phys, 6.173 + self.size_dt_strings) 6.174 + 6.175 +class _StringBlock: 6.176 + def __init__(self): 6.177 + self.table = [] 6.178 + def to_bin(self): 6.179 + return _bincat(self.table, '\0') + '\0' 6.180 + def add(self, str): 6.181 + self.table.append(str) 6.182 + def getoffset(self, str): 6.183 + return self.to_bin().index(str + '\0') 6.184 + 6.185 +class Tree(_Node): 6.186 + def __init__(self): 6.187 + self.last_phandle = 0 6.188 + self.strings = _StringBlock() 6.189 + self.reserved = [(0, 0)] 6.190 + _Node.__init__(self, self, '\0') 6.191 + 6.192 + def alloc_phandle(self): 6.193 + self.last_phandle += 1 6.194 + return self.last_phandle 6.195 + 6.196 + def stradd(self, str): 6.197 + return self.strings.add(str) 6.198 + 6.199 + def stroffset(self, str): 6.200 + return self.strings.getoffset(str) 6.201 + 6.202 + def reserve(self, start, len): 6.203 + self.reserved.insert(0, (start, len)) 6.204 + 6.205 + def to_bin(self): 6.206 + # layout: 6.207 + # header 6.208 + # reservation map 6.209 + # string block 6.210 + # data block 6.211 + 6.212 + datablock = _Node.to_bin(self) 6.213 + 6.214 + r = [ struct.pack('>QQ', rsrv[0], rsrv[1]) for rsrv in self.reserved ] 6.215 + reserved = _bincat(r) 6.216 + 6.217 + strblock = _pad(self.strings.to_bin(), 4) 6.218 + strblocklen = len(strblock) 6.219 + 6.220 + header = _Header() 6.221 + header.magic = _OF_DT_HEADER 6.222 + header.off_mem_rsvmap = _alignup(len(header.to_bin()), 8) 6.223 + header.off_dt_strings = header.off_mem_rsvmap + len(reserved) 6.224 + header.off_dt_struct = header.off_dt_strings + strblocklen 6.225 + header.version = 0x10 6.226 + header.last_comp_version = 0x10 6.227 + header.boot_cpuid_phys = 0 6.228 + header.size_dt_strings = strblocklen 6.229 + 6.230 + payload = reserved + \ 6.231 + strblock + \ 6.232 + datablock + \ 6.233 + struct.pack('>I', _OF_DT_END) 6.234 + header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8) 6.235 + return _pad(header.to_bin(), 8) + payload 6.236 + 6.237 +_host_devtree_root = '/proc/device-tree' 6.238 +def _getprop(propname): 6.239 + '''Extract a property from the system's device tree.''' 6.240 + f = file(os.path.join(_host_devtree_root, propname), 'r') 6.241 + data = f.read() 6.242 + f.close() 6.243 + return data 6.244 + 6.245 +def _copynode(node, dirpath, propfilter): 6.246 + '''Extract all properties from a node in the system's device tree.''' 6.247 + dirents = os.listdir(dirpath) 6.248 + for dirent in dirents: 6.249 + fullpath = os.path.join(dirpath, dirent) 6.250 + st = os.lstat(fullpath) 6.251 + if stat.S_ISDIR(st.st_mode): 6.252 + child = node.addnode(dirent) 6.253 + _copytree(child, fullpath, propfilter) 6.254 + elif stat.S_ISREG(st.st_mode) and propfilter(fullpath): 6.255 + node.addprop(dirent, _getprop(fullpath)) 6.256 + 6.257 +def _copytree(node, dirpath, propfilter): 6.258 + path = os.path.join(_host_devtree_root, dirpath) 6.259 + _copynode(node, path, propfilter) 6.260 + 6.261 +def build(imghandler): 6.262 + '''Construct a device tree by combining the domain's configuration and 6.263 + the host's device tree.''' 6.264 + root = Tree() 6.265 + 6.266 + # 4 pages: start_info, console, store, shared_info 6.267 + root.reserve(0x3ffc000, 0x4000) 6.268 + 6.269 + root.addprop('device_type', 'chrp-but-not-really\0') 6.270 + root.addprop('#size-cells', 2) 6.271 + root.addprop('#address-cells', 2) 6.272 + root.addprop('model', 'Momentum,Maple-D\0') 6.273 + root.addprop('compatible', 'Momentum,Maple\0') 6.274 + 6.275 + xen = root.addnode('xen') 6.276 + xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000) 6.277 + xen.addprop('version', 'Xen-3.0-unstable\0') 6.278 + xen.addprop('reg', 0, imghandler.vm.domid, 0, 0) 6.279 + xen.addprop('domain-name', imghandler.vm.getName() + '\0') 6.280 + xencons = xen.addnode('console') 6.281 + xencons.addprop('interrupts', 1, 0) 6.282 + 6.283 + # XXX split out RMA node 6.284 + mem = root.addnode('memory@0') 6.285 + totalmem = imghandler.vm.getMemoryTarget() * 1024 6.286 + mem.addprop('reg', 0, 0, 0, totalmem) 6.287 + mem.addprop('device_type', 'memory\0') 6.288 + 6.289 + cpus = root.addnode('cpus') 6.290 + cpus.addprop('smp-enabled') 6.291 + cpus.addprop('#size-cells', 0) 6.292 + cpus.addprop('#address-cells', 1) 6.293 + 6.294 + # Copy all properties the system firmware gave us, except for 'linux,' 6.295 + # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are 6.296 + # identical... 6.297 + cpu0 = None 6.298 + def _nolinuxprops(fullpath): 6.299 + return not os.path.basename(fullpath).startswith('linux,') 6.300 + for i in range(imghandler.vm.getVCpuCount()): 6.301 + cpu = cpus.addnode('PowerPC,970@0') 6.302 + _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops) 6.303 + # and then overwrite what we need to 6.304 + pft_size = imghandler.vm.info.get('pft-size', 0x14) 6.305 + cpu.setprop('ibm,pft-size', 0, pft_size) 6.306 + 6.307 + # set default CPU 6.308 + if cpu0 == None: 6.309 + cpu0 = cpu 6.310 + 6.311 + chosen = root.addnode('chosen') 6.312 + chosen.addprop('cpu', cpu0.get_phandle()) 6.313 + chosen.addprop('memory', mem.get_phandle()) 6.314 + chosen.addprop('linux,stdout-path', '/xen/console\0') 6.315 + chosen.addprop('interrupt-controller', xen.get_phandle()) 6.316 + chosen.addprop('bootargs', imghandler.cmdline + '\0') 6.317 + # xc_linux_load.c will overwrite these 64-bit properties later 6.318 + chosen.addprop('linux,initrd-start', 0, 0) 6.319 + chosen.addprop('linux,initrd-end', 0, 0) 6.320 + 6.321 + if 1: 6.322 + f = file('/tmp/domU.dtb', 'w') 6.323 + f.write(root.to_bin()) 6.324 + f.close() 6.325 + 6.326 + return root
7.1 --- a/tools/python/xen/xend/XendCheckpoint.py Tue Aug 29 17:53:57 2006 -0500 7.2 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Aug 30 14:09:31 2006 -0500 7.3 @@ -161,10 +161,12 @@ def restore(xd, fd): 7.4 if handler.store_mfn is None or handler.console_mfn is None: 7.5 raise XendError('Could not read store/console MFN') 7.6 7.7 + #Block until src closes connection 7.8 + os.read(fd, 1) 7.9 dominfo.unpause() 7.10 - 7.11 + 7.12 dominfo.completeRestore(handler.store_mfn, handler.console_mfn) 7.13 - 7.14 + 7.15 return dominfo 7.16 except: 7.17 dominfo.destroy()
8.1 --- a/tools/python/xen/xend/XendDomain.py Tue Aug 29 17:53:57 2006 -0500 8.2 +++ b/tools/python/xen/xend/XendDomain.py Wed Aug 30 14:09:31 2006 -0500 8.3 @@ -431,7 +431,8 @@ class XendDomain: 8.4 sock.send("receive\n") 8.5 sock.recv(80) 8.6 XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst) 8.7 - 8.8 + dominfo.testDeviceComplete() 8.9 + sock.close() 8.10 8.11 def domain_save(self, domid, dst): 8.12 """Start saving a domain to file.
9.1 --- a/tools/python/xen/xend/XendDomainInfo.py Tue Aug 29 17:53:57 2006 -0500 9.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Aug 30 14:09:31 2006 -0500 9.3 @@ -30,7 +30,6 @@ import string 9.4 import time 9.5 import threading 9.6 import os 9.7 -import math 9.8 9.9 import xen.lowlevel.xc 9.10 from xen.util import asserts 9.11 @@ -703,6 +702,9 @@ class XendDomainInfo: 9.12 if security[idx][0] == 'ssidref': 9.13 to_store['security/ssidref'] = str(security[idx][1]) 9.14 9.15 + if not self.readVm('xend/restart_count'): 9.16 + to_store['xend/restart_count'] = str(0) 9.17 + 9.18 log.debug("Storing VM details: %s", to_store) 9.19 9.20 self.writeVm(to_store) 9.21 @@ -824,6 +826,9 @@ class XendDomainInfo: 9.22 def setResume(self, state): 9.23 self.info['resume'] = state 9.24 9.25 + def getRestartCount(self): 9.26 + return self.readVm('xend/restart_count') 9.27 + 9.28 def refreshShutdown(self, xeninfo = None): 9.29 # If set at the end of this method, a restart is required, with the 9.30 # given reason. This restart has to be done out of the scope of 9.31 @@ -1280,34 +1285,28 @@ class XendDomainInfo: 9.32 for v in range(0, self.info['max_vcpu_id']+1): 9.33 xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) 9.34 9.35 - # set domain maxmem in KiB 9.36 - xc.domain_setmaxmem(self.domid, self.info['maxmem'] * 1024) 9.37 + # set memory limit 9.38 + maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) 9.39 + xc.domain_setmaxmem(self.domid, maxmem) 9.40 9.41 - m = self.image.getDomainMemory(self.info['memory'] * 1024) 9.42 + mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) 9.43 9.44 # get the domain's shadow memory requirement 9.45 - sm = int(math.ceil(self.image.getDomainShadowMemory(m) / 1024.0)) 9.46 - if self.info['shadow_memory'] > sm: 9.47 - sm = self.info['shadow_memory'] 9.48 + shadow_kb = self.image.getRequiredShadowMemory(mem_kb) 9.49 + shadow_kb_req = self.info['shadow_memory'] * 1024 9.50 + if shadow_kb_req > shadow_kb: 9.51 + shadow_kb = shadow_kb_req 9.52 + shadow_mb = (shadow_kb + 1023) / 1024 9.53 9.54 # Make sure there's enough RAM available for the domain 9.55 - balloon.free(m + sm * 1024) 9.56 + balloon.free(mem_kb + shadow_mb * 1024) 9.57 9.58 # Set up the shadow memory 9.59 - sm = xc.shadow_mem_control(self.domid, mb=sm) 9.60 - self.info['shadow_memory'] = sm 9.61 + shadow_cur = xc.shadow_mem_control(self.domid, shadow_mb) 9.62 + self.info['shadow_memory'] = shadow_cur 9.63 9.64 - init_reservation = self.info['memory'] * 1024 9.65 - if os.uname()[4] in ('ia64', 'ppc64'): 9.66 - # Workaround for architectures that don't yet support 9.67 - # ballooning. 9.68 - init_reservation = m 9.69 - # Following line from xiantao.zhang@intel.com 9.70 - # Needed for IA64 until supports ballooning -- okay for PPC64? 9.71 - xc.domain_setmaxmem(self.domid, m) 9.72 - 9.73 - xc.domain_memory_increase_reservation(self.domid, init_reservation, 9.74 - 0, 0) 9.75 + # initial memory allocation 9.76 + xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) 9.77 9.78 self.createChannels() 9.79 9.80 @@ -1495,6 +1494,21 @@ class XendDomainInfo: 9.81 if rc != 0: 9.82 raise XendError("Device of type '%s' refuses migration." % n) 9.83 9.84 + def testDeviceComplete(self): 9.85 + """ For Block IO migration safety we must ensure that 9.86 + the device has shutdown correctly, i.e. all blocks are 9.87 + flushed to disk 9.88 + """ 9.89 + while True: 9.90 + test = 0 9.91 + for i in self.getDeviceController('vbd').deviceIDs(): 9.92 + test = 1 9.93 + log.info("Dev %s still active, looping...", i) 9.94 + time.sleep(0.1) 9.95 + 9.96 + if test == 0: 9.97 + break 9.98 + 9.99 def migrateDevices(self, network, dst, step, domName=''): 9.100 """Notify the devices about migration 9.101 """ 9.102 @@ -1615,6 +1629,9 @@ class XendDomainInfo: 9.103 try: 9.104 new_dom = XendDomain.instance().domain_create(config) 9.105 new_dom.unpause() 9.106 + rst_cnt = self.readVm('xend/restart_count') 9.107 + rst_cnt = int(rst_cnt) + 1 9.108 + self.writeVm('xend/restart_count', str(rst_cnt)) 9.109 new_dom.removeVm(RESTART_IN_PROGRESS) 9.110 except: 9.111 if new_dom:
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/python/xen/xend/arch.py Wed Aug 30 14:09:31 2006 -0500 10.3 @@ -0,0 +1,32 @@ 10.4 +#!/usr/bin/env python 10.5 +# 10.6 +# This library is free software; you can redistribute it and/or 10.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 10.8 +# License as published by the Free Software Foundation. 10.9 +# 10.10 +# This library is distributed in the hope that it will be useful, 10.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 10.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10.13 +# Lesser General Public License for more details. 10.14 +# 10.15 +# You should have received a copy of the GNU Lesser General Public 10.16 +# License along with this library; if not, write to the Free Software 10.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 10.18 +# 10.19 +# Copyright (C) IBM Corp. 2006 10.20 +# 10.21 +# Authors: Hollis Blanchard <hollisb@us.ibm.com> 10.22 + 10.23 +import os 10.24 + 10.25 +_types = { 10.26 + "i386": "x86", 10.27 + "i486": "x86", 10.28 + "i586": "x86", 10.29 + "i686": "x86", 10.30 + "x86_64": "x86", 10.31 + "ia64": "ia64", 10.32 + "ppc": "powerpc", 10.33 + "ppc64": "powerpc", 10.34 +} 10.35 +type = _types.get(os.uname()[4], "unknown")
11.1 --- a/tools/python/xen/xend/image.py Tue Aug 29 17:53:57 2006 -0500 11.2 +++ b/tools/python/xen/xend/image.py Wed Aug 30 14:09:31 2006 -0500 11.3 @@ -27,6 +27,8 @@ from xen.xend.XendError import VmError 11.4 from xen.xend.XendLogging import log 11.5 from xen.xend.server.netif import randomMAC 11.6 from xen.xend.xenstore.xswatch import xswatch 11.7 +from xen.xend import arch 11.8 +from xen.xend import FlatDeviceTree 11.9 11.10 11.11 xc = xen.lowlevel.xc.xc() 11.12 @@ -141,19 +143,10 @@ class ImageHandler: 11.13 raise VmError('Building domain failed: ostype=%s dom=%d err=%s' 11.14 % (self.ostype, self.vm.getDomid(), str(result))) 11.15 11.16 - 11.17 - def getDomainMemory(self, mem_kb): 11.18 - """@return The memory required, in KiB, by the domain to store the 11.19 - given amount, also in KiB.""" 11.20 - if os.uname()[4] != 'ia64': 11.21 - # A little extra because auto-ballooning is broken w.r.t. HVM 11.22 - # guests. Also, slack is necessary for live migration since that 11.23 - # uses shadow page tables. 11.24 - if 'hvm' in xc.xeninfo()['xen_caps']: 11.25 - mem_kb += 4*1024; 11.26 + def getRequiredMemory(self, mem_kb): 11.27 return mem_kb 11.28 11.29 - def getDomainShadowMemory(self, mem_kb): 11.30 + def getRequiredShadowMemory(self, mem_kb): 11.31 """@return The minimum shadow memory required, in KiB, for a domain 11.32 with mem_kb KiB of RAM.""" 11.33 # PV domains don't need any shadow memory 11.34 @@ -197,9 +190,39 @@ class LinuxImageHandler(ImageHandler): 11.35 ramdisk = self.ramdisk, 11.36 features = self.vm.getFeatures()) 11.37 11.38 -class HVMImageHandler(ImageHandler): 11.39 +class PPC_LinuxImageHandler(LinuxImageHandler): 11.40 + 11.41 + ostype = "linux" 11.42 + 11.43 + def configure(self, imageConfig, deviceConfig): 11.44 + LinuxImageHandler.configure(self, imageConfig, deviceConfig) 11.45 + self.imageConfig = imageConfig 11.46 + 11.47 + def buildDomain(self): 11.48 + store_evtchn = self.vm.getStorePort() 11.49 + console_evtchn = self.vm.getConsolePort() 11.50 11.51 - ostype = "hvm" 11.52 + log.debug("dom = %d", self.vm.getDomid()) 11.53 + log.debug("image = %s", self.kernel) 11.54 + log.debug("store_evtchn = %d", store_evtchn) 11.55 + log.debug("console_evtchn = %d", console_evtchn) 11.56 + log.debug("cmdline = %s", self.cmdline) 11.57 + log.debug("ramdisk = %s", self.ramdisk) 11.58 + log.debug("vcpus = %d", self.vm.getVCpuCount()) 11.59 + log.debug("features = %s", self.vm.getFeatures()) 11.60 + 11.61 + devtree = FlatDeviceTree.build(self) 11.62 + 11.63 + return xc.linux_build(dom = self.vm.getDomid(), 11.64 + image = self.kernel, 11.65 + store_evtchn = store_evtchn, 11.66 + console_evtchn = console_evtchn, 11.67 + cmdline = self.cmdline, 11.68 + ramdisk = self.ramdisk, 11.69 + features = self.vm.getFeatures(), 11.70 + arch_args = devtree.to_bin()) 11.71 + 11.72 +class HVMImageHandler(ImageHandler): 11.73 11.74 def configure(self, imageConfig, deviceConfig): 11.75 ImageHandler.configure(self, imageConfig, deviceConfig) 11.76 @@ -282,7 +305,7 @@ class HVMImageHandler(ImageHandler): 11.77 for (name, info) in deviceConfig: 11.78 if name == 'vbd': 11.79 uname = sxp.child_value(info, 'uname') 11.80 - if 'file:' in uname: 11.81 + if uname is not None and 'file:' in uname: 11.82 (_, vbdparam) = string.split(uname, ':', 1) 11.83 if not os.path.isfile(vbdparam): 11.84 raise VmError('Disk image does not exist: %s' % 11.85 @@ -355,32 +378,6 @@ class HVMImageHandler(ImageHandler): 11.86 os.waitpid(self.pid, 0) 11.87 self.pid = 0 11.88 11.89 - def getDomainMemory(self, mem_kb): 11.90 - """@see ImageHandler.getDomainMemory""" 11.91 - if os.uname()[4] == 'ia64': 11.92 - page_kb = 16 11.93 - # ROM size for guest firmware, ioreq page and xenstore page 11.94 - extra_pages = 1024 + 2 11.95 - else: 11.96 - page_kb = 4 11.97 - # This was derived emperically: 11.98 - # 2.4 MB overhead per 1024 MB RAM + 8 MB constant 11.99 - # + 4 to avoid low-memory condition 11.100 - extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; 11.101 - extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) 11.102 - return mem_kb + extra_pages * page_kb 11.103 - 11.104 - def getDomainShadowMemory(self, mem_kb): 11.105 - """@return The minimum shadow memory required, in KiB, for a domain 11.106 - with mem_kb KiB of RAM.""" 11.107 - if os.uname()[4] in ('ia64', 'ppc64'): 11.108 - # Explicit shadow memory is not a concept 11.109 - return 0 11.110 - else: 11.111 - # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 11.112 - # the minimum that Xen would allocate if no value were given. 11.113 - return 1024 * self.vm.getVCpuCount() + mem_kb / 256 11.114 - 11.115 def register_shutdown_watch(self): 11.116 """ add xen store watch on control/shutdown """ 11.117 self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \ 11.118 @@ -417,15 +414,51 @@ class HVMImageHandler(ImageHandler): 11.119 11.120 return 1 # Keep watching 11.121 11.122 -"""Table of image handler classes for virtual machine images. Indexed by 11.123 -image type. 11.124 -""" 11.125 -imageHandlerClasses = {} 11.126 +class IA64_HVM_ImageHandler(HVMImageHandler): 11.127 + 11.128 + ostype = "hvm" 11.129 + 11.130 + def getRequiredMemory(self, mem_kb): 11.131 + page_kb = 16 11.132 + # ROM size for guest firmware, ioreq page and xenstore page 11.133 + extra_pages = 1024 + 2 11.134 + return mem_kb + extra_pages * page_kb 11.135 + 11.136 + def getRequiredShadowMemory(self, mem_kb): 11.137 + # Explicit shadow memory is not a concept 11.138 + return 0 11.139 + 11.140 +class X86_HVM_ImageHandler(HVMImageHandler): 11.141 + 11.142 + ostype = "hvm" 11.143 11.144 + def getRequiredMemory(self, mem_kb): 11.145 + page_kb = 4 11.146 + # This was derived emperically: 11.147 + # 2.4 MB overhead per 1024 MB RAM + 8 MB constant 11.148 + # + 4 to avoid low-memory condition 11.149 + extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; 11.150 + extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) 11.151 + return mem_kb + extra_pages * page_kb 11.152 11.153 -for h in LinuxImageHandler, HVMImageHandler: 11.154 - imageHandlerClasses[h.ostype] = h 11.155 + def getRequiredShadowMemory(self, mem_kb): 11.156 + # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 11.157 + # the minimum that Xen would allocate if no value were given. 11.158 + return 1024 * self.vm.getVCpuCount() + mem_kb / 256 11.159 11.160 +_handlers = { 11.161 + "powerpc": { 11.162 + "linux": PPC_LinuxImageHandler, 11.163 + }, 11.164 + "ia64": { 11.165 + "linux": LinuxImageHandler, 11.166 + "hvm": IA64_HVM_ImageHandler, 11.167 + }, 11.168 + "x86": { 11.169 + "linux": LinuxImageHandler, 11.170 + "hvm": X86_HVM_ImageHandler, 11.171 + }, 11.172 +} 11.173 11.174 def findImageHandlerClass(image): 11.175 """Find the image handler class for an image config. 11.176 @@ -433,10 +466,10 @@ def findImageHandlerClass(image): 11.177 @param image config 11.178 @return ImageHandler subclass or None 11.179 """ 11.180 - ty = sxp.name(image) 11.181 - if ty is None: 11.182 + type = sxp.name(image) 11.183 + if type is None: 11.184 raise VmError('missing image type') 11.185 - imageClass = imageHandlerClasses.get(ty) 11.186 - if imageClass is None: 11.187 - raise VmError('unknown image type: ' + ty) 11.188 - return imageClass 11.189 + try: 11.190 + return _handlers[arch.type][type] 11.191 + except KeyError: 11.192 + raise VmError('unknown image type: ' + type)
12.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py Tue Aug 29 17:53:57 2006 -0500 12.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py Wed Aug 30 14:09:31 2006 -0500 12.3 @@ -78,7 +78,8 @@ def get_log(): 12.4 methods = ['device_create', 'device_configure', 'destroyDevice', 12.5 'getDeviceSxprs', 12.6 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', 12.7 - 'send_sysrq', 'getVCPUInfo', 'waitForDevices'] 12.8 + 'send_sysrq', 'getVCPUInfo', 'waitForDevices', 12.9 + 'getRestartCount'] 12.10 12.11 exclude = ['domain_create', 'domain_restore'] 12.12
13.1 --- a/tools/python/xen/xend/server/blkif.py Tue Aug 29 17:53:57 2006 -0500 13.2 +++ b/tools/python/xen/xend/server/blkif.py Wed Aug 30 14:09:31 2006 -0500 13.3 @@ -52,10 +52,18 @@ class BlkifController(DevController): 13.4 except ValueError: 13.5 dev_type = "disk" 13.6 13.7 - try: 13.8 - (typ, params) = string.split(uname, ':', 1) 13.9 - except ValueError: 13.10 - (typ, params) = ("", "") 13.11 + if uname is None: 13.12 + if dev_type == 'cdrom': 13.13 + (typ, params) = ("", "") 13.14 + else: 13.15 + raise VmError( 13.16 + 'Block device must have physical details specified') 13.17 + else: 13.18 + try: 13.19 + (typ, params) = string.split(uname, ':', 1) 13.20 + except ValueError: 13.21 + (typ, params) = ("", "") 13.22 + 13.23 back = { 'dev' : dev, 13.24 'type' : typ, 13.25 'params' : params,
14.1 --- a/tools/python/xen/xm/migrate.py Tue Aug 29 17:53:57 2006 -0500 14.2 +++ b/tools/python/xen/xm/migrate.py Wed Aug 30 14:09:31 2006 -0500 14.3 @@ -57,7 +57,8 @@ def main(argv): 14.4 opts.usage() 14.5 return 14.6 if len(args) != 2: 14.7 - opts.err('Invalid arguments: ' + str(args)) 14.8 + opts.usage() 14.9 + sys.exit(1) 14.10 dom = args[0] 14.11 dst = args[1] 14.12 server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port)
15.1 --- a/tools/python/xen/xm/shutdown.py Tue Aug 29 17:53:57 2006 -0500 15.2 +++ b/tools/python/xen/xm/shutdown.py Wed Aug 30 14:09:31 2006 -0500 15.3 @@ -48,21 +48,48 @@ gopts.opt('reboot', short='R', 15.4 fn=set_true, default=0, 15.5 use='Shutdown and reboot.') 15.6 15.7 +def wait_reboot(opts, doms, rcs): 15.8 + while doms: 15.9 + alive = server.xend.domains(0) 15.10 + reboot = [] 15.11 + for d in doms: 15.12 + if d in alive: 15.13 + rc = server.xend.domain.getRestartCount(d) 15.14 + if rc == rcs[d]: continue 15.15 + reboot.append(d) 15.16 + else: 15.17 + opts.info("Domain %s destroyed for failed in rebooting" % d) 15.18 + doms.remove(d) 15.19 + for d in reboot: 15.20 + opts.info("Domain %s rebooted" % d) 15.21 + doms.remove(d) 15.22 + time.sleep(1) 15.23 + opts.info("All domains rebooted") 15.24 + 15.25 +def wait_shutdown(opts, doms): 15.26 + while doms: 15.27 + alive = server.xend.domains(0) 15.28 + dead = [] 15.29 + for d in doms: 15.30 + if d in alive: continue 15.31 + dead.append(d) 15.32 + for d in dead: 15.33 + opts.info("Domain %s terminated" % d) 15.34 + doms.remove(d) 15.35 + time.sleep(1) 15.36 + opts.info("All domains terminated") 15.37 + 15.38 def shutdown(opts, doms, mode, wait): 15.39 + rcs = {} 15.40 for d in doms: 15.41 + rcs[d] = server.xend.domain.getRestartCount(d) 15.42 server.xend.domain.shutdown(d, mode) 15.43 + 15.44 if wait: 15.45 - while doms: 15.46 - alive = server.xend.domains(0) 15.47 - dead = [] 15.48 - for d in doms: 15.49 - if d in alive: continue 15.50 - dead.append(d) 15.51 - for d in dead: 15.52 - opts.info("Domain %s terminated" % d) 15.53 - doms.remove(d) 15.54 - time.sleep(1) 15.55 - opts.info("All domains terminated") 15.56 + if mode == 'reboot': 15.57 + wait_reboot(opts, doms, rcs) 15.58 + else: 15.59 + wait_shutdown(opts, doms) 15.60 15.61 def shutdown_mode(opts): 15.62 if opts.vals.halt and opts.vals.reboot: