# HG changeset patch
# User emellor@ewan
# Node ID adbe7d45472b3d5c775b0446c545fe694c1127d5
# Parent db4a0526d4e5e520de578ee01987e58445b8735c
Revert accidental commit.
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
diff -r db4a0526d4e5 -r adbe7d45472b tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Mon Sep 19 12:44:05 2005
+++ b/tools/python/xen/xend/XendDomain.py Mon Sep 19 13:19:22 2005
@@ -275,7 +275,8 @@
@param config: configuration
@return: domain
"""
- return XendDomainInfo.create(self.dbmap.getPath(), config)
+ dominfo = XendDomainInfo.create(self.dbmap, config)
+ return dominfo
def domain_restart(self, dominfo):
"""Restart a domain.
@@ -308,7 +309,8 @@
@param vmconfig: vm configuration
"""
config = sxp.child_value(vmconfig, 'config')
- return XendDomainInfo.restore(self.dbmap.getPath(), config)
+ dominfo = XendDomainInfo.restore(self.dbmap, config)
+ return dominfo
def domain_restore(self, src, progress=False):
"""Restore a domain from file.
@@ -350,12 +352,13 @@
dompath = self.domroot
log.info("Creating entry for unknown xend domain: id=%d uuid=%s",
dom0, uuid)
- try:
- dominfo = XendDomainInfo.recreate(uuid, dompath, info)
- except Exception, exn:
- log.exception(exn)
- raise XendError("Error recreating xend domain info: id=%d: %s" %
- (dom0, str(exn)))
+ db = self.dbmap.addChild("%s/xend" % uuid)
+ try:
+ dominfo = XendDomainInfo.recreate(uuid, dompath, dom0,
+ db, info)
+ except:
+ raise XendError("Error recreating xend domain info: id=%d" %
+ dom0)
self._add_domain(dominfo)
return dominfo
diff -r db4a0526d4e5 -r adbe7d45472b tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Sep 19 12:44:05 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Sep 19 13:19:22 2005
@@ -136,179 +136,123 @@
"""
MINIMUM_RESTART_TIME = 20
-
- def create(cls, parentdbpath, config):
+ def create(cls, parentdb, config):
"""Create a VM from a configuration.
- @param parentdbpath: parent db path
+ @param parentdb: parent db
@param config configuration
@raise: VmError for invalid configuration
"""
-
- log.debug("XendDomainInfo.create(%s, ...)", parentdbpath)
-
- vm = cls(getUuid(), parentdbpath, cls.parseConfig(config))
- vm.construct()
+ uuid = getUuid()
+ db = parentdb.addChild("%s/xend" % uuid)
+ path = parentdb.getPath()
+ vm = cls(uuid, path, db)
+ vm.construct(config)
+ vm.saveToDB(sync=True)
+
return vm
create = classmethod(create)
-
- def recreate(cls, uuid, dompath, info):
+ def recreate(cls, uuid, path, domid, db, info):
"""Create the VM object for an existing domain.
- @param dompath: The path to all domain information
+ @param db: domain db
@param info: domain info from xc
"""
-
- log.debug("XendDomainInfo.recreate(%s, %s, ...)", uuid, dompath)
-
- # ??? vm.setDomid(domid)
-# vm.name, vm.start_time = vm.gatherVm(("name", str),
-# ("start-time", float))
-# config = vm.config
-# log.debug('info=' + str(info))
-# log.debug('config=' + prettyprintstring(config))
-
-# vm.memory = info['mem_kb'] / 1024
-# vm.target = info['mem_kb'] * 1024
-
-
- # Parse the configuration in the store, but allow the info we've
- # been given (from xc) to override it.
- path = "%s/%s" % (dompath, uuid)
-
- config = xstransact.Read(path, 'config')
+ vm = cls(uuid, path, db)
+ vm.setDomid(domid)
+ vm.name, vm.start_time = vm.gatherVm(("name", str),
+ ("start-time", float))
+ try:
+ db.readDB()
+ except: pass
+ vm.importFromDB()
+ config = vm.config
+ log.debug('info=' + str(info))
+ log.debug('config=' + prettyprintstring(config))
+
+ vm.memory = info['mem_kb'] / 1024
+ vm.target = info['mem_kb'] * 1024
+
if config:
- temp_info = cls.parseConfig(config)
- temp_info.update(info)
- info = temp_info
-
- return cls(uuid, dompath, info)
+ try:
+ vm.recreate = True
+ vm.construct(config)
+ finally:
+ vm.recreate = False
+ else:
+ vm.setName("Domain-%d" % domid)
+
+ vm.exportToDB(save=True)
+ return vm
recreate = classmethod(recreate)
-
- def restore(cls, parentdbpath, config, uuid = None):
+ def restore(cls, parentdb, config, uuid=None):
"""Create a domain and a VM object to do a restore.
- @param parentdbpath: parent db
+ @param parentdb: parent db
@param config: domain configuration
@param uuid: uuid to use
"""
-
- log.debug("XendDomainInfo.restore(%s, ..., %s)", parentdbpath, uuid)
-
if not uuid:
uuid = getUuid()
-
+ db = parentdb.addChild("%s/xend" % uuid)
+ path = parentdb.getPath()
+ vm = cls(uuid, path, db)
+ ssidref = int(sxp.child_value(config, 'ssidref'))
+ log.debug('restoring with ssidref='+str(ssidref))
+ id = xc.domain_create(ssidref = ssidref)
+ vm.setDomid(id)
+ vm.clear_shutdown()
try:
- ssidref = int(sxp.child_value(config, 'ssidref'))
- except TypeError, exn:
- raise VmError('Invalid ssidref in config: %s' % exn)
-
- log.debug('restoring with ssidref = %d' % ssidref)
-
- vm = cls(uuid, parentdbpath, cls.parseConfig(config),
- xc.domain_create(ssidref = ssidref))
- vm.clear_shutdown()
+ vm.restore = True
+ vm.construct(config)
+ finally:
+ vm.restore = False
+ vm.exportToDB(save=True, sync=True)
return vm
restore = classmethod(restore)
-
- def parseConfig(cls, config):
- def get_cfg(name, default = None):
- return sxp.child_value(config, name, default)
-
- def int_get_cfg(name):
- val = get_cfg(name)
- if val:
- return int(val)
- else:
- return None
-
- def flo_get_cfg(name):
- val = get_cfg(name)
- if val:
- return float(val)
- else:
- return None
-
-
- log.debug("parseConfig: config is %s" % str(config))
-
-
- result = {}
- imagecfg = "()"
- try:
- result['name'] = get_cfg('name')
- result['ssidref'] = int_get_cfg('ssidref')
- result['memory'] = int_get_cfg('memory')
- result['maxmem'] = int_get_cfg('maxmem')
- result['cpu'] = int_get_cfg('cpu')
- result['cpu_weight'] = flo_get_cfg('cpu_weight')
- result['bootloader'] = get_cfg('bootloader')
- result['restart_mode'] = get_cfg('restart')
-
- imagecfg = get_cfg('image')
-
- if imagecfg:
- result['image'] = imagecfg
- result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus', 1))
- else:
- result['vcpus'] = 1
-
- result['backend'] = []
- for c in sxp.children(config, 'backend'):
- result['backend'].append(sxp.name(sxp.child0(c)))
-
- result['device'] = []
- for d in sxp.children(config, 'device'):
- c = sxp.child0(d)
- result['device'].append((sxp.name(c), c))
-
-
- log.debug("parseConfig: result is %s" % str(result))
- return result
-
- except TypeError, exn:
- raise VmError(
- 'Invalid ssidref / memory / cpu / cpu_weight / vcpus value: %s
%s %s %s %s: %s' %
- (get_cfg('ssidref'),
- get_cfg('memory'),
- get_cfg('cpu'),
- get_cfg('cpu_weight'),
- sxp.child_value(imagecfg, 'vcpus', 1),
- str(exn)))
-
- parseConfig = classmethod(parseConfig)
-
+ __exports__ = [
+ DBVar('config', ty='sxpr'),
+ DBVar('state', ty='str'),
+ DBVar('restart_mode', ty='str'),
+ DBVar('restart_state', ty='str'),
+ DBVar('restart_time', ty='float'),
+ DBVar('restart_count', ty='int'),
+ ]
- def __init__(self, uuid, parentpath, info, domid = None):
-
+ def __init__(self, uuid, path, db):
self.uuid = uuid
- self.info = info
-
- self.path = parentpath + "/" + uuid
-
- if domid:
- self.domid = domid
- elif 'dom' in info:
- self.domid = int(info['dom'])
- else:
- self.domid = None
-
- self.validateInfo()
-
+ self.path = path + "/" + uuid
+
+ self.db = db
+
+ self.recreate = 0
+ self.restore = 0
+
+ self.config = None
+ self.domid = None
+ self.cpu_weight = 1
self.start_time = None
+ self.name = None
+ self.memory = None
+ self.ssidref = None
self.image = None
+
+ self.target = None
self.store_channel = None
self.store_mfn = None
self.console_channel = None
self.console_mfn = None
+ self.info = None
+ self.backend_flags = 0
+
#todo: state: running, suspended
self.state = STATE_VM_OK
self.state_updated = threading.Condition()
@@ -317,69 +261,17 @@
#todo: set to migrate info if migrating
self.migrate = None
+ self.restart_mode = RESTART_ONREBOOT
self.restart_state = None
self.restart_time = None
self.restart_count = 0
- self.device_model_pid = 0
+ self.vcpus = 1
+ self.bootloader = None
self.writeVm("uuid", self.uuid)
self.storeDom("vm", self.path)
-
- def validateInfo(self):
- """Validate and normalise the info block. This has either been parsed
- by parseConfig, or received from xc through recreate.
- """
- def defaultInfo(name, val):
- if name not in self.info or self.info[name] is None:
- self.info[name] = val()
-
-
- try:
- defaultInfo('name', lambda: "Domain-%d" % self.domid)
- defaultInfo('memory', lambda: self.info['mem_kb'] / 1024)
- defaultInfo('maxmem', lambda: self.info['memory'])
- defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
- defaultInfo('cpu_weight', lambda: 1.0)
- defaultInfo('bootloader', lambda: None)
- defaultInfo('backend', lambda: [])
- defaultInfo('device', lambda: [])
-
- # vm.target = info['mem_kb'] * 1024
-
- # !!! Consistency checks have the possibility of going wrong if
- # xen updates us with a setting which should stay consistent with
- # another. We should be storing only one value instead.
-
- # Validate the given backend names.
- for s in self.info['backend']:
- if s not in backendFlags:
- raise VmError('Invalid backend type: %s' % s)
-
- for (n, c) in self.info['device']:
- if not n or not c or n not in controllerClasses:
- raise VmError('invalid device (%s, %s)' %
- (str(n), str(c)))
-
- if self.info['restart_mode'] not in restart_modes:
- raise VmError('invalid restart mode: ' +
- str(self.info['restart_mode']))
-
- if self.info['memory'] <= 0:
- # !!! memory / mem_kb consistency check
- raise VmError('Invalid memory size: %d', self.info['memory'])
-
- if 'cpumap' not in self.info:
- if [self.info['vcpus'] == 1]:
- self.info['cpumap'] = [1];
- else:
- raise VmError('Cannot create CPU map')
-
- except KeyError, exn:
- raise VmError('Unspecified domain detail: %s' % str(exn))
-
-
def readVm(self, *args):
return xstransact.Read(self.path, *args)
@@ -410,27 +302,18 @@
def storeDom(self, *args):
return xstransact.Store(self.path, *args)
-
- def exportToDB(self, save=False):
- to_store = {
- 'id': str(self.domid),
- 'uuid': self.uuid,
- 'config': sxp.to_string(self.sxpr()),
-
- 'start_time': str(self.start_time),
- 'state': self.state,
- 'restart_time': str(self.restart_time),
- 'restart_count': str(self.restart_count),
- 'device_model_pid': str(self.device_model_pid)
- }
-
- for (k, v) in self.info.items():
- to_store[k] = str(v)
-
- log.debug("Storing %s" % str(to_store))
-
- self.writeVm(to_store)
-
+ def setDB(self, db):
+ self.db = db
+
+ def saveToDB(self, save=False, sync=False):
+ self.db.saveDB(save=save, sync=sync)
+
+ def exportToDB(self, save=False, sync=False):
+ self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
+
+ def importFromDB(self):
+ self.db.importFromDB(self, fields=self.__exports__)
+ self.store_channel = self.eventChannel("store/port")
def setDomid(self, domid):
"""Set the domain id.
@@ -444,11 +327,11 @@
return self.domid
def setName(self, name):
- self.info['name'] = name
+ self.name = name
self.storeVm("name", name)
def getName(self):
- return self.info['name']
+ return self.name
def getPath(self):
return self.path
@@ -457,14 +340,14 @@
return self.uuid
def getVCpuCount(self):
- return self.info['vcpus']
+ return self.vcpus
def getSsidref(self):
- return self.info['ssidref']
+ return self.ssidref
def getMemoryTarget(self):
"""Get this domain's target memory size, in MiB."""
- return self.info['memory']
+ return self.memory
def setStoreRef(self, ref):
self.store_mfn = ref
@@ -472,8 +355,7 @@
def getBackendFlags(self):
- return reduce(lambda x, y: x | backendFlags[y],
- self.info['backend'], 0)
+ return self.backend_flags
def closeStoreChannel(self):
@@ -497,19 +379,18 @@
def setMemoryTarget(self, target):
self.storeDom("memory/target", target)
-
- def update(self, info = None):
- """Update with info from xc.domain_getinfo().
- """
-
- if not info:
- info = dom_get(self.domid)
- if not info:
+ def update(self, info=None):
+ """Update with info from xc.domain_getinfo().
+ """
+ if info:
+ self.info = info
+ else:
+ di = dom_get(self.domid)
+ if not di:
return
-
- self.info.update(info)
- self.validateInfo()
-
+ self.info = di
+ self.memory = self.info['mem_kb'] / 1024
+ self.ssidref = self.info['ssidref']
def state_set(self, state):
self.state_updated.acquire()
@@ -517,7 +398,7 @@
self.state = state
self.state_updated.notifyAll()
self.state_updated.release()
- self.exportToDB()
+ self.saveToDB()
def state_wait(self, state):
self.state_updated.acquire()
@@ -528,9 +409,9 @@
def __str__(self):
s = "<domain"
s += " id=" + str(self.domid)
- s += " name=" + self.info['name']
- s += " memory=" + str(self.info['memory'])
- s += " ssidref=" + str(self.info['ssidref'])
+ s += " name=" + self.name
+ s += " memory=" + str(self.memory)
+ s += " ssidref=" + str(self.ssidref)
s += ">"
return s
@@ -560,43 +441,32 @@
def sxpr(self):
sxpr = ['domain',
['domid', self.domid],
- ['name', self.info['name']],
- ['memory', self.info['memory']],
- ['ssidref', self.info['ssidref']]]
-# , ['target', self.target] ]
+ ['name', self.name],
+ ['memory', self.memory],
+ ['ssidref', self.ssidref],
+ ['target', self.target] ]
if self.uuid:
sxpr.append(['uuid', self.uuid])
if self.info:
- sxpr.append(['maxmem', self.info['maxmem']])
-
- def stateChar(name):
- if name in self.info:
- if self.info[name]:
- return name[0]
- else:
- return '-'
- else:
- return '?'
-
- state = reduce(
- lambda x, y: x + y,
- map(stateChar,
- ['running', 'blocked', 'paused', 'shutdown', 'crashed']))
-
+ sxpr.append(['maxmem', self.info['maxmem_kb']/1024 ])
+ run = (self.info['running'] and 'r') or '-'
+ block = (self.info['blocked'] and 'b') or '-'
+ pause = (self.info['paused'] and 'p') or '-'
+ shut = (self.info['shutdown'] and 's') or '-'
+ crash = (self.info['crashed'] and 'c') or '-'
+ state = run + block + pause + shut + crash
sxpr.append(['state', state])
- if 'shutdown' in self.info and self.info['shutdown']:
+ if self.info['shutdown']:
reason = shutdown_reason(self.info['shutdown_reason'])
sxpr.append(['shutdown_reason', reason])
- if 'cpu_time' in self.info:
- sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
+ sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
+ sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
sxpr.append(['vcpus', self.info['vcpus']])
sxpr.append(['cpumap', self.info['cpumap']])
- if 'vcpu_to_cpu' in self.info:
- sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
- # build a string, using '|' to separate items, show only up
- # to number of vcpus in domain, and trim the trailing '|'
- sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
-
self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
+ # build a string, using '|' to seperate items, show only up
+ # to number of vcpus in domain, and trim the trailing '|'
+ sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
+ self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
if self.start_time:
up_time = time.time() - self.start_time
@@ -622,8 +492,8 @@
sxpr.append(['restart_state', self.restart_state])
if self.restart_time:
sxpr.append(['restart_time', str(self.restart_time)])
-# if self.config:
-# sxpr.append(['config', self.config])
+ if self.config:
+ sxpr.append(['config', self.config])
return sxpr
def check_name(self, name):
@@ -634,6 +504,7 @@
@param name: name
@raise: VMerror if invalid
"""
+ if self.recreate: return
if name is None or name == '':
raise VmError('missing vm name')
for c in name:
@@ -652,49 +523,26 @@
if not self.domid or (dominfo.domid != self.domid):
raise VmError('vm name clash: ' + name)
- def construct(self):
+ def construct(self, config):
"""Construct the vm instance from its configuration.
@param config: configuration
@raise: VmError on error
"""
# todo - add support for scheduling params?
+ self.config = config
try:
# Initial domain create.
- self.check_name(self.info['name'])
- self.setName(self.info['name'])
-
- if 'image' not in self.info:
- raise VmError('Missing image in configuration')
-
- self.image = ImageHandler.create(self, self.info['image'])
-
- self.setMemoryTarget(self.info['memory'] * (1 << 20))
-
- log.error('%s %s %s %s %s',
- str(self.domid),
- str(self.info['memory']),
- str(self.info['ssidref']),
- str(self.info['cpu']),
- str(self.info['cpu_weight']))
-
- self.setDomid(self.image.initDomain(self.domid,
- self.info['memory'],
- self.info['ssidref'],
- self.info['cpu'],
- self.info['cpu_weight'],
- self.info['bootloader']))
-
- if self.start_time is None:
- self.start_time = time.time()
- self.storeVm(("start-time", self.start_time))
-
- log.debug('init_domain> Created domain=%d name=%s memory=%d',
- self.domid, self.info['name'], self.info['memory'])
-
+ self.setName(sxp.child_value(config, 'name'))
+ self.check_name(self.name)
+ self.init_image()
+ self.configure_cpus(config)
+ self.init_domain()
self.register_domain()
# Create domain devices.
+ self.configure_backends()
+ self.configure_restart()
self.construct_image()
self.configure()
self.exportToDB(save=True)
@@ -711,11 +559,40 @@
xd._add_domain(self)
self.exportToDB(save=True)
+ def configure_cpus(self, config):
+ try:
+ self.cpu_weight = float(sxp.child_value(config, 'cpu_weight', '1'))
+ except:
+ raise VmError('invalid cpu weight')
+ self.memory = int(sxp.child_value(config, 'memory'))
+ if self.memory is None:
+ raise VmError('missing memory size')
+ self.setMemoryTarget(self.memory * (1 << 20))
+ self.ssidref = int(sxp.child_value(config, 'ssidref'))
+ cpu = sxp.child_value(config, 'cpu')
+ if self.recreate and self.domid and cpu is not None and int(cpu) >= 0:
+ xc.domain_pincpu(self.domid, 0, 1<<int(cpu))
+ try:
+ image = sxp.child_value(self.config, 'image')
+ vcpus = sxp.child_value(image, 'vcpus')
+ if vcpus:
+ self.vcpus = int(vcpus)
+ except:
+ raise VmError('invalid vcpus value')
+
def configure_vcpus(self, vcpus):
d = {}
for v in range(0, vcpus):
d["cpu/%d/availability" % v] = "online"
self.writeVm(d)
+
+ def init_image(self):
+ """Create boot image handler for the domain.
+ """
+ image = sxp.child_value(self.config, 'image')
+ if image is None:
+ raise VmError('missing image')
+ self.image = ImageHandler.create(self, image)
def construct_image(self):
"""Construct the boot image for the domain.
@@ -727,17 +604,21 @@
IntroduceDomain(self.domid, self.store_mfn,
self.store_channel.port1, self.path)
# get the configured value of vcpus and update store
- self.configure_vcpus(self.info['vcpus'])
-
+ self.configure_vcpus(self.vcpus)
def delete(self):
"""Delete the vm's db.
"""
+ self.domid = None
+ self.saveToDB(sync=True)
try:
- xstransact.Remove(self.path, 'id')
+ # Todo: eventually will have to wait for devices to signal
+ # destruction before can delete the db.
+ if self.db:
+ self.db.delete()
except Exception, ex:
log.warning("error in domain db delete: %s", ex)
-
+ pass
def destroy_domain(self):
"""Destroy the vm's domain.
@@ -749,7 +630,7 @@
try:
xc.domain_destroy(dom=self.domid)
except Exception, err:
- log.exception("Domain destroy failed: %s", self.info['name'])
+ log.exception("Domain destroy failed: %s", self.name)
def cleanup(self):
"""Cleanup vm resources: release devices.
@@ -772,14 +653,11 @@
pass
def destroy(self):
- """Cleanup vm and destroy domain.
- """
-
- log.debug("XendDomainInfo.destroy")
-
+ """Clenup vm and destroy domain.
+ """
self.destroy_domain()
self.cleanup()
- self.exportToDB()
+ self.saveToDB()
return 0
def is_terminated(self):
@@ -792,7 +670,6 @@
"""
t = xstransact("%s/device" % self.path)
-
for n in controllerClasses.keys():
for d in t.list(n):
try:
@@ -809,10 +686,27 @@
def show(self):
"""Print virtual machine info.
"""
- print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.domid,
self.info['name'], self.info['memory'], self.info['ssidref'])
+ print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.domid,
self.name, self.memory, self.ssidref)
print "image:"
sxp.show(self.image)
print "]"
+
+ def init_domain(self):
+ """Initialize the domain memory.
+ """
+ if self.recreate:
+ return
+ if self.start_time is None:
+ self.start_time = time.time()
+ self.storeVm(("start-time", self.start_time))
+ try:
+ cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
+ except:
+ raise VmError('invalid cpu')
+ id = self.image.initDomain(self.domid, self.memory, self.ssidref, cpu,
self.cpu_weight)
+ log.debug('init_domain> Created domain=%d name=%s memory=%d',
+ id, self.name, self.memory)
+ self.setDomid(id)
def eventChannel(self, path=None):
"""Create an event channel to the domain.
@@ -837,8 +731,14 @@
self.console_channel = self.eventChannel("console/port")
def create_configured_devices(self):
- for (n, c) in self.info['device']:
- self.createDevice(n, c)
+ devices = sxp.children(self.config, 'device')
+ for d in devices:
+ dev_config = sxp.child0(d)
+ if dev_config is None:
+ raise VmError('invalid device')
+ dev_type = sxp.name(dev_config)
+
+ self.createDevice(dev_type, dev_config)
def create_devices(self):
@@ -870,6 +770,14 @@
self.configureDevice(deviceClass, devid, dev_config)
+ def configure_restart(self):
+ """Configure the vm restart mode.
+ """
+ r = sxp.child_value(self.config, 'restart', RESTART_ONREBOOT)
+ if r not in restart_modes:
+ raise VmError('invalid restart mode: ' + str(r))
+ self.restart_mode = r;
+
def restart_needed(self, reason):
"""Determine if the vm needs to be restarted when shutdown
for the given reason.
@@ -877,11 +785,11 @@
@param reason: shutdown reason
@return True if needs restart, False otherwise
"""
- if self.info['restart_mode'] == RESTART_NEVER:
+ if self.restart_mode == RESTART_NEVER:
return False
- if self.info['restart_mode'] == RESTART_ALWAYS:
+ if self.restart_mode == RESTART_ALWAYS:
return True
- if self.info['restart_mode'] == RESTART_ONREBOOT:
+ if self.restart_mode == RESTART_ONREBOOT:
return reason == 'reboot'
return False
@@ -913,7 +821,7 @@
tdelta = tnow - self.restart_time
if tdelta < self.MINIMUM_RESTART_TIME:
self.restart_cancel()
- msg = 'VM %s restarting too fast' % self.info['name']
+ msg = 'VM %s restarting too fast' % self.name
log.error(msg)
raise VmError(msg)
self.restart_time = tnow
@@ -932,13 +840,14 @@
self.exportToDB()
self.restart_state = STATE_RESTART_BOOTING
self.configure_bootloader()
- self.construct()
- self.exportToDB()
+ self.construct(self.config)
+ self.saveToDB()
finally:
self.restart_state = None
def configure_bootloader(self):
- if not self.info['bootloader']:
+ self.bootloader = sxp.child_value(self.config, "bootloader")
+ if not self.bootloader:
return
# if we're restarting with a bootloader, we need to run it
# FIXME: this assumes the disk is the first device and
@@ -949,13 +858,30 @@
if dev:
disk = sxp.child_value(dev, "uname")
fn = blkdev_uname_to_file(disk)
- blcfg = bootloader(self.info['bootloader'], fn, 1,
self.info['vcpus'])
+ blcfg = bootloader(self.bootloader, fn, 1, self.vcpus)
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
self.config = sxp.merge(['vm', ['image', blcfg]], self.config)
+ def configure_backends(self):
+ """Set configuration flags if the vm is a backend for netif or blkif.
+ Configure the backends to use for vbd and vif if specified.
+ """
+ for c in sxp.children(self.config, 'backend'):
+ v = sxp.child0(c)
+ name = sxp.name(v)
+ if name == 'blkif':
+ self.backend_flags |= SIF_BLK_BE_DOMAIN
+ elif name == 'netif':
+ self.backend_flags |= SIF_NET_BE_DOMAIN
+ elif name == 'usbif':
+ pass
+ elif name == 'tpmif':
+ self.backend_flags |= SIF_TPM_BE_DOMAIN
+ else:
+ raise VmError('invalid backend type:' + str(name))
def configure(self):
"""Configure a vm.
@@ -973,16 +899,19 @@
"""
return
-
def configure_maxmem(self):
- xc.domain_setmaxmem(self.domid,
- maxmem_kb = self.info['maxmem'] * 1024)
+ try:
+ maxmem = int(sxp.child_value(self.config, 'maxmem', self.memory))
+ xc.domain_setmaxmem(self.domid, maxmem_kb = maxmem * 1024)
+ except:
+ raise VmError("invalid maxmem: " +
+ sxp.child_value(self.config, 'maxmem'))
def vcpu_hotplug(self, vcpu, state):
"""Disable or enable VCPU in domain.
"""
- if vcpu > self.info['vcpus']:
+ if vcpu > self.vcpus:
log.error("Invalid VCPU %d" % vcpu)
return
if int(state) == 0:
@@ -1071,24 +1000,16 @@
controllerClasses = {}
-"""A map of backend names and the corresponding flag."""
-backendFlags = {}
-
-
-def addControllerClass(device_class, backend_name, backend_flag, cls):
+def addControllerClass(device_class, cls):
"""Register a subclass of DevController to handle the named device-class.
-
- @param backend_flag One of the SIF_XYZ_BE_DOMAIN constants, or None if
- no flag is to be set.
"""
cls.deviceClass = device_class
- backendFlags[backend_name] = backend_flag
controllerClasses[device_class] = cls
from xen.xend.server import blkif, netif, tpmif, pciif, usbif
-addControllerClass('vbd', 'blkif', SIF_BLK_BE_DOMAIN, blkif.BlkifController)
-addControllerClass('vif', 'netif', SIF_NET_BE_DOMAIN, netif.NetifController)
-addControllerClass('vtpm', 'tpmif', SIF_TPM_BE_DOMAIN, tpmif.TPMifController)
-addControllerClass('pci', 'pciif', None, pciif.PciController)
-addControllerClass('usb', 'usbif', None, usbif.UsbifController)
+addControllerClass('vbd', blkif.BlkifController)
+addControllerClass('vif', netif.NetifController)
+addControllerClass('vtpm', tpmif.TPMifController)
+addControllerClass('pci', pciif.PciController)
+addControllerClass('usb', usbif.UsbifController)
diff -r db4a0526d4e5 -r adbe7d45472b tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Mon Sep 19 12:44:05 2005
+++ b/tools/python/xen/xend/image.py Mon Sep 19 13:19:22 2005
@@ -145,21 +145,22 @@
except OSError, ex:
log.warning("error removing bootloader file '%s': %s", f, ex)
- def initDomain(self, dom, memory, ssidref, cpu, cpu_weight, bootloading):
+ def initDomain(self, dom, memory, ssidref, cpu, cpu_weight):
"""Initial domain create.
@return domain id
"""
mem_kb = self.getDomainMemory(memory)
- dom = xc.domain_create(dom = dom or 0, ssidref = ssidref)
- # if bootloader, unlink here. But should go after buildDomain() ?
- if bootloading:
- self.unlink(self.kernel)
- self.unlink(self.ramdisk)
- if dom <= 0:
- raise VmError('Creating domain failed: name=%s' %
- self.vm.getName())
+ if not self.vm.restore:
+ dom = xc.domain_create(dom = dom or 0, ssidref = ssidref)
+ # if bootloader, unlink here. But should go after buildDomain() ?
+ if self.vm.bootloader:
+ self.unlink(self.kernel)
+ self.unlink(self.ramdisk)
+ if dom <= 0:
+ raise VmError('Creating domain failed: name=%s' %
+ self.vm.getName())
log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu,
mem_kb, ssidref, dom)
xc.domain_setcpuweight(dom, cpu_weight)
xc.domain_setmaxmem(dom, mem_kb)
@@ -183,6 +184,9 @@
def createDomain(self):
"""Build the domain boot image.
"""
+ if self.vm.recreate or self.vm.restore:
+ return
+
# Set params and call buildDomain().
self.flags = self.vm.getBackendFlags()
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|