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