*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
/**
* @class OMVModuleZPool.
*/
require 'OMVModulePoolType.php';
class OMVModuleZPool {
private $params;
private $log;
private $mirror_log;
private $cache;
private $spare;
/**
* Constructor of class OMVModuleZPool.
* @param params Array which can contain all or a subset of
* the following fields:
* \em atime Either true or false. Default is true.
* \em compress Either true or false. Default is false.
* \em dedub Either true or false. Default is false.
* \em name Name for pool
* \em size Size of pool in either MB or GB. 100M or 100G.
* \em sync Either true or false. Default is false.
* \em type See OMVModulePoolType.
* \em vdevs Number of vdevs in pool. Default is 1.
* @param debug Print debug information to STDERR.
* @throws Exception.
*/
public function __construct(array $params = array(), $debug = false) {
$this->params = array(
'atime' => 'on',
'compress' => 'off',
'dedub' => 'off',
'name' => '',
'size' => '0M',
'sync' => 'off',
'type' => OMVModulePoolType::OMVModulePoolType_TYPE_NONE,
'vdevs' => 1
);
foreach ($params as $key => $value) {
if (array_key_exists($key, $this->params)) {
$this->validate($key, $value);
$this->params[$key] = $value;
} else {
throw new Exception("$key: Not valid parameter");
}
}
if ($debug) {
fprintf(STDERR, "OMVModuleZPool instantiate with the following params\n");
foreach ($this->params as $key => $value) {
$param = ($key == 'type') ? OMVModulePoolType::toString($value) : $value;
fprintf(STDERR, " %-8s => %s\n", $key, $param);
}
}
}
/**
* Create pool.
* @param disks Array of disks. Format: /dev/sdx or /dev/vdx.
* @param options Array which can contain all or a subset of
* the following fields:
* \em log Array which contains the following fields:
* \em disks Array of disks. Format: /dev/sdx or /dev/vdx.
* \em mirror Either true or false. Default is false.
* \em cache Disk to use for cache. Default use internal.
* \em spare Array of disks. Format: /dev/sdx or /dev/vdx.
* @throws Exception.
*/
public function createPool(array $disks, array $options = array()) {
$disk_num = count($disks);
if ($disk_num < 1) {
throw new Exception("Pool must have at least 1 disk");
};
switch ($this->params['type']) {
case OMVModulePoolType::OMVModulePoolType_TYPE_NONE:
print "Create basic pool\n";
if ($disk_num % $this->params['vdevs']) {
throw new Exception("$disk_num disk(s) != ".$this->params['vdevs']." vdev(s)");
}
foreach ($options as $key => $value) {
$this->validate($key, $value, OMVPoolType::OMV_TYPE_NONE);
}
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_MIRROR:
print "Create mirrored pool\n";
if ($disk_num / $this->params['vdevs'] < 2 ||
($disk_num / $this->params['vdevs']) % $this->params['vdevs']) {
throw new Exception("$disk_num disk(s) cannot be evenly distributed to ".
$this->params['vdevs']." vdev(s) and form a proper mirror");
}
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ1:
print "Create raidz1 pool\n";
if ($disk_num / $this->params['vdevs'] < 3 ||
($disk_num / $this->params['vdevs']) % $this->params['vdevs']) {
throw new Exception("$disk_num disk and ".$this->params['vdevs'].
" vdev(s) cannot provide mininum 3 disks per vdev for raidz1");
}
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ2:
print "Create raidz2 pool\n";
if ($disk_num / $this->params['vdevs'] < 5 ||
($disk_num / $this->params['vdevs']) % $this->params['vdevs']) {
throw new Exception("$disk_num disk and ".$this->params['vdevs'].
" vdev(s) cannot provide mininum 5 disks per vdev for raidz2");
}
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ3:
print "Create raidz3 pool\n";
if ($disk_num / $this->params['vdevs'] < 8 ||
($disk_num / $this->params['vdevs']) % $this->params['vdevs']) {
throw new Exception("$disk_num disk and ".$this->params['vdevs'].
" vdev(s) cannot provide mininum 8 disks per vdev for raidz3");
}
break;
}
}
private function validate($key, $value, $type = -1) {
if ($type > -1) {
switch ($type) {
case OMVModulePoolType::OMVModulePoolType_TYPE_NONE:
print "Create basic pool\n";
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_MIRROR:
print "Create mirrored pool\n";
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ1:
print "Create raidz1 pool\n";
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ2:
print "Create raidz2 pool\n";
break;
case OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ3:
print "Create raidz3 pool\n";
break;
default:
throw new Exception("$type: Unknown OMVModulePoolType");
}
} else {
switch ($key) {
case 'atime':
case 'compress':
case 'dedub':
case 'sync':
if ($value != 'on' && $value != 'off') {
throw new Exception("$key: Value must be 'on' or 'off' found '$value'");
}
break;
case 'size':
if (! preg_match('/^\d+(M|G)$/', $value)) {
throw new Exception("$key: Value must have format '100M' or '100G' found '$value'");
}
break;
case 'type':
if (OMVModulePoolType::OMVModulePoolType_TYPE_NONE > $value ||
OMVModulePoolType::OMVModulePoolType_TYPE_RAIDZ3 < $value) {
throw new Exception("$key: Value must be type of OMVPoolType found '$value'");
}
break;
case 'vdevs':
if (! preg_match('/^\d+$/', $value) || $value < 1) {
throw new Exception("$key: Value must be positive int found '$value'");
}
}
}
}
}