]> git.datanom.net - omvzfs.git/blame_incremental - src/Vdev.php
Made it optional to use /dev/disk/by-path
[omvzfs.git] / src / Vdev.php
... / ...
CommitLineData
1<?php
2require_once("Exception.php");
3require_once("VdevType.php");
4require_once("openmediavault/util.inc");
5
6/**
7 * Contains a Vdev
8 *
9 * @author Michael Rasmussen
10 * @version 0.1
11 * @copyright Michael Rasmussen <mir@datanom.net>
12 */
13class OMVModuleZFSVdev {
14 // Attributes
15 /**
16 * Array holding disks
17 *
18 * @var array $disks
19 * @access private
20 */
21 private $disks;
22
23 /**
24 * Name of pool
25 *
26 * @var string $pool pool name
27 * @access private
28 */
29 private $pool;
30
31 /**
32 * This vdev type
33 *
34 * @var OMVModuleZFSVdevType $type Vdev type
35 * @access private
36 */
37 private $type;
38
39 // Associations
40 // Operations
41 /**
42 * Constructor
43 *
44 * @param $pool pool this mirror belongs to
45 * @throws OMVModuleZFSException
46 */
47
48 public function __construct($pool, $type, array $disks) {
49 switch ($type) {
50 case OMVModuleZFSVdevType::OMVMODULEZFSPLAIN:
51 break;
52 case OMVModuleZFSVdevType::OMVMODULEZFSMIRROR:
53 if (count($disks) < 2)
54 throw new OMVModuleZFSException("A mirror must contain at least 2 disks");
55 break;
56 case OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ1:
57 if (count($disks) < 3)
58 throw new OMVModuleZFSException("A Raidz1 must contain at least 3 disks");
59 break;
60 case OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ2:
61 if (count($disks) < 4)
62 throw new OMVModuleZFSException("A Raidz2 must contain at least 4 disks");
63 break;
64 case OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ3:
65 if (count($disks) < 5)
66 throw new OMVModuleZFSException("A Raidz3 must contain at least 5 disks");
67 break;
68 default:
69 throw new OMVModuleZFSException("$type: Unknown zpool type");
70 }
71 $this->pool = $pool;
72 $this->disks = $disks;
73 $this->type = $type;
74 }
75
76 /**
77 * Helper function to execute an external program.
78 * @param command The command that will be executed.
79 * @param output If the output argument is present, then the specified
80 * array will be filled with every line of output from the command.
81 * Trailing whitespace, such as \n, is not included in this array.
82 * @return The exit code of the command.
83 * @throws E_EXEC_FAILED
84 */
85 private function exec($command, &$output = NULL) {
86 OMVUtil::exec($command, $output, $result);
87 return $result;
88 }
89
90 private function safeExec($disk, $add = true, $change = false) {
91 $result = 1;
92
93 if ($add) {
94 if ($change || $this->type == OMVModuleZFSVdevType::OMVMODULEZFSMIRROR) {
95 $disk1 = $this->disks[0];
96 $result = exec("zpool attach {$this->pool} $disk1 $disk", $err);
97 } else {
98 $result = exec("zpool add {$this->pool} $disk", $err);
99 }
100 } else {
101 if ($this->type == OMVModuleZFSVdevType::OMVMODULEZFSMIRROR) {
102 $disk1 = $this->disks[0];
103 if (($res = exec("zpool offline {$this->pool} $disk", $err)) > 0)
104 $result = $res;
105 else
106 $result = exec("zpool detach {$this->pool} $disk", $err);
107 } else {
108 $result = 1;
109 $err = "Cannot remove $disk from {$this->pool}";
110 }
111 }
112
113 return ($result) ? $err : null;
114 }
115
116 /**
117 * Add a disk to this Vdev
118 *
119 * @param $disk the disk
120 * @throws OMVModuleZFSException
121 * @access public
122 */
123 public function addDisk($disk, $changeType = false) {
124 if ($this->type != OMVModuleZFSVdevType::OMVMODULEZFSPLAIN ||
125 $this->type != OMVModuleZFSVdevType::OMVMODULEZFSMIRROR)
126 throw new OMVModuleZFSException("A Raidz Vdev cannot be changed");
127
128 if (in_array($disk, $this->disks))
129 throw new OMVModuleZFSException("$disk: Already part of Vdev");
130
131 if ($this->type == OMVModuleZFSVdevType::OMVMODULEZFSPLAIN &&
132 count($this->disks) < 2 && $changeType) {
133 $this->type = OMVModuleZFSVdevType::OMVMODULEZFSMIRROR;
134 }
135
136 if (($err = safeExec($disk, true, $changeType)) != null)
137 throw new OMVModuleZFSException($err);
138 else
139 array_push($this->disks, $disk);
140 }
141
142 /**
143 * Remove a disk from Vdev
144 *
145 * @param $disk disk to remove
146 * @throws OMVModuleZFSException
147 * @access public
148 */
149 public function removeDisk($disk, $changeType = false) {
150 $new_disks = array();
151
152 if ($this->type != OMVModuleZFSVdevType::OMVMODULEZFSMIRROR)
153 throw new OMVModuleZFSException("Only inactive hot spares," .
154 "cache, top-level, or log devices can be removed");
155
156 if (count($this->disks) < 3 && ! $changeType)
157 throw new OMVModuleZFSException("A mirror must contain at least 2 disks");
158
159 if (! in_array($disk, $this->disks))
160 throw new OMVModuleZFSException("$disk: Not part of Vdev");
161
162 if (($err = safeExec($disk, false, $changeType)) != null)
163 throw new OMVModuleZFSException($err);
164 else {
165 foreach ($this->disks as $_disk) {
166 if (strcmp($_disk, $disk) != 0)
167 array_push($new_disks, $_disk);
168 }
169 }
170
171 $this->disks = $new_disks;
172 }
173
174 /**
175 * Get disk array
176 *
177 * @return array with disks
178 * @access public
179 */
180 public function getDisks() {
181 return $this->disks;
182 }
183
184 /**
185 * Get pool
186 *
187 * @return string pool
188 * @access public
189 */
190 public function getPool() {
191 return $this->pool;
192 }
193
194 /**
195 * Get type
196 *
197 * @return OMVModuleZFSVdevType
198 * @access public
199 */
200 public function getType() {
201 return $this->type;
202 }
203
204}
205
206?>
This page took 0.035598 seconds and 5 git commands to generate.