aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bbot/agent.cxx10
-rw-r--r--bbot/machine.cxx52
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");