mirror of
https://github.com/unraid/webgui.git
synced 2026-01-03 16:14:54 -06:00
Parity check sometimes shows last historical check and not the current parity check just completed.
This commit is contained in:
@@ -212,15 +212,53 @@ function tail($file, $rows=1) {
|
||||
}
|
||||
return implode($echo);
|
||||
}
|
||||
|
||||
/* Get the last parity check from the parity history. */
|
||||
function last_parity_log() {
|
||||
$log = '/boot/config/parity-checks.log';
|
||||
[$date,$duration,$speed,$status,$error,$action,$size] = file_exists($log) ? my_explode('|',tail($log),7) : array_fill(0,7,0);
|
||||
if ($date) {
|
||||
[$y,$m,$d,$t] = my_preg_split('/ +/',$date,4);
|
||||
$date = strtotime("$d-$m-$y $t");
|
||||
}
|
||||
return [$date,$duration,$speed,$status,$error,$action,$size];
|
||||
$log = '/boot/config/parity-checks.log';
|
||||
|
||||
if (file_exists($log)) {
|
||||
list($date, $duration, $speed, $status, $error, $action, $size) = my_explode('|', tail($log), 7);
|
||||
} else {
|
||||
list($date, $duration, $speed, $status, $error, $action, $size) = array_fill(0, 7, 0);
|
||||
}
|
||||
|
||||
if ($date) {
|
||||
list($y, $m, $d, $t) = my_preg_split('/ +/', $date, 4);
|
||||
$date = strtotime("$d-$m-$y $t");
|
||||
}
|
||||
|
||||
return [$date, $duration, $speed, $status, $error, $action, $size];
|
||||
}
|
||||
|
||||
/* Get the last parity check from Unraid. */
|
||||
function last_parity_check() {
|
||||
global $var;
|
||||
|
||||
/* Files for the latest parity check. */
|
||||
$stamps = '/var/tmp/stamps.ini';
|
||||
$resync = '/var/tmp/resync.ini';
|
||||
|
||||
/* Get the latest parity information from Unraid. */
|
||||
$synced = file_exists($stamps) ? explode(',',file_get_contents($stamps)) : [];
|
||||
$sbSynced = array_shift($synced) ?: _var($var,'sbSynced',0);
|
||||
$idle = [];
|
||||
while (count($synced) > 1) {
|
||||
$idle[] = array_pop($synced) - array_pop($synced);
|
||||
}
|
||||
$action = _var($var, 'mdResyncAction');
|
||||
$size = _var($var, 'mdResyncSize', 0);
|
||||
if (file_exists($resync)) {
|
||||
list($action, $size) = my_explode(',', file_get_contents($resync));
|
||||
}
|
||||
$duration = $var['sbSynced2']-$sbSynced-array_sum($idle);
|
||||
$status = _var($var,'sbSyncExit');
|
||||
$speed = $status==0 ? round($size*1024/$duration) : 0;
|
||||
$error = _var($var,'sbSyncErrs',0);
|
||||
|
||||
return [$duration, $speed, $status, $error, $action, $size];
|
||||
}
|
||||
|
||||
function urlencode_path($path) {
|
||||
return str_replace("%2F", "/", urlencode($path));
|
||||
}
|
||||
@@ -285,14 +323,12 @@ function my_mkdir($dirname,$permissions = 0777,$recursive = false,$own = "nobody
|
||||
$parent = str_replace('/mnt/user/', "/mnt/$realdisk/", $parent);
|
||||
}
|
||||
}
|
||||
$fstype = trim(shell_exec(" stat -f -c '%T' $parent"));
|
||||
$fstype = trim(shell_exec(" stat -f -c '%T' $parent"));
|
||||
$rtncode = false;
|
||||
switch ($fstype) {
|
||||
case "zfs":
|
||||
$zfsdataset = trim(shell_exec("zfs list -H -o name $parent")) ;
|
||||
if (strpos($zfsdataset,'/') !== false) $zfsdataset .= str_replace($parent,"",$dirname); else {
|
||||
$zfsdataset .= str_replace("/mnt/$zfsdataset","",$dirname);
|
||||
}
|
||||
$zfsdataset .= str_replace($parent,"",$dirname);
|
||||
if ($recursive) $rtncode=exec("zfs create -p \"$zfsdataset\"");else $rtncode=exec("zfs create \"$zfsdataset\"");
|
||||
if (!$rtncode) mkdir($dirname, $permissions, $recursive); else chmod($zfsdataset,$permissions);
|
||||
break;
|
||||
|
||||
@@ -63,7 +63,7 @@ if (isset($_POST['#apply'])) {
|
||||
break;
|
||||
}
|
||||
$cron[] = "# Generated parity check schedule:";
|
||||
if ($_POST['cumulative']==1) {
|
||||
if (isset($_POST['cumulative']) && $_POST['cumulative']==1) {
|
||||
[$m, $h] = explode(' ',$time);
|
||||
$h = ($h + $_POST['duration']) % 24;
|
||||
if ($_POST['frequency']==7) {
|
||||
|
||||
@@ -69,65 +69,89 @@ function create_file($file,...$data) {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
$var = (array)@parse_ini_file("$varroot/var.ini");
|
||||
// check for language changes
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
if (_var($display,'locale') != $locale_init) {
|
||||
$locale_init = _var($display,'locale');
|
||||
update_translation($locale_init);
|
||||
}
|
||||
$synced = create_sync($stamps);
|
||||
$sbSynced = array_shift($synced) ?: _var($var,'sbSynced',0);
|
||||
$echo = [];
|
||||
$spot = _var($var,'mdResyncPos',0);
|
||||
if ($spot>0) {
|
||||
[$size,$delta,$bytes] = [_var($var,'mdResyncSize',0),_var($var,'mdResyncDt',0),_var($var,'mdResyncDb',0)];
|
||||
create_file($resync,_var($var,'mdResyncAction'),$size);
|
||||
$echo[] = my_scale($size*1024,$unit,-1)." $unit";
|
||||
$echo[] = _(my_clock(floor((time()-$sbSynced)/60)),2).($delta ? '' : ' ('._('paused').')');
|
||||
$echo[] = my_scale($spot*1024,$unit)." $unit (".number_format($spot/($size/100+1),1,$dot,'')." %)";
|
||||
$echo[] = $delta ? my_scale($bytes*1024/$delta,$unit, 1)." $unit/sec" : '---';
|
||||
$echo[] = $bytes ? _(my_clock(round(((($delta*(($size-$spot)/($bytes/100+1)))/100)/60),0)),2) : _('Unknown');
|
||||
$echo[] = $var['sbSyncErrs'];
|
||||
} elseif (_var($var,'sbSynced') && _var($var,'sbSynced2')) {
|
||||
$timestamp = str_replace(['.0','.'],[' ',' '],date('Y.M.d H:i:s',$var['sbSynced2']));
|
||||
if (new_parity_log($timestamp)) {
|
||||
$idle = []; while (count($synced)>1) $idle[] = array_pop($synced)-array_pop($synced);
|
||||
[$action,$size] = file_exists($resync) ? my_explode(',',file_get_contents($resync)) : [_var($var,'mdResyncAction'),_var($var,'mdResyncSize',0)];
|
||||
$duration = $var['sbSynced2']-$sbSynced-array_sum($idle);
|
||||
$status = _var($var,'sbSyncExit');
|
||||
$speed = $status==0 ? round($size*1024/$duration) : 0;
|
||||
$error = _var($var,'sbSyncErrs',0);
|
||||
file_put_contents($log,"$timestamp|$duration|$speed|$status|$error|$action|$size\n",FILE_APPEND);
|
||||
}
|
||||
delete_file($stamps,$resync);
|
||||
}
|
||||
if (_var($var,'fsState')=='Copying') $fsState = _var($var,'fsCopyPrcnt')."% "._('completed');
|
||||
elseif ($var['fsState']=='Clearing') $fsState = _var($var,'fsClearPrcnt')."% "._('completed');
|
||||
elseif (substr(_var($var,'fsState'),-3)!='ing') $fsState = 'stop';
|
||||
else $fsState = '';
|
||||
$var = (array)@parse_ini_file("$varroot/var.ini");
|
||||
|
||||
if (_var($var,'fsState')!="Started") $process = -1;
|
||||
elseif ($spot>0 && $bytes>0) $process = 1;
|
||||
elseif (file_exists('/var/run/mover.pid')) $process = 2;
|
||||
elseif (exec('ps -C btrfs -o cmd=|grep -cv show')>0) $process = 3;
|
||||
elseif (exec("zpool status|grep -c 'scrub in progress'")>0) $process = 4;
|
||||
else $process = 0;
|
||||
/* Check for language changes */
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
if (_var($display, 'locale') != $locale_init) {
|
||||
$locale_init = _var($display, 'locale');
|
||||
update_translation($locale_init);
|
||||
}
|
||||
|
||||
$echo = json_encode($echo);
|
||||
$md5_new = md5($echo,true);
|
||||
if ($md5_new !== $md5_old) {
|
||||
$md5_old = publish('parity',$echo)!==false ? $md5_new : -1;
|
||||
}
|
||||
if ($spot !== $spot_old) {
|
||||
$spot_old = publish('paritymonitor',$spot>0 ? 1 : 0)!==false ? $spot : -1;
|
||||
}
|
||||
if ($fsState !== $fs_old) {
|
||||
$fs_old = publish('fsState',$fsState)!==false ? $fsState : -1;
|
||||
}
|
||||
if ($process !== $proc_old) {
|
||||
$proc_old = publish('mymonitor',$process)!==false ? $process : -1;
|
||||
}
|
||||
sleep(1);
|
||||
$synced = create_sync($stamps);
|
||||
$sbSynced = array_shift($synced) ?: _var($var, 'sbSynced', 0);
|
||||
$echo = [];
|
||||
$spot = _var($var, 'mdResyncPos', 0);
|
||||
|
||||
if ($spot > 0) {
|
||||
$size = _var($var, 'mdResyncSize', 0);
|
||||
$delta = _var($var, 'mdResyncDt', 0);
|
||||
$bytes = _var($var, 'mdResyncDb', 0);
|
||||
|
||||
create_file($resync, _var($var, 'mdResyncAction'), $size);
|
||||
|
||||
$echo[] = my_scale($size * 1024, $unit, -1) . " $unit";
|
||||
$echo[] = _(my_clock(floor((time() - $sbSynced) / 60)), 2) . ($delta ? '' : ' (' . _('paused') . ')');
|
||||
$echo[] = my_scale($spot * 1024, $unit) . " $unit (" . number_format($spot / ($size / 100 + 1), 1, $dot, '') . " %)";
|
||||
$echo[] = $delta ? my_scale($bytes * 1024 / $delta, $unit, 1) . " $unit/sec" : '---';
|
||||
$echo[] = $bytes ? _(my_clock(round(((($delta * (($size - $spot) / ($bytes / 100 + 1))) / 100) / 60), 0)), 2) : _('Unknown');
|
||||
$echo[] = $var['sbSyncErrs'];
|
||||
} elseif (_var($var, 'sbSynced') && _var($var, 'sbSynced2')) {
|
||||
$timestamp = str_replace(['.0', '.'], [' ', ' '], date('Y.M.d H:i:s', $var['sbSynced2']));
|
||||
|
||||
if (new_parity_log($timestamp)) {
|
||||
/* Get the results from the latest parity check. */
|
||||
list($duration, $speed, $status, $error, $action, $size) = last_parity_check();
|
||||
|
||||
/* Save the result in the parity history log. */
|
||||
file_put_contents($log, "$timestamp|$duration|$speed|$status|$error|$action|$size\n", FILE_APPEND);
|
||||
|
||||
delete_file($stamps, $resync);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle fsState changes */
|
||||
if (_var($var, 'fsState') == 'Copying') {
|
||||
$fsState = _var($var, 'fsCopyPrcnt') . "% " . _('completed');
|
||||
} elseif (_var($var, 'fsState') == 'Clearing') {
|
||||
$fsState = _var($var, 'fsClearPrcnt') . "% " . _('completed');
|
||||
} elseif (substr(_var($var, 'fsState'), -3) != 'ing') {
|
||||
$fsState = 'stop';
|
||||
} else {
|
||||
$fsState = '';
|
||||
}
|
||||
|
||||
/* Determine process state */
|
||||
if (_var($var, 'fsState') != "Started") {
|
||||
$process = -1;
|
||||
} elseif ($spot > 0 && $bytes > 0) {
|
||||
$process = 1;
|
||||
} elseif (file_exists('/var/run/mover.pid')) {
|
||||
$process = 2;
|
||||
} elseif (exec('ps -C btrfs -o cmd=|grep -cv show') > 0) {
|
||||
$process = 3;
|
||||
} elseif (exec("zpool status|grep -c 'scrub in progress'") > 0) {
|
||||
$process = 4;
|
||||
} else {
|
||||
$process = 0;
|
||||
}
|
||||
|
||||
/* Publish changes */
|
||||
$echo = json_encode($echo);
|
||||
$md5_new = md5($echo, true);
|
||||
if ($md5_new !== $md5_old) {
|
||||
$md5_old = publish('parity', $echo) !== false ? $md5_new : -1;
|
||||
}
|
||||
if ($spot !== $spot_old) {
|
||||
$spot_old = publish('paritymonitor', $spot > 0 ? 1 : 0) !== false ? $spot : -1;
|
||||
}
|
||||
if ($fsState !== $fs_old) {
|
||||
$fs_old = publish('fsState', $fsState) !== false ? $fsState : -1;
|
||||
}
|
||||
if ($process !== $proc_old) {
|
||||
$proc_old = publish('mymonitor', $process) !== false ? $process : -1;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -244,30 +244,47 @@ if ($warn>0) {
|
||||
}
|
||||
}
|
||||
|
||||
// process parity check, parity sync and data-rebuild notifications
|
||||
/* Process parity check, parity sync, and data-rebuild notifications */
|
||||
$name = 'parity';
|
||||
$last = $saved[$item][$name] ?? '';
|
||||
|
||||
if ($var['mdResyncPos']) {
|
||||
if (!$last) {
|
||||
$action = preg_split('/\s+/',$var['mdResyncAction']);
|
||||
switch ($action[0]) {
|
||||
case 'recon': $last = $action[1]=='P' ? 'Parity-Sync' : 'Data-Rebuild'; break;
|
||||
case 'check': $last = count($action)>1 ? 'Parity-Check' : 'Read-Check'; break;
|
||||
case 'clear': $last = 'Disk-Clear'; break;
|
||||
default : $last = '';
|
||||
}
|
||||
$info = "Size: ".my_scale($var['mdResyncSize']*1024,$unit)." $unit";
|
||||
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $last")." -s ".escapeshellarg("Notice [$server] - $last started")." -d ".escapeshellarg("$info")." -i \"warning\" 2>/dev/null");
|
||||
$saved[$item][$name] = $last;
|
||||
}
|
||||
if (!$last) {
|
||||
$action = preg_split('/\s+/', $var['mdResyncAction']);
|
||||
switch ($action[0]) {
|
||||
case 'recon':
|
||||
$last = $action[1] == 'P' ? 'Parity-Sync' : 'Data-Rebuild';
|
||||
break;
|
||||
case 'check':
|
||||
$last = count($action) > 1 ? 'Parity-Check' : 'Read-Check';
|
||||
break;
|
||||
case 'clear':
|
||||
$last = 'Disk-Clear';
|
||||
break;
|
||||
default:
|
||||
$last = '';
|
||||
}
|
||||
$info = "Size: " . my_scale($var['mdResyncSize'] * 1024, $unit) . " $unit";
|
||||
exec("$notify -l '/Main' -e " . escapeshellarg("Unraid $last") . " -s " . escapeshellarg("Notice [$server] - $last started") . " -d " . escapeshellarg("$info") . " -i \"warning\" 2>/dev/null");
|
||||
$saved[$item][$name] = $last;
|
||||
}
|
||||
} else {
|
||||
if ($last) {
|
||||
[$date,$duration,$speed,$status,$error,$action,$size] = last_parity_log();
|
||||
$info = $status==0 ? "Duration: ".my_check($duration, $speed) : ($status==-4 ? "Canceled" : "Error code: $status");
|
||||
$level = ($status==0 && $var['sbSyncErrs']==0) ? "normal" : "warning";
|
||||
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $last")." -s ".escapeshellarg("Notice [$server] - $last finished ($error errors)")." -d ".escapeshellarg("$info")." -i \"$level\" 2>/dev/null");
|
||||
unset($saved[$item][$name]);
|
||||
}
|
||||
if ($last) {
|
||||
/* File for the latest parity check. */
|
||||
$resync = '/var/tmp/resync.ini';
|
||||
|
||||
if (file_exists($resync)) {
|
||||
list($duration, $speed, $status, $error, $action, $size) = last_parity_check();
|
||||
} else {
|
||||
list($date, $duration, $speed, $status, $error, $action, $size) = last_parity_log();
|
||||
}
|
||||
|
||||
$info = ($status == 0) ? "Duration: " . my_check($duration, $speed) : ($status == -4 ? "Canceled" : "Error code: $status");
|
||||
$level = ($status == 0 && $var['sbSyncErrs'] == 0) ? "normal" : "warning";
|
||||
exec("$notify -l '/Main' -e " . escapeshellarg("Unraid $last") . " -s " . escapeshellarg("Notice [$server] - $last finished ($error errors)") . " -d " . escapeshellarg("$info") . " -i \"$level\" 2>/dev/null");
|
||||
|
||||
unset($saved[$item][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
// check read-write status of USB flash drive
|
||||
|
||||
Reference in New Issue
Block a user