mirror of
https://github.com/unraid/webgui.git
synced 2026-04-21 17:29:28 -05:00
Merge pull request #98 from bergware/master
Disk read/write IO in background daemon
This commit is contained in:
@@ -36,7 +36,7 @@ function toggle_diskio(init) {
|
||||
}
|
||||
function array_status() {
|
||||
var diskio = $.cookie('diskio')===undefined ? 0 : 1;
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'array',diskio:diskio},function(data) {
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'array'},function(data) {
|
||||
if (data) {$('#array_devices').html(data); display_diskio();}
|
||||
<?if ($update && $var['fsState']=='Started'):?>
|
||||
<?if ($tabbed):?>
|
||||
|
||||
@@ -15,8 +15,7 @@ Title="Boot Device"
|
||||
?>
|
||||
<script>
|
||||
function boot_status() {
|
||||
var diskio = $.cookie('diskio')===undefined ? 0 : 1;
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'flash'<?if ($tabbed):?>,diskio:diskio<?endif?>},function(data) {
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'flash'},function(data) {
|
||||
if (data) {$('#boot_device').html(data); display_diskio();}
|
||||
<?if ($update && $var['fsState']=='Started'):?>
|
||||
<?if ($tabbed):?>
|
||||
|
||||
@@ -16,8 +16,7 @@ Cond="($var['fsState']=='Stopped' || $var['cacheSbNumDisks'])"
|
||||
?>
|
||||
<script>
|
||||
function cache_status() {
|
||||
var diskio = $.cookie('diskio')===undefined ? 0 : 1;
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'cache'<?if ($tabbed):?>,diskio:diskio<?endif?>},function(data) {
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'cache'},function(data) {
|
||||
if (data) {$('#cache_device').html(data); display_diskio();}
|
||||
<?if ($update && $var['fsState']=='Started'):?>
|
||||
<?if ($tabbed):?>
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="$name Settings"
|
||||
Png="devicesettings.png"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -17,11 +17,11 @@ Png="devicesettings.png"
|
||||
<?
|
||||
require_once "$docroot/webGui/include/Preselect.php";
|
||||
$disk = &$disks[$name];
|
||||
$events = isset($disk['smEvents']) ? explode('|',$disk['smEvents']) : (isset($var['smEvents']) ? explode('|',$var['smEvents']) : $numbers);
|
||||
$events = explode('|',$disk['smEvents'] ?? $var['smEvents'] ?? $numbers);
|
||||
|
||||
function displayTemp($temp) {
|
||||
global $display;
|
||||
return $display['unit']=='F' ? round(9/5*$temp)+32 : $temp;
|
||||
return $display['unit']=='F' ? round($temp*9/5)+32 : $temp;
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
@@ -45,6 +45,8 @@ function prepareDeviceInfo(form) {
|
||||
var custom = custom.length ? custom.split(',') : [];
|
||||
for (var i=0; i < custom.length; i++) events.push(custom[i].trim());
|
||||
form.smEvents.value = events.join('|');
|
||||
if (form.smEvents.value == '<?=implode('|',$events)?>') form.smEvents.value = '';
|
||||
if (form.smLevel.value == 1.00) form.smLevel.value = '';
|
||||
}
|
||||
function setGlue(form) {
|
||||
var data = [{glue:'' ,more:0},
|
||||
@@ -91,7 +93,6 @@ Partition format:
|
||||
|
||||
<?if ($disk['type']!="Parity"):?>
|
||||
<?if ($disk['type']=="Data" || $disk['name']=="cache"):?>
|
||||
|
||||
Comments:
|
||||
: <input type="text" name="diskComment.<?=$disk['idx'];?>" maxlength="256" value="<?=htmlspecialchars($disk['comment'])?>">
|
||||
|
||||
@@ -99,10 +100,8 @@ Comments:
|
||||
> Enter anything you like, up to 256 characters.
|
||||
|
||||
<?endif;?>
|
||||
|
||||
File system status:
|
||||
: <?=$disk['fsStatus']?><?if ($disk['fsError']) echo " - {$disk['fsError']}";?>
|
||||
|
||||
<?endif;?>
|
||||
<?if ($disk['type']=="Data" || ($disk['type']=="Cache" && $var['SYS_CACHE_SLOTS']==1)):?>
|
||||
<?if ($var['fsState']=="Stopped"):?>
|
||||
@@ -115,7 +114,6 @@ File system type:
|
||||
<?=mk_option($disk['fsType'], "reiserfs", "reiserfs")?>
|
||||
<?=mk_option($disk['fsType'], "xfs", "xfs")?>
|
||||
</select>
|
||||
|
||||
<?else:?>
|
||||
|
||||
File system type:
|
||||
@@ -125,13 +123,11 @@ File system type:
|
||||
<?=mk_option($disk['fsType'], "reiserfs", "reiserfs")?>
|
||||
<?=mk_option($disk['fsType'], "xfs", "xfs")?>
|
||||
</select> Array must be <span class="strong big">Stopped</span> to change
|
||||
|
||||
<?endif;?>
|
||||
<?elseif ($disk['type']=="Cache" && $var['SYS_CACHE_SLOTS']>1):?>
|
||||
|
||||
File system type:
|
||||
: <?=$disk['fsType'];?>
|
||||
|
||||
<?endif;?>
|
||||
|
||||
Spin down delay:
|
||||
@@ -185,10 +181,8 @@ Critical disk temperature threshold (°<?=$display['unit']?>):
|
||||
> A value of zero will disable the critical threshold (including notifications).
|
||||
|
||||
<?if (($var['spinupGroups']=="yes")&&($disk['type']!="Cache")):?>
|
||||
|
||||
Spinup group(s):
|
||||
: <input type="text" name="diskSpinupGroup.<?=$disk['idx'];?>" maxlength="256" value="<?=$disk['spinupGroup']?>">
|
||||
|
||||
<?endif;?>
|
||||
|
||||
|
||||
@@ -202,11 +196,10 @@ btrfs filesystem show:
|
||||
: <?echo "<pre>".shell_exec("/sbin/btrfs filesystem show {$disk['uuid']}")."</pre>";?>
|
||||
|
||||
<?if ($disk['fsStatus']=="Mounted"):?>
|
||||
|
||||
btrfs filesystem df:
|
||||
: <?echo "<pre>".shell_exec("/sbin/btrfs filesystem df /mnt/{$disk['name']}")."</pre>";?>
|
||||
|
||||
<?endif;?>
|
||||
|
||||
<?if ($var['cacheSbNumDisks']>1):?>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<?if ($disk['fsStatus']=="Mounted"):?>
|
||||
@@ -242,9 +235,6 @@ btrfs balance status:
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
|
||||
: <input type="submit" value="Balance" disabled>
|
||||
|
||||
> **Balance** is only available when the Device is Mounted.
|
||||
|
||||
<?endif;?>
|
||||
@@ -288,14 +278,12 @@ btrfs scrub status:
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
|
||||
: <input type="submit" value="Scrub" disabled>
|
||||
|
||||
> **Scrub** is only available when the Device is Mounted.
|
||||
|
||||
<?endif;?>
|
||||
</form>
|
||||
<?endif?>
|
||||
<?if ($disk['fsType']=="btrfs"):?>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<?if ($var['fsState']=="Started" && $var['startMode']=='Maintenance'):?>
|
||||
<?exec("$docroot/webGui/scripts/btrfs_check status /dev/{$disk['deviceSb']} {$disk['id']}", $check_status, $retval);?>
|
||||
@@ -338,13 +326,11 @@ btrfs check status:
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
|
||||
: <input type="submit" value="Check" disabled>
|
||||
|
||||
> **Check** is only available when array is Started in **Mainenance** mode.
|
||||
|
||||
<?endif;?>
|
||||
</form>
|
||||
<?endif;?>
|
||||
<?if ($disk['fsType']=="reiserfs"):?>
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame">
|
||||
<?if ($var['fsState']=="Started" && $var['startMode']=='Maintenance'):?>
|
||||
@@ -389,9 +375,6 @@ reiserfsck status:
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
|
||||
: <input type="submit" value="Check" disabled>
|
||||
|
||||
> **Check** is only available when array is Started in **Mainenance** mode.
|
||||
|
||||
<?endif;?>
|
||||
@@ -439,9 +422,6 @@ xfs_repair status:
|
||||
<?endif;?>
|
||||
<?else:?>
|
||||
|
||||
|
||||
: <input type="submit" value="Check" disabled>
|
||||
|
||||
> **Check** is only available when array is Started in **Mainenance** mode.
|
||||
|
||||
<?endif;?>
|
||||
@@ -486,7 +466,7 @@ SMART notification tolerance level:
|
||||
SMART controller type:
|
||||
: <select name="smType" size="1" onchange="setGlue(this.form)">
|
||||
<?=mk_option($disk['smType'], "-1", "Use default")?>
|
||||
<?=mk_option($disk['smType'], "", "Automatic")?>
|
||||
<?=mk_option($disk['smType'], " ", "Automatic")?>
|
||||
<?=mk_option($disk['smType'], "-d ata", "ATA")?>
|
||||
<?=mk_option($disk['smType'], "-d sat", "SATA")?>
|
||||
<?=mk_option($disk['smType'], "-d scsi", "SCSI")?>
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Disk Settings"
|
||||
Icon="disk-settings.png"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -16,7 +16,7 @@ Icon="disk-settings.png"
|
||||
?>
|
||||
<?
|
||||
require_once "$docroot/webGui/include/Preselect.php";
|
||||
$events = isset($var['smEvents']) ? explode('|', $var['smEvents']) : $numbers;
|
||||
$events = explode('|',$var['smEvents'] ?? $numbers);
|
||||
|
||||
function displayTemp($temp) {
|
||||
global $display;
|
||||
@@ -44,6 +44,8 @@ function prepareDiskSettings(form) {
|
||||
var custom = custom.length ? custom.split(',') : [];
|
||||
for (var i=0; i < custom.length; i++) events.push(custom[i].trim());
|
||||
form.smEvents.value = events.join('|');
|
||||
if (form.smEvents.value == '<?=$numbers?>') form.smEvents.value = '';
|
||||
if (form.smLevel.value == 1.00) form.smLevel.value = '';
|
||||
}
|
||||
function setIndex(form) {
|
||||
form.smIndex.value = form.smType.selectedIndex;
|
||||
@@ -216,6 +218,7 @@ Default critical disk temperature threshold (°<?=$display['unit']?>):
|
||||
<form markdown="1" name="smart_settings" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareDiskSettings(this)">
|
||||
<input type="hidden" name="#file" value="/boot/config/smart-all.cfg">
|
||||
<input type="hidden" name="#include" value="webGui/include/update.smart.php">
|
||||
<input type="hidden" name="#top" value="1">
|
||||
<input type="hidden" name="smEvents" value="">
|
||||
<input type="hidden" name="smIndex" value="0">
|
||||
Default SMART notification value:
|
||||
|
||||
@@ -131,7 +131,7 @@ function checkNetworkSettings(form,index) {
|
||||
netmask.prop('disabled',disabled);
|
||||
if (ipaddr.val()=='') netmask.append('<option value="none" selected="selected"></option>');
|
||||
if (i==0 && form.GATEWAY !== undefined) {form.GATEWAY.disabled = disabled; form.GATEWAY.required = !disabled;}
|
||||
if (dns) form.DHCP_KEEPRESOLV.disabled = !disabled;
|
||||
if (dns && i==0) form.DHCP_KEEPRESOLV.disabled = !disabled;
|
||||
});
|
||||
} else {
|
||||
var disabled = $(form).find('select[name="USE_DHCP:'+index+'"]').val()!='no';
|
||||
@@ -143,8 +143,8 @@ function checkNetworkSettings(form,index) {
|
||||
if (none.length) {netmask.val('255.255.255.0'); none.remove();}
|
||||
}
|
||||
if (index==0 && form.GATEWAY !== undefined) {form.GATEWAY.disabled = disabled; form.GATEWAY.required = !disabled;}
|
||||
if (dns) {
|
||||
form.DHCP_KEEPRESOLV.value = 'yes';
|
||||
if (dns && index==0) {
|
||||
form.DHCP_KEEPRESOLV.value = disabled ? 'no' : 'yes';
|
||||
form.DHCP_KEEPRESOLV.disabled = !disabled;
|
||||
checkDNSSettings(form);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ $tabX = '#tab'.($var['fsState']=='Stopped'||is_dir('/mnt/cache') ? '4' : '3');
|
||||
?>
|
||||
<script>
|
||||
function open_status() {
|
||||
var diskio = $.cookie('diskio')===undefined ? 0 : 1;
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=addslashes(htmlspecialchars($path))?>',device:'open'<?if ($tabbed):?>,diskio:diskio<?endif?>},function(data) {
|
||||
$.post('/webGui/include/DeviceList.php',{path:'<?=addslashes(htmlspecialchars($path))?>',device:'open'},function(data) {
|
||||
if (data) {$('#open_devices').html(data); display_diskio();}
|
||||
<?if ($update && $var['fsState']=='Started'):?>
|
||||
<?if ($tabbed):?>
|
||||
|
||||
@@ -111,7 +111,7 @@ function saveSMART() {
|
||||
});
|
||||
}
|
||||
function testUpdate(init) {
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'update',port:'<?=addslashes(htmlspecialchars($dev))?>',name:'<?=addslashes(htmlspecialchars($name))?>',type:'<?=addslashes(htmlspecialchars($type))?>'},function(data) {
|
||||
$.post('/webGui/include/SmartInfo.php',{cmd:'update',port:'<?=addslashes(htmlspecialchars($dev))?>',name:'<?=addslashes(htmlspecialchars($name))?>',type:'<?=addslashes(htmlspecialchars($type))?>',csrf:'<?=$var['csrf_token']?>'},function(data) {
|
||||
$('#test_result').html(data);
|
||||
if (data.indexOf('%')>=0) {
|
||||
if ($('#smart_selftest').length) {
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
/usr/local/emhttp/webGui/scripts/rc.diskload start >/dev/null
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
/usr/local/emhttp/webGui/scripts/rc.diskload stop >/dev/null
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -18,9 +18,8 @@ $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];
|
||||
$new = '/var/tmp/diskio';
|
||||
$old = '/var/tmp/lastio';
|
||||
$diskio= parse_ini_file('state/diskload.ini');
|
||||
$sum = ['count'=>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";
|
||||
@@ -113,29 +112,8 @@ function fs_info(&$disk) {
|
||||
echo "<td colspan='2'></td><td>{$disk['fsStatus']}</td><td></td>";
|
||||
echo "<td>".device_browse($disk)."</td>";
|
||||
}
|
||||
function disk_map(&$rows) {
|
||||
$map = [];
|
||||
foreach ($rows as $row) {
|
||||
$key = explode(' ',$row);
|
||||
$map[$key[0]] = $key[3].' '.$key[7];
|
||||
}
|
||||
$rows = $map;
|
||||
}
|
||||
function sectors(&$data,$i) {
|
||||
return $data ? explode(' ',$data)[$i] : 0;
|
||||
}
|
||||
function my_diskio($id,$i) {
|
||||
global $diskio, $lastio, $disks;
|
||||
if (empty($diskio) || empty($lastio)) return my_scale(0,$unit,1)." $unit/s";
|
||||
$time = max($diskio['time']-$lastio['time'],1);
|
||||
if ($id=='A' || $id=='P') {
|
||||
$type = $id=='A' ? '/Parity|Data/' : '/Cache/';
|
||||
$disksum = 0;
|
||||
foreach ($disks as $disk) if (preg_match($type,$disk['type'])) $disksum += sectors($diskio[$disk['device']],$i)-sectors($lastio[$disk['device']],$i);
|
||||
return my_scale($disksum*512/$time,$unit,1)." $unit/s";
|
||||
} else {
|
||||
return my_scale((sectors($diskio[$id],$i)-sectors($lastio[$id],$i))*512/$time,$unit,1)." $unit/s";
|
||||
}
|
||||
function my_diskio($data) {
|
||||
return my_scale($data,$unit,1)." $unit/s";
|
||||
}
|
||||
function array_offline(&$disk,$w) {
|
||||
$warning = $w ? '<span class="red-text"><em>ALL DATA ON THIS DISK WILL BE ERASED WHEN ARRAY IS STARTED</em></span>' : '';
|
||||
@@ -174,11 +152,14 @@ function array_offline(&$disk,$w) {
|
||||
echo "</tr>";
|
||||
}
|
||||
function array_online(&$disk) {
|
||||
global $sum;
|
||||
global $sum, $diskio;
|
||||
$data = 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'];
|
||||
@@ -208,8 +189,8 @@ function array_online(&$disk) {
|
||||
echo "<td>".device_info($disk)."</td>";
|
||||
echo "<td>".device_desc($disk)."</td>";
|
||||
echo "<td>".my_temp($disk['temp'])."</td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($disk['device'],0)."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($disk['device'],1)."</span><span class='number'>".my_number($disk['numWrites'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[1])."</span><span class='number'>".my_number($disk['numWrites'])."</span></td>";
|
||||
echo "<td>".my_number($disk['numErrors'])."</td>";
|
||||
fs_info($disk);
|
||||
break;
|
||||
@@ -223,14 +204,14 @@ function my_clock($time) {
|
||||
$mins = $time%60;
|
||||
return plus($days,'day',($hour|$mins)==0).plus($hour,'hour',$mins==0).plus($mins,'minute',true);
|
||||
}
|
||||
function read_disk(&$device, $item) {
|
||||
function read_disk($dev, $part) {
|
||||
global $var;
|
||||
switch ($item) {
|
||||
switch ($part) {
|
||||
case 'color':
|
||||
return exec("hdparm -C ".escapeshellarg("/dev/$device")."|grep -Po active") ? 'blue-on' : 'blue-blink';
|
||||
return exec("hdparm -C ".escapeshellarg("/dev/$dev")."|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 ".escapeshellarg("/dev/$device")." >".escapeshellarg($smart)." &");
|
||||
$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 ?: '*';
|
||||
}
|
||||
@@ -241,8 +222,8 @@ function show_totals($text) {
|
||||
echo "<td><img src='/webGui/images/sum.png' class='icon'>Total</td>";
|
||||
echo "<td>$text</td>";
|
||||
echo "<td>".($sum['count']>0 ? my_temp(round($sum['temp']/$sum['count'],1)) : '*')."</td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($text[0],0)."</span><span class='number'>".my_number($sum['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($text[0],1)."</span><span class='number'>".my_number($sum['numWrites'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($sum['ioReads'])."</span><span class='number'>".my_number($sum['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($sum['ioWrites'])."</span><span class='number'>".my_number($sum['numWrites'])."</span></td>";
|
||||
echo "<td>".my_number($sum['numErrors'])."</td>";
|
||||
echo "<td></td>";
|
||||
if (strstr($text,'Array') && ($var['startMode']=='Normal')) {
|
||||
@@ -295,21 +276,6 @@ function cache_slots() {
|
||||
$out .= "</select></form>";
|
||||
return $out;
|
||||
}
|
||||
$time = time();
|
||||
$last = @parse_ini_file($new);
|
||||
if ($_POST['diskio'] && $time-$last['time']>8) {
|
||||
@copy($new, $old);
|
||||
$lastio = $last;
|
||||
exec("grep -o '\(sd[a-z]*\|nvme[0-9]n1\) .*' /proc/diskstats",$diskio);
|
||||
disk_map($diskio);
|
||||
$diskio['time'] = $time;
|
||||
$keys = [];
|
||||
foreach ($diskio as $key => $data) $keys[] = "$key=$data";
|
||||
file_put_contents($new, implode("\n",$keys));
|
||||
} else {
|
||||
$lastio = @parse_ini_file($old);
|
||||
$diskio = $last;
|
||||
}
|
||||
switch ($_POST['device']) {
|
||||
case 'array':
|
||||
if ($var['fsState']=='Stopped') {
|
||||
@@ -325,13 +291,14 @@ case 'array':
|
||||
break;
|
||||
case 'flash':
|
||||
$disk = &$disks['flash'];
|
||||
$data = explode(' ',$diskio[$disk['device']]);
|
||||
$disk['fsUsed'] = $disk['fsSize']-$disk['fsFree'];
|
||||
echo "<tr>";
|
||||
echo "<td>".device_info($disk)."</td>";
|
||||
echo "<td>".device_desc($disk)."</td>";
|
||||
echo "<td>*</td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($disk['device'],0)."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($disk['device'],1)."</span><span class='number'>".my_number($disk['numWrites'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($disk['numReads'])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[1])."</span><span class='number'>".my_number($disk['numWrites'])."</span></td>";
|
||||
echo "<td>".my_number($disk['numErrors'])."</td>";
|
||||
fs_info($disk);
|
||||
echo "</tr>";
|
||||
@@ -346,19 +313,21 @@ case 'cache':
|
||||
}
|
||||
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');
|
||||
foreach ($devs as $disk) {
|
||||
$dev = $disk['device'];
|
||||
$data = explode(' ',$diskio[$dev]);
|
||||
$disk['name'] = $dev;
|
||||
$disk['type'] = 'New';
|
||||
$disk['color'] = read_disk($dev,'color');
|
||||
$disk['temp'] = read_disk($dev,'temp');
|
||||
echo "<tr>";
|
||||
echo "<td>".device_info($dev)."</td>";
|
||||
echo "<td>".device_desc($dev)."</td>";
|
||||
echo "<td>".my_temp($dev['temp'])."</td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($dev['device'],0)."</span><span class='number'>-</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($dev['device'],1)."</span><span class='number'>-</span></td>";
|
||||
if (file_exists("/tmp/preclear_stat_{$dev['device']}")) {
|
||||
$text = exec("cut -d'|' -f3 /tmp/preclear_stat_{$dev['device']}|sed 's:\^n:\<br\>:g'");
|
||||
echo "<td>".device_info($disk)."</td>";
|
||||
echo "<td>".device_desc($disk)."</td>";
|
||||
echo "<td>".my_temp($disk['temp'])."</td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[0])."</span><span class='number'>".my_number($data[2])."</span></td>";
|
||||
echo "<td><span class='diskio'>".my_diskio($data[1])."</span><span class='number'>".my_number($data[3])."</span></td>";
|
||||
if (file_exists("/tmp/preclear_stat_$dev")) {
|
||||
$text = exec("cut -d'|' -f3 /tmp/preclear_stat_$dev|sed 's:\^n:\<br\>:g'");
|
||||
if (strpos($text,'Total time')===false) $text = 'Preclear in progress... '.$text;
|
||||
echo "<td colspan='6' style='text-align:right'><em>$text</em></td>";
|
||||
} else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -20,8 +20,9 @@ foreach ($_POST as $field => $value) {
|
||||
$keys[$section][$key] = $value;
|
||||
}
|
||||
foreach ($keys as $section => $block) {
|
||||
$text .= "[$section]\n";
|
||||
foreach ($block as $key => $value) $text .= "$key=\"$value\"\n";
|
||||
$pairs = "";
|
||||
foreach ($block as $key => $value) if (strlen($value) && $value != -1) $pairs .= "$key=\"$value\"\n";
|
||||
if ($pairs) $text .= "[$section]\n".$pairs;
|
||||
}
|
||||
file_put_contents($_POST['#cfg'], $text);
|
||||
if ($text) file_put_contents($_POST['#cfg'], $text); else @unlink($_POST['#cfg']);
|
||||
?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -20,4 +20,5 @@ $preselect = [['code' => 5, 'set' => true, 'text' => 'Reallocated sectors coun
|
||||
['code' => 198, 'set' => true, 'text' => 'Uncorrectable sector count']];
|
||||
|
||||
for ($x = 0; $x < count($preselect); $x++) if ($preselect[$x]['set']) $numbers[] = $preselect[$x]['code'];
|
||||
$numbers = implode('|',$numbers);
|
||||
?>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?: @$_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?? '/usr/local/emhttp';
|
||||
|
||||
function normalize($text, $glue='_') {
|
||||
$words = explode($glue,$text);
|
||||
@@ -31,32 +31,40 @@ function spindownDelay($port) {
|
||||
if ($disk['device']==$port) { file_put_contents("/var/tmp/diskSpindownDelay.{$disk['idx']}", $disk['spindownDelay']); break; }
|
||||
}
|
||||
}
|
||||
function get(&$ref,$n,$d) {
|
||||
global $var;
|
||||
$val = $ref[$n] ?? -1; if ($val==-1) $val = $var[$n] ?? $d;
|
||||
return $val;
|
||||
}
|
||||
function exist(&$ref) {
|
||||
return isset($ref) && strlen($ref);
|
||||
}
|
||||
function append(&$ref, &$info) {
|
||||
if (isset($info)) $ref .= ($ref ? " " : "").$info;
|
||||
}
|
||||
$disks = []; $var = [];
|
||||
require_once "$docroot/webGui/include/CustomMerge.php";
|
||||
$name = isset($_POST['name']) ? $_POST['name'] : '';
|
||||
$port = isset($_POST['port']) ? $_POST['port'] : '';
|
||||
$name = $_POST['name'] ?? '';
|
||||
$port = $_POST['port'] ?? '';
|
||||
if ($name) {
|
||||
$disk = &$disks[$name];
|
||||
$type = isset($disk['smType']) ? $disk['smType'] : -1; if ($type==-1) $type = isset($var['smType']) ? $var['smType'] : '';
|
||||
$type = get($disk,'smType','');
|
||||
if ($type) {
|
||||
$ports = [];
|
||||
if (isset($disk['smDevice']) && strlen($disk['smDevice'])) $port = $disk['smDevice'];
|
||||
if (isset($disk['smPort1']) && strlen($disk['smPort1'])) $ports[] = $disk['smPort1'];
|
||||
if (isset($disk['smPort2']) && strlen($disk['smPort2'])) $ports[] = $disk['smPort2'];
|
||||
if (isset($disk['smPort3']) && strlen($disk['smPort3'])) $ports[] = $disk['smPort3'];
|
||||
if ($ports) {
|
||||
$glue = isset($disk['smGlue']) ? $disk['smGlue'] : ',';
|
||||
$type .= ','.implode($glue,$ports);
|
||||
}
|
||||
if (exist($disk['smDevice'])) $port = $disk['smDevice'];
|
||||
if (exist($disk['smPort1'])) $ports[] = $disk['smPort1'];
|
||||
if (exist($disk['smPort2'])) $ports[] = $disk['smPort2'];
|
||||
if (exist($disk['smPort3'])) $ports[] = $disk['smPort3'];
|
||||
if ($ports) $type .= ','.implode($disk['smGlue'] ?? ',',$ports);
|
||||
}
|
||||
}
|
||||
switch ($_POST['cmd']) {
|
||||
case "attributes":
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/webGui/include/Preselect.php";
|
||||
$select = isset($disk['smSelect']) ? $disk['smSelect'] : -1; if ($select==-1) $select = isset($var['smSelect']) ? $var['smSelect'] : 0;
|
||||
$level = isset($disk['smLevel']) ? $disk['smLevel'] : -1; if ($level==-1) $level = isset($var['smLevel']) ? $var['smLevel'] : 1;
|
||||
$events = isset($disk['smEvents']) ? explode('|',$disk['smEvents']) : (isset($var['smEvents']) ? explode('|',$var['smEvents']) : $numbers);
|
||||
$select = get($disk,'smSelect',0);
|
||||
$level = get($disk,'smLevel',1);
|
||||
$events = explode('|',$disk['smEvents'] ?? $var['smEvents'] ?? $numbers);
|
||||
$temps = [190,194];
|
||||
$unraid = parse_plugin_cfg('dynamix',true);
|
||||
$max = $unraid['display']['max'];
|
||||
@@ -87,9 +95,9 @@ case "capabilities":
|
||||
if (!$line) continue;
|
||||
$line = preg_replace('/^_/','__',preg_replace(['/__+/','/_ +_/'],'_',str_replace([chr(9),')','('],'_',$line)));
|
||||
$info = array_map('trim', explode('_', preg_replace('/_( +)_ /','__',$line), 3));
|
||||
if (isset($info[0])) $row[0] .= ($row[0] ? " " : "").$info[0];
|
||||
if (isset($info[1])) $row[1] .= ($row[1] ? " " : "").$info[1];
|
||||
if (isset($info[2])) $row[2] .= ($row[2] ? " " : "").$info[2];
|
||||
append($row[0],$info[0]);
|
||||
append($row[1],$info[1]);
|
||||
append($row[2],$info[2]);
|
||||
if (substr($row[2],-1)=='.') {
|
||||
echo "<tr><td>${row[0]}</td><td>${row[1]}</td><td>${row[2]}</td></tr>";
|
||||
$row = ['','',''];
|
||||
@@ -116,7 +124,7 @@ case "identify":
|
||||
if ($empty) echo "<tr><td colspan='2' style='text-align:center;padding-top:12px'>Can not read identification</td></tr>";
|
||||
break;
|
||||
case "save":
|
||||
exec("smartctl -a $type ".escapeshellarg("/dev/$port")." >".escapeshellarg("{$_SERVER['DOCUMENT_ROOT']}/{$_POST['file']}"));
|
||||
exec("smartctl -a $type ".escapeshellarg("/dev/$port")." >".escapeshellarg("$docroot/{$_POST['file']}"));
|
||||
break;
|
||||
case "delete":
|
||||
if (strpos(realpath("/var/tmp/{$_POST['file']}"), "/var/tmp/") === 0) {
|
||||
@@ -137,7 +145,7 @@ case "stop":
|
||||
case "update":
|
||||
if (!exec("hdparm -C ".escapeshellarg("/dev/$port")."|grep -Pom1 'active|unknown'")) {
|
||||
$cmd = $_POST['type']=='New' ? "cmd=/webGui/scripts/hd_parm&arg1=up&arg2=$name" : "cmdSpinup=$name";
|
||||
echo "<a href='/update.htm?$cmd&csrf_token={$var['csrf_token']}' class='info' target='progressFrame'><input type='button' value='Spin Up'></a><span class='orange-text'><span class='big'>Unavailable - disk must be spun up</span></span>";
|
||||
echo "<a href='/update.htm?$cmd&csrf_token={$_POST['csrf']}' class='info' target='progressFrame'><input type='button' value='Spin Up'></a><span class='big orange-text'>Unavailable - disk must be spun up</span>";
|
||||
break;
|
||||
}
|
||||
$progress = exec("smartctl -c $type ".escapeshellarg("/dev/$port")."|grep -Pom1 '\d+%'");
|
||||
@@ -151,14 +159,14 @@ case "update":
|
||||
break;
|
||||
}
|
||||
if (strpos($result, "Completed without error")!==false) {
|
||||
echo "<span class='green-text'><span class='big'>$result</span></span>";
|
||||
echo "<span class='big green-text'>$result</span>";
|
||||
break;
|
||||
}
|
||||
if (strpos($result, "Aborted")!==false or strpos($result, "Interrupted")!==false) {
|
||||
echo "<span class='orange-text'><span class='big'>$result</span></span>";
|
||||
echo "<span class='big orange-text'>$result</span>";
|
||||
break;
|
||||
}
|
||||
echo "<span class='red-text'><span class='big'>Errors occurred - Check SMART report</span></span>";
|
||||
echo "<span class='big red-text'>Errors occurred - Check SMART report</span>";
|
||||
break;
|
||||
case "selftest":
|
||||
echo shell_exec("smartctl -l selftest $type ".escapeshellarg("/dev/$port")."|awk 'NR>5'");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2016, Lime Technology
|
||||
* Copyright 2012-2016, Bergware International.
|
||||
/* Copyright 2005-2017, Lime Technology
|
||||
* Copyright 2012-2017, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,8 +11,16 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
if (isset($_POST['#default'])) {
|
||||
$text = '';
|
||||
if (!isset($_POST['#default'])) {
|
||||
$top = isset($_POST['#top']);
|
||||
foreach ($_POST as $key => $value) if ($key[0] != '#') {
|
||||
if (!strlen($value) || ($top && !$value) || $value == -1) {
|
||||
unset($_POST[$key]);
|
||||
if (isset($_POST['#section'])) unset($keys[$_POST['#section']][$key]); else unset($keys[$key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$text = "";
|
||||
if (isset($_POST['#section'])) {
|
||||
unset($keys[$_POST['#section']]);
|
||||
foreach ($keys as $section => $block) {
|
||||
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
ini=/var/local/emhttp/diskload.ini
|
||||
declare -a sector reads writes
|
||||
|
||||
# t = poll interval in seconds
|
||||
t=6
|
||||
# get sector size of each disk
|
||||
c=0
|
||||
for dev in $(awk '/(sd[a-z]*|nvme[0-9]n1) /{print $3}' /proc/diskstats); do
|
||||
sector[c]=$(cat /sys/block/$dev/queue/hw_sector_size 2>/dev/null)
|
||||
[[ -z ${sector[c]} ]] && sector[c]=512
|
||||
((c++))
|
||||
done
|
||||
|
||||
# start daemon
|
||||
while :; do
|
||||
stats=($(awk '/(sd[a-z]*|nvme[0-9]n1) /{print $3,$6,$10,$4,$8}' /proc/diskstats))
|
||||
c=0; s=${#stats[@]}
|
||||
echo -n >$ini
|
||||
for ((i=0;i<s;i+=5)); do
|
||||
reads[c]=$((stats[i+1]-reads[c]))
|
||||
writes[c]=$((stats[i+2]-writes[c]))
|
||||
echo ${stats[i]}=$((reads[c]*sector[c]/t)) $((writes[c]*sector[c]/t)) ${stats[i+3]} ${stats[i+4]} >>$ini
|
||||
reads[c]=${stats[i+1]}
|
||||
writes[c]=${stats[i+2]}
|
||||
((c++))
|
||||
done
|
||||
sleep $t
|
||||
done &
|
||||
@@ -58,7 +58,7 @@ if ($bridging = $ini['eth0']['BRIDGING']=='yes') {
|
||||
// ensure additional NICs in bridge are set free
|
||||
if ($run && $set=='eth0' && !$bonding) foreach ($br0 as $nic) {
|
||||
if (isset($old['SYSNICS'])) $nic = ifname($nic);
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_start")." >/dev/null");
|
||||
if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
script="diskload"
|
||||
daemon="/usr/local/emhttp/webGui/scripts/$script"
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
if [[ -z $(pgrep -f $daemon) ]]; then
|
||||
$daemon 1>/dev/null 2>&1
|
||||
echo "$script started"
|
||||
else
|
||||
echo "$script already running!"
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
if [[ -n $(pgrep -f $daemon) ]]; then
|
||||
pkill -f $daemon 1>/dev/null 2>&1
|
||||
timer=5
|
||||
until [[ -z $(pgrep -f $daemon) || $timer -eq 0 ]]; do
|
||||
((timer--))
|
||||
sleep 1
|
||||
done
|
||||
echo "$script stopped"
|
||||
else
|
||||
echo "$script not running!"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $(basename $0) start|stop"
|
||||
esac
|
||||
Reference in New Issue
Block a user