Files
webgui/plugins/dynamix/ArrayOperation.page
2020-09-20 10:58:39 -04:00

582 lines
35 KiB
Plaintext

Menu="Main:5"
Title="Array Operation"
Tag="snowflake-o"
---
<?PHP
/* Copyright 2005-2020, Lime Technology
* Copyright 2012-2020, 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,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$keyfile = file_exists($var['luksKeyfile']);
$missing = file_exists('/var/tmp/missing.tmp');
$encrypt = false;
/* only one of $present, $missing, or $wrong will be true, or all will be false */
$forced = $present = $wrong = false;
foreach ($disks as $disk) {
if (strpos($disk['fsType'],'luks:')!==false || ($disk['fsType']=='auto' && (strpos($var['defaultFsType'],'luks:')!==false || $disk['luksState']==2 || $disk['luksState']==3))) {
$encrypt = true;
if ($disk['luksState']==0) $forced = true;
if ($disk['luksState']==1) $present = true;
if ($disk['luksState']==2) $missing = true;
if ($disk['luksState']==3) $wrong = true;
}
}
if ($forced && ($present || $missing || $wrong)) $forced = false;
function check_encryption() {
global $forced, $missing, $wrong;
if ($forced) $status = _('Enter new key');
elseif ($missing) $status = _('Missing key');
elseif ($wrong) $status = _('Wrong key');
else return;
echo "<tr><td></td><td class='gap'>"._('Encryption status').":</td><td><span class='red-text'>$status</span><span id='pass'><input name='luksReformat' type='checkbox' onchange='selectInput(this.form)'>permit reformat</span></td></tr>";
echo "<tr><td></td><td class='gap'>"._('Encryption input').":</td><td>";
echo "<select name='input' size='1' onchange='selectInput(this.form)'>";
echo mk_option(1,'text',_('Passphrase'));
echo mk_option(1,'file',_('Keyfile'));
echo "</select></td></tr>";
echo "<tr id='text'><td></td><td class='gap'>"._('Passphrase').":</td><td><input type='password' name='text' maxlength='512' value='' onkeyup='selectInput(this.form)' placeholder=\""._('use printable characters only')."\"><input name='showPass' type='checkbox' onchange='selectInput(this.form)'>"._('show passphrase')."</td></tr>";
echo "<tr id='copy'><td></td><td class='gap'>"._('Retype passphrase').":</td><td><input type='password' name='copy' maxlength='512' value='' onkeyup='selectInput(this.form)'></td></tr>";
echo "<tr id='file'><td></td><td class='gap'>"._('Keyfile').":</td><td><input type='file' name='local' onchange='getFileContent(event,this.form)'></td></tr>";
}
function maintenance_mode() {
echo "<tr>";
echo "<td></td>";
echo "<td><input type='checkbox' name='startMode' value='Maintenance'>_(Maintenance mode)_</td>";
echo "<td><b>"._('Maintenance mode')."</b> - "._('if checked, Start array but do not mount disks')."</td>";
echo "</tr>";
}
function status_indicator() {
global $var;
switch ($var['mdColor']) {
case 'green-on': $orb = 'circle'; $color = 'green'; $help =_('Started, array protected'); break;
case 'green-blink': $orb = 'circle'; $color = 'grey'; $help = _('Stopped'); break;
case 'yellow-on': $orb = 'warning'; $color = 'yellow'; $help = _('Started, array unprotected'); break;
case 'yellow-blink': $orb = 'warning'; $color = 'grey'; $help = _('Stopped'); break;
}
echo "<a class='info'><i class='fa fa-$orb orb $color-orb'></i><span>$help</span></a>";
}
function missing_cache() {
global $disks;
$missing = false;
foreach (cache_filter($disks) as $disk) $missing |= (strpos($disk['status'],'_MISSING')!==false);
return $missing;
}
?>
<style>
tr#copy,tr#file{display:none}
td.gap{padding-left:26px!important}
td.wrap{white-space:normal!important}
span#pass{display:none;margin-left:20px}
</style>
<script src="<?autov('/webGui/javascript/jquery.base64.js')?>"></script>
<script>
var ctrl = '<span class="status <?=$tabbed?"":"vhshift"?>"><a style="cursor:pointer" class="tooltip_diskio" title="_(Toggle reads/writes display)_" onclick="toggle_diskio();return false"><i class="toggle fa"></i></a></span>';
function selectInput(form) {
<?if ($wrong && $keyfile):?>
form.input.value = 'file';
form.input.disabled = true;
<?endif;?>
if (form.input.value == 'text') {
form.file.value = '';
form.local.value = '';
<?if ($forced):?>
$('#text').show();
$('#copy').show();
$('#pass').hide();
$('input[name="confirmStart"]').prop('disabled',true);
<?elseif ($missing):?>
$('#text').show();
$('#copy').hide();
$('#pass').hide();
$('input[name="confirmStart"]').prop('disabled',true);
<?elseif ($wrong):?>
$('#text').show();
if ($('input[name="luksReformat"]').prop('checked')) $('#copy').show(); else $('#copy').hide();
$('#pass').show();
$('input[name="confirmStart"]').prop('disabled',true);
<?endif;?>
$('#file').hide();
$('input[name="text"],input[name="copy"]').attr('type',$('input[name="showPass"]').prop('checked')?'text':'password');
var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
item.prop('disabled',$('#copy').is(':visible') ? (form.text.value!=form.copy.value || form.text.value=='') : form.text.value=='');
} else {
form.text.value = '';
form.copy.value = '';
$('#text').hide();
$('#copy').hide();
$('#file').show();
<?if ($wrong):?>
$('#pass').show();
<?else:?>
$('#pass').hide();
<?endif;?>
var item = $('input[name="confirmStart"]').length ? $('input[name="confirmStart"]') : $('#cmdStart');
item.prop('disabled',!form.file.value);
}
}
function getFileContent(event,form) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(){form.file.value=reader.result;selectInput(form);};
reader.readAsDataURL(input.files[0]);
}
function prepareInput(form) {
$(form).append('<input type="hidden" name="cmdStart" value="Start">');
if (form.input === undefined) {
form.submit();
return;
}
form.input.disabled = true;
form.local.disabled = true;
form.file.disabled = true;
form.text.disabled = true;
form.copy.disabled = true;
if (form.text.value) {
var valid = new RegExp('^[ -~]+$');
if (valid.test(form.text.value)) {
$(form).append('<input type="hidden" name="luksKey" value="'+base64(form.text.value)+'">');
form.submit();
} else {
form.input.disabled = false;
form.local.disabled = false;
form.file.disabled = false;
form.text.disabled = false;
form.copy.disabled = false;
swal({title:"_(Printable Characters Only)_",text:"_(Use <b>ASCII</b> characters from space ' ' to tilde '~')_<br>_(Otherwise use the <b>keyfile</b> method for UTF8 input)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
}
return;
}
var data = {};
data['#file'] = 'unused';
data['#include'] = 'webGui/include/KeyUpload.php';
data['file'] = form.file.value;
$.post('/update.php',data,function(){form.submit();});
}
function parityWarning(form) {
if (form.md_invalidslot.checked) {
<?if (strpos($disks['parity2']['status'],'_NP')===false):?>
var text = "_(<i>Dual parity valid</i> requires <b>ALL</b> disks in their original slots)_";
<?else:?>
var text = "_(<i>Parity valid</i> requires <b>ALL</b> disks to have their original content)_";
<?endif;?>
} else {
var text = "_(<i>Parity</i> disk(s) content will be overwritten)_";
}
swal({title:"_(Proceed to start)_",text:text,html:true,type:'warning',showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){prepareInput(form);});
}
function tab0() {
$.removeCookie('one',{path:'/'});
$.cookie('tab','tab0',{path:'/'});
}
function parityStatus() {
$.post('/webGui/include/DeviceList.php',{path:'<?=$path?>',device:'parity'},function(data) {
if (data) {$.each(data.split(';'),function(k,v) {if ($('#line'+k).length>0) $('#line'+k).html(v);});}
timers.parityStatus = setTimeout(parityStatus,3000);
if (!data && $('#cancelButton').length>0 && $('#cancelButton').val()=="_(Cancel)_") {
$('#cancelButton').val('Done').prop('onclick',null).off('click').click(function(){refresh();});
$('#cancelText').html('');
$('#line4').html("_(completed)_");
}
});
}
function stopArray(form) {
$(form).append('<input type="hidden" name="cmdStop" value="Stop">');
<?if ($confirm['stop']):?>
swal({title:"_(Proceed)_?",text:"_(This will stop the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmdStop"]').remove();});
<?else:?>
form.submit();
<?endif;?>
}
function stopParity(form,text) {
$(form).append('<input type="hidden" name="cmdNoCheck" value="Cancel">');
<?if ($confirm['stop']):?>
swal({title:"_(Proceed)_?",text:"_(This will stop the running operation)_: "+text,type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmdNoCheck"]').remove();});
<?else:?>
form.submit();
<?endif;?>
}
function pauseParity(form) {
$(form).append('<input type="hidden" name="cmdNoCheck" value="Pause">');
$('#pauseButton').val("_(Resume)_").prop('onclick',null).off('click').click(function(){resumeParity(form);});
form.submit();
}
function resumeParity(form) {
$(form).append('<input type="hidden" name="cmdCheck" value="Resume">');
$('#pauseButton').val("_(Pause)_").prop('onclick',null).off('click').click(function(){pauseParity(form);});
form.submit();
}
function shutdown_now(form,cmd) {
$(form).append('<input type="hidden" name="cmd" value="'+cmd+'">');
<?if ($confirm['down']):?>
switch (cmd) {
case 'reboot': var text = "_(This will reboot the system)_"; break;
case 'shutdown': var text = "_(This will shutdown the system)_"; break;
}
swal({title:"_(Proceed)_?",text:text,type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(p){if (p) form.submit(); else $('input[name="cmd"]').remove();});
<?else:?>
form.submit();
<?endif;?>
}
function toggleApply(checked) {
$('input[name="#apply"]').prop('disabled',!checked);
}
parityStatus();
<?if ($tabbed):?>
$('.tabs').append(ctrl);
if ($.cookie('tab')=='tab0') $('i.toggle').hide();
$('#tab'+$('input[name$="tabs"]').length).click(function(){tab0(); $('i.toggle').hide('slow');});
<?else:?>
$('div[id=title]:not(":last, .disable_diskio")').each(function(){$(this).append(ctrl);});
<?endif;?>
<?if (substr($var['fsState'],-3)=='ing'):?>
function reload_page() {
$.get('/webGui/include/ReloadPage.php',function(data) {
switch (data) {
case 'wait':
setTimeout(reload_page,10000);
break;
case 'stop':
setTimeout(refresh,0);
break;
default:
if (data) $('#fsState').html(data);
setTimeout(reload_page,3000);
break;
}
});
}
reload_page();
<?endif;?>
$('.tooltip_diskio').tooltipster({delay:100,trigger:'custom',triggerOpen:{mouseenter:true},triggerClose:{click:false,scroll:true,mouseleave:true}});
toggle_diskio(true);
<?
$parity = $var['mdResync'] ? "<br><small>_(Disabled)_ -- _(Parity operation is running)_</small>" : "";
$mover = file_exists('/var/run/mover.pid') ? "<br><small>_(Disabled)_ -- _(Mover is running)_</small>" : "";
$btrfs = exec('pgrep -cf /sbin/btrfs') ? "<br><small>_(Disabled)_ -- _(BTRFS operation is running)_</small>" : "";
?>
$(function(){
var form = document.arrayOps;
if (form.input !== undefined) selectInput(form);
});
function formatWarning(val) {
if (val==true)
swal({
title:"_(Format Unmountable disks)_",
text: "_(Create an empty file system on the disks shown as <b>Unmountable</b> discarding all data currently on the disks and update parity to reflect this)_. "+
"_(This is typically done when a new disk is added to the array to get it ready for files to be written to it)_.<br>"+
"<p><br><b>_(WARNING)_</b>"+
"<p>_(A format is <b>NEVER</b> part of a data recovery or disk rebuild process and if done in such circumstances will normally lead to loss of all data on the disks being formatted)_.",
type: "warning",
confirmButtonText:"_(Ok)_",
html: true
});
}
</script>
<form name="arrayOps" method="POST" action="/update.htm" target="progressFrame">
<input type="hidden" name="startState" value="<?=htmlspecialchars($var['mdState'])?>">
<input type="hidden" name="file" value="">
<table markdown="1" class="array_status">
<?switch ($var['fsState']):
case "Started":?>
<tr><td><?status_indicator()?>**_(Started)_<?=(($var['startMode']=='Maintenance')?' - _(Maintenance Mode)_':'')?>**</td>
<td><input type="button" value="_(Stop)_" onclick="stopArray(this.form)"<?if ($parity||$mover||$btrfs):?> disabled<?endif;?>></td>
<td id="stop">**_(Stop)_** _(will take the array off-line)_.<?=$parity?:$mover?:$btrfs?:''?></td></tr>
<? if ($var['fsNumUnmountable']>0):?>
<tr><td>**<?=_('Unmountable disk'.($var['fsNumUnmountable']==1?'':'s').' present')?>:**<br>
<? $cache = [];
foreach ($disks as $disk) if (substr($disk['fsStatus'],0,11)=='Unmountable' || in_array(prefix($disk['name']),$cache)) {
if ($disk['id']) echo "<span class='blue-text'>".my_disk($disk['name'])."</span> &bullet; ".my_id($disk['id'])." (".$disk['device'].")<br>";
if (in_array($disk['name'],$pools)) $cache[] = $disk['name'];
}
?> </td><td><input type="submit" id="btnFormat" name="cmdFormat" value="_(Format)_" disabled><input type="hidden" name="unmountable_mask" value="<?=$var['fsUnmountableMask']?>"></td>
<td>**_(Format)_** _(will create a file system in all **Unmountable** disks)_.<br>
<a class="info none img nohand"><input type="checkbox" name="confirmFormat" value="OFF" onclick="formatWarning(this.checked),$('#btnFormat').prop('disabled',!arrayOps.confirmFormat.checked)">
<small>_(Yes, I want to do this)_</small></a>
</td></tr>
<? endif;
if (!$var['mdResyncPos']):
if (strstr($var['mdResyncAction'],"recon")):?>
<tr><td></td><td><input type="submit" name="cmdCheck" value="_(Sync)_"></td><td>**_(Sync)_** _(will start **Parity-Sync** and/or **Data-Rebuild**)_.</td></tr>
<? elseif (strstr($var['mdResyncAction'],"clear")):?>
<tr><td></td><td><input type="submit" name="cmdCheck" value="_(Clear)_"></td><td>**_(Clear)_** _(will start **Clearing** new data disk(s))_.</td></tr>
<? else:
if ($var['mdResyncAction']=="check"):?>
<tr><td></td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Read-Check** of all array disks)_.</td></tr>
<? elseif (strstr($var['mdResyncAction'],"check")):?>
<tr><td>_(Parity is valid)_.</td><td><input type="submit" name="cmdCheck" value="_(Check)_"></td><td>**_(Check)_** _(will start **Parity-Check**)_.&nbsp;&nbsp;<a href="/Main/Settings/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab1',{path:'/'})"<?endif;?>>(_(Schedule)_)</a>
<br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
<? endif;?>
<tr><td></td><td><input type="button" value="_(History)_" onclick="openBox('/webGui/include/ParityHistory.php','<?=_('Parity/Read-Check History')?>',600,900,false)"></td>
<? if ($var['sbSyncExit']!=0):?>
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time($var['sbSynced2']).day_count($var['sbSynced2']),0))?><?if ($var['sbSynced2']):?><br><?=sprintf(_('Finding **%s** error'.($var['sbSyncErrs']==1?'':'s')),$var['sbSyncErrs']?:'0')?><?endif;?>
<i class="fa fa-fw fa-dot-circle-o"></i>_(Error code)_: <?=my_error($var['sbSyncExit'])?></td></tr>
<? elseif ($var['sbSynced']==0):
[$date,$duration,$speed,$status,$error] = last_parity_log();?>
<? if ($status==0):?>
<td class="wrap"><?=sprintf(_('Last checked on **%s**'),_(my_time($date).day_count($date),0))?><br><?=sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0')?>
<i class="fa fa-fw fa-clock-o"></i>_(Duration)_: <?=my_check($duration,$speed)?></td></tr>
<? else:?>
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time($date).day_count($date),0))?><br><?=sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0')?>
<i class="fa fa-fw fa-dot-circle-o"></i>_(Error code)_: <?=my_error($status)?></td></tr>
<? endif;
elseif ($var['sbSynced2']==0):
[$date,$duration,$speed,$status,$error] = explode('|', read_parity_log($var['sbSynced']));
if ($status==0):?>
<td class="wrap"><?=sprintf(_('Last checked on **%s**'),_(my_time($var['sbSynced']).day_count($var['sbSynced']),0))?><br><?=sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0')?>
<i class="fa fa-fw fa-clock-o"></i>_(Duration)_: <?=my_check($duration,$speed)?></td></tr>
<? else:?>
<td class="wrap"><?=sprintf(_('Last check incomplete on **%s**'),_(my_time($var['sbSynced']).day_count($var['sbSynced']),0))?><br><?=sprintf(_('Finding **%s** error'.($error==1?'':'s')),$error?:'0')?>
<i class="fa fa-fw fa-dot-circle-o"></i>_(Error code)_: <?=my_error($status)?></td></tr>
<? endif;
else:
$duration = $var['sbSynced2']-$var['sbSynced'];
$speed = $duration?my_scale($var['mdResyncSize']*1024/$duration,$unit,1)." $unit/sec":'';?>
<td class="wrap"><?=sprintf(_('Last check completed on **%s**'),_(my_time($var['sbSynced2']).day_count($var['sbSynced2']),0))?><br><?=sprintf(_('Finding **%s** error'.($var['sbSyncErrs']==1?'':'s')),$var['sbSyncErrs']?:'0')?>
<i class="fa fa-fw fa-clock-o"></i>_(Duration)_: <?=my_check($duration,$speed)?></td></tr>
<? endif;
endif;
else:
if ($var['mdResyncAction']=="check"):?>
<tr><td>_(Read-Check in progress)_.</td><td>
<input type="button" id="pauseButton"<?if ($var['mdResync']):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?>>
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Read-Check')"></td>
<td id="cancelText"><?if ($var['mdResync']):?>**_(Pause)_** _(will pause the Read-Check)_.<?else:?>**_(Resume)_** _(will resume the paused Read-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop the Read-Check)_.</td></tr>
<? elseif (strstr($var['mdResyncAction'],"check")):?>
<tr><td>_(Parity-Check in progress)_.</td><td>
<input type="button" id="pauseButton"<?if ($var['mdResync']):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?>>
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Parity-Check')"></td>
<td id="cancelText"><?if ($var['mdResync']):?>**_(Pause)_** _(will pause the Parity-Check)_.<?else:?>**_(Resume)_** _(will resume the paused Parity-Check)_.<?endif;?><br>**_(Cancel)_** _(will stop the Parity-Check)_.</td></tr>
<? elseif (strstr($var['mdResyncAction'],"recon")):?>
<tr><td>_(Parity-Sync/Data-Rebuild in progress)_.</td><td>
<input type="button" id="pauseButton"<?if ($var['mdResync']):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?>>
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Parity-Sync/Data-Rebuild')"></td>
<td id="cancelText"><?if ($var['mdResync']):?>**_(Pause)_** _(will pause the Parity-Sync/Data-Rebuild)_.<?else:?>**_(Resume)_** _(will resume the paused Parity-Sync/Data-Rebuild)_.<?endif;?><br>**_(Cancel)_** _(will stop Parity-Sync/Data-Rebuild)_.
<br>_(WARNING: canceling may leave the array unprotected)_!</td></tr>
<? elseif (strstr($var['mdResyncAction'],"clear")):?>
<tr><td>_(Clearing in progress)_.</td><td>
<input type="button" id="pauseButton"<?if ($var['mdResync']):?> value="_(Pause)_" onclick="pauseParity(this.form)"<?else:?> value="_(Resume)_" onclick="resumeParity(this.form)"<?endif;?>>
<input type="button" id="cancelButton" value="_(Cancel)_" onclick="stopParity(this.form,'Clearing')"></td>
<td id="cancelText"><?if ($var['mdResync']):?>**_(Pause)_** _(will pause the Clearing)_.<?else:?>**_(Resume)_** _(will resume the paused Clearing)_.<?endif;?><br>**_(Cancel)_** _(will stop Clearing)_.</td></tr>
<? endif;?>
<tr><td></td><td><input type="button" value="_(History)_" onclick="openBox('/webGui/include/ParityHistory.php','<?=_('Parity/Read-Check History')?>',600,900,false)"></td>
<td><?=sprintf(_('Current operation %s on **%s**'),($var['mdResync']?_('started'):_('paused')),_(my_time($var['sbUpdated']).day_count($var['sbSynced']),0))?></td></tr>
<tr><td>_(Total size)_:</td><td id="line0"></td><td></td></tr>
<tr><td>_(Elapsed time)_:</td><td id="line1"></td><td></td></tr>
<tr><td>_(Current position)_:</td><td id="line2"></td><td></td></tr>
<tr><td>_(Estimated speed)_:</td><td id="line3"></td><td></td></tr>
<tr><td>_(Estimated finish)_:</td><td id="line4"></td><td></td></tr>
<? if (strstr($var['mdResyncAction'],"check ")):?>
<tr><td>_(Sync errors)_ <?if ($var['mdResyncCorr']==0):?>_(detected)_:<?else:?>_(corrected)_:<?endif;?></td><td id="line5"></td><td></td></tr>
<? endif;
endif;
break;
case "Starting":?>
<tr><td><?status_indicator()?>**_(Starting)_...**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td><td></td></tr>
<? break;
case "Formatting":?>
<tr><td><?status_indicator()?>**_(Started, formatting)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
<? break;
case "Copying":?>
<tr><td><?status_indicator()?><span id="fsState">**_(Copying)_, <?=$var['fsCopyPrcnt']?>% _(complete)_...**</span></td><td><input type="submit" name="cmdNoCopy" value="_(Cancel)_"></td><td></td></tr>
<? break;
case "Clearing":?>
<tr><td><?status_indicator()?><span id="fsState">**_(Clearing)_, <?=$var['fsClearPrcnt']?>% _(complete)_...**</span></td><td><input type="submit" name="cmdNoClear" value="_(Cancel)_"></td><td></td></tr>
<? break;
case "Stopping":?>
<tr><td><?status_indicator()?>**_(Stopping)_...**</td><td><input type="submit" name="cmdStop" value="_(Stop)_" disabled></td><td></td></tr>
<? break;
case "Stopped":
if ($var['configValid']=="error"):?>
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(Invalid, missing or expired)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
<? elseif ($var['configValid']=="invalid"):?>
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(Too many attached devices. Please consider upgrading your)_ <a href="/Tools/Registration">_(registration key)_</a>.</td></tr>
<? elseif ($var['configValid']=="nokeyserver"):?>
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(Cannot contact key-server. Please check your)_ <a href="/Settings/NetworkSettings">_(network settings)_</a>.</td></tr>
<? elseif ($var['configValid']=="withdrawn"):?>
<tr><td><?status_indicator()?>**_(Stopped)_.**</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(This Unraid OS release has been withdrawn and may no longer be used. Please)_ <a href="/Plugins">_(update)_</a> _(your server)_.</td></tr>
<? else:
switch ($var['mdState']):
case "STOPPED":
if (strstr($var['mdResyncAction'],"recon")):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will bring the array on-line and start **Parity-Sync** and/or **Data-Rebuild**)_.</td></tr>
<? elseif ($var['mdResyncAction']=="clear"):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(New data disk(s) detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will bring the array on-line and start **Clearing** new data disk(s))_.</td></tr>
<? elseif ($var['sbClean']!="yes" && $var['mdResyncAction']=="check"):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
<? elseif ($var['sbClean']!="yes" && strstr($var['mdResyncAction'],"check")):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Unclean shutdown detected)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will bring the array on-line and start **Parity-Check**)_.
<br><input type="checkbox" name="optionCorrect" value="correct" checked><small>_(Write corrections to parity)_</small></td></tr>
<? elseif (missing_cache()):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing Cache disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)" disabled></td>
<td>**_(Start)_** _(will remove the missing cache disk and then bring the array on-line)_.
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<? else:?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will bring the array on-line)_.</td></tr>
<? endif;
maintenance_mode();
check_encryption();
break;
case "NEW_ARRAY":
if (strpos($disks['parity']['status'],"DISK_NP")===0 && strpos($disks['parity2']['status'],"DISK_NP")===0):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will record all disk information and bring the array on-line)_.
<br>_(The array will be immediately available, but **unprotected** since *parity* has not been assigned)_.</td></tr>
<? else:?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Configuration valid)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="parityWarning(this.form)"></td>
<td>**_(Start)_** _(will record all disk information, bring the array on-line, and start Parity-Sync)_.
<br>_(The array will be immediately available, but **unprotected** until Parity-Sync completes)_.
<br><input type="checkbox" name="md_invalidslot" value="99">_(Parity is already valid)_.</td></tr>
<? endif;
maintenance_mode();
check_encryption();
break;
case "DISABLE_DISK":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Missing disk)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)" disabled></td>
<td>**_(Start)_** _(will disable the missing disk and then bring the array on-line. Install a replacement disk as soon as possible)_.
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="$('#cmdStart').prop('disabled',!arrayOps.confirmStart.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<? maintenance_mode();
check_encryption();
break;
case "RECON_DISK":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk installed)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will start **Parity-Sync** and/or **Data-Rebuild**)_.</td></tr>
<? maintenance_mode();
check_encryption();
break;
case "SWAP_DSBL":
if ($var['fsCopyPrcnt']=="100"):?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="button" id="cmdStart" value="_(Start)_" onclick="prepareInput(this.form)"></td>
<td>**_(Start)_** _(will expand the file system of the data disk (if possible); then bring the array on-line and start Data-Rebuild)_.</td></tr>
<? maintenance_mode();
check_encryption();
else:?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Upgrading disk/swapping parity)_.</td><td><input type="submit" name="cmdCopy" value="_(Copy)_" disabled></td>
<td>**_(Copy)_** _(will copy the parity information to the new *parity* disk)_.
<br>_(Once copy completes, the array may be Started, to initiate Data-Rebuild of the disabled disk)_.
<br><input type="checkbox" name="confirmStart" value="OFF" onclick="arrayOps.cmdCopy.disabled=!arrayOps.confirmStart.checked"><small>_(Yes, I want to do this)_</small></td></tr>
<? endif;
break;
case "ERROR:INVALID_EXPANSION":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid expansion)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(You may not add new disk(s) and also remove existing disk(s))_.</td></tr>
<? break;
case "ERROR:NEW_DISK_TOO_SMALL":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Replacement disk is too small)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(The replacement disk must be as big or bigger than the original)_.</td></tr>
<? break;
case "ERROR:PARITY_NOT_BIGGEST":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Disk in parity slot is not biggest)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(If this is a new array, move the largest disk into the *parity* slot)_.
<br>_(If you are adding a new disk or replacing a disabled disk, try Parity-Swap)_.</td></tr>
<? break;
case "ERROR:TOO_MANY_MISSING_DISKS":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(Invalid configuration)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(Too many wrong and/or missing disks)_!</td></tr>
<? break;
case "ERROR:NO_DATA_DISKS":?>
<tr><td><?status_indicator()?>**_(Stopped)_**. _(No data disks)_.</td><td><input type="submit" name="cmdStart" value="_(Start)_" disabled></td>
<td>_(No array data disks have been assigned)_!</td></tr>
<? break;
endswitch;
endif;
endswitch;?>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?if ($var['fsState']=="Started"):?>
<?if ($keyfile):?>
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="unused">
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
<table markdown="1" class="array_status noshift">
<tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_" disabled></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.
<br><input type="checkbox" onchange="toggleApply(this.checked)"><small>_(Yes, I want to do this)_</small></td></tr>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?endif;?><!-- markdown fix -->
<table markdown="1" class="array_status noshift">
<tr><td></td><td><input type="button" id="button-up" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('up')" value="_(Spin Up)_"<?=$parity?' disabled':''?>><input type="button" id="button-down" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('down')" value="_(Spin Down)_"<?=$parity?' disabled':''?>></td>
<td>**_(Spin Up)_** _(will immediately spin up all disks)_.<br>**_(Spin Down)_** _(will immediately spin down all disks)_.</td></tr>
<tr><td></td><td><input type="button" value="_(Clear Stats)_" onclick="toggle_state('Clear')"></td><td>**_(Clear Stats)_** _(will immediately clear all disk statistics)_.</td></tr>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
<?if ($var['shareUser']=='e' && $pool_devices):?>
<form name="mover_schedule" method="POST" action="/update.htm" target="progressFrame">
<table markdown="1" class="array_status noshift">
<tr><td></td>
<?if ($mover):?>
<td><input type="submit" name="cmdStartMover" value="_(Move)_" disabled></td><td>_(Disabled)_ - _(Mover is running)_.</td>
<?else:?>
<td><input type="submit" name="cmdStartMover" value="_(Move)_"></td><td>**_(Move)_** _(will immediately invoke the Mover)_.&nbsp;&nbsp;<a href="/Main/Settings/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab2',{path:'/'})"<?endif;?>>(_(Schedule)_)</a></td>
<?endif;?>
</tr>
</table>
</form>
<?endif;?>
<?elseif ($wrong && $keyfile):?>
<form name="delete_keyfile" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" name="#file" value="unused">
<input type="hidden" name="#include" value="webGui/include/KeyUpload.php">
<table markdown="1" class="array_status noshift">
<tr><td></td><td><input type="submit" name="#apply" value="_(Delete)_"></td><td>**_(Delete)_** _(will delete the encryption keyfile)_.</td></tr>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<?endif;?><!-- markdown fix -->
<form name="shutdownOps" method="POST" action="/webGui/include/Boot.php">
<table markdown="1" class="array_status noshift">
<tr><td></td><td><input type="button" name="reboot" value="_(Reboot)_" onclick="shutdown_now(this.form,'reboot')"><input type="button" name="shutdown" value="_(Shutdown)_" onclick="shutdown_now(this.form,'shutdown')"></td>
<td>**_(Reboot)_** _(will activate a *clean* system reset)_.<br>**_(Shutdown)_** _(will activate a *clean* system power down)_.<br><input type="checkbox" name="safemode"><small>_(Reboot in safe mode)_</small></td></tr>
<tr><td></td><td class="line" colspan="2"></td></tr>
</table>
</form>
<!-- markdown fix --></p><?if (isset($display['sleep'])) eval('?>'.parse_file($display['sleep']))?>
<?if ($btrfs):?>
<script>
function enable_stop() {
$.get('/webGui/include/ReloadPage.php',{btrfs:'btrfs'},function(data) {
switch (data) {
case 'disable':
setTimeout(enable_stop,5000);
break;
case 'enable':
var stop = $('td#stop');
stop.html(stop.html().replace("<?=$btrfs?>",""));
$('input[value="_(Stop)_"]').prop('disabled',false);
break;}
});
}
enable_stop();
</script>
<?endif;?>
:array_status_help:
<?if ($var['fsState'] == "Stopped"):?>
:array_devices_help:
<?if ($encrypt):?>
<div></div>
:encryption_help:
<?endif;?>
<?endif;?>