From eda8d37c12f29fcd314f2cf9f0b926d6d6d360ba Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Fri, 15 Sep 2023 21:10:06 +0100 Subject: [PATCH] Add option to try reflink first. Revert to rsync if not supported. --- .../include/libvirt_helpers.php | 15 ++++++++-- .../dynamix.vm.manager/scripts/VMClone.php | 29 ++++++++++++++----- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php index 67e8962b3..f0321a8ee 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php @@ -1509,9 +1509,13 @@ private static $encoding = 'UTF-8'; #Check free space. write("addLog\0".htmlspecialchars("Checking for free space")); $dirfree = disk_free_space($pathinfo["dirname"]) ; - + $sourcedir = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($pathinfo["dirname"])." 2>/dev/null")); + $repdir = str_replace('/mnt/user/', "/mnt/$sourcedir/", $pathinfo["dirname"]); + $repdirfree = disk_free_space($repdir) ; + $reflink = true ; $capacity *= 1 ; + if ($free == "yes" && $repdirfree < $capacity) { $reflink = false ;} if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false ;} #Clone XML @@ -1556,8 +1560,15 @@ private static $encoding = 'UTF-8'; foreach($file_clone as $diskid => $disk) { $target = $disk['target'] ; $source = $disk['source'] ; + $sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null")); + $reptgt = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $target); + $repsrc = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $source); + #var_dump($repsrc,$reptgt) ; + + $cmdstr = "cp --reflink=always '$repsrc' '$reptgt'" ; + if ($reflink == true) { $refcmd = $cmdstr ; } else {$refcmd = false; } $cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$source' '$target'" ; - $error = execCommand_nchan($cmdstr,$path) ; + $error = execCommand_nchan($cmdstr,$path,$refcmd) ; if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false) ; } } diff --git a/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php b/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php index 05f350e4c..93a2fa7d1 100755 --- a/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php +++ b/emhttp/plugins/dynamix.vm.manager/scripts/VMClone.php @@ -36,27 +36,42 @@ function write(...$messages){ } curl_close($com); } -function execCommand_nchan($command,$idx) { + function execCommand_nchan($command,$idx,$refcmd=false) { $waitID = mt_rand(); + if ($refcmd) { + [$cmd,$args] = explode(' ',$refcmd,2); + write("

","addLog\0
"._('Command execution')."".basename($cmd).' '.str_replace(" -","
  -",htmlspecialchars($args))."
"._('Please wait')."

","show_Wait\0$waitID"); + $rtn = exec("$refcmd 2>&1", $output,$return) ; + if ($return == 0) $reflinkok = true ; else $reflinkok = false ; + write("addLog\0
{$output[0]}"); + $out = $return ? _('The command failed revert to rsync')."." : _('The command finished successfully').'!'; + write("stop_Wait\0$waitID","addLog\0
$out"); + } + + if ($reflinkok) { + return true ; + } else { + $waitID = mt_rand(); [$cmd,$args] = explode(' ',$command,2); write("

","addLog\0
"._('Command execution')."".basename($cmd).' '.str_replace(" -","
  -",htmlspecialchars($args))."
"._('Please wait')."

","show_Wait\0$waitID"); - + write("addToID\0$idx\0Cloning VM: ") ; $proc = popen("$command 2>&1 &",'r'); while ($out = fread($proc,100)) { $out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out); - $out = trim($out) ; - $values = explode(' ',$out) ; - $string = _("Data copied: ").$values[0]._(" Percentage: ").$values[1]._(" Transfer Rate: ").$values[3]._(" Time remaining: ").$values[4].$values[5] ; + $out = trim($out) ; + $values = explode(' ',$out) ; + $string = _("Data copied: ").$values[0].' '._(" Percentage: ").$values[1].' '._(" Transfer Rate: ").$values[2].' '._(" Time remaining: ").$values[4].$values[5] ; write("progress\0$idx\0".htmlspecialchars($string)) ; - if ($out) $stringsave=$string ; + if ($out) $stringsave=$string ; } $retval = pclose($proc); - write("progress\0$idx\0".htmlspecialchars($stringsave)) ; + write("progress\0$idx\0".htmlspecialchars($stringsave)) ; $out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!'; write("stop_Wait\0$waitID","addLog\0
$out"); return $retval===0; } +} #{action:"snap-", uuid:uuid , snapshotname:target , remove:remove, free:free ,removemeta:removemeta ,keep:keep, desc:desc} #VM ID [ 99]: pull. .Block Pull: [ 0 %]Block Pull: [100 %].Pull complete.