diff --git a/plugins/dynamix/nchan/device_list b/plugins/dynamix/nchan/device_list new file mode 100755 index 000000000..fcb056cc2 --- /dev/null +++ b/plugins/dynamix/nchan/device_list @@ -0,0 +1,440 @@ +#!/usr/bin/php -q + +0, 'temp'=>0, 'fsSize'=>0, 'fsUsed'=>0, 'fsFree'=>0, 'ioReads'=>0, 'ioWrites'=>0, 'numReads'=>0, 'numWrites'=>0, 'numErrors'=>0]; +} +function model($id) { + return substr($id,0,strrpos($id,'_')); +} +function device_info(&$disk,$online) { + global $pools, $var, $crypto; + $name = $disk['name']; + $fancyname = compress(_(my_disk($name),3),16,5); + $type = $disk['type']=='Flash' ? $disk['type'] : 'Device'; + $action = strpos($disk['color'],'blink')===false ? 'down' : 'up'; + switch ($disk['color']) { + case 'green-on': $orb = 'circle'; $color = 'green'; $help = _('Normal operation, device is active'); break; + case 'green-blink': $orb = 'circle'; $color = 'grey'; $help = _('Device is in standby mode (spun-down)'); break; + case 'blue-on': $orb = 'square'; $color = 'blue'; $help = _('New device'); break; + case 'blue-blink': $orb = 'square'; $color = 'grey'; $help = _('New device, in standby mode (spun-down)'); break; + case 'yellow-on': $orb = 'warning'; $color = 'yellow'; $help = $disk['type']=='Parity' ? _('Parity is invalid') : _('Device contents emulated'); break; + case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $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': $orb = 'times'; $color = 'red'; $help = $disk['type']=='Parity' ? _('Parity device is disabled') : _('Device is disabled, contents emulated'); break; + case 'red-off': $orb = 'times'; $color = 'red'; $help = $disk['type']=='Parity' ? _('Parity device is missing') : _('Device is missing (disabled), contents emulated'); break; + case 'grey-off': $orb = 'square'; $color = 'grey'; $help = _('Device not present'); break; + } + $ctrl = ''; + if ($var['fsState']=='Started' && $type!='Flash' && strpos($disk['status'],'_NP')===false) { + $ctrl = " style='cursor:pointer' onclick=\"toggle_state('$type','$name','$action')\""; + $help .= "
"._("Click to spin $action device"); + } + $status = "$help"; + $link = ($disk['type']=='Parity' && strpos($disk['status'],'_NP')===false) || + ($disk['type']=='Data' && $disk['status']!='DISK_NP') || + ($disk['type']=='Cache' && $disk['status']!='DISK_NP') || + ($disk['name']=='flash') || in_array($disk['name'],$pools) || + $disk['type']=='New' ? "$fancyname" : $fancyname; + if ($crypto) switch ($disk['luksState']) { + case 0: + if (!vfs_luks($disk['fsType'])) + $luks = ""; + else + $luks = ""._('Device to be encrypted').""; + break; + case 1: + if ($online) { + $luks = ""._('Device encrypted and unlocked').""; + break; + } + /* fall thru */ + case 2: + $luks = ""._('Device encrypted').""; + break; + case 3: + $luks = ""._('Device locked: wrong encryption key').""; + break; + default: + $luks = ""._('Device locked: unknown error').""; + break; + } else $luks = ''; + return $status.$luks.$link; +} +function device_browse(&$disk) { + $dir = $disk['name']=='flash' ? "/boot" : "/mnt/{$disk['name']}"; + return ""; +} +function device_desc(&$disk) { + global $var; + $size = my_scale($disk['size'] ? $disk['size']*1024 : $disk['sectors']*$disk['sector_size'],$unit,-1); + switch ($disk['type']) { + case 'Flash' : $type = 'usb'; break; + case 'Parity': $type = $disk['rotational'] ? 'disk' : 'nvme'; break; + case 'Data' : + case 'Cache' : $type = $disk['rotational'] ? ($disk['luksState'] ? 'disk-encrypted' : 'disk') : 'nvme'; break; + default : $type = 'disk'; break; + } + $log = $var['fsState']=='Started' + ? ""._('Disk Log Information')."" + : ""; + return $log."".my_id($disk['id'])." - $size $unit ({$disk['device']})"; +} +function assignment(&$disk) { + global $var, $devs; + $out = "
"; + $out .= ""; + $out .= ""; + $out .= "
"; +} +function vfs_type($fs) { + return str_replace('luks:','',$fs); +} +function vfs_luks($fs) { + return ($fs != vfs_type($fs)); +} +function fs_info(&$disk) { + global $display; + $echo = []; + if (empty($disk['fsStatus'])) { + return ($disk['type']=='Cache') ? ""._('Device is part of a pool')."" : ""; + } elseif ($disk['fsStatus']=='Mounted') { + $echo[] = "".vfs_type($disk['fsType']).""; + $echo[] = "".my_scale(($disk['fsSize']??0)*1024,$unit,-1)." $unit"; + if ($display['text']%10==0) { + $echo[] = "".my_scale($disk['fsUsed']*1024,$unit)." $unit"; + } else { + $used = isset($disk['fsSize']) && $disk['fsSize']>0 ? 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 = isset($disk['fsSize']) && $disk['fsSize']>0 ? round(100*$disk['fsFree']/$disk['fsSize']) : 0; + $echo[] = "
".my_scale($disk['fsFree']*1024,$unit)." $unit
"; + } + $echo[] = "".device_browse($disk).""; + } else + $echo[] = "".vfs_type($disk['fsType']).""._($disk['fsStatus']); + return implode('',$echo); +} +function my_diskio($data) { + return my_scale($data,$unit,1)." $unit/s"; +} +function array_offline(&$disk,$pool='') { + global $var, $disks; + $echo = []; + if (strpos($var['mdState'],'ERROR:')===false) { + $text = ""._('All existing data on this device will be OVERWRITTEN when array is Started').""; + if ($disk['type']=='Cache') { + if (!empty($disks[$pool]['uuid']) && $disk['status']=='DISK_NEW') $warning = $text; + } else { + if ($var['mdState']=='NEW_ARRAY') { + if ($disk['type']=='Parity') $warning = $text; + } else if ($var['mdNumInvalid']<=1) { + if (in_array($disk['status'],['DISK_INVALID','DISK_DSBL_NEW','DISK_WRONG','DISK_NEW'])) $warning = $text; + } + } + } + $echo[] = ""; + switch ($disk['status']) { + case 'DISK_NP': + case 'DISK_NP_DSBL': + $echo[] = "".device_info($disk,false).""; + $echo[] = "".assignment($disk).""; + $echo[] = ""; + break; + case 'DISK_NP_MISSING': + $echo[] = "".device_info($disk,false)."
"._('Missing').""; + $echo[] = "".assignment($disk)."{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit"; + $echo[] = ""; + break; + case 'DISK_OK': + case 'DISK_DSBL': + case 'DISK_INVALID': + case 'DISK_DSBL_NEW': + case 'DISK_NEW': + $echo[] = "".device_info($disk,false).""; + $echo[] = "".assignment($disk).""; + $echo[] = "".my_temp($disk['temp']).""; + $echo[] = "$warning"; + break; + case 'DISK_WRONG': + $echo[] = "".device_info($disk,false)."
"._('Wrong').""; + $echo[] = "".assignment($disk)."{$disk['idSb']} - ".my_scale($disk['sizeSb']*1024,$unit)." $unit"; + $echo[] = "".my_temp($disk['temp']).""; + $echo[] = "$warning"; + break; + } + $echo[] = ""; + return implode('',$echo); +} +function array_online(&$disk) { + global $pools, $sum, $diskio; + $echo = []; + if ($disk['device']!='') { + $dev = $disk['device']; + $data = explode(' ',$diskio[$dev] ?? '0 0'); + $sum['ioReads'] += $data[0]; + $sum['ioWrites'] += $data[1]; + } + 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'])) { + $sum['fsSize'] += $disk['fsSize']; + $sum['fsUsed'] += $disk['fsUsed']; + $sum['fsFree'] += $disk['fsFree']; + } + $echo[] = ""; + switch ($disk['status']) { + case 'DISK_NP': + if (in_array($disk['name'],$pools)) { + $echo[] = "".device_info($disk,true).""; + $echo[] = ""._('Not installed').""; + $echo[] = ""; + $echo[] = fs_info($disk); + } + break; + case 'DISK_NP_DSBL': + $echo[] = "".device_info($disk,true).""; + $echo[] = ""._('Not installed').""; + $echo[] = ""; + $echo[] = fs_info($disk); + break; + case 'DISK_DSBL': + default: + $echo[] = "".device_info($disk,true).""; + $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']).""; + $echo[] = fs_info($disk); + break; + } + $echo[] = ""; + return implode('',$echo); +} +function show_totals($text,$array,$name) { + global $var, $display, $sum; + $echo = []; + $ctrl1 = "onclick=\"toggle_state('Device','$name','down')\""; + $ctrl2 = "onclick=\"toggle_state('Device','$name','up')\""; + $help1 = _('Spin Down').' '._(ucfirst(substr($name,0,-1))); + $help2 = _('Spin Up').' '._(ucfirst(substr($name,0,-1))); + $echo[] = ""; + $echo[] = "$help1$help2"; + $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 ($array && ($var['startMode']=='Normal')) { + $echo[] = "".my_scale($sum['fsSize']*1024,$unit,-1)." $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[] = ""; + return implode('',$echo); +} +function array_slots() { + global $var; + $min = max($var['sbNumDisks'], 3); + $max = $var['MAX_ARRAYSZ']; + $out = "
"; + $out .= ""; + $out .= ""; + $out .= "
"; + return $out; +} +function cache_slots($off,$pool,$min,$slots) { + global $var; + $off = $off && $min ? ' disabled' : ''; + $max = $var['MAX_CACHESZ']; + $out = "
"; + $out .= ""; + $out .= ""; + $out .= ""; + $out .= "
"; + return $out; +} + +while (true) { + $var = (array)parse_ini_file("$varroot/var.ini"); + $devs = (array)parse_ini_file("$varroot/devs.ini",true); + $disks = (array)parse_ini_file("$varroot/disks.ini",true); + $sec = (array)parse_ini_file("$varroot/sec.ini",true); + $diskio = @(array)parse_ini_file("$varroot/diskload.ini"); + extract(parse_plugin_cfg('dynamix',true)); + $crypto = false; + $pools = pools_filter($disks); + $echo = []; + + // sort unassigned devices on disk identification + if (count($devs)>1) array_multisort(array_column($devs,'sectors'),SORT_DESC,array_map('model',array_column($devs,'id')),SORT_NATURAL|SORT_FLAG_CASE,array_column($devs,'device'),$devs); + + // merge device custom settings + if (file_exists($smartALL)) $var = array_merge($var, parse_ini_file($smartALL)); + if (file_exists($smartONE)) { + $smarts = parse_ini_file($smartONE,true); + foreach ($smarts as $id => $smart) { + if (isset($disks)) { + foreach ($disks as $key => $disk) { + if ($disk['id'] == $id) $disks[$key] = array_merge($disks[$key], $smart); + } + } + if (isset($devs)) { + foreach ($devs as $key => $disk) { + if ($disk['id'] == $id) $devs[$key] = array_merge($devs[$key], $smart); + } + } + } + } + + $sum = initSum(); + $echo[0] = "array_devices\n"; + $parity = parity_filter($disks); + $data = data_filter($disks); + foreach ($data as $disk) $crypto |= $disk['luksState']!=0 || vfs_luks($disk['fsType']); + if ($var['fsState']=='Stopped') { + foreach ($parity as $disk) $echo[0] .= array_offline($disk); + $echo[0] .= ""; + foreach ($data as $disk) $echo[0] .= array_offline($disk); + $echo[0] .= ""._('Slots').":".array_slots().""; + } else { + foreach ($parity as $disk) if ($disk['status']!='DISK_NP_DSBL') $echo[0] .= array_online($disk); + foreach ($data as $disk) $echo[0] .= array_online($disk); + if ($display['total'] && $var['mdNumDisks']>1) $echo[0] .= show_totals(sprintf(_('Array of %s devices'),my_word($var['mdNumDisks'])),true,'array*'); + } + + $echo[1] = "boot_device\n"; + $disk = &$disks['flash']; + $data = explode(' ',$diskio[$disk['device']] ?? '0 0'); + $flash = &$sec['flash']; $share = ""; + if ($var['shareSMBEnabled']=='yes' && $flash['export']=='e' && $flash['security']=='public') + $share = ""._('Flash device is set as public share')."
"._('Please change share SMB security')."
"._('Click on **FLASH** above this message')."
"; + $echo[1] .= ""; + $echo[1] .= "".$share.device_info($disk,true).""; + $echo[1] .= "".device_desc($disk).""; + $echo[1] .= "*"; + $echo[1] .= "".my_diskio($data[0])."".my_number($disk['numReads']).""; + $echo[1] .= "".my_diskio($data[1])."".my_number($disk['numWrites']).""; + $echo[1] .= "".my_number($disk['numErrors']).""; + $echo[1] .= fs_info($disk); + $echo[1] .= ""; + + $sum = initSum(); + $cache = cache_filter($disks); $n = 2; + foreach ($pools as $pool) { + $echo[$n] = "pool_device".($n-2)."\n"; + $tmp = "/var/tmp/$pool.log.tmp"; + foreach ($cache as $disk) if (prefix($disk['name'])==$pool) $crypto |= $disk['luksState']!=0 || vfs_luks($disk['fsType']); + if ($var['fsState']=='Stopped') { + $log = @(array)parse_ini_file($tmp); + $off = false; + foreach ($cache as $disk) if (prefix($disk['name'])==$pool) { + $echo[$n] .= array_offline($disk,$pool); + if (isset($log[$disk['name']])) $off |= ($log[$disk['name']]!=$disk['id']); else $log[$disk['name']] = $disk['id']; + } + $data = []; foreach ($log as $key => $value) $data[] = "$key=\"$value\""; + file_put_contents($tmp,implode("\n",$data)); + $echo[$n] .= ""._('Slots').":".cache_slots($off,$pool,$cache[$pool]['devicesSb'],$cache[$pool]['slots']).""; + } else { + if ($cache[$pool]['devices']) { + foreach ($cache as $disk) if (prefix($disk['name'])==$pool) { + if (substr($cache[$pool]['fsStatus'],0,11)=='Unmountable' && empty($disk['fsStatus'])) $disk['fsStatus'] = $cache[$pool]['fsStatus']; + $echo[$n] .= array_online($disk); + } + if ($display['total'] && $cache[$pool]['devices']>1) $echo[$n] .= show_totals(sprintf(_('Pool of %s devices'),my_word($cache[$pool]['devices'])),false,"$pool*"); + $sum = initSum(); + } + @unlink($tmp); + } + $n++; + } + + $echo[$n] = "open_devices\n"; + foreach ($devs as $disk) { + $dev = $disk['device']; + $data = explode(' ',$diskio[$dev] ?? '0 0 0 0'); + $disk['type'] = 'New'; + $disk['color'] = $disk['spundown']=="0" ? 'blue-on' : 'blue-blink'; + $echo[$n] .= ""; + $echo[$n] .= "".device_info($disk,true).""; + $echo[$n] .= "".device_desc($disk).""; + $echo[$n] .= "".my_temp($disk['temp']).""; + $echo[$n] .= "".my_diskio($data[0])."".my_number($disk['numReads']).""; + $echo[$n] .= "".my_diskio($data[1])."".my_number($disk['numWrites']).""; + $echo[$n] .= "".my_number($disk['numErrors']).""; + 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[$n] .= "$text"; + } else + $echo[$n] .= ""; + $echo[$n] .= ""; + } + + publish('devices', implode("\0",$echo)); + sleep(1); +} +?>