From 98221a2a6ece544486366cdaa35af2615b3c36d7 Mon Sep 17 00:00:00 2001 From: Lisa Zangrando Date: Wed, 23 Nov 2016 11:09:22 +0100 Subject: [PATCH] Fix scheduling when shared quota is disabled - quota.py: now the method allocate() handles the case of quota disabled and blocking=True - quota_manager.py: fixed the method updateDynamicQuota() which set the shared quota disabled or enabled - scheduler_manager.py: in case the shared quota is disabled, the scheduling process is stopped Change-Id: I80dd04505f8ce4cb65b04d2ee46819fe078a363f Sem-Ver: bugfix Closes-bug: #1643833 --- synergy_scheduler_manager/common/quota.py | 40 +++++++++++++------ synergy_scheduler_manager/quota_manager.py | 23 ++++++----- .../scheduler_manager.py | 13 ++++-- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/synergy_scheduler_manager/common/quota.py b/synergy_scheduler_manager/common/quota.py index 02cfce1..fbeeccd 100644 --- a/synergy_scheduler_manager/common/quota.py +++ b/synergy_scheduler_manager/common/quota.py @@ -132,7 +132,6 @@ class Quota(SynergyObject): if server.isEphemeral(): if SharedQuota.allocate(server, blocking): - LOG.info(">> SharedQuota.allocate OK") shared = self.get("shared") servers = shared["servers"] resources = shared["resources"] @@ -147,23 +146,25 @@ class Quota(SynergyObject): self.condition.notifyAll() return True else: - LOG.info(">> SharedQuota.allocate NO") return False private = self.get("private") servers = private["servers"] resources = private["resources"] - if vcpus > resources["vcpus"]["size"] or \ - memory > resources["memory"]["size"]: - raise Exception("the required resources for server %r " - "exceed the quota size" % server_id) - with self.condition: + if vcpus > resources["vcpus"]["size"] or \ + memory > resources["memory"]["size"]: + self.condition.notifyAll() + raise Exception("the required resources for server %r " + "exceed the quota size" % server_id) + if server_id in servers["active"]: + self.condition.notifyAll() raise Exception("resources for server %r already allocated" % server_id) elif server_id in servers["building"]: + self.condition.notifyAll() raise Exception("resources for server %r waiting " "to be allocated" % server_id) elif state: @@ -318,6 +319,7 @@ class SharedQuota(SynergyObject): lastAllocationTime = datetime.now() lastReleaseTime = datetime.now() enabled = False + total = 0 def __init__(self): super(SharedQuota, self).__init__() @@ -327,6 +329,7 @@ class SharedQuota(SynergyObject): self.set("enabled", SharedQuota.enabled) self.set("lastAllocationTime", SharedQuota.lastAllocationTime) self.set("lastReleaseTime", SharedQuota.lastReleaseTime) + self.set("total", SharedQuota.total) @classmethod def isEnabled(cls): @@ -398,16 +401,26 @@ class SharedQuota(SynergyObject): memory = flavor.getMemory() found = False - if vcpus > cls.resources["vcpus"]["size"] or \ - memory > cls.resources["memory"]["size"]: - raise Exception("the required resources for server %r " - "exceed the quota size" % server_id) - with cls.condition: + if not cls.enabled: + if blocking: + cls.condition.wait() + else: + cls.condition.notifyAll() + return False + + if vcpus > cls.resources["vcpus"]["size"] or \ + memory > cls.resources["memory"]["size"]: + cls.condition.notifyAll() + raise Exception("the required resources for server %r " + "exceed the quota size" % server_id) + if server_id in cls.servers["active"]: + cls.condition.notifyAll() raise Exception("resources for server %r already allocated" % server_id) elif server_id in cls.servers["building"]: + cls.condition.notifyAll() raise Exception("resources for server %r already waiting " "to be allocated" % server_id) elif state: @@ -416,6 +429,7 @@ class SharedQuota(SynergyObject): cls.resources["instances"]["used"] += 1 cls.servers[state].append(server_id) + cls.total += 1 found = True else: @@ -462,6 +476,7 @@ class SharedQuota(SynergyObject): cls.resources["memory"]["size"])) cls.lastAllocationTime = datetime.now() + cls.total += 1 elif blocking: LOG.info("allocate wait!!!") cls.condition.wait() @@ -540,6 +555,7 @@ class SharedQuota(SynergyObject): cls.resources = entity["resources"] cls.enabled = entity["enabled"] + cls.total = entity["total"] if isinstance(entity["lastAllocationTime"], datetime): cls.lastAllocationTime = entity["lastAllocationTime"] diff --git a/synergy_scheduler_manager/quota_manager.py b/synergy_scheduler_manager/quota_manager.py index 8e2a0be..cb27342 100644 --- a/synergy_scheduler_manager/quota_manager.py +++ b/synergy_scheduler_manager/quota_manager.py @@ -199,6 +199,7 @@ class QuotaManager(Manager): % (uuid, TTL, state, prj_id)) self.nova_manager.deleteServer(server) + SharedQuota.release(server) except Exception as ex: LOG.error(ex) raise ex @@ -248,6 +249,8 @@ class QuotaManager(Manager): if quota.getSize("memory") > 0: static_memory += quota.getSize("memory") + enabled = False + if total_vcpus < static_vcpus: if self.getProjects(): LOG.warn("shared quota: the total statically " @@ -257,17 +260,15 @@ class QuotaManager(Manager): else: shared_vcpus = total_vcpus - static_vcpus - if total_memory < static_memory: - enabled = False - - if self.getProjects(): - LOG.warn("shared quota: the total statically " - "allocated memory (%s) is greater than the " - "total amount of memory allowed (%s)" - % (static_memory, total_memory)) - else: - enabled = True - shared_memory = total_memory - static_memory + if total_memory < static_memory: + if self.getProjects(): + LOG.warn("shared quota: the total statically " + "allocated memory (%s) is greater than " + "the total amount of memory allowed (%s)" + % (static_memory, total_memory)) + else: + enabled = True + shared_memory = total_memory - static_memory if enabled: LOG.info("shared quota enabled: vcpus=%s memory=%s" diff --git a/synergy_scheduler_manager/scheduler_manager.py b/synergy_scheduler_manager/scheduler_manager.py index 254757c..0000e9c 100644 --- a/synergy_scheduler_manager/scheduler_manager.py +++ b/synergy_scheduler_manager/scheduler_manager.py @@ -174,13 +174,20 @@ class Worker(Thread): continue quota = self.projects[prj_id].getQuota() + quota = self.projects[prj_id].getQuota() + computes = [] + blocking = False - if quota.allocate(server, blocking=False): + if server.isEphemeral() and not SharedQuota.isEnabled(): + blocking = True + + if quota.allocate(server, blocking=blocking): try: computes = self.nova_manager.selectComputes(request) except Exception as ex: - LOG.warn("Worker %s: compute %r not found! reason=%s" - % (self.name, server.getId(), ex)) + LOG.warn("Worker %s: compute not found for server %r!" + " [reason=%s]" % (self.name, + server.getId(), ex)) found = False