Skip to content

Commit fed104c

Browse files
committed
Skip memory balance for preloaded until pause
Balloon is allowed before paused and can be canceled by touching the file. For: QubesOS/qubes-issues#1512
1 parent 774fb6b commit fed104c

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

qubes/qmemman/systemstate.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ def init(self) -> None:
7373
def get_xs_path(self, domid, key) -> str:
7474
return "/local/domain/" + str(domid) + "/memory/" + key
7575

76+
def can_membalance(self, domid) -> bool:
77+
file = "/var/run/qubes/do-not-membalance-domid-" + domid
78+
if os.path.isfile(file):
79+
self.log.debug("%s file present" % file)
80+
return False
81+
return True
82+
7683
def add_domain(self, domid) -> None:
7784
self.log.debug("add_domain(domid={!r})".format(domid))
7885
self.dom_dict[domid] = DomainState(domid)
@@ -208,6 +215,7 @@ def inhibit_balloon_up(self) -> None:
208215
if (
209216
dom.mem_actual is not None
210217
and dom.mem_actual + 200 * 1024 < dom.last_target
218+
and self.can_membalance(domid)
211219
):
212220
self.log.info(
213221
"Preventing balloon up to {}".format(dom.last_target)
@@ -247,7 +255,7 @@ def do_balloon(self, mem_size) -> bool:
247255
xenfree_ring[ring_slot] = xenfree
248256
for domid, prev_mem in prev_mem_actual.items():
249257
dom = self.dom_dict[domid]
250-
if prev_mem == dom.mem_actual:
258+
if prev_mem == dom.mem_actual or not self.can_membalance(domid):
251259
# domain not responding to memset requests, remove it
252260
# from donors
253261
dom.no_progress = True
@@ -289,6 +297,9 @@ def do_balloon_dom(self, dom_memset: dict) -> bool:
289297
memset_reqs = {}
290298
for domid, memset in dom_memset.items():
291299
dom = dom_dict[domid]
300+
if not self.can_membalance(domid):
301+
succeeded.append(domid)
302+
continue
292303
if memset == 0:
293304
# Domain hasn't sent meminfo back to the server, it is still at
294305
# the initial amount. pref_mem can't be calculated yet.
@@ -327,6 +338,8 @@ def do_balloon_dom(self, dom_memset: dict) -> bool:
327338
while True:
328339
self.refresh_mem_actual(domid_list)
329340
for domid, dom in dom_dict.items():
341+
if not self.can_membalance(domid):
342+
succeeded.append(domid)
330343
if domid in succeeded:
331344
continue
332345
assert isinstance(dom.mem_actual, int)

qubes/vm/dispvm.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import copy
2727
import subprocess
2828
from typing import Optional
29+
from pathlib import Path
2930

3031
import qubes.config
3132
import qubes.vm.appvm
@@ -487,6 +488,7 @@ def on_domain_loaded(self, event) -> None:
487488
"""
488489
# pylint: disable=unused-argument
489490
assert self.template
491+
self.do_not_membalance_file = Path("/var/run/qubes/do-not-membalance-domid-" + str(self.xid))
490492

491493
async def wait_operational_preload(
492494
self, service: str, timeout: int | float
@@ -632,6 +634,7 @@ async def on_domain_pre_paused(self, event, **kwargs) -> None:
632634
cancelled = True
633635
qmemman_task.cancel()
634636
else:
637+
self.do_not_membalance_file.touch(exist_ok=True)
635638
result = qmemman_task.result()
636639
break_task.cancel()
637640
except asyncio.CancelledError:
@@ -649,6 +652,7 @@ async def on_domain_pre_paused(self, event, **kwargs) -> None:
649652
if not result or cancelled:
650653
self.log.warning("Failed to set memory")
651654
if self.preload_requested:
655+
self.do_not_membalance_file.unlink(missing_ok=True)
652656
raise qubes.exc.QubesVMCancelledPauseError(
653657
self,
654658
"preload was requested before memory request completed",
@@ -665,6 +669,7 @@ def on_domain_paused(
665669
"""
666670
if self.is_preload:
667671
self.log.info("Paused preloaded qube")
672+
self.do_not_membalance_file.unlink(missing_ok=True)
668673

669674
@qubes.events.handler("domain-unpaused")
670675
async def on_domain_unpaused(

0 commit comments

Comments
 (0)