summaryrefslogtreecommitdiffstats
path: root/modules-available/vmstore/inc/vmstorebenchmark.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/vmstore/inc/vmstorebenchmark.inc.php')
-rw-r--r--modules-available/vmstore/inc/vmstorebenchmark.inc.php84
1 files changed, 84 insertions, 0 deletions
diff --git a/modules-available/vmstore/inc/vmstorebenchmark.inc.php b/modules-available/vmstore/inc/vmstorebenchmark.inc.php
new file mode 100644
index 00000000..b819ef8a
--- /dev/null
+++ b/modules-available/vmstore/inc/vmstorebenchmark.inc.php
@@ -0,0 +1,84 @@
+<?php
+
+class VmStoreBenchmark
+{
+
+ const PROP_LIST_KEY = 'vmstore.benchmark';
+
+ /**
+ * @param string[] $machineUuids List of UUIDs
+ * @return void
+ */
+ public static function prepareSelectDialog(array $uuids)
+ {
+ Module::isAvailable('rebootcontrol');
+ User::assertPermission('.vmstore.benchmark');
+ $uuids = array_values(Request::post('uuid', Request::REQUIRED, 'array'));
+ $machines = RebootUtils::getFilteredMachineList($uuids, '.vmstore.benchmark');
+ if ($machines === false)
+ return;
+ $machines = array_column($machines, 'machineuuid');
+ $id = Property::addToList(self::PROP_LIST_KEY,
+ json_encode(['machines' => $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 = <<<COMMAND
+(
+ exec &> /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;
+ }
+
+} \ No newline at end of file