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