0, 'temp'=>0, 'fsSize'=>0, 'fsUsed'=>0, 'fsFree'=>0, 'ioReads'=>0, 'ioWrites'=>0, 'numReads'=>0, 'numWrites'=>0, 'numErrors'=>0]; extract(parse_plugin_cfg('dynamix',true)); require_once "$docroot/webGui/include/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.my_id($disk['id'])." - $size $unit ({$disk['device']})"; } function assignment(&$disk) { global $var, $devs; $out = "
"; $out .= ""; $out .= "
"; } function fs_info(&$disk) { global $display; if ($disk['fsStatus']=='-') { echo ""; return; } elseif ($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 my_diskio($data) { return my_scale($data,$unit,1)." $unit/s"; } 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, $diskio; $data = $diskio ? explode(' ',$diskio[$disk['device']]) : []; if (is_numeric($disk['temp'])) { $sum['count']++; $sum['temp'] += $disk['temp']; } $sum['ioReads'] += $data[0]; $sum['ioWrites'] += $data[1]; $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_diskio($data[0])."".my_number($disk['numReads']).""; echo "".my_diskio($data[1])."".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($dev, $part) { global $var; switch ($part) { case 'color': return exec("hdparm -C ".escapeshellarg("/dev/$dev")."|grep -Po active") ? 'blue-on' : 'blue-blink'; case 'temp': $smart = "/var/local/emhttp/smart/$dev"; if (!file_exists($smart) || (time()-filemtime($smart)>=$var['poll_attributes'])) exec("smartctl -n standby -A ".escapeshellarg("/dev/$dev")." >".escapeshellarg($smart)." &"); $temp = exec("awk '\$1==190||\$1==194{print \$10;exit}' $smart"); return $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_diskio($sum['ioReads'])."".my_number($sum['numReads']).""; echo "".my_diskio($sum['ioWrites'])."".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 = "
"; $out .= ""; $out .= ""; $out .= "
"; return $out; } function cache_slots() { global $var; $min = $var['cacheSbNumDisks']; $max = $var['MAX_CACHESZ']; $out = "
"; $out .= ""; $out .= ""; $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,$var['mdResyncAction']=='clear');} 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']; $data = $diskio ? explode(' ',$diskio[$disk['device']]) : []; $disk['fsUsed'] = $disk['fsSize']-$disk['fsFree']; echo ""; echo "".device_info($disk).""; echo "".device_desc($disk).""; echo "*"; echo "".my_diskio($data[0])."".my_number($disk['numReads']).""; echo "".my_diskio($data[1])."".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 $disk) { $dev = $disk['device']; $data = $diskio ? explode(' ',$diskio[$dev]) : []; $disk['name'] = $dev; $disk['type'] = 'New'; $disk['color'] = read_disk($dev,'color'); $disk['temp'] = read_disk($dev,'temp'); echo ""; echo "".device_info($disk).""; echo "".device_desc($disk).""; echo "".my_temp($disk['temp']).""; echo "".my_diskio($data[0])."".my_number($data[2]).""; echo "".my_diskio($data[1])."".my_number($data[3]).""; if (file_exists("/tmp/preclear_stat_$dev")) { $text = exec("cut -d'|' -f3 /tmp/preclear_stat_$dev|sed 's:\^n:\:g'"); if (strpos($text,'Total time')===false) $text = 'Preclear in progress... '.$text; echo "$text"; } else echo ""; echo ""; } break; case 'parity': $data = []; 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']*1024/$var['mdResyncDt'],$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"; $error = $var['sbSyncErrs']; $year = date('Y',$var['sbSynced2']); if ($status==0||file_exists($log)) file_put_contents($log,"$year $timestamp|$duration|$speed|$status|$error\n",FILE_APPEND); } break; } ?>