Make VM Settings work with grub

This commit is contained in:
Christoph Hummer
2024-08-09 12:38:18 +02:00
committed by GitHub
parent 663665a61b
commit fb2b66b5b0
@@ -33,30 +33,60 @@ function scan($line, $text) {
return stripos($line,$text)!==false; return stripos($line,$text)!==false;
} }
function embed(&$syslinux, $key, $value) { function embed(&$bootcfg, $env, $key, $value) {
$size = count($syslinux); if ($env === 'syslinux') {
$make = false; $size = count($bootcfg);
$new = strlen($value) ? "$key=$value" : false; $make = false;
$i = 0; $new = strlen($value) ? "$key=$value" : false;
while ($i < $size) { $i = 0;
// find sections and exclude safemode while ($i < $size) {
if (scan($syslinux[$i],'label ') && !scan($syslinux[$i],'safe mode') && !scan($syslinux[$i],'safemode')) { // find sections and exclude safemode
$n = $i + 1; if (scan($bootcfg[$i],'label ') && !scan($bootcfg[$i],'safe mode') && !scan($bootcfg[$i],'safemode')) {
// find the current requested setting $n = $i + 1;
while (!scan($syslinux[$n],'label ') && $n < $size) { // find the current requested setting
if (scan($syslinux[$n],'append ')) { while (!scan($bootcfg[$n],'label ') && $n < $size) {
$cmd = preg_split('/\s+/',trim($syslinux[$n])); if (scan($bootcfg[$n],'append ')) {
// replace the existing setting $cmd = preg_split('/\s+/',trim($bootcfg[$n]));
for ($c = 1; $c < count($cmd); $c++) if (scan($cmd[$c],$key)) {$make |= ($cmd[$c]!=$new); $cmd[$c] = $new; break;} // replace the existing setting
// or insert the new setting for ($c = 1; $c < count($cmd); $c++) if (scan($cmd[$c],$key)) {$make |= ($cmd[$c]!=$new); $cmd[$c] = $new; break;}
if ($c==count($cmd) && $new) {array_splice($cmd,-1,0,$new); $make = true;} // or insert the new setting
$syslinux[$n] = ' '.str_replace(' ',' ',implode(' ',$cmd)); if ($c==count($cmd) && $new) {array_splice($cmd,-1,0,$new); $make = true;}
$bootcfg[$n] = ' '.str_replace(' ',' ',implode(' ',$cmd));
}
$n++;
} }
$n++; $i = $n - 1;
} }
$i = $n - 1; $i++;
}
} elseif ($env === 'grub') {
$size = count($bootcfg);
$make = false;
$new = strlen($value) ? "$key=$value" : false;
$i = 0;
while ($i < $size) {
// find sections and exclude safemode/memtest
if (scan($bootcfg[$i],'menuentry ') && !scan($bootcfg[$i],'safe mode') && !scan($bootcfg[$i],'safemode') && !scan($bootcfg[$i],'memtest')) {
$n = $i + 1;
// find the current requested setting
while (!scan($bootcfg[$n],'menuentry ') && $n < $size) {
if (scan($bootcfg[$n],'linux ')) {
$cmd = preg_split('/\s+/',trim($bootcfg[$n]));
// replace the existing setting
for ($c = 1; $c < count($cmd); $c++) if (scan($cmd[$c],$key)) {$make |= ($cmd[$c]!=$new); $cmd[$c] = $new; break;}
// or insert the new setting
if ($c == count($cmd) && $new) {
$cmd[] = $new;
$make = true;
}
$bootcfg[$n] = ' ' . str_replace(' ', ' ', implode(' ', $cmd));
}
$n++;
}
$i = $n - 1;
}
$i++;
} }
$i++;
} }
return $make; return $make;
} }
@@ -536,26 +566,39 @@ case 'hot-detach-usb':
//TODO //TODO
break; break;
case 'syslinux': case 'cmdlineoverride':
$cfg = '/boot/syslinux/syslinux.cfg'; if (is_file('/boot/syslinux/syslinux.cfg')) {
$syslinux = file($cfg, FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES); $cfg = '/boot/syslinux/syslinux.cfg';
$m1 = embed($syslinux, 'pcie_acs_override', $_REQUEST['pcie']); $env = 'syslinux';
$m2 = embed($syslinux, 'vfio_iommu_type1.allow_unsafe_interrupts', $_REQUEST['vfio']); $bootcfg = file($cfg, FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES);
if ($m1||$m2) file_put_contents($cfg, implode("\n",$syslinux)."\n"); } elseif (is_file('/boot/grub/grub.cfg')) {
$cfg = '/boot/grub/grub.cfg';
$env = 'grub';
$bootcfg = file($cfg, FILE_IGNORE_NEW_LINES);
}
$m1 = embed($bootcfg, $env, 'pcie_acs_override', $_REQUEST['pcie']);
$m2 = embed($bootcfg, $env, 'vfio_iommu_type1.allow_unsafe_interrupts', $_REQUEST['vfio']);
if ($m1||$m2) file_put_contents($cfg, implode("\n",$bootcfg)."\n");
$arrResponse = ['success' => true, 'modified' => $m1|$m2]; $arrResponse = ['success' => true, 'modified' => $m1|$m2];
break; break;
case 'reboot': case 'reboot':
$cfg = '/boot/syslinux/syslinux.cfg'; if (is_file('/boot/syslinux/syslinux.cfg')) {
$syslinux = file($cfg, FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES); $cfg = '/boot/syslinux/syslinux.cfg';
$env = 'syslinux';
} elseif (is_file('/boot/grub/grub.cfg')) {
$cfg = '/boot/grub/grub.cfg';
$env = 'grub';
}
$bootcfg = file($cfg, FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES);
$cmdline = explode(' ',file_get_contents('/proc/cmdline')); $cmdline = explode(' ',file_get_contents('/proc/cmdline'));
$pcie = $vfio = ''; $pcie = $vfio = '';
foreach ($cmdline as $cmd) { foreach ($cmdline as $cmd) {
if (scan($cmd,'pcie_acs_override')) $pcie = explode('=',$cmd)[1]; if (scan($cmd,'pcie_acs_override')) $pcie = explode('=',$cmd)[1];
if (scan($cmd,'allow_unsafe_interrupts')) $vfio = explode('=',$cmd)[1]; if (scan($cmd,'allow_unsafe_interrupts')) $vfio = explode('=',$cmd)[1];
} }
$m1 = embed($syslinux, 'pcie_acs_override', $pcie); $m1 = embed($bootcfg, $env, 'pcie_acs_override', $pcie);
$m2 = embed($syslinux, 'vfio_iommu_type1.allow_unsafe_interrupts', $vfio); $m2 = embed($bootcfg, $env, 'vfio_iommu_type1.allow_unsafe_interrupts', $vfio);
$arrResponse = ['success' => true, 'modified' => $m1|$m2]; $arrResponse = ['success' => true, 'modified' => $m1|$m2];
break; break;