Merge pull request #1490 from bergware/master

Fixes for ZFS subpools
This commit is contained in:
tom mortensen
2023-11-03 11:03:51 -07:00
committed by GitHub
62 changed files with 263 additions and 256 deletions

View File

@@ -3,8 +3,8 @@ Title="UPS Details"
Tag="battery-3"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
* Copyright 2015, Dan Landon.
*
* This program is free software; you can redistribute it and/or

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2018, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
* Copyright 2015, Dan Landon.
*
* This program is free software; you can redistribute it and/or

View File

@@ -5,7 +5,7 @@ Lock="true"
Cond="exec(\"grep -o '^DOCKER_ENABLED=.yes' /boot/config/docker.cfg 2>/dev/null\")"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
*

View File

@@ -232,16 +232,14 @@ _(Template Authoring Mode)_:
:docker_authoring_mode_help:
<?if ($bridge):?>
_(Docker custom network type)_:
: <select name="DOCKER_NETWORK_TYPE">
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'))?>
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'))?>
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'), $bridge?'':'disabled')?>
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'), $bridge?'':'selected')?>
</select>&nbsp;_(Please read the Help carefully)_. _(Misconfiguration can cause problems)_.
:docker_custom_network_type_help:
<?endif;?>
_(Host access to custom networks)_:
: <select name="DOCKER_ALLOW_ACCESS">
<?=mk_option(_var($dockercfg,'DOCKER_ALLOW_ACCESS'), '', _('Disabled'))?>
@@ -440,13 +438,11 @@ _(Docker LOG rotation)_:
:docker_log_rotation_active_help:
<?if ($bridge):?>
_(Docker custom network type)_:
: <?=_var($dockercfg,'DOCKER_NETWORK_TYPE')=='1' ? _('ipvlan') : _('macvlan')?>
: <?=_var($dockercfg,'DOCKER_NETWORK_TYPE')!='1' || !$bridge ? _('macvlan') : _('ipvlan')?>
:docker_custom_network_type_help:
<?endif;?>
_(Host access to custom networks)_:
: <?=_var($dockercfg,'DOCKER_ALLOW_ACCESS')=='yes' ? _('Enabled') : _('Disabled')?>

View File

@@ -3,8 +3,8 @@ Title="Install Plugin"
Tag="download"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="puzzle-piece"
Cond="glob('/boot/config/plugins-error/*.plg')"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="puzzle-piece"
Cond="glob('/boot/config/plugins-stale/*.plg')"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
#!/usr/bin/php -q
<?PHP
// Copyright 2005-2022, Lime Technology
// Copyright 2005-2023, Lime Technology
// License: GPLv2 only
//
// Program updates made by Bergware International (April 2020)

View File

