mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
xend: Move some backend configuration info.
This patch moves some dom0 variables and backend device configuration from frontend directories to /local/domain/<backdomid>/backend or /vm. Also, - /vm_path/<domid> is introduced, referencing the /vm path - /vm_path/device/backend holds the backend device location, rather than storing it in the frontend directory Signed-off-by: Pascal Bouchareine <pascal@gandi.net> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
1 parent
e62e563483
commit
e9f884ceda
4 files changed
+64
-127
No files matched your search
@@ -142,9 +142,7 @@ def recreate(info, priv):
|
||||
xeninfo['is_control_domain'] = priv
|
||||
xeninfo['is_a_template'] = False
|
||||
domid = xeninfo['domid']
|
||||
uuid1 = uuid.fromString(xeninfo['uuid'])
|
||||
needs_reinitialising = False
|
||||
|
||||
|
||||
dompath = GetDomainPath(domid)
|
||||
if not dompath:
|
||||
raise XendError('No domain path in store for existing '
|
||||
@@ -153,42 +151,12 @@ def recreate(info, priv):
|
||||
log.info("Recreating domain %d, UUID %s. at %s" %
|
||||
(domid, xeninfo['uuid'], dompath))
|
||||
|
||||
# need to verify the path and uuid if not Domain-0
|
||||
# if the required uuid and vm aren't set, then that means
|
||||
# we need to recreate the dom with our own values
|
||||
#
|
||||
# NOTE: this is probably not desirable, really we should just
|
||||
# abort or ignore, but there may be cases where xenstore's
|
||||
# entry disappears (eg. xenstore-rm /)
|
||||
#
|
||||
try:
|
||||
vmpath = xstransact.Read(dompath, "vm")
|
||||
if not vmpath:
|
||||
if not priv:
|
||||
log.warn('/local/domain/%d/vm is missing. recreate is '
|
||||
'confused, trying our best to recover' % domid)
|
||||
needs_reinitialising = True
|
||||
raise XendError('reinit')
|
||||
|
||||
uuid2_str = xstransact.Read(vmpath, "uuid")
|
||||
if not uuid2_str:
|
||||
log.warn('%s/uuid/ is missing. recreate is confused, '
|
||||
'trying our best to recover' % vmpath)
|
||||
needs_reinitialising = True
|
||||
raise XendError('reinit')
|
||||
|
||||
uuid2 = uuid.fromString(uuid2_str)
|
||||
if uuid1 != uuid2:
|
||||
log.warn('UUID in /vm does not match the UUID in /dom/%d.'
|
||||
'Trying out best to recover' % domid)
|
||||
needs_reinitialising = True
|
||||
except XendError:
|
||||
pass # our best shot at 'goto' in python :)
|
||||
vmpath = xstransact.Read("/vm_path", str(domid))
|
||||
|
||||
vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv,
|
||||
vmpath = vmpath)
|
||||
|
||||
if needs_reinitialising:
|
||||
|
||||
if not vmpath:
|
||||
vm._recreateDom()
|
||||
vm._removeVm()
|
||||
vm._storeVmDetails()
|
||||
@@ -477,8 +445,8 @@ class XendDomainInfo:
|
||||
try:
|
||||
self._constructDomain()
|
||||
self._storeVmDetails()
|
||||
self._createDevices()
|
||||
self._createChannels()
|
||||
self._createDevices()
|
||||
self._storeDomDetails()
|
||||
self._endRestore()
|
||||
except:
|
||||
@@ -1240,6 +1208,8 @@ class XendDomainInfo:
|
||||
return xstransact.Write(self.vmpath, *args)
|
||||
|
||||
def _removeVm(self, *args):
|
||||
if len(args) == 0:
|
||||
self._removeVmPath()
|
||||
return xstransact.Remove(self.vmpath, *args)
|
||||
|
||||
def _gatherVm(self, *args):
|
||||
@@ -1254,31 +1224,6 @@ class XendDomainInfo:
|
||||
def permissionsVm(self, *args):
|
||||
return xstransact.SetPermissions(self.vmpath, *args)
|
||||
|
||||
|
||||
def _readVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.read(*paths)
|
||||
|
||||
def _writeVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.write(*paths)
|
||||
|
||||
def _removeVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.remove(*paths)
|
||||
|
||||
def _gatherVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.gather(paths)
|
||||
|
||||
def storeVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.store(*paths)
|
||||
|
||||
def permissionsVmTxn(self, transaction, *args):
|
||||
paths = map(lambda x: self.vmpath + "/" + x, args)
|
||||
return transaction.set_permissions(*paths)
|
||||
|
||||
#
|
||||
# Function to update xenstore /dom/*
|
||||
#
|
||||
@@ -2715,6 +2660,15 @@ class XendDomainInfo:
|
||||
log.info("Dev still active but hit max loop timeout")
|
||||
break
|
||||
|
||||
def _storeVmPath(self):
|
||||
log.info("storeVmPath(%s) => %s", self.domid, self.vmpath)
|
||||
if self.domid is not None:
|
||||
xstransact.Write('/vm_path', str(self.domid), self.vmpath)
|
||||
|
||||
def _removeVmPath(self):
|
||||
if self.domid is not None:
|
||||
xstransact.Remove('/vm_path/%s' % str(self.domid))
|
||||
|
||||
def _storeVmDetails(self):
|
||||
to_store = {}
|
||||
|
||||
@@ -2739,7 +2693,7 @@ class XendDomainInfo:
|
||||
|
||||
self._writeVm(to_store)
|
||||
self._setVmPermissions()
|
||||
|
||||
self._storeVmPath()
|
||||
|
||||
def _setVmPermissions(self):
|
||||
"""Allow the guest domain to read its UUID. We don't allow it to
|
||||
@@ -2759,7 +2713,7 @@ class XendDomainInfo:
|
||||
log.warn("".join(traceback.format_stack()))
|
||||
return self._stateGet()
|
||||
else:
|
||||
raise AttributeError()
|
||||
raise AttributeError(name)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name == "state":
|
||||
@@ -2869,12 +2823,6 @@ class XendDomainInfo:
|
||||
ignore_devices = ignore_store,
|
||||
legacy_only = legacy_only)
|
||||
|
||||
#if not ignore_store and self.dompath:
|
||||
# vnc_port = self.readDom('console/vnc-port')
|
||||
# if vnc_port is not None:
|
||||
# result.append(['device',
|
||||
# ['console', ['vnc-port', str(vnc_port)]]])
|
||||
|
||||
return result
|
||||
|
||||
# Xen API
|
||||
@@ -3140,7 +3088,7 @@ class XendDomainInfo:
|
||||
if not config.has_key('device'):
|
||||
devid = config.get('id')
|
||||
if devid != None:
|
||||
config['device'] = 'eth%d' % devid
|
||||
config['device'] = 'eth%s' % devid
|
||||
else:
|
||||
config['device'] = ''
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@ class ImageHandler:
|
||||
os.close(null)
|
||||
os.close(logfd)
|
||||
sentinel_write.close()
|
||||
self.vm.storeDom("image/device-model-pid", self.pid)
|
||||
self.vm.storeVm("image/device-model-pid", self.pid)
|
||||
log.info("device model pid: %d", self.pid)
|
||||
# we would very much prefer not to have a thread here and instead
|
||||
# have a callback but sadly we don't have Twisted in xend
|
||||
@@ -502,7 +502,7 @@ class ImageHandler:
|
||||
if fifo_fd >= 0:
|
||||
self._openSentinel(sentinel_path_fifo)
|
||||
os.close(fifo_fd)
|
||||
self.pid = self.vm.gatherDom(('image/device-model-pid', int))
|
||||
self.pid = self.vm.gatherVm(('image/device-model-pid', int))
|
||||
log.debug("%s device model rediscovered, pid %s sentinel fifo %s",
|
||||
name, self.pid, sentinel_path_fifo)
|
||||
self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,())
|
||||
|
||||
@@ -126,8 +126,11 @@ class DevController:
|
||||
log.debug(
|
||||
'DevController: still waiting to write device entries.')
|
||||
|
||||
devpath = self.devicePath(devid)
|
||||
|
||||
t.remove(frontpath)
|
||||
t.remove(backpath)
|
||||
t.remove(devpath)
|
||||
|
||||
t.mkdir(backpath)
|
||||
t.set_permissions(backpath,
|
||||
@@ -142,6 +145,14 @@ class DevController:
|
||||
t.write2(frontpath, front)
|
||||
t.write2(backpath, back)
|
||||
|
||||
t.mkdir(devpath)
|
||||
t.write2(devpath, {
|
||||
'backend' : backpath,
|
||||
'backend-id' : "%i" % backdom,
|
||||
'frontend' : frontpath,
|
||||
'frontend-id' : "%i" % self.vm.getDomid()
|
||||
})
|
||||
|
||||
if t.commit():
|
||||
return devid
|
||||
|
||||
@@ -246,11 +257,12 @@ class DevController:
|
||||
|
||||
if force:
|
||||
frontpath = self.frontendPath(dev)
|
||||
backpath = xstransact.Read(frontpath, "backend")
|
||||
backpath = self.readVm(devid, "backend")
|
||||
if backpath:
|
||||
xstransact.Remove(backpath)
|
||||
xstransact.Remove(frontpath)
|
||||
|
||||
# xstransact.Remove(self.devicePath()) ?? Below is the same ?
|
||||
self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
|
||||
|
||||
def configurations(self, transaction = None):
|
||||
@@ -294,9 +306,10 @@ class DevController:
|
||||
@return: dict
|
||||
"""
|
||||
if transaction is None:
|
||||
backdomid = xstransact.Read(self.frontendPath(devid), "backend-id")
|
||||
backdomid = xstransact.Read(self.devicePath(devid), "backend-id")
|
||||
else:
|
||||
backdomid = transaction.read(self.frontendPath(devid) + "/backend-id")
|
||||
backdomid = transaction.read(self.devicePath(devid) + "/backend-id")
|
||||
|
||||
if backdomid is None:
|
||||
raise VmError("Device %s not connected" % devid)
|
||||
|
||||
@@ -438,17 +451,22 @@ class DevController:
|
||||
else:
|
||||
raise VmError("Device %s not connected" % devid)
|
||||
|
||||
def readVm(self, devid, *args):
|
||||
devpath = self.devicePath(devid)
|
||||
if devpath:
|
||||
return xstransact.Read(devpath, *args)
|
||||
else:
|
||||
raise VmError("Device config %s not found" % devid)
|
||||
|
||||
def readBackend(self, devid, *args):
|
||||
frontpath = self.frontendPath(devid)
|
||||
backpath = xstransact.Read(frontpath, "backend")
|
||||
backpath = self.readVm(devid, "backend")
|
||||
if backpath:
|
||||
return xstransact.Read(backpath, *args)
|
||||
else:
|
||||
raise VmError("Device %s not connected" % devid)
|
||||
|
||||
def readBackendTxn(self, transaction, devid, *args):
|
||||
frontpath = self.frontendPath(devid)
|
||||
backpath = transaction.read(frontpath + "/backend")
|
||||
backpath = self.readVm(devid, "backend")
|
||||
if backpath:
|
||||
paths = map(lambda x: backpath + "/" + x, args)
|
||||
return transaction.read(*paths)
|
||||
@@ -466,7 +484,7 @@ class DevController:
|
||||
"""@return The IDs of each of the devices currently configured for
|
||||
this instance's deviceClass.
|
||||
"""
|
||||
fe = self.backendRoot()
|
||||
fe = self.deviceRoot()
|
||||
|
||||
if transaction:
|
||||
return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))
|
||||
@@ -475,8 +493,7 @@ class DevController:
|
||||
|
||||
|
||||
def writeBackend(self, devid, *args):
|
||||
frontpath = self.frontendPath(devid)
|
||||
backpath = xstransact.Read(frontpath, "backend")
|
||||
backpath = self.readVm(devid, "backend")
|
||||
|
||||
if backpath:
|
||||
xstransact.Write(backpath, *args)
|
||||
@@ -541,9 +558,8 @@ class DevController:
|
||||
|
||||
|
||||
def waitForBackend(self, devid):
|
||||
|
||||
frontpath = self.frontendPath(devid)
|
||||
# lookup a phantom
|
||||
# lookup a phantom
|
||||
phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
|
||||
if phantomPath is not None:
|
||||
log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
|
||||
@@ -556,7 +572,7 @@ class DevController:
|
||||
if result['status'] != 'Connected':
|
||||
return (result['status'], err)
|
||||
|
||||
backpath = xstransact.Read(frontpath, "backend")
|
||||
backpath = self.readVm(devid, "backend")
|
||||
|
||||
|
||||
if backpath:
|
||||
@@ -621,17 +637,20 @@ class DevController:
|
||||
def frontendRoot(self):
|
||||
return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass)
|
||||
|
||||
def backendRoot(self):
|
||||
"""Construct backend root path assuming backend is domain 0."""
|
||||
from xen.xend.XendDomain import DOM0_ID
|
||||
from xen.xend.xenstore.xsutil import GetDomainPath
|
||||
return "%s/backend/%s/%s" % (GetDomainPath(DOM0_ID),
|
||||
self.deviceClass, self.vm.getDomid())
|
||||
|
||||
def frontendMiscPath(self):
|
||||
return "%s/device-misc/%s" % (self.vm.getDomainPath(),
|
||||
self.deviceClass)
|
||||
|
||||
def deviceRoot(self):
|
||||
"""Return the /vm/device. Because backendRoot assumes the
|
||||
backend domain is 0"""
|
||||
return "%s/device/%s" % (self.vm.vmpath, self.deviceClass)
|
||||
|
||||
def devicePath(self, devid):
|
||||
"""Return the /device entry of the given VM. We use it to store
|
||||
backend/frontend locations"""
|
||||
return "%s/device/%s/%s" % (self.vm.vmpath,
|
||||
self.deviceClass, devid)
|
||||
|
||||
def hotplugStatusCallback(statusPath, ev, result):
|
||||
log.debug("hotplugStatusCallback %s.", statusPath)
|
||||
|
||||
@@ -142,10 +142,6 @@ class NetifController(DevController):
|
||||
if sec_lab:
|
||||
back['security_label'] = sec_lab
|
||||
|
||||
config_path = "device/%s/%d/" % (self.deviceClass, devid)
|
||||
for x in back:
|
||||
self.vm._writeVm(config_path + x, back[x])
|
||||
|
||||
back['handle'] = "%i" % devid
|
||||
back['script'] = os.path.join(xoptions.network_script_dir, script)
|
||||
if rate:
|
||||
@@ -189,40 +185,14 @@ class NetifController(DevController):
|
||||
|
||||
result = DevController.getDeviceConfiguration(self, devid, transaction)
|
||||
|
||||
config_path = "device/%s/%d/" % (self.deviceClass, devid)
|
||||
devinfo = ()
|
||||
for x in ( 'script', 'ip', 'bridge', 'mac',
|
||||
'type', 'vifname', 'rate', 'uuid', 'model', 'accel',
|
||||
'security_label'):
|
||||
if transaction is None:
|
||||
y = self.vm._readVm(config_path + x)
|
||||
y = self.readBackend(devid, x)
|
||||
else:
|
||||
y = self.vm._readVmTxn(transaction, config_path + x)
|
||||
devinfo += (y,)
|
||||
(script, ip, bridge, mac, typ, vifname, rate, uuid,
|
||||
model, accel, security_label) = devinfo
|
||||
|
||||
if script:
|
||||
result['script'] = script
|
||||
if ip:
|
||||
result['ip'] = ip
|
||||
if bridge:
|
||||
result['bridge'] = bridge
|
||||
if mac:
|
||||
result['mac'] = mac
|
||||
if typ:
|
||||
result['type'] = typ
|
||||
if vifname:
|
||||
result['vifname'] = vifname
|
||||
if rate:
|
||||
result['rate'] = rate
|
||||
if uuid:
|
||||
result['uuid'] = uuid
|
||||
if model:
|
||||
result['model'] = model
|
||||
if accel:
|
||||
result['accel'] = accel
|
||||
if security_label:
|
||||
result['security_label'] = security_label
|
||||
y = self.readBackendTxn(transaction, devid, x)
|
||||
if y:
|
||||
result[x] = y
|
||||
|
||||
return result
|
||||