debuggers.hg
changeset 6973:951c8ee275b7
Use DevController.allocateDeviceID rather than using a local variable.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
Signed-off-by: Ewan Mellor <ewan@xensource.com>
author | emellor@ewan |
---|---|
date | Mon Sep 19 13:41:41 2005 +0100 (2005-09-19) |
parents | 8f9dfc5fb51c |
children | db4a0526d4e5 |
files | tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/server/netif.py |
line diff
1.1 --- a/tools/python/xen/xend/XendDomain.py Sun Sep 18 22:42:02 2005 +0100 1.2 +++ b/tools/python/xen/xend/XendDomain.py Mon Sep 19 13:41:41 2005 +0100 1.3 @@ -275,8 +275,7 @@ class XendDomain: 1.4 @param config: configuration 1.5 @return: domain 1.6 """ 1.7 - dominfo = XendDomainInfo.create(self.dbmap, config) 1.8 - return dominfo 1.9 + return XendDomainInfo.create(self.dbmap.getPath(), config) 1.10 1.11 def domain_restart(self, dominfo): 1.12 """Restart a domain. 1.13 @@ -309,8 +308,7 @@ class XendDomain: 1.14 @param vmconfig: vm configuration 1.15 """ 1.16 config = sxp.child_value(vmconfig, 'config') 1.17 - dominfo = XendDomainInfo.restore(self.dbmap, config) 1.18 - return dominfo 1.19 + return XendDomainInfo.restore(self.dbmap.getPath(), config) 1.20 1.21 def domain_restore(self, src, progress=False): 1.22 """Restore a domain from file. 1.23 @@ -352,13 +350,12 @@ class XendDomain: 1.24 dompath = self.domroot 1.25 log.info("Creating entry for unknown xend domain: id=%d uuid=%s", 1.26 dom0, uuid) 1.27 - db = self.dbmap.addChild("%s/xend" % uuid) 1.28 try: 1.29 - dominfo = XendDomainInfo.recreate(uuid, dompath, dom0, 1.30 - db, info) 1.31 - except: 1.32 - raise XendError("Error recreating xend domain info: id=%d" % 1.33 - dom0) 1.34 + dominfo = XendDomainInfo.recreate(uuid, dompath, info) 1.35 + except Exception, exn: 1.36 + log.exception(exn) 1.37 + raise XendError("Error recreating xend domain info: id=%d: %s" % 1.38 + (dom0, str(exn))) 1.39 self._add_domain(dominfo) 1.40 return dominfo 1.41
2.1 --- a/tools/python/xen/xend/XendDomainInfo.py Sun Sep 18 22:42:02 2005 +0100 2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Sep 19 13:41:41 2005 +0100 2.3 @@ -136,123 +136,179 @@ class XendDomainInfo: 2.4 """ 2.5 MINIMUM_RESTART_TIME = 20 2.6 2.7 - def create(cls, parentdb, config): 2.8 + 2.9 + def create(cls, parentdbpath, config): 2.10 """Create a VM from a configuration. 2.11 2.12 - @param parentdb: parent db 2.13 + @param parentdbpath: parent db path 2.14 @param config configuration 2.15 @raise: VmError for invalid configuration 2.16 """ 2.17 - uuid = getUuid() 2.18 - db = parentdb.addChild("%s/xend" % uuid) 2.19 - path = parentdb.getPath() 2.20 - vm = cls(uuid, path, db) 2.21 - vm.construct(config) 2.22 - vm.saveToDB(sync=True) 2.23 2.24 + log.debug("XendDomainInfo.create(%s, ...)", parentdbpath) 2.25 + 2.26 + vm = cls(getUuid(), parentdbpath, cls.parseConfig(config)) 2.27 + vm.construct() 2.28 return vm 2.29 2.30 create = classmethod(create) 2.31 2.32 - def recreate(cls, uuid, path, domid, db, info): 2.33 + 2.34 + def recreate(cls, uuid, dompath, info): 2.35 """Create the VM object for an existing domain. 2.36 2.37 - @param db: domain db 2.38 + @param dompath: The path to all domain information 2.39 @param info: domain info from xc 2.40 """ 2.41 - vm = cls(uuid, path, db) 2.42 - vm.setDomid(domid) 2.43 - vm.name, vm.start_time = vm.gatherVm(("name", str), 2.44 - ("start-time", float)) 2.45 - try: 2.46 - db.readDB() 2.47 - except: pass 2.48 - vm.importFromDB() 2.49 - config = vm.config 2.50 - log.debug('info=' + str(info)) 2.51 - log.debug('config=' + prettyprintstring(config)) 2.52 + 2.53 + log.debug("XendDomainInfo.recreate(%s, %s, ...)", uuid, dompath) 2.54 + 2.55 + # ??? vm.setDomid(domid) 2.56 +# vm.name, vm.start_time = vm.gatherVm(("name", str), 2.57 +# ("start-time", float)) 2.58 +# config = vm.config 2.59 +# log.debug('info=' + str(info)) 2.60 +# log.debug('config=' + prettyprintstring(config)) 2.61 + 2.62 +# vm.memory = info['mem_kb'] / 1024 2.63 +# vm.target = info['mem_kb'] * 1024 2.64 2.65 - vm.memory = info['mem_kb'] / 1024 2.66 - vm.target = info['mem_kb'] * 1024 2.67 2.68 + # Parse the configuration in the store, but allow the info we've 2.69 + # been given (from xc) to override it. 2.70 + path = "%s/%s" % (dompath, uuid) 2.71 + 2.72 + config = xstransact.Read(path, 'config') 2.73 if config: 2.74 - try: 2.75 - vm.recreate = True 2.76 - vm.construct(config) 2.77 - finally: 2.78 - vm.recreate = False 2.79 - else: 2.80 - vm.setName("Domain-%d" % domid) 2.81 - 2.82 - vm.exportToDB(save=True) 2.83 - return vm 2.84 + temp_info = cls.parseConfig(config) 2.85 + temp_info.update(info) 2.86 + info = temp_info 2.87 + 2.88 + return cls(uuid, dompath, info) 2.89 2.90 recreate = classmethod(recreate) 2.91 2.92 - def restore(cls, parentdb, config, uuid=None): 2.93 + 2.94 + def restore(cls, parentdbpath, config, uuid = None): 2.95 """Create a domain and a VM object to do a restore. 2.96 2.97 - @param parentdb: parent db 2.98 + @param parentdbpath: parent db 2.99 @param config: domain configuration 2.100 @param uuid: uuid to use 2.101 """ 2.102 + 2.103 + log.debug("XendDomainInfo.restore(%s, ..., %s)", parentdbpath, uuid) 2.104 + 2.105 if not uuid: 2.106 uuid = getUuid() 2.107 - db = parentdb.addChild("%s/xend" % uuid) 2.108 - path = parentdb.getPath() 2.109 - vm = cls(uuid, path, db) 2.110 - ssidref = int(sxp.child_value(config, 'ssidref')) 2.111 - log.debug('restoring with ssidref='+str(ssidref)) 2.112 - id = xc.domain_create(ssidref = ssidref) 2.113 - vm.setDomid(id) 2.114 + 2.115 + try: 2.116 + ssidref = int(sxp.child_value(config, 'ssidref')) 2.117 + except TypeError, exn: 2.118 + raise VmError('Invalid ssidref in config: %s' % exn) 2.119 + 2.120 + log.debug('restoring with ssidref = %d' % ssidref) 2.121 + 2.122 + vm = cls(uuid, parentdbpath, cls.parseConfig(config), 2.123 + xc.domain_create(ssidref = ssidref)) 2.124 vm.clear_shutdown() 2.125 - try: 2.126 - vm.restore = True 2.127 - vm.construct(config) 2.128 - finally: 2.129 - vm.restore = False 2.130 - vm.exportToDB(save=True, sync=True) 2.131 return vm 2.132 2.133 restore = classmethod(restore) 2.134 2.135 - __exports__ = [ 2.136 - DBVar('config', ty='sxpr'), 2.137 - DBVar('state', ty='str'), 2.138 - DBVar('restart_mode', ty='str'), 2.139 - DBVar('restart_state', ty='str'), 2.140 - DBVar('restart_time', ty='float'), 2.141 - DBVar('restart_count', ty='int'), 2.142 - ] 2.143 - 2.144 - def __init__(self, uuid, path, db): 2.145 - self.uuid = uuid 2.146 - self.path = path + "/" + uuid 2.147 + 2.148 + def parseConfig(cls, config): 2.149 + def get_cfg(name, default = None): 2.150 + return sxp.child_value(config, name, default) 2.151 + 2.152 + def int_get_cfg(name): 2.153 + val = get_cfg(name) 2.154 + if val: 2.155 + return int(val) 2.156 + else: 2.157 + return None 2.158 + 2.159 + def flo_get_cfg(name): 2.160 + val = get_cfg(name) 2.161 + if val: 2.162 + return float(val) 2.163 + else: 2.164 + return None 2.165 + 2.166 + 2.167 + log.debug("parseConfig: config is %s" % str(config)) 2.168 + 2.169 + 2.170 + result = {} 2.171 + imagecfg = "()" 2.172 + try: 2.173 + result['name'] = get_cfg('name') 2.174 + result['ssidref'] = int_get_cfg('ssidref') 2.175 + result['memory'] = int_get_cfg('memory') 2.176 + result['maxmem'] = int_get_cfg('maxmem') 2.177 + result['cpu'] = int_get_cfg('cpu') 2.178 + result['cpu_weight'] = flo_get_cfg('cpu_weight') 2.179 + result['bootloader'] = get_cfg('bootloader') 2.180 + result['restart_mode'] = get_cfg('restart') 2.181 + 2.182 + imagecfg = get_cfg('image') 2.183 + 2.184 + if imagecfg: 2.185 + result['image'] = imagecfg 2.186 + result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus', 1)) 2.187 + else: 2.188 + result['vcpus'] = 1 2.189 2.190 - self.db = db 2.191 + result['backend'] = [] 2.192 + for c in sxp.children(config, 'backend'): 2.193 + result['backend'].append(sxp.name(sxp.child0(c))) 2.194 + 2.195 + result['device'] = [] 2.196 + for d in sxp.children(config, 'device'): 2.197 + c = sxp.child0(d) 2.198 + result['device'].append((sxp.name(c), c)) 2.199 + 2.200 + 2.201 + log.debug("parseConfig: result is %s" % str(result)) 2.202 + return result 2.203 2.204 - self.recreate = 0 2.205 - self.restore = 0 2.206 - 2.207 - self.config = None 2.208 - self.domid = None 2.209 - self.cpu_weight = 1 2.210 + except TypeError, exn: 2.211 + raise VmError( 2.212 + 'Invalid ssidref / memory / cpu / cpu_weight / vcpus value: %s %s %s %s %s: %s' % 2.213 + (get_cfg('ssidref'), 2.214 + get_cfg('memory'), 2.215 + get_cfg('cpu'), 2.216 + get_cfg('cpu_weight'), 2.217 + sxp.child_value(imagecfg, 'vcpus', 1), 2.218 + str(exn))) 2.219 + 2.220 + parseConfig = classmethod(parseConfig) 2.221 + 2.222 + 2.223 + def __init__(self, uuid, parentpath, info, domid = None): 2.224 + 2.225 + self.uuid = uuid 2.226 + self.info = info 2.227 + 2.228 + self.path = parentpath + "/" + uuid 2.229 + 2.230 + if domid: 2.231 + self.domid = domid 2.232 + elif 'dom' in info: 2.233 + self.domid = int(info['dom']) 2.234 + else: 2.235 + self.domid = None 2.236 + 2.237 + self.validateInfo() 2.238 + 2.239 self.start_time = None 2.240 - self.name = None 2.241 - self.memory = None 2.242 - self.ssidref = None 2.243 self.image = None 2.244 2.245 - self.target = None 2.246 - 2.247 self.store_channel = None 2.248 self.store_mfn = None 2.249 self.console_channel = None 2.250 self.console_mfn = None 2.251 2.252 - self.info = None 2.253 - self.backend_flags = 0 2.254 - 2.255 #todo: state: running, suspended 2.256 self.state = STATE_VM_OK 2.257 self.state_updated = threading.Condition() 2.258 @@ -261,17 +317,69 @@ class XendDomainInfo: 2.259 #todo: set to migrate info if migrating 2.260 self.migrate = None 2.261 2.262 - self.restart_mode = RESTART_ONREBOOT 2.263 self.restart_state = None 2.264 self.restart_time = None 2.265 self.restart_count = 0 2.266 2.267 - self.vcpus = 1 2.268 - self.bootloader = None 2.269 + self.device_model_pid = 0 2.270 2.271 self.writeVm("uuid", self.uuid) 2.272 self.storeDom("vm", self.path) 2.273 2.274 + 2.275 + def validateInfo(self): 2.276 + """Validate and normalise the info block. This has either been parsed 2.277 + by parseConfig, or received from xc through recreate. 2.278 + """ 2.279 + def defaultInfo(name, val): 2.280 + if name not in self.info or self.info[name] is None: 2.281 + self.info[name] = val() 2.282 + 2.283 + 2.284 + try: 2.285 + defaultInfo('name', lambda: "Domain-%d" % self.domid) 2.286 + defaultInfo('memory', lambda: self.info['mem_kb'] / 1024) 2.287 + defaultInfo('maxmem', lambda: self.info['memory']) 2.288 + defaultInfo('restart_mode', lambda: RESTART_ONREBOOT) 2.289 + defaultInfo('cpu_weight', lambda: 1.0) 2.290 + defaultInfo('bootloader', lambda: None) 2.291 + defaultInfo('backend', lambda: []) 2.292 + defaultInfo('device', lambda: []) 2.293 + 2.294 + # vm.target = info['mem_kb'] * 1024 2.295 + 2.296 + # !!! Consistency checks have the possibility of going wrong if 2.297 + # xen updates us with a setting which should stay consistent with 2.298 + # another. We should be storing only one value instead. 2.299 + 2.300 + # Validate the given backend names. 2.301 + for s in self.info['backend']: 2.302 + if s not in backendFlags: 2.303 + raise VmError('Invalid backend type: %s' % s) 2.304 + 2.305 + for (n, c) in self.info['device']: 2.306 + if not n or not c or n not in controllerClasses: 2.307 + raise VmError('invalid device (%s, %s)' % 2.308 + (str(n), str(c))) 2.309 + 2.310 + if self.info['restart_mode'] not in restart_modes: 2.311 + raise VmError('invalid restart mode: ' + 2.312 + str(self.info['restart_mode'])) 2.313 + 2.314 + if self.info['memory'] <= 0: 2.315 + # !!! memory / mem_kb consistency check 2.316 + raise VmError('Invalid memory size: %d', self.info['memory']) 2.317 + 2.318 + if 'cpumap' not in self.info: 2.319 + if [self.info['vcpus'] == 1]: 2.320 + self.info['cpumap'] = [1]; 2.321 + else: 2.322 + raise VmError('Cannot create CPU map') 2.323 + 2.324 + except KeyError, exn: 2.325 + raise VmError('Unspecified domain detail: %s' % str(exn)) 2.326 + 2.327 + 2.328 def readVm(self, *args): 2.329 return xstransact.Read(self.path, *args) 2.330 2.331 @@ -302,18 +410,27 @@ class XendDomainInfo: 2.332 def storeDom(self, *args): 2.333 return xstransact.Store(self.path, *args) 2.334 2.335 - def setDB(self, db): 2.336 - self.db = db 2.337 2.338 - def saveToDB(self, save=False, sync=False): 2.339 - self.db.saveDB(save=save, sync=sync) 2.340 + def exportToDB(self, save=False): 2.341 + to_store = { 2.342 + 'id': str(self.domid), 2.343 + 'uuid': self.uuid, 2.344 + 'config': sxp.to_string(self.sxpr()), 2.345 2.346 - def exportToDB(self, save=False, sync=False): 2.347 - self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync) 2.348 + 'start_time': str(self.start_time), 2.349 + 'state': self.state, 2.350 + 'restart_time': str(self.restart_time), 2.351 + 'restart_count': str(self.restart_count), 2.352 + 'device_model_pid': str(self.device_model_pid) 2.353 + } 2.354 2.355 - def importFromDB(self): 2.356 - self.db.importFromDB(self, fields=self.__exports__) 2.357 - self.store_channel = self.eventChannel("store/port") 2.358 + for (k, v) in self.info.items(): 2.359 + to_store[k] = str(v) 2.360 + 2.361 + log.debug("Storing %s" % str(to_store)) 2.362 + 2.363 + self.writeVm(to_store) 2.364 + 2.365 2.366 def setDomid(self, domid): 2.367 """Set the domain id. 2.368 @@ -327,11 +444,11 @@ class XendDomainInfo: 2.369 return self.domid 2.370 2.371 def setName(self, name): 2.372 - self.name = name 2.373 + self.info['name'] = name 2.374 self.storeVm("name", name) 2.375 2.376 def getName(self): 2.377 - return self.name 2.378 + return self.info['name'] 2.379 2.380 def getPath(self): 2.381 return self.path 2.382 @@ -340,14 +457,14 @@ class XendDomainInfo: 2.383 return self.uuid 2.384 2.385 def getVCpuCount(self): 2.386 - return self.vcpus 2.387 + return self.info['vcpus'] 2.388 2.389 def getSsidref(self): 2.390 - return self.ssidref 2.391 + return self.info['ssidref'] 2.392 2.393 def getMemoryTarget(self): 2.394 """Get this domain's target memory size, in MiB.""" 2.395 - return self.memory 2.396 + return self.info['memory'] 2.397 2.398 def setStoreRef(self, ref): 2.399 self.store_mfn = ref 2.400 @@ -355,7 +472,8 @@ class XendDomainInfo: 2.401 2.402 2.403 def getBackendFlags(self): 2.404 - return self.backend_flags 2.405 + return reduce(lambda x, y: x | backendFlags[y], 2.406 + self.info['backend'], 0) 2.407 2.408 2.409 def closeStoreChannel(self): 2.410 @@ -379,18 +497,19 @@ class XendDomainInfo: 2.411 def setMemoryTarget(self, target): 2.412 self.storeDom("memory/target", target) 2.413 2.414 - def update(self, info=None): 2.415 - """Update with info from xc.domain_getinfo(). 2.416 + 2.417 + def update(self, info = None): 2.418 + """Update with info from xc.domain_getinfo(). 2.419 """ 2.420 - if info: 2.421 - self.info = info 2.422 - else: 2.423 - di = dom_get(self.domid) 2.424 - if not di: 2.425 + 2.426 + if not info: 2.427 + info = dom_get(self.domid) 2.428 + if not info: 2.429 return 2.430 - self.info = di 2.431 - self.memory = self.info['mem_kb'] / 1024 2.432 - self.ssidref = self.info['ssidref'] 2.433 + 2.434 + self.info.update(info) 2.435 + self.validateInfo() 2.436 + 2.437 2.438 def state_set(self, state): 2.439 self.state_updated.acquire() 2.440 @@ -398,7 +517,7 @@ class XendDomainInfo: 2.441 self.state = state 2.442 self.state_updated.notifyAll() 2.443 self.state_updated.release() 2.444 - self.saveToDB() 2.445 + self.exportToDB() 2.446 2.447 def state_wait(self, state): 2.448 self.state_updated.acquire() 2.449 @@ -409,9 +528,9 @@ class XendDomainInfo: 2.450 def __str__(self): 2.451 s = "<domain" 2.452 s += " id=" + str(self.domid) 2.453 - s += " name=" + self.name 2.454 - s += " memory=" + str(self.memory) 2.455 - s += " ssidref=" + str(self.ssidref) 2.456 + s += " name=" + self.info['name'] 2.457 + s += " memory=" + str(self.info['memory']) 2.458 + s += " ssidref=" + str(self.info['ssidref']) 2.459 s += ">" 2.460 return s 2.461 2.462 @@ -441,32 +560,43 @@ class XendDomainInfo: 2.463 def sxpr(self): 2.464 sxpr = ['domain', 2.465 ['domid', self.domid], 2.466 - ['name', self.name], 2.467 - ['memory', self.memory], 2.468 - ['ssidref', self.ssidref], 2.469 - ['target', self.target] ] 2.470 + ['name', self.info['name']], 2.471 + ['memory', self.info['memory']], 2.472 + ['ssidref', self.info['ssidref']]] 2.473 +# , ['target', self.target] ] 2.474 if self.uuid: 2.475 sxpr.append(['uuid', self.uuid]) 2.476 if self.info: 2.477 - sxpr.append(['maxmem', self.info['maxmem_kb']/1024 ]) 2.478 - run = (self.info['running'] and 'r') or '-' 2.479 - block = (self.info['blocked'] and 'b') or '-' 2.480 - pause = (self.info['paused'] and 'p') or '-' 2.481 - shut = (self.info['shutdown'] and 's') or '-' 2.482 - crash = (self.info['crashed'] and 'c') or '-' 2.483 - state = run + block + pause + shut + crash 2.484 + sxpr.append(['maxmem', self.info['maxmem']]) 2.485 + 2.486 + def stateChar(name): 2.487 + if name in self.info: 2.488 + if self.info[name]: 2.489 + return name[0] 2.490 + else: 2.491 + return '-' 2.492 + else: 2.493 + return '?' 2.494 + 2.495 + state = reduce( 2.496 + lambda x, y: x + y, 2.497 + map(stateChar, 2.498 + ['running', 'blocked', 'paused', 'shutdown', 'crashed'])) 2.499 + 2.500 sxpr.append(['state', state]) 2.501 - if self.info['shutdown']: 2.502 + if 'shutdown' in self.info and self.info['shutdown']: 2.503 reason = shutdown_reason(self.info['shutdown_reason']) 2.504 sxpr.append(['shutdown_reason', reason]) 2.505 - sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) 2.506 - sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) 2.507 + if 'cpu_time' in self.info: 2.508 + sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) 2.509 sxpr.append(['vcpus', self.info['vcpus']]) 2.510 sxpr.append(['cpumap', self.info['cpumap']]) 2.511 - # build a string, using '|' to seperate items, show only up 2.512 - # to number of vcpus in domain, and trim the trailing '|' 2.513 - sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|', 2.514 - self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]]) 2.515 + if 'vcpu_to_cpu' in self.info: 2.516 + sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) 2.517 + # build a string, using '|' to separate items, show only up 2.518 + # to number of vcpus in domain, and trim the trailing '|' 2.519 + sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|', 2.520 + self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]]) 2.521 2.522 if self.start_time: 2.523 up_time = time.time() - self.start_time 2.524 @@ -492,8 +622,8 @@ class XendDomainInfo: 2.525 sxpr.append(['restart_state', self.restart_state]) 2.526 if self.restart_time: 2.527 sxpr.append(['restart_time', str(self.restart_time)]) 2.528 - if self.config: 2.529 - sxpr.append(['config', self.config]) 2.530 +# if self.config: 2.531 +# sxpr.append(['config', self.config]) 2.532 return sxpr 2.533 2.534 def check_name(self, name): 2.535 @@ -504,7 +634,6 @@ class XendDomainInfo: 2.536 @param name: name 2.537 @raise: VMerror if invalid 2.538 """ 2.539 - if self.recreate: return 2.540 if name is None or name == '': 2.541 raise VmError('missing vm name') 2.542 for c in name: 2.543 @@ -523,26 +652,49 @@ class XendDomainInfo: 2.544 if not self.domid or (dominfo.domid != self.domid): 2.545 raise VmError('vm name clash: ' + name) 2.546 2.547 - def construct(self, config): 2.548 + def construct(self): 2.549 """Construct the vm instance from its configuration. 2.550 2.551 @param config: configuration 2.552 @raise: VmError on error 2.553 """ 2.554 # todo - add support for scheduling params? 2.555 - self.config = config 2.556 try: 2.557 # Initial domain create. 2.558 - self.setName(sxp.child_value(config, 'name')) 2.559 - self.check_name(self.name) 2.560 - self.init_image() 2.561 - self.configure_cpus(config) 2.562 - self.init_domain() 2.563 + self.check_name(self.info['name']) 2.564 + self.setName(self.info['name']) 2.565 + 2.566 + if 'image' not in self.info: 2.567 + raise VmError('Missing image in configuration') 2.568 + 2.569 + self.image = ImageHandler.create(self, self.info['image']) 2.570 + 2.571 + self.setMemoryTarget(self.info['memory'] * (1 << 20)) 2.572 + 2.573 + log.error('%s %s %s %s %s', 2.574 + str(self.domid), 2.575 + str(self.info['memory']), 2.576 + str(self.info['ssidref']), 2.577 + str(self.info['cpu']), 2.578 + str(self.info['cpu_weight'])) 2.579 + 2.580 + self.setDomid(self.image.initDomain(self.domid, 2.581 + self.info['memory'], 2.582 + self.info['ssidref'], 2.583 + self.info['cpu'], 2.584 + self.info['cpu_weight'], 2.585 + self.info['bootloader'])) 2.586 + 2.587 + if self.start_time is None: 2.588 + self.start_time = time.time() 2.589 + self.storeVm(("start-time", self.start_time)) 2.590 + 2.591 + log.debug('init_domain> Created domain=%d name=%s memory=%d', 2.592 + self.domid, self.info['name'], self.info['memory']) 2.593 + 2.594 self.register_domain() 2.595 2.596 # Create domain devices. 2.597 - self.configure_backends() 2.598 - self.configure_restart() 2.599 self.construct_image() 2.600 self.configure() 2.601 self.exportToDB(save=True) 2.602 @@ -559,41 +711,12 @@ class XendDomainInfo: 2.603 xd._add_domain(self) 2.604 self.exportToDB(save=True) 2.605 2.606 - def configure_cpus(self, config): 2.607 - try: 2.608 - self.cpu_weight = float(sxp.child_value(config, 'cpu_weight', '1')) 2.609 - except: 2.610 - raise VmError('invalid cpu weight') 2.611 - self.memory = int(sxp.child_value(config, 'memory')) 2.612 - if self.memory is None: 2.613 - raise VmError('missing memory size') 2.614 - self.setMemoryTarget(self.memory * (1 << 20)) 2.615 - self.ssidref = int(sxp.child_value(config, 'ssidref')) 2.616 - cpu = sxp.child_value(config, 'cpu') 2.617 - if self.recreate and self.domid and cpu is not None and int(cpu) >= 0: 2.618 - xc.domain_pincpu(self.domid, 0, 1<<int(cpu)) 2.619 - try: 2.620 - image = sxp.child_value(self.config, 'image') 2.621 - vcpus = sxp.child_value(image, 'vcpus') 2.622 - if vcpus: 2.623 - self.vcpus = int(vcpus) 2.624 - except: 2.625 - raise VmError('invalid vcpus value') 2.626 - 2.627 def configure_vcpus(self, vcpus): 2.628 d = {} 2.629 for v in range(0, vcpus): 2.630 d["cpu/%d/availability" % v] = "online" 2.631 self.writeVm(d) 2.632 2.633 - def init_image(self): 2.634 - """Create boot image handler for the domain. 2.635 - """ 2.636 - image = sxp.child_value(self.config, 'image') 2.637 - if image is None: 2.638 - raise VmError('missing image') 2.639 - self.image = ImageHandler.create(self, image) 2.640 - 2.641 def construct_image(self): 2.642 """Construct the boot image for the domain. 2.643 """ 2.644 @@ -604,21 +727,17 @@ class XendDomainInfo: 2.645 IntroduceDomain(self.domid, self.store_mfn, 2.646 self.store_channel.port1, self.path) 2.647 # get the configured value of vcpus and update store 2.648 - self.configure_vcpus(self.vcpus) 2.649 + self.configure_vcpus(self.info['vcpus']) 2.650 + 2.651 2.652 def delete(self): 2.653 """Delete the vm's db. 2.654 """ 2.655 - self.domid = None 2.656 - self.saveToDB(sync=True) 2.657 try: 2.658 - # Todo: eventually will have to wait for devices to signal 2.659 - # destruction before can delete the db. 2.660 - if self.db: 2.661 - self.db.delete() 2.662 + xstransact.Remove(self.path, 'id') 2.663 except Exception, ex: 2.664 log.warning("error in domain db delete: %s", ex) 2.665 - pass 2.666 + 2.667 2.668 def destroy_domain(self): 2.669 """Destroy the vm's domain. 2.670 @@ -630,7 +749,7 @@ class XendDomainInfo: 2.671 try: 2.672 xc.domain_destroy(dom=self.domid) 2.673 except Exception, err: 2.674 - log.exception("Domain destroy failed: %s", self.name) 2.675 + log.exception("Domain destroy failed: %s", self.info['name']) 2.676 2.677 def cleanup(self): 2.678 """Cleanup vm resources: release devices. 2.679 @@ -653,11 +772,14 @@ class XendDomainInfo: 2.680 pass 2.681 2.682 def destroy(self): 2.683 - """Clenup vm and destroy domain. 2.684 + """Cleanup vm and destroy domain. 2.685 """ 2.686 + 2.687 + log.debug("XendDomainInfo.destroy") 2.688 + 2.689 self.destroy_domain() 2.690 self.cleanup() 2.691 - self.saveToDB() 2.692 + self.exportToDB() 2.693 return 0 2.694 2.695 def is_terminated(self): 2.696 @@ -670,6 +792,7 @@ class XendDomainInfo: 2.697 """ 2.698 2.699 t = xstransact("%s/device" % self.path) 2.700 + 2.701 for n in controllerClasses.keys(): 2.702 for d in t.list(n): 2.703 try: 2.704 @@ -686,28 +809,11 @@ class XendDomainInfo: 2.705 def show(self): 2.706 """Print virtual machine info. 2.707 """ 2.708 - print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.domid, self.name, self.memory, self.ssidref) 2.709 + print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.domid, self.info['name'], self.info['memory'], self.info['ssidref']) 2.710 print "image:" 2.711 sxp.show(self.image) 2.712 print "]" 2.713 2.714 - def init_domain(self): 2.715 - """Initialize the domain memory. 2.716 - """ 2.717 - if self.recreate: 2.718 - return 2.719 - if self.start_time is None: 2.720 - self.start_time = time.time() 2.721 - self.storeVm(("start-time", self.start_time)) 2.722 - try: 2.723 - cpu = int(sxp.child_value(self.config, 'cpu', '-1')) 2.724 - except: 2.725 - raise VmError('invalid cpu') 2.726 - id = self.image.initDomain(self.domid, self.memory, self.ssidref, cpu, self.cpu_weight) 2.727 - log.debug('init_domain> Created domain=%d name=%s memory=%d', 2.728 - id, self.name, self.memory) 2.729 - self.setDomid(id) 2.730 - 2.731 def eventChannel(self, path=None): 2.732 """Create an event channel to the domain. 2.733 2.734 @@ -731,14 +837,8 @@ class XendDomainInfo: 2.735 self.console_channel = self.eventChannel("console/port") 2.736 2.737 def create_configured_devices(self): 2.738 - devices = sxp.children(self.config, 'device') 2.739 - for d in devices: 2.740 - dev_config = sxp.child0(d) 2.741 - if dev_config is None: 2.742 - raise VmError('invalid device') 2.743 - dev_type = sxp.name(dev_config) 2.744 - 2.745 - self.createDevice(dev_type, dev_config) 2.746 + for (n, c) in self.info['device']: 2.747 + self.createDevice(n, c) 2.748 2.749 2.750 def create_devices(self): 2.751 @@ -770,14 +870,6 @@ class XendDomainInfo: 2.752 self.configureDevice(deviceClass, devid, dev_config) 2.753 2.754 2.755 - def configure_restart(self): 2.756 - """Configure the vm restart mode. 2.757 - """ 2.758 - r = sxp.child_value(self.config, 'restart', RESTART_ONREBOOT) 2.759 - if r not in restart_modes: 2.760 - raise VmError('invalid restart mode: ' + str(r)) 2.761 - self.restart_mode = r; 2.762 - 2.763 def restart_needed(self, reason): 2.764 """Determine if the vm needs to be restarted when shutdown 2.765 for the given reason. 2.766 @@ -785,11 +877,11 @@ class XendDomainInfo: 2.767 @param reason: shutdown reason 2.768 @return True if needs restart, False otherwise 2.769 """ 2.770 - if self.restart_mode == RESTART_NEVER: 2.771 + if self.info['restart_mode'] == RESTART_NEVER: 2.772 return False 2.773 - if self.restart_mode == RESTART_ALWAYS: 2.774 + if self.info['restart_mode'] == RESTART_ALWAYS: 2.775 return True 2.776 - if self.restart_mode == RESTART_ONREBOOT: 2.777 + if self.info['restart_mode'] == RESTART_ONREBOOT: 2.778 return reason == 'reboot' 2.779 return False 2.780 2.781 @@ -821,7 +913,7 @@ class XendDomainInfo: 2.782 tdelta = tnow - self.restart_time 2.783 if tdelta < self.MINIMUM_RESTART_TIME: 2.784 self.restart_cancel() 2.785 - msg = 'VM %s restarting too fast' % self.name 2.786 + msg = 'VM %s restarting too fast' % self.info['name'] 2.787 log.error(msg) 2.788 raise VmError(msg) 2.789 self.restart_time = tnow 2.790 @@ -840,14 +932,13 @@ class XendDomainInfo: 2.791 self.exportToDB() 2.792 self.restart_state = STATE_RESTART_BOOTING 2.793 self.configure_bootloader() 2.794 - self.construct(self.config) 2.795 - self.saveToDB() 2.796 + self.construct() 2.797 + self.exportToDB() 2.798 finally: 2.799 self.restart_state = None 2.800 2.801 def configure_bootloader(self): 2.802 - self.bootloader = sxp.child_value(self.config, "bootloader") 2.803 - if not self.bootloader: 2.804 + if not self.info['bootloader']: 2.805 return 2.806 # if we're restarting with a bootloader, we need to run it 2.807 # FIXME: this assumes the disk is the first device and 2.808 @@ -858,30 +949,13 @@ class XendDomainInfo: 2.809 if dev: 2.810 disk = sxp.child_value(dev, "uname") 2.811 fn = blkdev_uname_to_file(disk) 2.812 - blcfg = bootloader(self.bootloader, fn, 1, self.vcpus) 2.813 + blcfg = bootloader(self.info['bootloader'], fn, 1, self.info['vcpus']) 2.814 if blcfg is None: 2.815 msg = "Had a bootloader specified, but can't find disk" 2.816 log.error(msg) 2.817 raise VmError(msg) 2.818 self.config = sxp.merge(['vm', ['image', blcfg]], self.config) 2.819 2.820 - def configure_backends(self): 2.821 - """Set configuration flags if the vm is a backend for netif or blkif. 2.822 - Configure the backends to use for vbd and vif if specified. 2.823 - """ 2.824 - for c in sxp.children(self.config, 'backend'): 2.825 - v = sxp.child0(c) 2.826 - name = sxp.name(v) 2.827 - if name == 'blkif': 2.828 - self.backend_flags |= SIF_BLK_BE_DOMAIN 2.829 - elif name == 'netif': 2.830 - self.backend_flags |= SIF_NET_BE_DOMAIN 2.831 - elif name == 'usbif': 2.832 - pass 2.833 - elif name == 'tpmif': 2.834 - self.backend_flags |= SIF_TPM_BE_DOMAIN 2.835 - else: 2.836 - raise VmError('invalid backend type:' + str(name)) 2.837 2.838 def configure(self): 2.839 """Configure a vm. 2.840 @@ -899,19 +973,16 @@ class XendDomainInfo: 2.841 """ 2.842 return 2.843 2.844 + 2.845 def configure_maxmem(self): 2.846 - try: 2.847 - maxmem = int(sxp.child_value(self.config, 'maxmem', self.memory)) 2.848 - xc.domain_setmaxmem(self.domid, maxmem_kb = maxmem * 1024) 2.849 - except: 2.850 - raise VmError("invalid maxmem: " + 2.851 - sxp.child_value(self.config, 'maxmem')) 2.852 + xc.domain_setmaxmem(self.domid, 2.853 + maxmem_kb = self.info['maxmem'] * 1024) 2.854 2.855 2.856 def vcpu_hotplug(self, vcpu, state): 2.857 """Disable or enable VCPU in domain. 2.858 """ 2.859 - if vcpu > self.vcpus: 2.860 + if vcpu > self.info['vcpus']: 2.861 log.error("Invalid VCPU %d" % vcpu) 2.862 return 2.863 if int(state) == 0: 2.864 @@ -1000,16 +1071,24 @@ implements the device control specific t 2.865 controllerClasses = {} 2.866 2.867 2.868 -def addControllerClass(device_class, cls): 2.869 +"""A map of backend names and the corresponding flag.""" 2.870 +backendFlags = {} 2.871 + 2.872 + 2.873 +def addControllerClass(device_class, backend_name, backend_flag, cls): 2.874 """Register a subclass of DevController to handle the named device-class. 2.875 + 2.876 + @param backend_flag One of the SIF_XYZ_BE_DOMAIN constants, or None if 2.877 + no flag is to be set. 2.878 """ 2.879 cls.deviceClass = device_class 2.880 + backendFlags[backend_name] = backend_flag 2.881 controllerClasses[device_class] = cls 2.882 2.883 2.884 from xen.xend.server import blkif, netif, tpmif, pciif, usbif 2.885 -addControllerClass('vbd', blkif.BlkifController) 2.886 -addControllerClass('vif', netif.NetifController) 2.887 -addControllerClass('vtpm', tpmif.TPMifController) 2.888 -addControllerClass('pci', pciif.PciController) 2.889 -addControllerClass('usb', usbif.UsbifController) 2.890 +addControllerClass('vbd', 'blkif', SIF_BLK_BE_DOMAIN, blkif.BlkifController) 2.891 +addControllerClass('vif', 'netif', SIF_NET_BE_DOMAIN, netif.NetifController) 2.892 +addControllerClass('vtpm', 'tpmif', SIF_TPM_BE_DOMAIN, tpmif.TPMifController) 2.893 +addControllerClass('pci', 'pciif', None, pciif.PciController) 2.894 +addControllerClass('usb', 'usbif', None, usbif.UsbifController)
3.1 --- a/tools/python/xen/xend/image.py Sun Sep 18 22:42:02 2005 +0100 3.2 +++ b/tools/python/xen/xend/image.py Mon Sep 19 13:41:41 2005 +0100 3.3 @@ -145,22 +145,21 @@ class ImageHandler: 3.4 except OSError, ex: 3.5 log.warning("error removing bootloader file '%s': %s", f, ex) 3.6 3.7 - def initDomain(self, dom, memory, ssidref, cpu, cpu_weight): 3.8 + def initDomain(self, dom, memory, ssidref, cpu, cpu_weight, bootloading): 3.9 """Initial domain create. 3.10 3.11 @return domain id 3.12 """ 3.13 3.14 mem_kb = self.getDomainMemory(memory) 3.15 - if not self.vm.restore: 3.16 - dom = xc.domain_create(dom = dom or 0, ssidref = ssidref) 3.17 - # if bootloader, unlink here. But should go after buildDomain() ? 3.18 - if self.vm.bootloader: 3.19 - self.unlink(self.kernel) 3.20 - self.unlink(self.ramdisk) 3.21 - if dom <= 0: 3.22 - raise VmError('Creating domain failed: name=%s' % 3.23 - self.vm.getName()) 3.24 + dom = xc.domain_create(dom = dom or 0, ssidref = ssidref) 3.25 + # if bootloader, unlink here. But should go after buildDomain() ? 3.26 + if bootloading: 3.27 + self.unlink(self.kernel) 3.28 + self.unlink(self.ramdisk) 3.29 + if dom <= 0: 3.30 + raise VmError('Creating domain failed: name=%s' % 3.31 + self.vm.getName()) 3.32 log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom) 3.33 xc.domain_setcpuweight(dom, cpu_weight) 3.34 xc.domain_setmaxmem(dom, mem_kb) 3.35 @@ -184,9 +183,6 @@ class ImageHandler: 3.36 def createDomain(self): 3.37 """Build the domain boot image. 3.38 """ 3.39 - if self.vm.recreate or self.vm.restore: 3.40 - return 3.41 - 3.42 # Set params and call buildDomain(). 3.43 self.flags = self.vm.getBackendFlags() 3.44
4.1 --- a/tools/python/xen/xend/server/netif.py Sun Sep 18 22:42:02 2005 +0100 4.2 +++ b/tools/python/xen/xend/server/netif.py Mon Sep 19 13:41:41 2005 +0100 4.3 @@ -27,9 +27,6 @@ from xen.xend import sxp 4.4 from xen.xend.server.DevController import DevController 4.5 4.6 4.7 -next_devid = 1 4.8 - 4.9 - 4.10 class NetifController(DevController): 4.11 """Network interface controller. Handles all network devices for a domain. 4.12 """ 4.13 @@ -41,8 +38,6 @@ class NetifController(DevController): 4.14 def getDeviceDetails(self, config): 4.15 """@see DevController.getDeviceDetails""" 4.16 4.17 - global next_devid 4.18 - 4.19 from xen.xend import XendRoot 4.20 xroot = XendRoot.instance() 4.21 4.22 @@ -52,9 +47,6 @@ class NetifController(DevController): 4.23 val.append(sxp.child0(ipaddr)) 4.24 return val 4.25 4.26 - devid = next_devid 4.27 - next_devid += 1 4.28 - 4.29 script = os.path.join(xroot.network_script_dir, 4.30 sxp.child_value(config, 'script', 4.31 xroot.get_vif_script())) 4.32 @@ -63,6 +55,8 @@ class NetifController(DevController): 4.33 mac = sxp.child_value(config, 'mac') 4.34 ipaddr = _get_config_ipaddr(config) 4.35 4.36 + devid = self.allocateDeviceID() 4.37 + 4.38 back = { 'script' : script, 4.39 'mac' : mac, 4.40 'bridge' : bridge,