@@ -15,18 +15,21 @@ Tag="database"
*/
?>
<script>
String.prototype.no_tilde = function(){return this.replace('<?=$_tilde_?>','<?=$_proxy_?>');}
String.prototype.master = function(){return this.split('<?=$_tilde_?>')[0];}
function toggle_state(device,name,action) {
var button = null;
if (name) {
var group = name.replace(/(\d+|\*)$/,'');
if (name.slice(-1)!='*') {
$('#dev-'+name).removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
$('#dev-'+name.no_tilde()).removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
} else {
if (group=='array') {
$('[id^="dev-parity"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
$('[id^="dev-disk"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
} else {
$('[id^="dev-'+group+'"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
$('[id^="dev-'+group.master()+'"]').removeClass('fa-circle fa-square fa-warning fa-times').addClass('fa-refresh fa-spin');
}
}
} else if (device!='Clear') {
@@ -34,7 +37,7 @@ function toggle_state(device,name,action) {
button = '[id^=button-]';
}
devices.stop();
$.post('/webGui/include/ToggleState.php',{device:device,name:name,action:action,state:'<?=$var['mdState']?>',csrf:'<?=$var['csrf_token']?>'},function(){setTimeout(function(){devices.start();},1000);if (button) $(button).prop('disabled',false);});
$.post('/webGui/include/ToggleState.php',{device:device,name:name,action:action},function(){setTimeout(function(){devices.start();},1000);if (button) $(button).prop('disabled',false);});
}
function display_diskio() {
if ($.cookie('diskio')===undefined) {

View File

@@ -320,9 +320,9 @@ devices.on('message', function(msg,meta) {
// stop updating when array is stopped
if (stopped==1) {
<?if (_var($var,'fsState')=='Started'):?>
setTimeout(refresh,0);
setTimeout(refresh);
<?else:?>
if (!timers.stopped) timers.stopped = setTimeout(function(){devices.stop(); arraymonitor.start();},1000);
if (!timers.stopped) timers.stopped = setTimeout(function(){devices.stop(); arraymonitor.start();},1500);
<?endif;?>
}
break;

View File

@@ -3,8 +3,8 @@ Title="CPU Isolation"
Tag="icon-cpu"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -3,8 +3,8 @@ Title="CPU Pinning Docker"
Tag="icon-cpu"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -22,11 +22,6 @@ function makeList($list) {
function sharename($share) {
return basename($share,'.cfg');
}
function isSubpool($name) {
global $subpools;
$subpool = my_explode('~',$name)[1];
return in_array($subpool,$subpools) ? $subpool : false;
}
?>
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
@@ -120,7 +115,7 @@ function addSubpoolPopup(poolname,currentsubpools) {
buttons: {
"_(Add)_": function() {
subpool=$(this).find('select[name="subpool"]').val();
$(this).find('input[name="poolName"]').val(poolname + "~" + subpool);
$(this).find('input[name="poolName"]').val(poolname + '<?=$_tilde_?>' + subpool);
$(this).find('form').submit();
$(this).dialog('close');
},
@@ -141,9 +136,7 @@ $('#tab2').bind({click:function() {$('i.toggle').show('slow');}});
<?foreach ($pools as $pool):?>
<?if (isset($disks[$pool]['devices']) or _var($var,'fsState')=="Stopped"):?>
<table class="disk_status wide<?=$i?' divider':''?>">
<?if (isSubpool($pool)):?>
<thead></thead>
<?else:?>
<?if (!isSubpool($pool)):?>
<thead><tr><td>_(Device)_</td><td>_(Identification)_</td><td>_(Temp)_.</td><td>_(Reads)_</td><td>_(Writes)_</td><td>_(Errors)_</td><td>_(FS)_</td><td>_(Size)_</td><td>_(Used)_</td><td>_(Free)_</td></tr></thead>
<?endif;?>
<tbody id="pool_device<?=$i++?>">

View File

@@ -4,8 +4,8 @@ Icon="icon-confirmations"
Tag="check-square"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -570,7 +570,7 @@ if (!$group) {
<?$i=0?>
<?foreach ($pools as $pool):?>
<tbody id='pool_list<?=$i?>' title="_(<?=ucfirst($pool)?> Information)_">
<tr><td><i class='icon-disk f32'></i><div class='section'><?=ucfirst($pool)?><?if (!$started):?> (_(stopped)_)<?endif;?><br>
<tr><td><i class='icon-disk f32'></i><div class='section'><?=ucfirst(str_replace($_tilde_," $_arrow_ ",$pool))?><?if (!$started):?> (_(stopped)_)<?endif;?><br>
<span><?if ($started):?><?=sprintf(_("%s used of %s (%s %%)"),my_scale($cache_used[$pool]*1024,$unit)." $unit",my_scale($cache_size[$pool]*1024,$unit,-1,-1)." $unit",$cache_rate[$pool])?><?endif;?></span><br></div>
<a href='/Dashboard/Settings/Device?name=<?=$pool?>' title="_(Go to disk settings)_"><i class='fa fa-fw fa-cog control'></i></a>
</td></tr>

View File

@@ -79,11 +79,6 @@ function maintenance_mode() {
global $var;
return _var($var,'fsState')=="Started" && _var($var,'startMode')=="Maintenance" && _var($disk,'luksState',0)<=1;
}
function isSubpool($name) {
global $subpools;
$subpool = my_explode('~',$name)[1];
return in_array($subpool,$subpools) ? $subpool : false;
}
function isPool($name) {
global $pools;
return in_array($name,$pools);
@@ -542,7 +537,7 @@ _(Name)_:
<?else:?>
_(Name)_:
: <?=_(my_disk($name),3)?>
: <?=str_replace($_tilde_," $_arrow_ ",_(my_disk($name),3))?>
<?endif;?>
<?if (diskStatus('_NP')):?>
@@ -596,7 +591,7 @@ _(Spin down delay)_:
_(File system status)_:
: <?=_(_var($disk,'fsStatus'))?>&nbsp;
<?$disabled = (_var($var,'fsState')=="Stopped" && _var($disk,'uuid')) || (_var($var,'fsState')=="Started" && _var($disk,'fsStatus')=='Mounted') ? "disabled" : ""?>
<?$disabled = (_var($var,'fsState')=="Stopped" && !empty(_var($disk,'uuid'))) || (_var($var,'fsState')=="Started" && _var($disk,'fsStatus')=='Mounted') ? "disabled" : ""?>
<?if (diskType('Data') || (!isSubpool($name) && _var($disk,'slots',0)==1)):?>
_(File system type)_:
: <select id="diskFsType" name="diskFsType.<?=_var($disk,'idx',0)?>" onchange="changeFsType()" <?=$disabled?>>
@@ -727,19 +722,13 @@ _(Critical disk utilization threshold)_ (%):
: <input type="submit" name="changeDisk" value="_(Apply)_" disabled><input type="button" id="doneButton" value="_(Done)_" onclick="done()">
<?$erasable=false?>
<?if (diskType('Parity','Data')):?>
<?if (_var($var,'fsState')=="Stopped" && diskStatus('_NEW')):?>
<?$erasable=true?>
<?endif;?>
<?if (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal" && diskType('Data')):?>
<?$erasable=true?>
<?endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<?if (_var($var,'fsState')=="Stopped" && diskStatus('_NEW')): $erasable=true; endif;?>
<?if (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal" && diskType('Data')): $erasable=true; endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<?endif;?>
<?if (isPool($name)):?>
<?if (_var($var,'fsState')=="Stopped" || (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal")):?>
<?$erasable=true?>
<?endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<?if (isPool($name) && strpos($name,$_tilde_)===false):?>
<?if (_var($var,'fsState')=="Stopped" || (_var($var,'fsState')=="Started" && _var($var,'startMode')!="Normal")): $erasable=true; endif;?>
<input type="button" id="eraseButton" value="_(Erase)_" onclick="eraseDisk('<?=$name?>')"<?=$erasable?'':' disabled'?>>
<?endif;?>
<?if (_var($var,'fsState')=="Stopped" && isPool($name)):?>
<?$empty = _var($disk,'devices',0)==0?>

View File

@@ -4,8 +4,8 @@ Icon="icon-ftp"
Tag="globe"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020 Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -5,8 +5,8 @@ Tag="icon-u-chat"
Code="e93e"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -3,8 +3,8 @@ Title="Flash Device Settings"
Tag="usb"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-profile"
Tag="wrench"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-u-display"
Code="e930"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-language"
Tag="icon-language"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-u-log"
Code="e936"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -5,8 +5,8 @@ Code="e937"
Cond="$_SERVER['HTTP_HOST']!='localhost'"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -3,8 +3,8 @@ Title="Mover Settings"
Tag="calendar-check-o"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-linux"
Tag="linux"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="unlink"
Cond="(count($devs)>0)"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="list-ul"
Cond="($var['shareSMBEnabled']=='ads')"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="sitemap"
Cond="($var['shareSMBEnabled']=='yes')"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -3,8 +3,8 @@ Title="SMB Settings"
Tag="windows"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Tag="linux"
Cond="(($var['shareNFSEnabled']!='no') && (isset($name)?array_key_exists($name,$sec_nfs):0))"
---
<?PHP
/* Copyright 2005-2022, Lime Technology
* Copyright 2012-2022, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -4,8 +4,8 @@ Icon="icon-u-terminal"
Code="e93f"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,17 +11,24 @@
*/
?>
<?
$ram = "/var/local/emhttp/monitor.ini";
$rom = "/boot/config/plugins/dynamix/monitor.ini";
$saved = parse_ini_file($ram,true);
$saved["smart"]["{$_POST['disk']}.ack"] = "true";
$ram = "/var/local/emhttp/monitor.ini";
$rom = "/boot/config/plugins/dynamix/monitor.ini";
$disk = $_POST['disk'] ?? '';
$text = "";
foreach ($saved as $item => $block) {
if ($block) $text .= "[$item]\n";
foreach ($block as $key => $value) $text .= "$key=\"$value\"\n";
if ($disk) {
$text = "";
$saved = parse_ini_file($ram,true);
$saved["smart"]["$disk.ack"] = "true";
foreach ($saved as $item => $block) {
if ($block) $text .= "[$item]\n";
foreach ($block as $key => $value) $text .= "$key=\"$value\"\n";
}
file_put_contents($ram, $text);
file_put_contents($rom, $text);
echo "200 OK";
} else {
echo "404 ERROR";
}
file_put_contents($ram, $text);
file_put_contents($rom, $text);
echo "200 OK";
?>
?>

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -63,9 +63,6 @@ function my_disks($disk) {
function my_hyperlink($text, $link) {
return str_replace(['[',']'],["<a href=\"$link\">","</a>"],$text);
}
function prefix($key) {
return preg_replace('/\d+$/','',$key);
}
function parity_only($disk) {
return _var($disk,'type')=='Parity';
}

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -274,8 +274,8 @@ _(Search pattern)_:
<!--!
<style>div#dfm_editor{position:absolute;top:0;bottom:0;left:0;right:0}</style>
<div id="dfm_editor"></div>
<script src="<?autov('/plugins/dynamix.file.manager/javascript/ace/ace.js')?>"></script>
<script src="<?autov('/plugins/dynamix.file.manager/javascript/ace/ext-modelist.js')?>"></script>
<script src="<?autov('/webGui/javascript/ace/ace.js')?>"></script>
<script src="<?autov('/webGui/javascript/ace/ext-modelist.js')?>"></script>
<script>
function getMode(file){
var modelist = require('ace/ext/modelist');
@@ -291,7 +291,7 @@ editor.setOptions({
theme:'ace/theme/<?if (in_array($theme,['black','gray'])):?>tomorrow_night<?else:?>tomorrow<?endif;?>'
});
timers.editor = setTimeout(function(){$('div.spinner.fixed').show();},500);
$.post('/plugins/dynamix.file.manager/include/Control.php',{mode:'edit',file:encodeURIComponent(source)},function(data){
$.post('/webGui/include/Control.php',{mode:'edit',file:encodeURIComponent(source)},function(data){
clearTimeout(timers.editor);
$('div.spinner.fixed').hide();
editor.session.setValue(data);
@@ -303,7 +303,7 @@ $.post('/plugins/dynamix.file.manager/include/Control.php',{mode:'edit',file:enc
<div id="dfm_templateViewFile">
<!--!
<img id="dfm_viewer" href="{$0}">
<script src="<?autov('/plugins/dynamix.file.manager/javascript/EZView.js')?>"></script>
<script src="<?autov('/webGui/javascript/EZView.js')?>"></script>
<script>
$('#dfm_viewer').EZView();
$('#dfm_viewer').click();
@@ -316,7 +316,7 @@ $('#dfm_viewer').click();
<style>div#dfm_jobs{position:absolute;top:0;bottom:0;left:0;right:0;line-height:3rem}</style>
<div id="dfm_jobs"></div>
<script>
$.post('/plugins/dynamix.file.manager/include/Control.php',{mode:'jobs'},function(jobs){
$.post('/webGui/include/Control.php',{mode:'jobs'},function(jobs){
$('#dfm_jobs').html(jobs);
});
</script>

View File

@@ -17,37 +17,26 @@ require_once "$docroot/webGui/include/Wrappers.php";
$device = $_POST['device']??'';
$name = $_POST['name']??'';
$action = $_POST['action']??'';
$state = $_POST['state']??'';
$csrf = $_POST['csrf']??'';
function prefix($key) {
return preg_replace('/\d+$/','',$key);
function emcmd($cmd) {
exec("emcmd $cmd");
}
function emhttpd($cmd) {
global $state, $csrf;
$ch = curl_init("http://127.0.0.1/update");
$options = [CURLOPT_UNIX_SOCKET_PATH => '/var/run/emhttpd.socket', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => "$cmd&startState=$state&csrf_token=$csrf"];
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
}
switch ($device) {
case 'New':
emhttpd("cmdSpin{$action}={$name}");
emcmd("cmdSpin{$action}={$name}");
break;
case 'Clear':
emhttpd("clearStatistics=true");
emcmd("clearStatistics=true");
break;
default:
if (!$name) {
// spin up/down all devices
emhttpd("cmdSpin{$device}All=true");
emcmd("cmdSpin{$device}All=true");
break;
}
if (substr($name,-1) != '*') {
// spin up/down single device
emhttpd("cmdSpin{$action}={$name}");
emcmd("cmdSpin{$action}={$name}");
break;
}
// spin up/down group of devices
@@ -57,7 +46,7 @@ default:
foreach ($disks as $disk) {
if (_var($disk,'status') != 'DISK_OK') continue;
$array = ($name=='array' && in_array(_var($disk,'type'),['Parity','Data']));
if ($array || prefix(_var($disk,'name'))==$name) emhttpd("cmdSpin{$action}="._var($disk,'name'));
if ($array || explode($_tilde_,prefix(_var($disk,'name')))[0]==$name) emcmd("cmdSpin{$action}="._var($disk,'name'));
}
break;
}

View File

@@ -13,6 +13,14 @@
<?
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
// pool name ending in any of these => zfs subpool
$subpools = ['special','logs','dedup','cache','spares'];
// ZFS subpool name separator and replacement
$_tilde_ = '~';
$_proxy_ = '__';
$_arrow_ = '&#187;';
// Wrapper functions
function parse_plugin_cfg($plugin, $sections=false, $scanner=INI_SCANNER_NORMAL) {
global $docroot;
@@ -86,6 +94,18 @@ function ipaddr($ethX='eth0', $prot=4) {
return _var($$ethX,'IPADDR:0');
}
}
function no_tilde($name) {
global $_tilde_,$_proxy_;
return str_replace($_tilde_,$_proxy_,$name);
}
function prefix($key) {
return preg_replace('/\d+$/','',$key);
}
function isSubpool($name) {
global $subpools, $_tilde_;
$subpool = my_explode($_tilde_,$name)[1];
return in_array($subpool,$subpools) ? $subpool : false;
}
// convert strftime to date format
function my_date($fmt, $time) {
$legacy = ['%c' => 'D j M Y h:i A','%A' => 'l','%Y' => 'Y','%B' => 'F','%e' => 'j','%d' => 'd','%m' => 'm','%I' => 'h','%H' => 'H','%M' => 'i','%S' => 's','%p' => 'a','%R' => 'H:i', '%F' => 'Y-m-d', '%T' => 'H:i:s'];

View File

@@ -1,5 +1,5 @@
<?PHP
/* Copyright 2005-2021, Lime Technology
/* Copyright 2005-2023, Lime Technology
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
@@ -10,21 +10,20 @@
*/
?>
<?
function curl_socket($socket, $url, $postdata=NULL)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_UNIX_SOCKET_PATH, $socket);
if ($postdata !== NULL) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
function curl_socket($socket, $url, $message) {
$com = curl_init($url);
curl_setopt_array($com,[
CURLOPT_UNIX_SOCKET_PATH => $socket,
CURLOPT_POST=> 1,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => true
]);
$reply = curl_exec($com);
curl_close($com);
return $reply;
}
function publish($endpoint, $message, $len=1)
{
return curl_socket("/var/run/nginx.socket", "http://localhost/pub/$endpoint?buffer_length=$len", $message);
function publish($endpoint, $message, $len=1) {
return curl_socket("/var/run/nginx.socket", "http://localhost/pub/$endpoint?buffer_length=$len", $message);
}
?>

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -1,6 +1,6 @@
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -30,22 +30,14 @@ require_once "$docroot/webGui/include/Translations.php";
// remember current language
$locale_init = $locale;
// pool name ending in any of these => zfs subpool
$subpools = ['special','logs','dedup','cache','spares'];
function initSum() {
return ['count'=>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 isSubpool($name) {
global $subpools;
$subpool = my_explode('~',$name)[1];
return in_array($subpool,$subpools) ? $subpool : false;
}
function device_info(&$disk,$online) {
global $pools, $var, $crypto;
global $pools, $var, $crypto, $_tilde_, $_arrow_;
if (!$online || _var($disk,'fsStatus')!='Mounted' || (in_array(_var($disk,'type'),['Parity','Cache']) && (!in_array(_var($disk,'name'),$pools) || isSubpool(_var($disk,'name'))))) {
$view = "<a class='view'></a>";
} else {
@@ -53,19 +45,23 @@ function device_info(&$disk,$online) {
$view = "<a class='view' href=\"/Main/Browse?dir=".htmlspecialchars($dir)."\"><i class=\"icon-u-tab\" title=\""._('Browse')." $dir\"></i></a>";
}
$name = _var($disk,'name');
$fancyname = compress(_(my_disk($name),3),16,5);
$named = no_tilde($name);
$extra = my_explode($_tilde_,$name)[1];
$fancyname = compress($extra ? "$_arrow_ "._(my_disk($extra),3) : _(my_disk($name),3),16,5);
$type = _var($disk,'type')=='Flash' ? $disk['type'] : 'Device';
$pool = _var($disk,'type')=='Cache';
$parity = _var($disk,'type')=='Parity';
$action = strpos(_var($disk,'color'),'blink')===false ? 'down' : 'up';
switch (_var($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 = _var($disk,'type')=='Parity' ? _('Parity is invalid') : _('Device contents emulated'); break;
case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $help = _var($disk,'type')=='Parity' ? _('Parity is invalid, in standby mode (spun-down)') : _('Device contents emulated, in standby mode (spun-down)'); break;
case 'yellow-on': $orb = 'warning'; $color = 'yellow'; $help = $pool ? _('Device contents invalid') : ($parity ? _('Parity is invalid') : _('Device contents emulated')); break;
case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $help = $pool ? _('Device contents invalid, in standby mode (spun-down)') : ($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 = _var($disk,'type')=='Parity' ? _('Parity device is disabled') : _('Device is disabled, contents emulated'); break;
case 'red-off': $orb = 'times'; $color = 'red'; $help = _var($disk,'type')=='Parity' ? _('Parity device is missing') : _('Device is missing (disabled), contents emulated'); break;
case 'red-blink': $orb = 'times'; $color = 'red'; $help = $pool ? _('Device is disabled') : ($parity ? _('Parity device is disabled') : _('Device is disabled, contents emulated')); break;
case 'red-off': $orb = 'times'; $color = 'red'; $help = $pool ? _('Device is missing (disabled)') : ($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 = '';
@@ -74,7 +70,7 @@ function device_info(&$disk,$online) {
$ctrl = " style='cursor:pointer' onclick=\"toggle_state('$type','$name','$action')\"";
$help .= "<br>"._("Click to spin $action device");
}
$status = "<a class='info'><i ".($ctrl?"id='dev-$name' ":"")."class='fa fa-$orb orb $color-orb'$ctrl></i><span>$help</span></a>";
$status = "<a class='info'><i ".($ctrl?"id='dev-$named' ":"")."class='fa fa-$orb orb $color-orb'$ctrl></i><span>$help</span></a>";
$link = (_var($disk,'type')=='Parity' && strpos($disk_status,'_NP')===false) ||
(_var($disk,'type')=='Data' && $disk_status!='DISK_NP') ||
(_var($disk,'type')=='Cache' && $disk_status!='DISK_NP') ||
@@ -126,7 +122,7 @@ function assignment(&$disk) {
$echo[] = "<form method='POST' action='/update.htm' target='progressFrame'>";
$echo[] = "<input type='hidden' name='changeDevice' value='apply'>";
$echo[] = "<input type='hidden' name='csrf_token' value='"._var($var,'csrf_token')."'>";
$echo[] = "<select class='slot' name='slotId."._var($disk,'idx')."' onChange='this.form.submit()'>";
$echo[] = "<select class='slot' name='slotId."._var($disk,'idx')."' onChange='devices.start();this.form.submit()'>";
$empty = _var($disk,'idSb')!='' ? _('no device') : _('unassigned');
if (_var($disk,'id')) {
$echo[] = "<option value=\"{$disk['id']}\" selected>".device_desc($disk)."</option>";
@@ -179,15 +175,16 @@ function my_diskio($data) {
function array_offline(&$disk, $pool='') {
global $var, $disks;
$echo = []; $warning = '';
$status = ['DISK_DSBL','DISK_INVALID','DISK_DSBL_NEW','DISK_NEW','DISK_WRONG'];
$text = "<span class='red-text'><em>"._('All existing data on this device will be OVERWRITTEN when array is Started')."</em></span>";
if (strpos(_var($var,'mdState'),'ERROR:')===false) {
$text = "<span class='red-text'><em>"._('All existing data on this device will be OVERWRITTEN when array is Started')."</em></span>";
if (_var($disk,'type')=='Cache') {
if (_var($disks[$pool],'uuid') && _var($disk,'status')=='DISK_NEW') $warning = $text;
if (!empty(_var($disks[$pool],'uuid')) && _var($disk,'status')=='DISK_NEW') $warning = $text;
} else {
if (_var($var,'mdState')=='NEW_ARRAY') {
if (_var($disk,'type')=='Parity') $warning = $text;
} elseif (_var($var,'mdNumInvalid',0)<=1) {
if (in_array(_var($disk,'status'),['DISK_INVALID','DISK_DSBL_NEW','DISK_WRONG','DISK_NEW'])) $warning = $text;
if (in_array(_var($disk,'status'),$status)) $warning = $text;
}
}
}
@@ -331,7 +328,7 @@ function array_slots() {
$echo[] = "<form method='POST' action='/update.htm' target='progressFrame'>";
$echo[] = "<input type='hidden' name='csrf_token' value='"._var($var,'csrf_token')."'>";
$echo[] = "<input type='hidden' name='changeSlots' value='apply'>";
$echo[] = "<select class='narrow' name='SYS_ARRAY_SLOTS' onChange='this.form.submit()'>";
$echo[] = "<select class='narrow' name='SYS_ARRAY_SLOTS' onChange='devices.start();this.form.submit()'>";
for ($n=$min; $n<=$max; $n++) {
$selected = $n==_var($var,'SYS_ARRAY_SLOTS') ? ' selected' : '';
$echo[] = "<option value='$n'{$selected}>$n</option>";
@@ -348,7 +345,7 @@ function cache_slots($off,$pool,$min,$slots) {
$echo[] = "<input type='hidden' name='csrf_token' value='"._var($var,'csrf_token')."'>";
$echo[] = "<input type='hidden' name='changeSlots' value='apply'>";
$echo[] = "<input type='hidden' name='poolName' value='$pool'>";
$echo[] = "<select class='narrow' name='poolSlots' onChange='this.form.submit()'{$off}>";
$echo[] = "<select class='narrow' name='poolSlots' onChange='devices.start();this.form.submit()'{$off}>";
for ($n=$min; $n<=$max; $n++) {
$option = $n ?: _('none');
$selected = ($n==$slots) ? ' selected' : '';
@@ -445,45 +442,47 @@ while (true) {
$echo[1] .= "</tr>";
$sum = initSum();
$cache = cache_filter($disks); $n = 2;
$cache = cache_filter($disks); $n = 2;
foreach ($cache as $disk) $crypto |= _var($disk,'luksState',0)!=0 || vfs_luks(_var($disk,'fsType'));
foreach ($pools as $pool) {
$echo[$n] = "pool_device".($n-2)."\n";
foreach ($cache as $disk) if (prefix(_var($disk,'name'))==$pool) $crypto |= _var($disk,'luksState',0)!=0 || vfs_luks(_var($disk,'fsType'));
$root = explode($_tilde_,$pool)[0];
$print = array_filter(array_column($cache,'name'),function($name) use ($pools,$root) {return in_array($name,$pools) && strncmp($root,$name,strlen($root))==0;});
$print = end($print);
if (_var($var,'fsState')=='Stopped') {
$log = @parse_ini_file($pool_log) ?: [];
$off = false;
foreach ($cache as $disk) if (prefix(_var($disk,'name'))==$pool) {
$echo[$n] .= array_offline($disk,$pool);
$name = _var($disk,'name');
// tilde is not allowed in array key - replace it
$diskname = str_replace('~','_-_',_var($disk,'name'));
if (isset($log[$diskname])) $off |= ($log[$diskname] != _var($disk,'id')); elseif ($diskname) $log[$diskname] = _var($disk,'id');
$named = no_tilde($name);
if (isset($log[$named])) $off |= ($log[$named] != _var($disk,'id')); elseif ($named) $log[$named] = _var($disk,'id');
}
$data = []; foreach ($log as $key => $value) $data[] = "$key=\"$value\"";
$off &= !empty(_var($cache[$pool],'uuid'));
file_put_contents($pool_log,implode("\n",$data));
$echo[$n] .= "<tr class='tr_last'><td>"._('Slots')."</td><td colspan='8'>".cache_slots($off,$pool,_var($cache[$pool],'devicesSb'),_var($cache[$pool],'slots',0))."</td><td></td></tr>";
$echo[$n] .= "<tr class='tr_last'><td>"._('Slots').":</td><td colspan='8'><span class='slots'><span class='slots-left'>".cache_slots($off,$pool,_var($cache[$pool],'devicesSb'),_var($cache[$pool],'slots',0))."</span>";
$zfsPool = strstr(_var($cache[$pool],'fsType'),'zfs') && !isSubpool($pool);
if ($zfsPool) {
$current_subpools = array_filter($pools, function ($element) use ($pool) {
return strpos($element, "$pool~")!==false;
});
if (count($current_subpools) < count($subpools)) {
$current_subpools_list = str_replace("$pool~","", implode(',', $current_subpools));
$subPoolButton = "<input type='button' value='"._('Add Subpool')."' style='margin:0' onclick='addSubpoolPopup(\"$pool\",\"$current_subpools_list\")'>";
} else {
$subPoolButton = "<input type='button' value='"._('Add Subpool')."' style='margin:0' disabled>";
}
$echo[$n] .= "<tr class='tr_last'><td></td><td colspan='8'>$subPoolButton</td><td></td></tr>";
$current_subpools = array_filter($pools, function($element) use ($pool,$_tilde_) {return strpos($element, "{$pool}{$_tilde_}")!==false;});
$current_subpools_list = str_replace("{$pool}{$_tilde_}","", implode(',', $current_subpools));
$echo[$n] .= "<input type='button' value='"._('Add Subpool')."' class='subpool' onclick='addSubpoolPopup(\"$pool\",\"$current_subpools_list\")'".(count($current_subpools)<count($subpools)?'':' disabled').">";
}
$echo[$n] .= "</span></td><td></td></tr>";
} else {
foreach ($cache as $disk) if (prefix($disk['name'])==$pool) {
if (isset($disk['fsType'])) $fstype = vfs_type($disk['fsType']);
if (substr(_var($cache[$pool],'fsStatus'),0,11)=='Unmountable' && empty($disk['fsStatus'])) $disk['fsStatus'] = _var($cache[$pool],'fsStatus');
$echo[$n] .= array_online($disk,$fstype);
}
delete_file($pool_log);
if (_var($display,'total') && _var($cache[$pool],'devices',0)>1) $echo[$n] .= show_totals(sprintf(_('Pool of %s devices'),my_word($cache[$pool]['devices'])),false,"$pool*");
$sum = initSum();
}
if (strcmp($root,$pool)!=0) $cache[$root]['devices'] += $cache[$pool]['devices'];
if (strcmp($pool,$print)==0) {
delete_file($pool_log);
if (_var($display,'total') && _var($cache[$root],'devices',0)>1) $echo[$n] .= show_totals(sprintf(_('Pool of %s devices'),my_word($cache[$root]['devices'])),strpos($pool,$_tilde_)!==false,"$root*");
$sum = initSum();
}
}
$n++;
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/php -q
<?PHP
/* Copyright 2005-2021, Lime Technology
* Copyright 2012-2021, Bergware International.
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, 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,

View File

@@ -126,16 +126,17 @@ function active_disks($disk) {
return substr(_var($disk,'status'),0,7)!='DISK_NP' && in_array(_var($disk,'type'),['Parity','Data']);
}
function device_name(&$disk) {
global $_tilde_, $_arrow_;
switch (_var($disk,'type')) {
case 'Extra' :
case 'Parity': $type = _var($disk,'rotational') ? 'disk' : 'nvme'; break;
case 'Data' :
case 'Cache' : $type = _var($disk,'rotational') ? (_var($disk,'luksState') ? 'disk-encrypted' : 'disk') : 'nvme'; break;
}
$name = my_disk(_var($disk,'name'));
[$p1,$p2] = my_explode(' ',$name);
$name = _($p1).($p2?" $p2":"");
return "<i class='icon-$type f14'></i> <a href=\"".htmlspecialchars("/Dashboard/Main/Settings/Device?name="._var($disk,'name'))."\" title=\"$name settings\">$name</a>";
$name = _var($disk,'name');
$extra = my_explode($_tilde_,$name)[1];
$fancyname = compress($extra ? "$_arrow_ "._(my_disk($extra),3) : _(my_disk($name),3),16,5);
return "<i class='icon-$type f14'></i> <a href=\"".htmlspecialchars("/Dashboard/Main/Settings/Device?name=$name")."\" title=\"$fancyname settings\">$fancyname</a>";
}
function device_status(&$disk, &$error, &$warning) {
global $var;
@@ -175,6 +176,7 @@ function device_smart(&$disk, &$fail, &$smart) {
if (!_var($disk,'device') || strpos(_var($disk,'color'),'blink')!==false) return "-";
$failed = ['FAILED','NOK'];
$name = _var($disk,'name');
$named = no_tilde($name);
$select = get_value($name,'smSelect',0);
$level = get_value($name,'smLevel',1);
$events = explode('|',get_value($disk,'smEvents',$numbers));
@@ -186,7 +188,7 @@ function device_smart(&$disk, &$fail, &$smart) {
if (file_exists("$file") && exec("grep -Pom1 '^SMART.*: \K[A-Z]+' ".escapeshellarg($file)." |tr -d '\n' 2>/dev/null", $ssa) && in_array("$ssa",$failed)) {
$title = _('SMART health-check failed')."\n"; $thumb = 'thumbs-o-down'; $color = 'red'; $text = 'fail'; $fail++;
} else {
if (empty($saved["smart"]["$name.ack"])) {
if (empty($saved["smart"]["$named.ack"])) {
exec("awk 'NR>7{print $1,$2,$4,$6,$9,$10}' ".escapeshellarg($file)." 2>/dev/null", $codes);
foreach ($codes as $code) {
if (!$code || !is_numeric($code[0])) continue;
@@ -199,7 +201,7 @@ function device_smart(&$disk, &$fail, &$smart) {
}
}
$title .= _('Click for context menu');
return "<span id='smart-$name' name=Device class='fa fa-$thumb $color-text' style='margin-right:8px' onmouseover='this.style.cursor=\"pointer\"' title='$title'></span><span id='text-$name'>$text</span>";
return "<span id='smart-$named' name=Device class='fa fa-$thumb $color-text' style='margin-right:8px' onmouseover='this.style.cursor=\"pointer\"' title='$title'></span><span id='text-$named'>$text</span>";
}
function device_usage(&$disk, &$full, &$high) {
global $display;

View File

@@ -44,28 +44,30 @@ $top = 120;
function check_temp(&$disk,$text,$info) {
global $notify,$saved,$server,$display,$top;
$name = _var($disk,'name');
$temp = _var($disk,'temp','*');
$max = _var($disk,'maxTemp')>=0 ? $disk['maxTemp'] : (_var($display,'max')>=0 ? $display['max'] : 0);
$hot = _var($disk,'hotTemp')>=0 ? $disk['hotTemp'] : (_var($display,'hot')>=0 ? $display['hot'] : 0);
$warn = exceed($temp,$max,$top) ? 'alert' : (exceed($temp,$hot,$top) ? 'warning' : false);
$item = 'temp';
$last = $saved[$item][$name] ?? 0;
$name = _var($disk,'name');
$named = no_tilde($name);
$temp = _var($disk,'temp','*');
$max = _var($disk,'maxTemp')>=0 ? $disk['maxTemp'] : (_var($display,'max')>=0 ? $display['max'] : 0);
$hot = _var($disk,'hotTemp')>=0 ? $disk['hotTemp'] : (_var($display,'hot')>=0 ? $display['hot'] : 0);
$warn = exceed($temp,$max,$top) ? 'alert' : (exceed($temp,$hot,$top) ? 'warning' : false);
$item = 'temp';
$last = $saved[$item][$named] ?? 0;
if ($warn) {
if ($temp>$last) {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text temperature")." -s ".escapeshellarg(ucfirst($warn)." [$server] - $text ".($warn=='alert'?'overheated (':'is hot (').my_temp($temp).")")." -d ".escapeshellarg("$info")." -i \"$warn\" 2>/dev/null");
$saved[$item][$name] = max($max,$temp);
$saved[$item][$named] = max($max,$temp);
}
} else {
if ($last && $temp<=$top) {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text message")." -s ".escapeshellarg("Notice [$server] - $text returned to normal temperature")." -d ".escapeshellarg("$info")." 2>/dev/null");
unset($saved[$item][$name]);
unset($saved[$item][$named]);
}
}
}
function check_smart(&$disk,$port,$text,$info) {
global $notify,$saved,$server,$numbers;
$name = _var($disk,'name');
$named = no_tilde($name);
$select = get_value($disk,'smSelect',0);
$level = get_value($disk,'smLevel',1);
$events = explode('|',get_value($disk,'smEvents',$numbers));
@@ -80,10 +82,10 @@ function check_smart(&$disk,$port,$text,$info) {
$fail = strpos($when,'FAILING_NOW')!==false;
if (!$fail && !in_array($id,$events)) continue;
$word = str_replace(['_',' (-)'],[' ',''],strtolower("$class ($when)"));
$ack = "$name.ack";
$ack = "$named.ack";
switch ($select) {
case 0:
$attr = "$name.$id";
$attr = "$named.$id";
$last = ($saved[$item][$attr] ?? 0)*$level;
if ($raw>0 || $fail) {
if ($raw>$last) {
@@ -100,7 +102,7 @@ function check_smart(&$disk,$port,$text,$info) {
}
break;
case 1:
$attr = "$name.{$id}n";
$attr = "$named.{$id}n";
$last = $saved[$item][$attr] ?? 255;
if (($thres>0 && $value<=$thres*$level) || $fail) {
if ($value*($value>$thres?$level:1)<$last) {
@@ -122,32 +124,34 @@ function check_smart(&$disk,$port,$text,$info) {
function check_usage(&$disk,$used,$text,$info) {
global $notify,$saved,$server,$display;
if ($used == -1) return;
$name = _var($disk,'name');
$name = _var($disk,'name');
$named = no_tilde($name);
$critical = _var($disk,'critical')>=0 ? $disk['critical'] : (_var($display,'critical')>=0 ? $display['critical'] : 0);
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
$warn = exceed($used,$critical) ? 'alert' : (exceed($used,$warning) ? 'warning' : false);
$item = 'used';
$last = $saved[$item][$name] ?? 0;
$warning = _var($disk,'warning')>=0 ? $disk['warning'] : (_var($display,'warning')>=0 ? $display['warning'] : 0);
$warn = exceed($used,$critical) ? 'alert' : (exceed($used,$warning) ? 'warning' : false);
$item = 'used';
$last = $saved[$item][$named] ?? 0;
if ($warn) {
if ($used>$last) {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text disk utilization")." -s ".escapeshellarg(ucfirst($warn)." [$server] - $text is ".($warn=='alert'?'low on space':'high on usage')." ({$used}%)")." -d ".escapeshellarg("$info")." -i \"$warn\" 2>/dev/null");
$saved[$item][$name] = max($critical,$used);
$saved[$item][$named] = max($critical,$used);
}
} else {
if ($last && $used<=100) {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text message")." -s ".escapeshellarg("Notice [$server] - $text returned to normal utilization level")." -d ".escapeshellarg("$info")." 2>/dev/null");
unset($saved[$item][$name]);
unset($saved[$item][$named]);
}
}
}
// check array devices
foreach ($disks as $disk) {
$name = _var($disk,'name');
$name = _var($disk,'name');
if ($name=='flash' || substr(_var($disk,'status'),-3)=='_NP') continue;
$text = my_disk($name).(in_array($name,$pools)||$name=='parity'?' disk':'');
$named = no_tilde($name);
$text = my_disk($name).(in_array($name,$pools)||$name=='parity'?' disk':'');
$device = _var($disk,'device');
$info = !empty($disk['id']) ? "{$disk['id']} ($device)" : "No device identification ($device)";
$info = !empty($disk['id']) ? "{$disk['id']} ($device)" : "No device identification ($device)";
// process disk temperature notifications
check_temp($disk,$text,$info);
// process disk SMART notifications
@@ -157,7 +161,7 @@ foreach ($disks as $disk) {
// process disk operation notifications
$warn = strtok(_var($disk,'color'),'-');
$item = 'disk';
$last = $saved[$item][$name] ?? '';
$last = $saved[$item][$named] ?? '';
switch ($warn) {
case 'red':
if ($warn!=$last) {
@@ -165,7 +169,7 @@ foreach ($disks as $disk) {
$status = strtolower(str_replace(['NP_','_'],['',' '],_var($disk,'status')));
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text error")." -s ".escapeshellarg("Alert [$server] - $text in error state ($status)")." -d ".escapeshellarg("$info")." -i \"alert\" 2>/dev/null");
}
$saved[$item][$name] = $warn;
$saved[$item][$named] = $warn;
}
break;
case 'yellow':
@@ -174,7 +178,7 @@ foreach ($disks as $disk) {
$status = $name=='parity' ? "parity-sync in progress" : " is being reconstructed and is available for normal operation";
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text message")." -s ".escapeshellarg("Notice [$server] - $text, $status")." -d ".escapeshellarg("$info")." 2>/dev/null");
}
$saved[$item][$name] = $warn;
$saved[$item][$named] = $warn;
}
break;
default:
@@ -182,7 +186,7 @@ foreach ($disks as $disk) {
if (_var($var,'fsState')!='Stopped') {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text message")." -s ".escapeshellarg("Notice [$server] - $text returned to normal operation")." -d ".escapeshellarg("$info")." 2>/dev/null");
}
unset($saved[$item][$name]);
unset($saved[$item][$named]);
}
break;}
// count disk errors
@@ -197,7 +201,7 @@ foreach ($disks as $disk) {
$saved[$item][$attr] = 1;
}
} elseif (isset($saved[$item][$attr])) unset($saved[$item][$attr]);
$attr = "profile-$name";
$attr = "profile-$named";
if (exec("/sbin/btrfs filesystem df /mnt/$name 2>/dev/null|grep -c '^Data'")>1) {
if (empty($saved[$item][$attr])) {
exec("$notify -l '/Main' -e ".escapeshellarg("Unraid $text message")." -s ".escapeshellarg("Warning [$server] - $pool pool BTRFS too many profiles (You can ignore this warning when a pool balance operation is in progress)")." -d ".escapeshellarg("$info")." -i \"warning\" 2>/dev/null");
@@ -318,7 +322,7 @@ if ($saved) {
$text = '';
foreach ($saved as $item => $block) {
if ($block) $text .= "[$item]\n";
foreach ($block as $key => $value) $text .= "$key=\"$value\"\n";
foreach ($block as $key => $value) $text .= no_tilde($key)."=\"$value\"\n";
}
if ($text) {
if ($text != @file_get_contents($ram)) file_put_contents($ram, $text);

View File

@@ -205,6 +205,9 @@ span.outer.stopped>img,span.outer.stopped>i.img{opacity:0.3}
span.outer.paused>img,span.outer.paused>i.img{opacity:0.6}
span.inner{display:inline-block;vertical-align:top}
span.state{font-size:1.1rem;margin-left:7px}
span.slots{display:inline-block;width:44rem;margin:0!important}
span.slots-left{float:left;margin:0!important}
input.subpool{float:right;margin:0}
i.padlock{margin-right:8px;cursor:default;vertical-align:middle}
i.nolock{visibility:hidden;margin-right:8px;vertical-align:middle}
i.lock{margin-left:8px;cursor:default;vertical-align:middle}

View File

@@ -199,6 +199,9 @@ span.outer.stopped>img,span.outer.stopped>i.img{opacity:0.3}
span.outer.paused>img,span.outer.paused>i.img{opacity:0.6}
span.inner{display:inline-block;vertical-align:top}
span.state{font-size:1.1rem;margin-left:7px}
span.slots{display:inline-block;width:44rem;margin:0!important}
span.slots-left{float:left;margin:0!important}
input.subpool{float:right;margin:0}
i.padlock{margin-right:8px;cursor:default;vertical-align:middle}
i.nolock{visibility:hidden;margin-right:8px;vertical-align:middle}
i.lock{margin-left:8px;cursor:default;vertical-align:middle}

View File

@@ -205,6 +205,9 @@ span.outer.stopped>img,span.outer.stopped>i.img{opacity:0.3}
span.outer.paused>img,span.outer.paused>i.img{opacity:0.6}
span.inner{display:inline-block;vertical-align:top}
span.state{font-size:1.1rem;margin-left:7px}
span.slots{display:inline-block;width:44rem;margin:0!important}
span.slots-left{float:left;margin:0!important}
input.subpool{float:right;margin:0}
i.padlock{margin-right:8px;cursor:default;vertical-align:middle}
i.nolock{visibility:hidden;margin-right:8px;vertical-align:middle}
i.lock{margin-left:8px;cursor:default;vertical-align:middle}

View File

@@ -199,6 +199,9 @@ span.outer.stopped>img,span.outer.stopped>i.img{opacity:0.3}
span.outer.paused>img,span.outer.paused>i.img{opacity:0.6}
span.inner{display:inline-block;vertical-align:top}
span.state{font-size:1.1rem;margin-left:7px}
span.slots{display:inline-block;width:44rem;margin:0!important}
span.slots-left{float:left;margin:0!important}
input.subpool{float:right;margin:0}
i.padlock{margin-right:8px;cursor:default;vertical-align:middle}
i.nolock{visibility:hidden;margin-right:8px;vertical-align:middle}
i.lock{margin-left:8px;cursor:default;vertical-align:middle}

View File

@@ -46,9 +46,6 @@ $pool_devices = false;
$pools = pools_filter($disks);
foreach ($pools as $pool) $pool_devices |= _var($disks[$pool],'devices')!='';
// pool name ending in any of these => zfs subpool
$subpools = ['special','logs','dedup','cache','spares'];
// Read network settings
extract(parse_ini_file('state/network.ini',true));