require_once 'Helpers.php';
$path = $_POST['path'];
$var = parse_ini_file('state/var.ini');
$devs = parse_ini_file('state/devs.ini',true);
$disks = parse_ini_file('state/disks.ini',true);
$sum = ['count'=>0, 'temp'=>0, 'fsSize'=>0, 'fsUsed'=>0, 'fsFree'=>0, 'numReads'=>0, 'numWrites'=>0, 'numErrors'=>0];
extract(parse_plugin_cfg('dynamix',true));
require_once 'CustomMerge.php';
function in_parity_log($log,$timestamp) {
if (file_exists($log)) {
$handle = fopen($log, 'r');
while (($line = fgets($handle)) !== false) {
if (strpos($line,$timestamp)!==false) break;
}
fclose($handle);
}
return !empty($line);
}
function device_info(&$disk) {
global $path, $var;
$name = $disk['name'];
$fancyname = $disk['type']=='New' ? $name : my_disk($name);
$type = $disk['type']=='Flash' || $disk['type']=='New' ? $disk['type'] : 'Device';
$action = strpos($disk['color'],'blink')===false ? 'down' : 'up';
if ($var['fsState']=='Started' && $type!='Flash') {
$cmd = $type=='New' ? "cmd=/webGui/scripts/hd_parm&arg1=$action&arg2=$name" : "cmdSpin$action=$name";
$ctrl = "";
} else
$ctrl = '';
switch ($disk['color']) {
case 'green-on': $help = 'Normal operation, device is active'; break;
case 'green-blink': $help = 'Device is in standby mode (spun-down)'; break;
case 'blue-on': $help = 'New device'; break;
case 'blue-blink': $help = 'New device, in standby mode (spun-down)'; break;
case 'yellow-on': $help = $disk['type']=='Parity' ? 'Parity is invalid' : 'Device contents emulated'; break;
case 'yellow-blink': $help = $disk['type']=='Parity' ? 'Parity is invalid, in standby mode (spun-down)' : 'Device contents emulated, in standby mode (spun-down)'; break;
case 'red-on': case 'red-blink': $help = $disk['type']=='Parity' ? 'Parity device is disabled' : 'Device is disabled, contents emulated'; break;
case 'red-off': $help = $disk['type']=='Parity' ? 'Parity device is missing' : 'Device is missing (disabled), contents emulated'; break;
case 'grey-off': $help = 'Device not present'; break;
}
$status = "$ctrl
$help";
$link = strpos($disk['status'], 'DISK_NP')===false ? "".$fancyname."" : $fancyname;
return $status.$link;
}
function device_browse(&$disk) {
global $path;
if ($disk['fsStatus']=='Mounted') {
$dir = $disk['name']=='flash' ? "/boot" : "/mnt/{$disk['name']}";
return "
";
}
}
function device_desc(&$disk) {
global $var;
$size = my_scale($disk['size']*1024,$unit);
$log = $var['fsState']=='Started' ? "" : "";
return "$log{$disk['id']} - $size $unit ({$disk['device']})";
}
function assignment(&$disk) {
global $var, $devs;
$out = "
";
}
function fs_info(&$disk) {
global $display;
if ($disk['fsStatus']=='-') {
echo " | ";
return;
} else if ($disk['fsStatus']=='Mounted') {
echo "{$disk['fsType']} | ";
echo "".my_scale($disk['fsSize']*1024,$unit)." $unit | ";
if ($display['text']%10==0) {
echo "".my_scale($disk['fsUsed']*1024,$unit)." $unit | ";
} else {
$used = $disk['fsSize'] ? 100-round(100*$disk['fsFree']/$disk['fsSize']) : 0;
echo "".my_scale($disk['fsUsed']*1024,$unit)." $unit | ";
}
if ($display['text']<10 ? $display['text']%10==0 : $display['text']%10!=0) {
echo "".my_scale($disk['fsFree']*1024,$unit)." $unit | ";
} else {
$free = $disk['fsSize'] ? round(100*$disk['fsFree']/$disk['fsSize']) : 0;
echo "".my_scale($disk['fsFree']*1024,$unit)." $unit | ";
}
} else
echo " | {$disk['fsStatus']} | | ";
echo "".device_browse($disk)." | ";
}
function array_offline(&$disk,$w) {
$warning = $w ? 'ALL DATA ON THIS DISK WILL BE ERASED WHEN ARRAY IS STARTED' : '';
echo "";
switch ($disk['status']) {
case 'DISK_NP':
case 'DISK_OK_NP':
case 'DISK_NP_DSBL':
echo "| ".device_info($disk)." | ";
echo "".assignment($disk)." | ";
echo " | ";
break;
case 'DISK_OK':
$warning = '';
case 'DISK_INVALID':
case 'DISK_DSBL':
case 'DISK_DSBL_NEW':
case 'DISK_NEW':
echo "".device_info($disk)." | ";
echo "".assignment($disk)." | ";
echo "".my_temp($disk['temp'])." | ";
echo "$warning | ";
break;
case 'DISK_NP_MISSING':
echo "".device_info($disk)."Missing | ";
echo "".assignment($disk)."{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit | ";
echo " | ";
break;
case 'DISK_WRONG':
echo "".device_info($disk)."Wrong | ";
echo "".assignment($disk)."{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit | ";
echo "".my_temp($disk['temp'])." | ";
echo "$warning | ";
break;
}
echo "
";
}
function array_online(&$disk) {
global $sum;
if (is_numeric($disk['temp'])) {
$sum['count']++;
$sum['temp'] += $disk['temp'];
}
$sum['numReads'] += $disk['numReads'];
$sum['numWrites'] += $disk['numWrites'];
$sum['numErrors'] += $disk['numErrors'];
if (isset($disk['fsFree'])) {
$disk['fsUsed'] = $disk['fsSize']-$disk['fsFree'];
$sum['fsSize'] += $disk['fsSize'];
$sum['fsUsed'] += $disk['fsUsed'];
$sum['fsFree'] += $disk['fsFree'];
}
echo "";
switch ($disk['status']) {
case 'DISK_NP':
// Suppress empty slots to keep device list short (make this configurable?)
// echo "| ".device_info($disk)." | ";
// echo "Not installed | ";
// echo " | ";
break;
case 'DISK_OK_NP':
case 'DISK_NP_DSBL':
echo "".device_info($disk)." | ";
echo "Not installed | ";
echo " | ";
fs_info($disk);
break;
case 'DISK_DSBL':
default:
echo "".device_info($disk)." | ";
echo "".device_desc($disk)." | ";
echo "".my_temp($disk['temp'])." | ";
echo "".my_number($disk['numReads'])." | ";
echo "".my_number($disk['numWrites'])." | ";
echo "".my_number($disk['numErrors'])." | ";
fs_info($disk);
break;
}
echo "
";
}
function my_clock($time) {
if (!$time) return 'less than a minute';
$days = floor($time/1440);
$hour = $time/60%24;
$mins = $time%60;
return plus($days,'day',($hour|$mins)==0).plus($hour,'hour',$mins==0).plus($mins,'minute',true);
}
function read_disk(&$device, $item) {
global $var;
switch ($item) {
case 'color':
return exec("hdparm -C /dev/$device|grep -Po active") ? 'blue-on' : 'blue-blink';
case 'temp':
$smart = "/var/local/emhttp/smart/$device";
if (!file_exists($smart) || (time()-filemtime($smart)>=$var['poll_attributes'])) exec("smartctl -n standby -A /dev/$device > $smart");
$temp = exec("awk '\$1==190||\$1==194{print \$10;exit}' $smart");
return $temp ? $temp : '*';
}
}
function show_totals($text) {
global $var, $display, $sum;
echo "";
echo " Total | ";
echo "$text | ";
echo "".($sum['count']>0 ? my_temp(round($sum['temp']/$sum['count'],1)) : '*')." | ";
echo "".my_number($sum['numReads'])." | ";
echo "".my_number($sum['numWrites'])." | ";
echo "".my_number($sum['numErrors'])." | ";
echo " | ";
if (strstr($text,'Array') && ($var['startMode']=='Normal')) {
echo "".my_scale($sum['fsSize']*1024,$unit)." $unit | ";
if ($display['text']%10==0) {
echo "".my_scale($sum['fsUsed']*1024,$unit)." $unit | ";
} else {
$used = $sum['fsSize'] ? 100-round(100*$sum['fsFree']/$sum['fsSize']) : 0;
echo "".my_scale($sum['fsUsed']*1024,$unit)." $unit | ";
}
if ($display['text']<10 ? $display['text']%10==0 : $display['text']%10!=0) {
echo "".my_scale($sum['fsFree']*1024,$unit)." $unit | ";
} else {
$free = $sum['fsSize'] ? round(100*$sum['fsFree']/$sum['fsSize']) : 0;
echo "".my_scale($sum['fsFree']*1024,$unit)." $unit | ";
}
echo " | ";
} else
echo " | ";
echo "
";
}
function array_slots() {
global $var;
$min = max($var['sbNumDisks'], 3);
$max = $var['MAX_ARRAYSZ'];
$out = "";
return $out;
}
function cache_slots() {
global $var;
$min = $var['cacheSbNumDisks'];
$max = $var['MAX_CACHESZ'];
$out = "";
return $out;
}
switch ($_POST['device']) {
case 'array':
if ($var['fsState']=='Stopped') {
foreach ($disks as $disk) {if ($disk['type']=='Parity') array_offline($disk,true);}
echo " |
";
foreach ($disks as $disk) {if ($disk['type']=='Data') array_offline($disk,false);}
echo " Slots: | ".array_slots()." | |
";
} else {
foreach ($disks as $disk) {if ($disk['type']=='Parity' && $disk['status']!='DISK_NP_DSBL') array_online($disk);}
foreach ($disks as $disk) {if ($disk['type']=='Data') array_online($disk);}
if ($display['total']) show_totals('Array of '.my_word($var['mdNumDisks']).' devices');
}
break;
case 'flash':
$disk = &$disks['flash'];
$disk['fsUsed'] = $disk['fsSize']-$disk['fsFree'];
echo "";
echo "| ".device_info($disk)." | ";
echo "".device_desc($disk)." | ";
echo "* | ";
echo "".my_number($disk['numReads'])." | ";
echo "".my_number($disk['numWrites'])." | ";
echo "".my_number($disk['numErrors'])." | ";
fs_info($disk);
echo "
";
break;
case 'cache':
if ($var['fsState']=='Stopped') {
foreach ($disks as $disk) {if ($disk['type']=='Cache') array_offline($disk,false);}
echo " Slots: | ".cache_slots()." | |
";
} else {
foreach ($disks as $disk) {if ($disk['type']=='Cache') array_online($disk);}
if ($display['total'] && $var['cacheSbNumDisks']>1) show_totals('Pool of '.my_word($var['cacheNumDevices']).' devices');
}
break;
case 'open':
foreach ($devs as $dev) {
$dev['name'] = $dev['device'];
$dev['type'] = 'New';
$dev['color'] = read_disk($dev['device'],'color');
$dev['temp'] = read_disk($dev['device'],'temp');
echo "";
echo "| ".device_info($dev)." | ";
echo "".device_desc($dev)." | ";
echo "".my_temp($dev['temp'])." | ";
if (file_exists("/tmp/preclear_stat_{$dev['device']}")) {
$text = exec("cut -d'|' -f3 /tmp/preclear_stat_{$dev['device']}|sed 's:\^n:\
:g'");
if (strpos($text,'Total time')===false) $text = 'Preclear in progress... '.$text;
echo "$text | ";
} else
echo " | ";
echo "
";
}
break;
case 'parity':
$data = array();
if ($var['mdResync']>0) {
$data[] = my_scale($var['mdResync']*1024,$unit)." $unit";
$data[] = my_clock(floor(($var['currTime']-$var['sbUpdated'])/60));
$data[] = my_scale($var['mdResyncPos']*1024,$unit)." $unit (".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),1,substr($display['number'],0,1),'')." %)";
$data[] = my_scale($var['mdResyncDb']/$var['mdResyncDt']*1024,$unit, 1)." $unit/sec";
$data[] = my_clock(round(((($var['mdResyncDt']*(($var['mdResync']-$var['mdResyncPos'])/($var['mdResyncDb']/100+1)))/100)/60),0));
$data[] = $var['sbSyncErrs'];
echo implode(';',$data);
} else {
if ($var['sbSynced']==0 || $var['sbSynced2']==0) break;
$log = '/boot/config/parity-checks.log';
$timestamp = str_replace(['.0','.'],[' ',' '],date('M.d H:i:s',$var['sbSynced2']));
if (in_parity_log($log,$timestamp)) break;
$duration = $var['sbSynced2'] - $var['sbSynced'];
$status = $var['sbSyncExit'];
$speed = ($status==0) ? my_scale($var['mdResyncSize']*1024/$duration,$unit,1)." $unit/s" : "Unavailable";
$year = date('Y',$var['sbSynced2']);
file_put_contents($log,"$year $timestamp|$duration|$speed|$status\n",FILE_APPEND);
}
break;
}
?>