1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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;
}
}
|