ia64/xen-unstable
changeset 18565:616eea24aefa
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 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>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Oct 01 13:35:39 2008 +0100 (2008-10-01) |
parents | 0a8ea3bbeb3d |
children | ab19284c5070 |
files | tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/server/netif.py |
line diff
1.1 --- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 01 09:31:13 2008 +0100 1.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 01 13:35:39 2008 +0100 1.3 @@ -142,9 +142,7 @@ def recreate(info, priv): 1.4 xeninfo['is_control_domain'] = priv 1.5 xeninfo['is_a_template'] = False 1.6 domid = xeninfo['domid'] 1.7 - uuid1 = uuid.fromString(xeninfo['uuid']) 1.8 - needs_reinitialising = False 1.9 - 1.10 + 1.11 dompath = GetDomainPath(domid) 1.12 if not dompath: 1.13 raise XendError('No domain path in store for existing ' 1.14 @@ -153,42 +151,12 @@ def recreate(info, priv): 1.15 log.info("Recreating domain %d, UUID %s. at %s" % 1.16 (domid, xeninfo['uuid'], dompath)) 1.17 1.18 - # need to verify the path and uuid if not Domain-0 1.19 - # if the required uuid and vm aren't set, then that means 1.20 - # we need to recreate the dom with our own values 1.21 - # 1.22 - # NOTE: this is probably not desirable, really we should just 1.23 - # abort or ignore, but there may be cases where xenstore's 1.24 - # entry disappears (eg. xenstore-rm /) 1.25 - # 1.26 - try: 1.27 - vmpath = xstransact.Read(dompath, "vm") 1.28 - if not vmpath: 1.29 - if not priv: 1.30 - log.warn('/local/domain/%d/vm is missing. recreate is ' 1.31 - 'confused, trying our best to recover' % domid) 1.32 - needs_reinitialising = True 1.33 - raise XendError('reinit') 1.34 - 1.35 - uuid2_str = xstransact.Read(vmpath, "uuid") 1.36 - if not uuid2_str: 1.37 - log.warn('%s/uuid/ is missing. recreate is confused, ' 1.38 - 'trying our best to recover' % vmpath) 1.39 - needs_reinitialising = True 1.40 - raise XendError('reinit') 1.41 - 1.42 - uuid2 = uuid.fromString(uuid2_str) 1.43 - if uuid1 != uuid2: 1.44 - log.warn('UUID in /vm does not match the UUID in /dom/%d.' 1.45 - 'Trying out best to recover' % domid) 1.46 - needs_reinitialising = True 1.47 - except XendError: 1.48 - pass # our best shot at 'goto' in python :) 1.49 + vmpath = xstransact.Read("/vm_path", str(domid)) 1.50 1.51 vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv, 1.52 vmpath = vmpath) 1.53 - 1.54 - if needs_reinitialising: 1.55 + 1.56 + if not vmpath: 1.57 vm._recreateDom() 1.58 vm._removeVm() 1.59 vm._storeVmDetails() 1.60 @@ -477,8 +445,8 @@ class XendDomainInfo: 1.61 try: 1.62 self._constructDomain() 1.63 self._storeVmDetails() 1.64 + self._createChannels() 1.65 self._createDevices() 1.66 - self._createChannels() 1.67 self._storeDomDetails() 1.68 self._endRestore() 1.69 except: 1.70 @@ -1240,6 +1208,8 @@ class XendDomainInfo: 1.71 return xstransact.Write(self.vmpath, *args) 1.72 1.73 def _removeVm(self, *args): 1.74 + if len(args) == 0: 1.75 + self._removeVmPath() 1.76 return xstransact.Remove(self.vmpath, *args) 1.77 1.78 def _gatherVm(self, *args): 1.79 @@ -1254,31 +1224,6 @@ class XendDomainInfo: 1.80 def permissionsVm(self, *args): 1.81 return xstransact.SetPermissions(self.vmpath, *args) 1.82 1.83 - 1.84 - def _readVmTxn(self, transaction, *args): 1.85 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.86 - return transaction.read(*paths) 1.87 - 1.88 - def _writeVmTxn(self, transaction, *args): 1.89 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.90 - return transaction.write(*paths) 1.91 - 1.92 - def _removeVmTxn(self, transaction, *args): 1.93 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.94 - return transaction.remove(*paths) 1.95 - 1.96 - def _gatherVmTxn(self, transaction, *args): 1.97 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.98 - return transaction.gather(paths) 1.99 - 1.100 - def storeVmTxn(self, transaction, *args): 1.101 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.102 - return transaction.store(*paths) 1.103 - 1.104 - def permissionsVmTxn(self, transaction, *args): 1.105 - paths = map(lambda x: self.vmpath + "/" + x, args) 1.106 - return transaction.set_permissions(*paths) 1.107 - 1.108 # 1.109 # Function to update xenstore /dom/* 1.110 # 1.111 @@ -2715,6 +2660,15 @@ class XendDomainInfo: 1.112 log.info("Dev still active but hit max loop timeout") 1.113 break 1.114 1.115 + def _storeVmPath(self): 1.116 + log.info("storeVmPath(%s) => %s", self.domid, self.vmpath) 1.117 + if self.domid is not None: 1.118 + xstransact.Write('/vm_path', str(self.domid), self.vmpath) 1.119 + 1.120 + def _removeVmPath(self): 1.121 + if self.domid is not None: 1.122 + xstransact.Remove('/vm_path/%s' % str(self.domid)) 1.123 + 1.124 def _storeVmDetails(self): 1.125 to_store = {} 1.126 1.127 @@ -2739,7 +2693,7 @@ class XendDomainInfo: 1.128 1.129 self._writeVm(to_store) 1.130 self._setVmPermissions() 1.131 - 1.132 + self._storeVmPath() 1.133 1.134 def _setVmPermissions(self): 1.135 """Allow the guest domain to read its UUID. We don't allow it to 1.136 @@ -2759,7 +2713,7 @@ class XendDomainInfo: 1.137 log.warn("".join(traceback.format_stack())) 1.138 return self._stateGet() 1.139 else: 1.140 - raise AttributeError() 1.141 + raise AttributeError(name) 1.142 1.143 def __setattr__(self, name, value): 1.144 if name == "state": 1.145 @@ -2869,12 +2823,6 @@ class XendDomainInfo: 1.146 ignore_devices = ignore_store, 1.147 legacy_only = legacy_only) 1.148 1.149 - #if not ignore_store and self.dompath: 1.150 - # vnc_port = self.readDom('console/vnc-port') 1.151 - # if vnc_port is not None: 1.152 - # result.append(['device', 1.153 - # ['console', ['vnc-port', str(vnc_port)]]]) 1.154 - 1.155 return result 1.156 1.157 # Xen API 1.158 @@ -3140,7 +3088,7 @@ class XendDomainInfo: 1.159 if not config.has_key('device'): 1.160 devid = config.get('id') 1.161 if devid != None: 1.162 - config['device'] = 'eth%d' % devid 1.163 + config['device'] = 'eth%s' % devid 1.164 else: 1.165 config['device'] = '' 1.166
2.1 --- a/tools/python/xen/xend/image.py Wed Oct 01 09:31:13 2008 +0100 2.2 +++ b/tools/python/xen/xend/image.py Wed Oct 01 13:35:39 2008 +0100 2.3 @@ -418,7 +418,7 @@ class ImageHandler: 2.4 os.close(null) 2.5 os.close(logfd) 2.6 sentinel_write.close() 2.7 - self.vm.storeDom("image/device-model-pid", self.pid) 2.8 + self.vm.storeVm("image/device-model-pid", self.pid) 2.9 log.info("device model pid: %d", self.pid) 2.10 # we would very much prefer not to have a thread here and instead 2.11 # have a callback but sadly we don't have Twisted in xend 2.12 @@ -502,7 +502,7 @@ class ImageHandler: 2.13 if fifo_fd >= 0: 2.14 self._openSentinel(sentinel_path_fifo) 2.15 os.close(fifo_fd) 2.16 - self.pid = self.vm.gatherDom(('image/device-model-pid', int)) 2.17 + self.pid = self.vm.gatherVm(('image/device-model-pid', int)) 2.18 log.debug("%s device model rediscovered, pid %s sentinel fifo %s", 2.19 name, self.pid, sentinel_path_fifo) 2.20 self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,())
3.1 --- a/tools/python/xen/xend/server/DevController.py Wed Oct 01 09:31:13 2008 +0100 3.2 +++ b/tools/python/xen/xend/server/DevController.py Wed Oct 01 13:35:39 2008 +0100 3.3 @@ -126,8 +126,11 @@ class DevController: 3.4 log.debug( 3.5 'DevController: still waiting to write device entries.') 3.6 3.7 + devpath = self.devicePath(devid) 3.8 + 3.9 t.remove(frontpath) 3.10 t.remove(backpath) 3.11 + t.remove(devpath) 3.12 3.13 t.mkdir(backpath) 3.14 t.set_permissions(backpath, 3.15 @@ -142,6 +145,14 @@ class DevController: 3.16 t.write2(frontpath, front) 3.17 t.write2(backpath, back) 3.18 3.19 + t.mkdir(devpath) 3.20 + t.write2(devpath, { 3.21 + 'backend' : backpath, 3.22 + 'backend-id' : "%i" % backdom, 3.23 + 'frontend' : frontpath, 3.24 + 'frontend-id' : "%i" % self.vm.getDomid() 3.25 + }) 3.26 + 3.27 if t.commit(): 3.28 return devid 3.29 3.30 @@ -246,11 +257,12 @@ class DevController: 3.31 3.32 if force: 3.33 frontpath = self.frontendPath(dev) 3.34 - backpath = xstransact.Read(frontpath, "backend") 3.35 + backpath = self.readVm(devid, "backend") 3.36 if backpath: 3.37 xstransact.Remove(backpath) 3.38 xstransact.Remove(frontpath) 3.39 3.40 + # xstransact.Remove(self.devicePath()) ?? Below is the same ? 3.41 self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev)) 3.42 3.43 def configurations(self, transaction = None): 3.44 @@ -294,9 +306,10 @@ class DevController: 3.45 @return: dict 3.46 """ 3.47 if transaction is None: 3.48 - backdomid = xstransact.Read(self.frontendPath(devid), "backend-id") 3.49 + backdomid = xstransact.Read(self.devicePath(devid), "backend-id") 3.50 else: 3.51 - backdomid = transaction.read(self.frontendPath(devid) + "/backend-id") 3.52 + backdomid = transaction.read(self.devicePath(devid) + "/backend-id") 3.53 + 3.54 if backdomid is None: 3.55 raise VmError("Device %s not connected" % devid) 3.56 3.57 @@ -438,17 +451,22 @@ class DevController: 3.58 else: 3.59 raise VmError("Device %s not connected" % devid) 3.60 3.61 + def readVm(self, devid, *args): 3.62 + devpath = self.devicePath(devid) 3.63 + if devpath: 3.64 + return xstransact.Read(devpath, *args) 3.65 + else: 3.66 + raise VmError("Device config %s not found" % devid) 3.67 + 3.68 def readBackend(self, devid, *args): 3.69 - frontpath = self.frontendPath(devid) 3.70 - backpath = xstransact.Read(frontpath, "backend") 3.71 + backpath = self.readVm(devid, "backend") 3.72 if backpath: 3.73 return xstransact.Read(backpath, *args) 3.74 else: 3.75 raise VmError("Device %s not connected" % devid) 3.76 3.77 def readBackendTxn(self, transaction, devid, *args): 3.78 - frontpath = self.frontendPath(devid) 3.79 - backpath = transaction.read(frontpath + "/backend") 3.80 + backpath = self.readVm(devid, "backend") 3.81 if backpath: 3.82 paths = map(lambda x: backpath + "/" + x, args) 3.83 return transaction.read(*paths) 3.84 @@ -466,7 +484,7 @@ class DevController: 3.85 """@return The IDs of each of the devices currently configured for 3.86 this instance's deviceClass. 3.87 """ 3.88 - fe = self.backendRoot() 3.89 + fe = self.deviceRoot() 3.90 3.91 if transaction: 3.92 return map(lambda x: int(x.split('/')[-1]), transaction.list(fe)) 3.93 @@ -475,8 +493,7 @@ class DevController: 3.94 3.95 3.96 def writeBackend(self, devid, *args): 3.97 - frontpath = self.frontendPath(devid) 3.98 - backpath = xstransact.Read(frontpath, "backend") 3.99 + backpath = self.readVm(devid, "backend") 3.100 3.101 if backpath: 3.102 xstransact.Write(backpath, *args) 3.103 @@ -541,9 +558,8 @@ class DevController: 3.104 3.105 3.106 def waitForBackend(self, devid): 3.107 - 3.108 frontpath = self.frontendPath(devid) 3.109 - # lookup a phantom 3.110 + # lookup a phantom 3.111 phantomPath = xstransact.Read(frontpath, 'phantom_vbd') 3.112 if phantomPath is not None: 3.113 log.debug("Waiting for %s's phantom %s.", devid, phantomPath) 3.114 @@ -556,7 +572,7 @@ class DevController: 3.115 if result['status'] != 'Connected': 3.116 return (result['status'], err) 3.117 3.118 - backpath = xstransact.Read(frontpath, "backend") 3.119 + backpath = self.readVm(devid, "backend") 3.120 3.121 3.122 if backpath: 3.123 @@ -621,17 +637,20 @@ class DevController: 3.124 def frontendRoot(self): 3.125 return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass) 3.126 3.127 - def backendRoot(self): 3.128 - """Construct backend root path assuming backend is domain 0.""" 3.129 - from xen.xend.XendDomain import DOM0_ID 3.130 - from xen.xend.xenstore.xsutil import GetDomainPath 3.131 - return "%s/backend/%s/%s" % (GetDomainPath(DOM0_ID), 3.132 - self.deviceClass, self.vm.getDomid()) 3.133 - 3.134 def frontendMiscPath(self): 3.135 return "%s/device-misc/%s" % (self.vm.getDomainPath(), 3.136 self.deviceClass) 3.137 3.138 + def deviceRoot(self): 3.139 + """Return the /vm/device. Because backendRoot assumes the 3.140 + backend domain is 0""" 3.141 + return "%s/device/%s" % (self.vm.vmpath, self.deviceClass) 3.142 + 3.143 + def devicePath(self, devid): 3.144 + """Return the /device entry of the given VM. We use it to store 3.145 + backend/frontend locations""" 3.146 + return "%s/device/%s/%s" % (self.vm.vmpath, 3.147 + self.deviceClass, devid) 3.148 3.149 def hotplugStatusCallback(statusPath, ev, result): 3.150 log.debug("hotplugStatusCallback %s.", statusPath)
4.1 --- a/tools/python/xen/xend/server/netif.py Wed Oct 01 09:31:13 2008 +0100 4.2 +++ b/tools/python/xen/xend/server/netif.py Wed Oct 01 13:35:39 2008 +0100 4.3 @@ -142,10 +142,6 @@ class NetifController(DevController): 4.4 if sec_lab: 4.5 back['security_label'] = sec_lab 4.6 4.7 - config_path = "device/%s/%d/" % (self.deviceClass, devid) 4.8 - for x in back: 4.9 - self.vm._writeVm(config_path + x, back[x]) 4.10 - 4.11 back['handle'] = "%i" % devid 4.12 back['script'] = os.path.join(xoptions.network_script_dir, script) 4.13 if rate: 4.14 @@ -189,40 +185,14 @@ class NetifController(DevController): 4.15 4.16 result = DevController.getDeviceConfiguration(self, devid, transaction) 4.17 4.18 - config_path = "device/%s/%d/" % (self.deviceClass, devid) 4.19 - devinfo = () 4.20 for x in ( 'script', 'ip', 'bridge', 'mac', 4.21 'type', 'vifname', 'rate', 'uuid', 'model', 'accel', 4.22 'security_label'): 4.23 if transaction is None: 4.24 - y = self.vm._readVm(config_path + x) 4.25 + y = self.readBackend(devid, x) 4.26 else: 4.27 - y = self.vm._readVmTxn(transaction, config_path + x) 4.28 - devinfo += (y,) 4.29 - (script, ip, bridge, mac, typ, vifname, rate, uuid, 4.30 - model, accel, security_label) = devinfo 4.31 - 4.32 - if script: 4.33 - result['script'] = script 4.34 - if ip: 4.35 - result['ip'] = ip 4.36 - if bridge: 4.37 - result['bridge'] = bridge 4.38 - if mac: 4.39 - result['mac'] = mac 4.40 - if typ: 4.41 - result['type'] = typ 4.42 - if vifname: 4.43 - result['vifname'] = vifname 4.44 - if rate: 4.45 - result['rate'] = rate 4.46 - if uuid: 4.47 - result['uuid'] = uuid 4.48 - if model: 4.49 - result['model'] = model 4.50 - if accel: 4.51 - result['accel'] = accel 4.52 - if security_label: 4.53 - result['security_label'] = security_label 4.54 + y = self.readBackendTxn(transaction, devid, x) 4.55 + if y: 4.56 + result[x] = y 4.57 4.58 return result