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 ms11 with LMTPS id 7xowBFmPW1/+WwAA0tVLHw (envelope-from ) for ; Fri, 11 Sep 2020 14:53:13 +0000 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 SPOyOViPW18xLgAAB5/wlQ (envelope-from ) for ; Fri, 11 Sep 2020 14:53:12 +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 B352794050F for ; Fri, 11 Sep 2020 14:53:12 +0000 (UTC) Received: from localhost ([::1]:55588 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kGkQJ-0001t9-MT for larch@yhetil.org; Fri, 11 Sep 2020 10:53:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33524) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kGkQA-0001pC-EC for guix-patches@gnu.org; Fri, 11 Sep 2020 10:53:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:33568) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kGkQA-0007z5-4z for guix-patches@gnu.org; Fri, 11 Sep 2020 10:53:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kGkQA-0006dV-3N for guix-patches@gnu.org; Fri, 11 Sep 2020 10:53:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43340] [PATCH 1/5] daemon: Generalize 'HookInstance' to 'Agent'. References: <20200911144049.14632-1-ludo@gnu.org> In-Reply-To: <20200911144049.14632-1-ludo@gnu.org> Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 11 Sep 2020 14:53:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43340 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43340@debbugs.gnu.org Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 43340-submit@debbugs.gnu.org id=B43340.159983594325403 (code B ref 43340); Fri, 11 Sep 2020 14:53:02 +0000 Received: (at 43340) by debbugs.gnu.org; 11 Sep 2020 14:52:23 +0000 Received: from localhost ([127.0.0.1]:45102 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kGkPW-0006be-M3 for submit@debbugs.gnu.org; Fri, 11 Sep 2020 10:52:23 -0400 Received: from eggs.gnu.org ([209.51.188.92]:57656) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kGkPU-0006bO-Fd for 43340@debbugs.gnu.org; Fri, 11 Sep 2020 10:52:21 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:40473) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kGkPP-0007vw-64; Fri, 11 Sep 2020 10:52:15 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=39314 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kGkPO-0004Uo-2Y; Fri, 11 Sep 2020 10:52:14 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Fri, 11 Sep 2020 16:51:50 +0200 Message-Id: <20200911145154.15057-1-ludo@gnu.org> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: -3.3 (---) X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Spam-Score: 3.99 X-TUID: +Cni8iKi93J7 * nix/libstore/build.cc (HookInstance): Rename to... (Agent): ... this. Rename 'toHook' and 'fromHook' similarly and update users. Change constructor to require a command and an argument list. (DerivationGoal::tryBuildHook): Pass arguments to the 'Agent' constructor. --- nix/libstore/build.cc | 90 ++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 29266f1dd6..b6fad493a9 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -85,7 +85,7 @@ static string pathNullDevice = "/dev/null"; /* Forward definition. */ class Worker; -struct HookInstance; +struct Agent; /* A pointer to a goal. */ @@ -265,7 +265,7 @@ public: LocalStore & store; - std::shared_ptr hook; + std::shared_ptr hook; Worker(LocalStore & store); ~Worker(); @@ -590,37 +590,41 @@ void UserLock::kill() ////////////////////////////////////////////////////////////////////// -struct HookInstance +/* An "agent" is a helper program that runs in the background and that we talk + to over pipes, such as the "guix offload" program. */ +struct Agent { - /* Pipes for talking to the build hook. */ - Pipe toHook; + /* Pipes for talking to the agent. */ + Pipe toAgent; - /* Pipe for the hook's standard output/error. */ - Pipe fromHook; + /* Pipe for the agent's standard output/error. */ + Pipe fromAgent; - /* Pipe for the builder's standard output/error. */ + /* Pipe for build standard output/error--e.g., for build processes started + by "guix offload". */ Pipe builderOut; - /* The process ID of the hook. */ + /* The process ID of the agent. */ Pid pid; - HookInstance(); + /* The 'guix' sub-command and arguments passed to the agent. */ + Agent(const string &command, const Strings &args); - ~HookInstance(); + ~Agent(); }; -HookInstance::HookInstance() +Agent::Agent(const string &command, const Strings &args) { - debug("starting build hook"); + debug(format("starting agent '%1%'") % command); const Path &buildHook = settings.guixProgram; /* Create a pipe to get the output of the child. */ - fromHook.create(); + fromAgent.create(); /* Create the communication pipes. */ - toHook.create(); + toAgent.create(); /* Create a pipe to get the output of the builder. */ builderOut.create(); @@ -628,38 +632,38 @@ HookInstance::HookInstance() /* Fork the hook. */ pid = startProcess([&]() { - commonChildInit(fromHook); + commonChildInit(fromAgent); if (chdir("/") == -1) throw SysError("changing into `/"); /* Dup the communication pipes. */ - if (dup2(toHook.readSide, STDIN_FILENO) == -1) + if (dup2(toAgent.readSide, STDIN_FILENO) == -1) throw SysError("dupping to-hook read side"); /* Use fd 4 for the builder's stdout/stderr. */ if (dup2(builderOut.writeSide, 4) == -1) throw SysError("dupping builder's stdout/stderr"); - execl(buildHook.c_str(), buildHook.c_str(), "offload", - settings.thisSystem.c_str(), - (format("%1%") % settings.maxSilentTime).str().c_str(), - (format("%1%") % settings.printBuildTrace).str().c_str(), - (format("%1%") % settings.buildTimeout).str().c_str(), - NULL); + Strings allArgs; + allArgs.push_back(buildHook); + allArgs.push_back(command); + allArgs.insert(allArgs.end(), args.begin(), args.end()); // append - throw SysError(format("executing `%1% offload'") % buildHook); + execv(buildHook.c_str(), stringsToCharPtrs(allArgs).data()); + + throw SysError(format("executing `%1% %2%'") % buildHook % command); }); pid.setSeparatePG(true); - fromHook.writeSide.close(); - toHook.readSide.close(); + fromAgent.writeSide.close(); + toAgent.readSide.close(); } -HookInstance::~HookInstance() +Agent::~Agent() { try { - toHook.writeSide.close(); + toAgent.writeSide.close(); pid.kill(true); } catch (...) { ignoreException(); @@ -760,7 +764,7 @@ private: Pipe builderOut; /* The build hook. */ - std::shared_ptr hook; + std::shared_ptr hook; /* Whether we're currently doing a chroot build. */ bool useChroot; @@ -1440,7 +1444,7 @@ void DerivationGoal::buildDone() /* Close the read side of the logger pipe. */ if (hook) { hook->builderOut.readSide.close(); - hook->fromHook.readSide.close(); + hook->fromAgent.readSide.close(); } else builderOut.readSide.close(); @@ -1587,8 +1591,16 @@ HookReply DerivationGoal::tryBuildHook() { if (!settings.useBuildHook) return rpDecline; - if (!worker.hook) - worker.hook = std::shared_ptr(new HookInstance); + if (!worker.hook) { + Strings args = { + settings.thisSystem.c_str(), + (format("%1%") % settings.maxSilentTime).str().c_str(), + (format("%1%") % settings.printBuildTrace).str().c_str(), + (format("%1%") % settings.buildTimeout).str().c_str() + }; + + worker.hook = std::shared_ptr(new Agent("offload", args)); + } /* Tell the hook about system features (beyond the system type) required from the build machine. (The hook could parse the @@ -1597,7 +1609,7 @@ HookReply DerivationGoal::tryBuildHook() foreach (Strings::iterator, i, features) checkStoreName(*i); /* !!! abuse */ /* Send the request to the hook. */ - writeLine(worker.hook->toHook.writeSide, (format("%1% %2% %3% %4%") + writeLine(worker.hook->toAgent.writeSide, (format("%1% %2% %3% %4%") % (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0") % drv.platform % drvPath % concatStringsSep(",", features)).str()); @@ -1605,7 +1617,7 @@ HookReply DerivationGoal::tryBuildHook() whether the hook wishes to perform the build. */ string reply; while (true) { - string s = readLine(worker.hook->fromHook.readSide); + string s = readLine(worker.hook->fromAgent.readSide); if (string(s, 0, 2) == "# ") { reply = string(s, 2); break; @@ -1637,21 +1649,21 @@ HookReply DerivationGoal::tryBuildHook() string s; foreach (PathSet::iterator, i, allInputs) { s += *i; s += ' '; } - writeLine(hook->toHook.writeSide, s); + writeLine(hook->toAgent.writeSide, s); /* Tell the hooks the missing outputs that have to be copied back from the remote system. */ s = ""; foreach (PathSet::iterator, i, missingPaths) { s += *i; s += ' '; } - writeLine(hook->toHook.writeSide, s); + writeLine(hook->toAgent.writeSide, s); - hook->toHook.writeSide.close(); + hook->toAgent.writeSide.close(); /* Create the log file and pipe. */ Path logFile = openLogFile(); set fds; - fds.insert(hook->fromHook.readSide); + fds.insert(hook->fromAgent.readSide); fds.insert(hook->builderOut.readSide); worker.childStarted(shared_from_this(), hook->pid, fds, false, true); @@ -2785,7 +2797,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) writeFull(fdLogFile, data); } - if (hook && fd == hook->fromHook.readSide) + if (hook && fd == hook->fromAgent.readSide) writeToStderr(prefix + data); } -- 2.28.0