ch-runner: move wait() out of run_ch

This commit is contained in:
Else Someone 2026-02-23 22:32:32 +02:00
parent 04befb6328
commit 8d1324da03

View file

@ -355,6 +355,16 @@ in
return args_mut
def alive_after(proc, timeout):
if proc.returncode is not None:
return False
try:
proc.wait(timeout)
except subprocess.TimeoutExpired:
return True
return False
class Processes:
def __init__(self, prefix, vm, check=True, **defaults):
self.prefix = prefix
@ -392,6 +402,7 @@ in
},
)
@contextmanager
def popen(self, *args, **kwargs):
kwargs["pass_fds"] = kwargs.get("pass_fds", ())
kwargs["env"] = kwargs.get("env", self.make_env())
@ -399,11 +410,20 @@ in
kwargs["stdin"] = kwargs.get("stdin", subprocess.DEVNULL)
kwargs["stdout"] = kwargs.get("stdout", subprocess.DEVNULL)
kwargs["stderr"] = kwargs.get("stderr", subprocess.DEVNULL)
return subprocess.Popen(
args,
**kwargs,
)
try:
proc = subprocess.Popen(
args,
**kwargs,
)
yield proc
finally:
try:
proc.wait(0.125)
except subprocess.TimeoutExpired:
proc.terminate()
proc.wait()
@contextmanager
def bwrap(
self,
*bwrap_args,
@ -447,7 +467,10 @@ in
bwrap_args_sock, remote = socket.socketpair()
remote.set_inheritable(True)
bwrap_args_f = bwrap_args_sock.makefile("w")
with closing(bwrap_args_sock), closing(bwrap_args_f):
with ExitStack() as cleanup:
# cleanup.enter_context(closing(bwrap_args_sock))
# cleanup.enter_context(closing(bwrap_args_f))
def print_arg(*args):
print(*args, file=bwrap_args_f, sep="\0", end="\0")
@ -491,15 +514,17 @@ in
bwrap_args_f.flush()
with closing(remote):
proc = self.popen(
with ExitStack() as es:
es.enter_context(closing(remote))
es.enter_context(closing(bwrap_args_sock))
es.enter_context(closing(bwrap_args_f))
proc = cleanup.enter_context(self.popen(
"bwrap", "--args", str(remote.fileno()), *bwrap_args,
**popen_kwargs,
executable=BWRAP_PATH,
pass_fds=(*pass_fds, remote.fileno()),
)
return proc
))
yield proc
@contextmanager
def run_ch(self):
@ -520,37 +545,27 @@ in
"fd=0",
# f"fd={s.fileno()}"
]
p = self.bwrap(
*args,
bind=[self.prefix],
# Probably just need the path to vmlinux
ro_bind=("/nix/store",), # A give up
unshare_net=False,
shell=False,
stderr=None,
# pass_fds=(s.fileno(),)
)
# s.close()
try:
p.wait(0.125)
needs_cleanup = False
except subprocess.TimeoutExpired:
needs_cleanup = False
with self.bwrap(
*args,
bind=[self.prefix],
# Probably just need the path to vmlinux
ro_bind=("/nix/store",), # A give up
unshare_net=False,
shell=False,
stderr=None,
# pass_fds=(s.fileno(),)
) as proc:
# s.close()
assert alive_after(proc, 0.125)
if not os.path.exists(self.prefix + "/vmm.sock"):
raise RuntimeError(
f"{self.prefix}/vmm.sock should exist by now")
needs_cleanup = True
if not os.path.exists(self.prefix + "/vmm.sock"):
raise RuntimeError(
f"{self.prefix}/vmm.sock should exist by now")
if p.returncode is not None:
raise RuntimeError("CH exited early")
yield p
if proc.returncode is not None:
raise RuntimeError("CH exited early")
yield proc
finally:
try:
p.poll()
except: # noqa: E722
pass
if p.returncode is None:
print("Terminating CH")
p.terminate() # CH handles SIG{INT,TERM}?
p.wait()
unlink_paths = [
self.prefix + "/vmm.sock",
self.prefix + "/vmm.sock.lock",
@ -621,13 +636,9 @@ in
# "pass_fds": (2, s.fileno()),
}
proc_ctx = self.popen(*args, **kwargs)
with proc_ctx as p:
with self.popen(*args, **kwargs) as p:
try:
try:
p.wait(0.125)
except subprocess.TimeoutExpired:
pass
assert alive_after(p, 0.125)
if p.returncode is not None:
raise RuntimeError("virtiofsd exited too early")
yield p, sock_path