mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xend: Make only selected subdirs of /local/domain/<domid> writable by the guest.
This protects critical data like
/local/domain/<domid>/console/{tty,limit}. It also means we can trust
.../vm, and hence do not need /vm_path. Various parts of the previous
two changesets disappear.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
1 parent
8fe9e65cb4
commit
eeed0ffe27
2 files changed
+42
-19
No files matched your search
@@ -142,7 +142,9 @@ 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 '
|
||||
@@ -151,12 +153,42 @@ def recreate(info, priv):
|
||||
log.info("Recreating domain %d, UUID %s. at %s" %
|
||||
(domid, xeninfo['uuid'], dompath))
|
||||
|
||||
vmpath = xstransact.Read("/vm_path", str(domid))
|
||||
# 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 :)
|
||||
|
||||
vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv,
|
||||
vmpath = vmpath)
|
||||
|
||||
if not vmpath:
|
||||
|
||||
if needs_reinitialising:
|
||||
vm._recreateDom()
|
||||
vm._removeVm()
|
||||
vm._storeVmDetails()
|
||||
@@ -1269,8 +1301,11 @@ class XendDomainInfo:
|
||||
def _recreateDomFunc(self, t):
|
||||
t.remove()
|
||||
t.mkdir()
|
||||
t.set_permissions({'dom' : self.domid})
|
||||
t.set_permissions({'dom' : self.domid, 'read' : True})
|
||||
t.write('vm', self.vmpath)
|
||||
for i in [ 'device', 'control', 'error' ]:
|
||||
t.mkdir(i)
|
||||
t.set_permissions(i, {'dom' : self.domid})
|
||||
|
||||
def _storeDomDetails(self):
|
||||
to_store = {
|
||||
@@ -1776,7 +1811,6 @@ class XendDomainInfo:
|
||||
self._releaseDevices()
|
||||
# Remove existing vm node in xenstore
|
||||
self._removeVm()
|
||||
self._removeVmPath()
|
||||
new_dom_info = self.info.copy()
|
||||
new_dom_info['name_label'] = self.info['name_label']
|
||||
new_dom_info['uuid'] = self.info['uuid']
|
||||
@@ -2357,7 +2391,6 @@ class XendDomainInfo:
|
||||
|
||||
paths = self._prepare_phantom_paths()
|
||||
|
||||
self._removeVmPath()
|
||||
if self.dompath is not None:
|
||||
try:
|
||||
xc.domain_destroy_hook(self.domid)
|
||||
@@ -2660,15 +2693,6 @@ 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 = {}
|
||||
|
||||
@@ -2693,7 +2717,6 @@ 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
|
||||
|
||||
@@ -418,7 +418,7 @@ class ImageHandler:
|
||||
os.close(null)
|
||||
os.close(logfd)
|
||||
sentinel_write.close()
|
||||
self.vm.storeVm("image/device-model-pid", self.pid)
|
||||
self.vm.storeDom("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._gatherVm(('image/device-model-pid', int))
|
||||
self.pid = self.vm._gatherDom(('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,())
|
||||
|
||||