From aa7d4c3e66db326be2281ff9c21e8510565ae707 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 21 Apr 2017 16:29:00 +0200 Subject: Various improvements --- bbot/agent.cxx | 10 ++++++---- bbot/machine.cxx | 52 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/bbot/agent.cxx b/bbot/agent.cxx index 55d95ec..383653a 100644 --- a/bbot/agent.cxx +++ b/bbot/agent.cxx @@ -167,14 +167,16 @@ bootstrap_machine (const dir_path& md, return nullopt; }; - // The first request should be the toolchain download. Wait for up to 60 - // seconds for that to arrive. In a sense we use it as an indication + // The first request should be the toolchain download. Wait for up to 3 + // minutes for that to arrive. In a sense we use it as an indication // that the machine has booted and the bootstrap process has started. + // Why wait so long you may wonder? Well, we may be using a new MAC + // address and operating systems like Windows may need to digest that. // size_t to; - const size_t startup_to (60); + const size_t startup_to (3 * 60); const size_t bootstrap_to (ops.bootstrap_timeout ()); - const size_t shutdown_to (60); + const size_t shutdown_to (3 * 60); if (!tftpd.serve ((to = startup_to))) return soft_fail ("bootstrap startup timeout"); diff --git a/bbot/machine.cxx b/bbot/machine.cxx index 976b79c..de394b6 100644 --- a/bbot/machine.cxx +++ b/bbot/machine.cxx @@ -33,18 +33,36 @@ namespace bbot const string& br, uint16_t port) { + string addr (iface_addr (br)); + run (t, "sudo", "iptables", "-t", "nat", a, "PREROUTING", - "-p", "udp", "-m", "udp", + "-p", "udp", "-m", "physdev", "-i", br, "--physdev-in", tap, "--dport", 69, "-j", "DNAT", - "--to-destination", iface_addr (br) + ':' + to_string (port)); + "--to-destination", addr + ':' + to_string (port)); + + // Nobody really knows whether this is really needed (really)... + // + run (t, + "sudo", "iptables", + a, "FORWARD", + "-m", "udp", + "-p", "udp", + "-m", "physdev", + "-o", br, + "--physdev-out", tap, + "-d", addr, + "--dport", port, + "-m", "state", + "--state", "NEW,ESTABLISHED,RELATED", + "-j", "ACCEPT"); } static string @@ -157,22 +175,23 @@ namespace bbot if (sizeof (sockaddr_un::sun_path) <= monitor.size ()) throw invalid_argument ("monitor unix socket path too long"); - // Start the VM. - // - // Notes: - // - // 1. For now we let qemu calculate sockets/cores/threads from the - // total number of CPUs (i.e., threads). - // - // 2. echo system_powerdown | socat - UNIX-CONNECT:.../monitor + // Map logical CPUs to sockets/cores/threads. Failed that, QEMU just makes + // it a machine with that number of sockets and some operating systems + // (like Windows) only can do two. // + size_t cpu (ops.cpu ()); + + size_t sockets (cpu <= 8 ? 1 : cpu <= 64 ? 2 : 4); + size_t cores (cpu / sockets); + size_t threads (cores <= 4 ? 1 : 2); + cores /= threads; + // We probably don't want to commit all the available RAM to the VM since // some of it could be used on the host side for caching, etc. So the // heuristics that we will use is 4G or 1G per CPU, whichever is greater // and the rest divide equally between the host and the VM. // - size_t cpu (ops.cpu ()); size_t ram ((cpu < 4 ? 4 : cpu) * 1024 * 1024); // Kb. if (ram > ops.ram ()) @@ -210,6 +229,12 @@ namespace bbot //"-device", "scsi-hd,drive=disk0" } + // Start the VM. + // + // Notes: + // + // 1. echo system_powerdown | socat - UNIX-CONNECT:.../monitor + // proc = run_io_start ( trace, fdnull (), @@ -221,7 +246,10 @@ namespace bbot "-no-reboot", // Exit on VM reboot. "-m", to_string (ram / 1024) + "M", "-cpu", "host", - "-smp", cpu, + "-smp", (to_string (cpu) + + ",sockets=" + to_string (sockets) + + ",cores=" + to_string (cores) + + ",threads=" + to_string (threads)), os, "-vnc", "127.0.0.1:" + to_string (tc_num), // 5900 + tc_num "-monitor", "unix:" + monitor.string () + ",server,nowait"); -- cgit v1.1