xend, security: Prevent changing of the policy while VMs are migrating

The net changes of this patch are that the reader-side lock is put
into the path of the migration code and the writer lock into the path
of the code that handles the changing of the policy. Simultaneous
migrations of multiple hosts still work after this lock has been added.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
Keir Fraser committed 2008-11-05 10:23:26 +00:00
1 parent 4b5d0b9cfb
commit 9d2a3ef6e8
2 files changed
+76 -64

No files matched your search

+18 -11
View File
@@ -50,7 +50,7 @@ from xen.xend.XendAPIConstants import *
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
from xen.util import mkdir
from xen.util import mkdir, rwlock
from xen.xend import uuid
xc = xen.lowlevel.xc.xc()
@@ -93,6 +93,8 @@ class XendDomain:
self.managed_domains = {}
self.domains_lock = threading.RLock()
self.policy_lock = rwlock.RWLock()
# xen api instance vars
# TODO: nothing uses this at the moment
self._allow_new_domains = True
@@ -1139,16 +1141,21 @@ class XendDomain:
"""
try:
return XendCheckpoint.restore(self, fd, paused=paused, relocating=relocating)
except XendError, e:
log.exception("Restore failed")
raise
except:
# I don't really want to log this exception here, but the error
# handling in the relocation-socket handling code (relocate.py) is
# poor, so we need to log this for debugging.
log.exception("Restore failed")
raise XendError("Restore failed")
self.policy_lock.acquire_reader()
try:
return XendCheckpoint.restore(self, fd, paused=paused, relocating=relocating)
except XendError, e:
log.exception("Restore failed")
raise
except:
# I don't really want to log this exception here, but the error
# handling in the relocation-socket handling code (relocate.py) is
# poor, so we need to log this for debugging.
log.exception("Restore failed")
raise XendError("Restore failed")
finally:
self.policy_lock.release()
def domain_unpause(self, domid):
"""Unpause domain execution.
+58 -53
View File
@@ -3011,64 +3011,69 @@ class XendDomainInfo:
if not xspol:
xspol = poladmin.get_policy_by_name(policy)
if state in [ DOM_STATE_RUNNING, DOM_STATE_PAUSED ]:
#if domain is running or paused try to relabel in hypervisor
if not xspol:
return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
try:
xen.xend.XendDomain.instance().policy_lock.acquire_writer()
if typ != xspol.get_type_name() or \
policy != xspol.get_name():
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
if typ == xsconstants.ACM_POLICY_ID:
new_ssidref = xspol.vmlabel_to_ssidref(label)
if new_ssidref == xsconstants.INVALID_SSIDREF:
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
# Check that all used resources are accessible under the
# new label
if not is_policy_update and \
not security.resources_compatible_with_vmlabel(xspol,
self, label):
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
#Check label against expected one. Can only do this
# if the policy hasn't changed underneath in the meantime
if xspol_old == None:
old_label = self.get_security_label()
if old_label != old_seclab:
log.info("old_label != old_seclab: %s != %s" %
(old_label, old_seclab))
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
# relabel domain in the hypervisor
rc, errors = security.relabel_domains([[domid, new_ssidref]])
log.info("rc from relabeling in HV: %d" % rc)
else:
return (-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED, "", "", 0)
if rc == 0:
# HALTED, RUNNING or PAUSED
if domid == 0:
if xspol:
self.info['security_label'] = seclab
ssidref = poladmin.set_domain0_bootlabel(xspol, label)
else:
if state in [ DOM_STATE_RUNNING, DOM_STATE_PAUSED ]:
#if domain is running or paused try to relabel in hypervisor
if not xspol:
return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
else:
if self.info.has_key('security_label'):
old_label = self.info['security_label']
# Check label against expected one, unless wildcard
if old_label != old_seclab:
if typ != xspol.get_type_name() or \
policy != xspol.get_name():
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
if typ == xsconstants.ACM_POLICY_ID:
new_ssidref = xspol.vmlabel_to_ssidref(label)
if new_ssidref == xsconstants.INVALID_SSIDREF:
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
self.info['security_label'] = seclab
# Check that all used resources are accessible under the
# new label
if not is_policy_update and \
not security.resources_compatible_with_vmlabel(xspol,
self, label):
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
try:
xen.xend.XendDomain.instance().managed_config_save(self)
except:
pass
return (rc, errors, old_label, new_ssidref)
#Check label against expected one. Can only do this
# if the policy hasn't changed underneath in the meantime
if xspol_old == None:
old_label = self.get_security_label()
if old_label != old_seclab:
log.info("old_label != old_seclab: %s != %s" %
(old_label, old_seclab))
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
# relabel domain in the hypervisor
rc, errors = security.relabel_domains([[domid, new_ssidref]])
log.info("rc from relabeling in HV: %d" % rc)
else:
return (-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED, "", "", 0)
if rc == 0:
# HALTED, RUNNING or PAUSED
if domid == 0:
if xspol:
self.info['security_label'] = seclab
ssidref = poladmin.set_domain0_bootlabel(xspol, label)
else:
return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
else:
if self.info.has_key('security_label'):
old_label = self.info['security_label']
# Check label against expected one, unless wildcard
if old_label != old_seclab:
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
self.info['security_label'] = seclab
try:
xen.xend.XendDomain.instance().managed_config_save(self)
except:
pass
return (rc, errors, old_label, new_ssidref)
finally:
xen.xend.XendDomain.instance().policy_lock.release()
def get_on_shutdown(self):
after_shutdown = self.info.get('actions_after_shutdown')
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.