$machines]), 60); Util::redirect('?do=vmstore&show=benchmark&action=select&id=' . $id); } /** * @param string $image relative path/name of image * @param string $serverOrMode IP address of DNBD3 server, OR 'auto' for all servers known to client, or 'nfs' for NFS * @param int $start timestamp when the clients should start * @return ?string taskId, or null on error */ public static function start(string $id, array $machineUuids, string $image, string $serverOrMode, int &$start): ?string { Module::isAvailable('rebootcontrol'); $clients = Database::queryAll('SELECT machineuuid, clientip FROM machine WHERE machineuuid IN (:uuids)', ['uuids' => $machineUuids]); if (empty($clients)) { ErrorHandler::traceError('Cannot start benchmark: No matching clients'); } // The more clients we have, the longer it takes to SSH into all of them. // As of 2022, RemoteExec processes 4 clients in parallel $start = ceil(count($clients) / 4 + 5 + time()); if ($serverOrMode === 'nfs') { $modeOption = '--nfs'; } elseif ($serverOrMode === 'auto') { $modeOption = ''; } else { $modeOption = "--servers '$serverOrMode'"; } // We fork off the benchmark into the background, and collect the results with another RemoteExec job // when we're done. This is because RemoteExec only does four concurrent SSH connections, so if we wanted to // do this the easy, synchronous way, we never could run more than four tests at the same time. $command = << /dev/null < /dev/null setsid while true; do echo 3 > /proc/sys/vm/drop_caches sleep 1 done & flush=\$! image_speedcheck --start $start --console $modeOption --file "$image" > "/tmp/speedcheck-$id" kill \$flush ) & COMMAND; $task = RebootControl::runScript($clients, $command); return $task['id'] ?? null; } /** * @return array{cpu: array, net: array} */ public static function parseBenchLine(string $line): array { $out = ['cpu' => [], 'net' => []]; foreach (explode(',', $line) as $elem) { $elem = explode('+', $elem); $out['net'][] = ['x' => (int)$elem[0], 'y' => (int)$elem[1]]; //$out['cpu'][] = ['x' => $elem[0], 'y' => $elem[2]]; } return $out; } }