From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id kAk5AJKzr2ALNwAAgWs5BA (envelope-from ) for ; Thu, 27 May 2021 16:58:26 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id yFePN5Gzr2DLEgAAB5/wlQ (envelope-from ) for ; Thu, 27 May 2021 14:58:25 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id BB52A25F85 for ; Thu, 27 May 2021 16:58:24 +0200 (CEST) Received: from localhost ([::1]:57954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lmHSp-0004lD-8y for larch@yhetil.org; Thu, 27 May 2021 10:58:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43540) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lmHSW-0004i9-4I for bug-guix@gnu.org; Thu, 27 May 2021 10:58:04 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:41044) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lmHST-0007pO-Oe for bug-guix@gnu.org; Thu, 27 May 2021 10:58:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lmHST-0008Gj-M7 for bug-guix@gnu.org; Thu, 27 May 2021 10:58:01 -0400 X-Loop: help-debbugs@gnu.org Subject: bug#41625: [PATCH v3] offload: Handle a possible EOF response from read-repl-response. Resent-From: Maxim Cournoyer Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Thu, 27 May 2021 14:58:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 41625 X-GNU-PR-Package: guix X-GNU-PR-Keywords: To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 41625-submit@debbugs.gnu.org id=B41625.162212745431745 (code B ref 41625); Thu, 27 May 2021 14:58:01 +0000 Received: (at 41625) by debbugs.gnu.org; 27 May 2021 14:57:34 +0000 Received: from localhost ([127.0.0.1]:52590 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lmHS1-0008Fx-SF for submit@debbugs.gnu.org; Thu, 27 May 2021 10:57:34 -0400 Received: from mail-qt1-f175.google.com ([209.85.160.175]:41803) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lmHRz-0008Fj-Kk for 41625@debbugs.gnu.org; Thu, 27 May 2021 10:57:32 -0400 Received: by mail-qt1-f175.google.com with SMTP id t20so392484qtx.8 for <41625@debbugs.gnu.org>; Thu, 27 May 2021 07:57:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=NF2/6IiKIKkD1LjYKSgElhHFqxQLFAFG00alQDtOR08=; b=PFhmaPvj/5xzQbRuPs8aALq3VNkFyDFuh+2lYYecrQzW+4hL3cLnzbegxxcBEkgyrb z8qZ+Bd2QAk51eBipv3rbH1cvE2sc4UeKYVLa8Q7u2SMImSn0+lnsOePsnz+q8HsG5Wy VHCVWP834f2SsNTk1wVVvjsZ9SotUAVnv5H7rIMAQjVHodyFI3V5XJqhiAs13jnZ9LtJ e6mRlzEbGmfPMPaLRi+k0k4Ln2OIyvYmbdcLdhQWGZVry26oYIOzLCI/XJTkHV5uwM3G MMFeXjM4DSQd4CSiNAOq8B0wNa6XbgVgaMs1k8Et8HVCwXAqkvfcyU1AqC9PRbIFLQeb HOCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=NF2/6IiKIKkD1LjYKSgElhHFqxQLFAFG00alQDtOR08=; b=Dh1F7TC8aNvH9y2dojUFsPe97L6ocer7PGxJ2xz8oyaFm9A0B2emAJdLEIYrQFK+YC LwuNERR9pVcYJLbiXwTgxd4sjqygD/ZJZQyaR7TyIE6qihBV8DVZcJsXj0p0PiyVIrqn Y+68XQb9jBBVXcXcGj/vZbJxPFxKmoXUkLIuYFf/RzBWXQ7AEGsE7pPI8Rws9yzdT7lq PigCObJqx3nc+FpcJMyH38PF2vhWVgstCv8upM51GptsLx11rzOOCYTb7MMZS6nz2NPz aczwEJlZFjuxPt068lfh/U1w5R47ndowZFQNrv/JI+18dqZYfH+MXQerNzSBYm9cMMqH EqkQ== X-Gm-Message-State: AOAM533q3RC2fFMdtAHrwgBVIX6k/kz8yjKQBucbZYnbX9ixaOJqVsgN nEVDQYjZygv/gHQypOzhgIo= X-Google-Smtp-Source: ABdhPJyIOCcEZjKmybApnSH4Tr7kWskMyHn8dr+PL5uShLRHQ+1kqDf2bWzSWArAL20wWl26ukkLOg== X-Received: by 2002:ac8:6a0f:: with SMTP id t15mr3472078qtr.104.1622127446007; Thu, 27 May 2021 07:57:26 -0700 (PDT) Received: from hurd (dsl-152-121.b2b2c.ca. [66.158.152.121]) by smtp.gmail.com with ESMTPSA id o10sm1541862qki.72.2021.05.27.07.57.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 May 2021 07:57:25 -0700 (PDT) From: Maxim Cournoyer References: <87mtsky9um.fsf@gmail.com> <20210525155003.27590-1-maxim.cournoyer@gmail.com> <875yz61rvt.fsf@gnu.org> <87mtsikwsm.fsf_-_@gmail.com> <87fsy9x3ev.fsf@gnu.org> Date: Thu, 27 May 2021 10:57:24 -0400 In-Reply-To: <87fsy9x3ev.fsf@gnu.org> ("Ludovic =?UTF-8?Q?Court=C3=A8s?="'s message of "Wed, 26 May 2021 11:14:32 +0200") Message-ID: <87r1hsjkbv.fsf_-_@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-guix@gnu.org List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: 41625@debbugs.gnu.org Errors-To: bug-guix-bounces+larch=yhetil.org@gnu.org Sender: "bug-Guix" X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1622127505; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=NF2/6IiKIKkD1LjYKSgElhHFqxQLFAFG00alQDtOR08=; b=BNn7eZXCpbsEubpH1zl3qZNMV2lk8wlK4CE4Jl1/URhFGrCb4FLh/n4G+1XE4cEG7U34VT 5Lm4VtjGcmbUexIBvfEcDRwLJ0nqV3DqaxkeJovFtV/GtRKag1xJdAi7KOJNNMBcKiCUzd QvBWz4AW05wVq64aTZpRoEtjUjFknxN3+xoZ7sIxUWTbI7B6cKGph3dRlojAPi24aFgGjn LgPTByKAdB05CD4u7oqsS5eyTpUvH+JSSdP1GuRX9H58gTbERnGUJ/1Y5mbbi0/zU/+j3Q 7kWOnW1qZs+XXArmuRui7EFcVhIRDVlZm9K3xMt5UdFvDKH0z5kzc7mWAS9Y0g== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1622127505; a=rsa-sha256; cv=none; b=ENbVN9VClIE7FeCxxhIUV76JpTRRAGkbG4hyNqq3mdChLFNuMg3uhi5BxaAmhKY8fNNghM yvAAQ82bFIshqiPADC4xpPcI/PWLXq5IGRkNkyJ4VUlVwWUyey7norY8Tco6UCoLmGNkeu 3RxcBGcoN/ZrisPyB5ACyzYY7LQ0YHzoaojKfEi4fQnxvsE1OvShifBUX68U0MG8yFKXkH OGGrh2Pqtgo0izfVToOAHX8eCx1PuHHMPgBVB15dMJdcnzMjKhPL3pdw7nlC54tzoeAVSR 7BYaNE9jHp3ecZMiN4TetZzxx/JROyYBgJAg/9jAo5LBw8JnNKObkK+y2/0jGQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20161025 header.b=PFhmaPvj; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of bug-guix-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=bug-guix-bounces@gnu.org X-Migadu-Spam-Score: -1.33 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20161025 header.b=PFhmaPvj; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of bug-guix-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=bug-guix-bounces@gnu.org X-Migadu-Queue-Id: BB52A25F85 X-Spam-Score: -1.33 X-Migadu-Scanner: scn0.migadu.com X-TUID: OvzIBAApkusF --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Ludo, Now that I have root access to overdrive1, I could strace the sshd process (I just did 'strace -p340', noting the process of sshd displayed with 'herd status sshd'): --8<---------------cut here---------------start------------->8--- pselect6(87, [3 4], NULL, NULL, NULL, NULL) =3D 1 (in [3]) accept(3, {sa_family=3DAF_INET, sin_port=3Dhtons(33262), sin_addr=3Dinet_ad= dr("66.158.152.121")}, [128->16]) =3D 5 fcntl(5, F_GETFL) =3D 0x2 (flags O_RDWR) pipe2([6, 7], 0) =3D 0 socketpair(AF_UNIX, SOCK_STREAM, 0, [8, 9]) =3D 0 clone(child_stack=3DNULL, flags=3DCLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|S= IGCHLD, child_tidptr=3D0xffff8e0ef0e0) =3D 644 close(7) =3D 0 close(9) =3D 0 write(8, "\0\0\1\245\0", 5) =3D 5 write(8, "\0\0\1\234\nPort 22\nPermitRootLogin no\n"..., 420) =3D 420 close(8) =3D 0 close(5) =3D 0 getpid() =3D 340 getpid() =3D 340 getpid() =3D 340 getpid() =3D 340 getpid() =3D 340 getpid() =3D 340 getpid() =3D 340 pselect6(87, [3 4 6], NULL, NULL, NULL, NULL) =3D 1 (in [6]) read(6, "\0", 1) =3D 1 pselect6(87, [3 4 6], NULL, NULL, NULL, NULL) =3D 1 (in [6]) read(6, "", 1) =3D 0 close(6) =3D 0 pselect6(87, [3 4], NULL, NULL, NULL, NULL) =3D ? ERESTARTNOHAND (To be res= tarted if no handler) --- SIGCHLD {si_signo=3DSIGCHLD, si_code=3DCLD_EXITED, si_pid=3D644, si_uid= =3D0, si_status=3D255, si_utime=3D1, si_stime=3D0} --- wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) =3D=3D 255}], WNOHANG, NULL) =3D= 644 wait4(-1, 0xfffffa4d90e4, WNOHANG, NULL) =3D 0 rt_sigreturn({mask=3D[]}) =3D -1 EINTR (Interrupted system = call) pselect6(87, [3 4], NULL, NULL, NULL, NULL --8<---------------cut here---------------end--------------->8--- With the attached v3 patch, the corresponding output (still problematic) was: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix offload test /etc/guix/machines.scm overdrive1 guix offload: Testing 1 build machines defined in '/etc/guix/machines.scm'.= .. guix offload: got premature EOF from machine 'overdrive1.guix.gnu.org' from= inferior '#' on port '#'; retrying connection Backtrace: In ice-9/boot-9.scm: 1752:10 10 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _) In unknown file: 9 (apply-smob/0 #) In ice-9/boot-9.scm: 724:2 8 (call-with-prompt _ _ #) In ice-9/eval.scm: 619:8 7 (_ #(#(#))) In guix/ui.scm: 2161:12 6 (run-guix-command _ . _) In ice-9/boot-9.scm: 1752:10 5 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _) 1747:15 4 (with-exception-handler # _ # _ # =E2=80=A6) In ice-9/threads.scm: 288:21 3 (loop _) In guix/scripts/offload.scm: 719:29 2 (_ _) 719:29 1 (_ _) In ice-9/boot-9.scm: 1685:16 0 (raise-exception _ #:continuable? _) ice-9/boot-9.scm:1685:16: In procedure raise-exception: Wrong type to apply: 2 --8<---------------cut here---------------end--------------->8--- I haven't tried analyzing the strace output yet. Maxim --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0001-offload-Parallelize-machine-check-in-offload-test.patch Content-Transfer-Encoding: quoted-printable >From c7b2ec1c58adf8c795df0a6aaf075dbc331f41e8 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Thu, 27 May 2021 08:44:44 -0400 Subject: [PATCH 1/2] offload: Parallelize machine check in offload test. * guix/scripts/offload.scm (check-machine-availability): Refactor so that it takes a single machine object. Ensure the cleanup code is always run. (check-machines-availability): New procedure. Call CHECK-MACHINES-AVAILABILITY in parallel, which improves performance (about twice as fast with 4 build machines, from ~30 s to ~15 s). --- guix/scripts/offload.scm | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm index 835078cb97..b0fd20e158 100644 --- a/guix/scripts/offload.scm +++ b/guix/scripts/offload.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Cour= t=C3=A8s ;;; Copyright =C2=A9 2017 Ricardo Wurmus -;;; Copyright =C2=A9 2020 Maxim Cournoyer +;;; Copyright =C2=A9 2020, 2021 Maxim Cournoyer ;;; Copyright =C2=A9 2020 Julien Lepiller ;;; ;;; This file is part of GNU Guix. @@ -53,6 +53,7 @@ #:use-module (ice-9 regex) #:use-module (ice-9 format) #:use-module (ice-9 binary-ports) + #:use-module (ice-9 threads) #:export (build-machine build-machine? build-machine-name @@ -684,7 +685,7 @@ daemon is not running." (leave (G_ "failed to import '~a' from '~a'~%") item name))))) =20 -(define (check-machine-availability machine-file pred) +(define (check-machines-availability machine-file pred) "Check that each machine matching PRED in MACHINE-FILE is usable as a bu= ild machine." (define (build-machine=3D? m1 m2) @@ -696,18 +697,28 @@ machine." (let ((machines (filter pred (delete-duplicates (build-machines machine-file) build-machine=3D?)))) - (info (G_ "testing ~a build machines defined in '~a'...~%") + (info (G_ "Testing ~a build machines defined in '~a'...~%") (length machines) machine-file) - (let* ((names (map build-machine-name machines)) - (sockets (map build-machine-daemon-socket machines)) - (sessions (map (cut open-ssh-session <> %short-timeout) machine= s)) - (nodes (map remote-inferior sessions))) - (for-each assert-node-has-guix nodes names) - (for-each assert-node-repl nodes names) - (for-each assert-node-can-import sessions nodes names sockets) - (for-each assert-node-can-export sessions nodes names sockets) - (for-each close-inferior nodes) - (for-each disconnect! sessions)))) + (par-for-each check-machine-availability machines))) + +(define (check-machine-availability machine) + "Check whether MACHINE is available. Exit with an error upon failure." + ;; Sometimes, the machine remote port may return EOF, presumably because= the + ;; connection was lost. Retry up to 3 times. + (let* ((name (build-machine-name machine)) + (socket (build-machine-daemon-socket machine)) + (session (open-ssh-session machine %short-timeout)) + (node (remote-inferior session))) + (dynamic-wind + (lambda () #t) + (lambda () + (assert-node-has-guix node name) + (assert-node-repl node name) + (assert-node-can-import session node name socket) + (assert-node-can-export session node name socket)) + (lambda () + (close-inferior node) + (disconnect! session))))) =20 (define (check-machine-status machine-file pred) "Print the load of each machine matching PRED in MACHINE-FILE." @@ -824,7 +835,7 @@ machine." ((file) (values file (const #t))) (() (values %machine-file (const #t))) (x (leave (G_ "wrong number of arguments~%")))= ))) - (check-machine-availability (or file %machine-file) pred)))) + (check-machines-availability (or file %machine-file) pred)))) (("status" rest ...) (with-error-handling (let-values (((file pred) --=20 2.31.1 --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0002-offload-Handle-a-possible-EOF-response-from-read-rep.patch Content-Transfer-Encoding: quoted-printable >From b5558777617e4674a150895458d57d202de56120 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Tue, 25 May 2021 08:42:06 -0400 Subject: [PATCH 2/2] offload: Handle a possible EOF response from read-repl-response. Partially fixes . * guix/scripts/offload.scm (check-machine-availability): Handle the case wh= ere the checks raised an exception due to receiving EOF prematurely, and retry = up to 3 times. * guix/inferior.scm (&inferior-premature-eof): New condition type. (read-repl-response): Raise a condition of the above type when reading EOF from the build machine's port. --- guix/inferior.scm | 15 ++++++++++++++ guix/scripts/offload.scm | 42 ++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/guix/inferior.scm b/guix/inferior.scm index 7c8e478f2a..e63b37a7dd 100644 --- a/guix/inferior.scm +++ b/guix/inferior.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright =C2=A9 2018, 2019, 2020, 2021 Ludovic Court=C3=A8s +;;; Copyright =C2=A9 2021 Maxim Cournoyer ;;; ;;; This file is part of GNU Guix. ;;; @@ -70,6 +71,9 @@ inferior-exception-arguments inferior-exception-inferior inferior-exception-stack + inferior-premature-eof? + inferior-premature-eof-port + inferior-premature-eof-inferior read-repl-response =20 inferior-packages @@ -228,6 +232,11 @@ equivalent. Return #f if the inferior could not be la= unched." (inferior inferior-exception-inferior) ; | #f (stack inferior-exception-stack)) ;list of (FILE COLUMN LI= NE) =20 +(define-condition-type &inferior-premature-eof &error + inferior-premature-eof? + (port inferior-premature-eof-port) + (inferior inferior-premature-eof-inferior)) + (define* (read-repl-response port #:optional inferior) "Read a (guix repl) response from PORT and return it as a Scheme object. Raise '&inferior-exception' when an exception is read from PORT." @@ -241,6 +250,12 @@ Raise '&inferior-exception' when an exception is read = from PORT." (match (read port) (('values objects ...) (apply values (map sexp->object objects))) + ((? eof-object?) + ;; Unexpectedly read EOF from the port. This can happen for example = when + ;; the underlying connection for PORT was lost with Guile-SSH. + (raise (condition (&inferior-premature-eof + (inferior inferior) + (port port))))) (('exception ('arguments key objects ...) ('stack frames ...)) ;; Protocol (0 1 1) and later. diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm index b0fd20e158..4312eb4e22 100644 --- a/guix/scripts/offload.scm +++ b/guix/scripts/offload.scm @@ -705,20 +705,34 @@ machine." "Check whether MACHINE is available. Exit with an error upon failure." ;; Sometimes, the machine remote port may return EOF, presumably because= the ;; connection was lost. Retry up to 3 times. - (let* ((name (build-machine-name machine)) - (socket (build-machine-daemon-socket machine)) - (session (open-ssh-session machine %short-timeout)) - (node (remote-inferior session))) - (dynamic-wind - (lambda () #t) - (lambda () - (assert-node-has-guix node name) - (assert-node-repl node name) - (assert-node-can-import session node name socket) - (assert-node-can-export session node name socket)) - (lambda () - (close-inferior node) - (disconnect! session))))) + (let loop ((retries 3)) + (guard (c ((inferior-premature-eof? c) + (let ((retries-left (1- retries)) + (inferior (inferior-premature-eof-inferior c))) + (if (> retries-left 0) + (begin + (info (G_ "got premature EOF from machine '~a' from= \ +inferior '~a' on port '~a'; retrying connection~%") + (build-machine-name machine) + inferior + (inferior-premature-eof-port c)) + (loop (retries-left))) + (leave (G_ "connection repeatedly lost with machine '= ~a'~%") + (build-machine-name machine)))))) + (let* ((name (build-machine-name machine)) + (socket (build-machine-daemon-socket machine)) + (session (open-ssh-session machine %short-timeout)) + (node (remote-inferior session))) + (dynamic-wind + (lambda () #t) + (lambda () + (assert-node-has-guix node name) + (assert-node-repl node name) + (assert-node-can-import session node name socket) + (assert-node-can-export session node name socket)) + (lambda () + (close-inferior node) + (disconnect! session))))))) =20 (define (check-machine-status machine-file pred) "Print the load of each machine matching PRED in MACHINE-FILE." --=20 2.31.1 --=-=-=--