]> git.datanom.net - omvzfs.git/blob - src/Utils.php
1f1e8ebbc59ae6fb17c1ac23c9f3ee529c9ff393
[omvzfs.git] / src / Utils.php
1 <?php
2 require_once("Exception.php");
3 require_once("openmediavault/util.inc");
4 require_once("Dataset.php");
5 require_once("Zvol.php");
6 require_once("Vdev.php");
7 require_once("Zpool.php");
8
9 /**
10 * Helper class for ZFS module
11 */
12 class OMVModuleZFSUtil {
13
14 /**
15 * Clears all ZFS labels on specified devices.
16 * Needed for blkid to display proper data.
17 *
18 */
19 public static function clearZFSLabel($disks) {
20 foreach ($disks as $disk) {
21 $cmd = "zpool labelclear /dev/" . $disk . "1";
22 OMVModuleZFSUtil::exec($cmd,$out,$res);
23 }
24 }
25
26 /**
27 * Return all disks in /dev/sdXX used by the pool
28 *
29 * @return array An array with all the disks
30 */
31 public static function getDevDisksByPool($name) {
32 $pool = new OMVModuleZFSZpool($name);
33 $disks = array();
34 $vdevs = $pool->getVdevs();
35 foreach ($vdevs as $vdev) {
36 $vdisks = $vdev->getDisks();
37 foreach ($vdisks as $vdisk) {
38 if (preg_match('/^[a-z0-9]+$/', $vdisk)) {
39 $disks[] = $vdisk;
40 continue;
41 }
42 $cmd = "ls -la /dev/disk/by-path/" . $vdisk;
43 unset($out);
44 OMVModuleZFSUtil::exec($cmd,$out,$res);
45 if (count($out) === 1) {
46 if (preg_match('/^.*\/([a-z0-9]+)$/', $out[0], $match)) {
47 $disks[] = $match[1];
48 }
49 }
50 }
51 }
52 return($disks);
53 }
54
55 /**
56 * Deletes all shared folders pointing to the specifc path
57 *
58 */
59 public static function deleteShares($name) {
60 global $xmlConfig;
61 $tmp = new OMVModuleZFSDataset($name);
62 $reldirpath = OMVModuleZFSUtil::getReldirpath($tmp->getMountPoint());
63 $poolname = OMVModuleZFSUtil::getPoolname($name);
64 $pooluuid = OMVModuleZFSUtil::getUUIDbyName($poolname);
65 $xpath = "//system/fstab/mntent[fsname='" . $pooluuid . "']";
66 $mountpoint = $xmlConfig->get($xpath);
67 $mntentuuid = $mountpoint['uuid'];
68 $xpath = "//system/shares/sharedfolder[mntentref='" . $mntentuuid . "' and reldirpath='" . $reldirpath . "']";
69 $object = $xmlConfig->get($xpath);
70 $xmlConfig->delete($xpath);
71 $dispatcher = &OMVNotifyDispatcher::getInstance();
72 $dispatcher->notify(OMV_NOTIFY_DELETE,"org.openmediavault.system.shares.sharedfolder",$object);
73 }
74
75 /**
76 * Get the relative path by complete path
77 *
78 * @return string Relative path of the complet path
79 */
80 public static function getReldirpath($path) {
81 $subdirs = preg_split('/\//',$path);
82 $reldirpath = "";
83 for ($i=2;$i<count($subdirs);$i++) {
84 $reldirpath .= $subdirs[$i] . "/";
85 }
86 return(rtrim($reldirpath, "/"));
87
88 }
89
90 /**
91 * Get /dev/disk/by-path from /dev/sdX
92 *
93 * @return string Disk identifier
94 */
95 public static function getDiskPath($disk) {
96 preg_match("/^.*\/([A-Za-z0-9]+)$/", $disk, $identifier);
97 $cmd = "ls -la /dev/disk/by-path | grep '$identifier[1]$'";
98 OMVModuleZFSUtil::exec($cmd, $out, $res);
99 if (is_array($out)) {
100 $cols = preg_split('/[\s]+/', $out[0]);
101 return($cols[count($cols)-3]);
102 }
103 }
104
105
106 /**
107 * Get poolname from name of dataset/volume etc.
108 *
109 * @return string Name of the pool
110 */
111 public static function getPoolname($name) {
112 $tmp = preg_split('/[\/]+/', $name);
113 return($tmp[0]);
114 }
115
116 /**
117 * Get UUID of ZFS pool by name
118 *
119 * @return string UUID of the pool
120 */
121 public static function getUUIDbyName($poolname) {
122 $cmd = "zpool get guid " . $poolname . " 2>&1";
123 OMVModuleZFSUtil::exec($cmd, $out, $res);
124 if (isset($out)) {
125 $headers = preg_split('/[\s]+/', $out[0]);
126 for ($i=0; $i<count($headers); $i++) {
127 if (strcmp($headers[$i], "VALUE") === 0) {
128 $valuecol=$i;
129 break;
130 }
131 }
132 $line = preg_split('/[\s]+/', $out[1]);
133 return $line[$valuecol];
134 }
135 return null;
136 }
137
138 /**
139 * Add any missing ZFS pool to the OMV backend
140 *
141 */
142 public static function addMissingOMVMntEnt() {
143 global $xmlConfig;
144 $cmd = "zpool list -H -o name";
145 OMVModuleZFSUtil::exec($cmd, $out, $res);
146 foreach($out as $name) {
147 $pooluuid = OMVModuleZFSUtil::getUUIDbyName($name);
148 $xpath = "//system/fstab/mntent[fsname='" . $pooluuid . "']";
149 $mountpoint = $xmlConfig->get($xpath);
150 if (is_null($mountpoint)) {
151 $uuid = OMVUtil::uuid();
152 $pool = new OMVModuleZFSZpool($name);
153 $dir = $pool->getMountPoint();
154 $object = array(
155 "uuid" => $uuid,
156 "fsname" => $pooluuid,
157 "dir" => $dir,
158 "type" => "zfs",
159 "opts" => "rw,relatime,xattr,noacl",
160 "freq" => "0",
161 "passno" => "0"
162 );
163 $xmlConfig->set("//system/fstab",array("mntent" => $object));
164 $dispatcher = &OMVNotifyDispatcher::getInstance();
165 $dispatcher->notify(OMV_NOTIFY_CREATE,"org.openmediavault.system.fstab.mntent", $object);
166 }
167 }
168 return null;
169 }
170
171 /**
172 * Get an array with all ZFS objects
173 *
174 * @return An array with all ZFS objects
175 */
176 public static function getZFSFlatArray() {
177 $prefix = "root/pool-";
178 $objects = array();
179 $cmd = "zfs list -H -t all -o name,type 2>&1";
180 $expanded = true;
181 OMVModuleZFSUtil::exec($cmd,$out,$res);
182 foreach ($out as $line) {
183 $parts = preg_split('/\t/',$line);
184 $path = $parts[0];
185 $type = $parts[1];
186 $subdirs = preg_split('/\//',$path);
187 $root = $subdirs[0];
188 $tmp = array();
189
190 switch ($type) {
191 case "filesystem":
192 if (strpos($path,'/') === false) {
193 //This is a Pool
194 $tmp = array('id'=>$prefix . $path,
195 'parentid'=>'root',
196 'name'=>$path,
197 'type'=>'Pool',
198 'icon'=>'images/raid.png',
199 'expanded'=>$expanded,
200 'path'=>$path);
201 $pool = new OMVModuleZFSZpool($path);
202 $tmp['size'] = $pool->getSize();
203 $tmp['used'] = $pool->getAttribute("allocated");
204 $tmp['available'] = $pool->getAttribute("free");
205 $tmp['mountpoint'] = $pool->getMountPoint();
206 array_push($objects,$tmp);
207 } else {
208 //This is a Filesystem
209 preg_match('/(.*)\/(.*)$/', $path, $result);
210 $tmp = array('id'=>$prefix . $path,
211 'parentid'=>$prefix . $result[1],
212 'name'=>$result[2],
213 'icon'=>"images/filesystem.png",
214 'path'=>$path,
215 'expanded'=>$expanded);
216 $ds = new OMVModuleZFSDataset($path);
217 if ($ds->isClone()) {
218 //This is a cloned Filesystem
219 $tmp['type'] = "Clone";
220 $tmp['origin'] = $ds->getOrigin();
221 } else {
222 //This is a standard Filesystem.
223 $tmp['type']= ucfirst($type);
224 }
225 $tmp['size'] = "n/a";
226 $used = $ds->getProperty("used");
227 $tmp['used'] = $used['value'];
228 $available = $ds->getProperty("available");
229 $tmp['available'] = $available['value'];
230 $tmp['mountpoint'] = $ds->getMountPoint();
231 array_push($objects,$tmp);
232 }
233 break;
234
235 case "volume":
236 preg_match('/(.*)\/(.*)$/', $path, $result);
237 $tmp = array('id'=>$prefix . $path,
238 'parentid'=>$prefix . $result[1],
239 'name'=>$result[2],
240 'type'=>ucfirst($type),
241 'icon'=>"images/save.png",
242 'path'=>$path,
243 'expanded'=>$expanded);
244 $vol = new OMVModuleZFSZvol();
245 $tmp['size'] = $vol->getSize();
246 $tmp['used'] = "n/a";
247 $tmp['available'] = "n/a";
248 $tmp['mountpoint'] = "n/a";
249 array_push($objects,$tmp);
250 break;
251
252 case "snapshot":
253 preg_match('/(.*)\@(.*)$/', $path, $result);
254 $subdirs = preg_split('/\//',$result[1]);
255 $root = $subdirs[0];
256 $tmp = array('id'=>$prefix . $path,
257 'parentid'=>$prefix . $result[1],
258 'name'=>$result[2],
259 'type'=>ucfirst($type),
260 'icon'=>'images/zfs_snap.png',
261 'path'=>$path,
262 'expanded'=>$expanded);
263 $tmp['size'] = "n/a";
264 $tmp['used'] = "n/a";
265 $tmp['available'] = "n/a";
266 $tmp['mountpoint'] = "n/a";
267 array_push($objects,$tmp);
268 break;
269
270 default:
271 break;
272 }
273 }
274 return $objects;
275 }
276
277 /**
278 * Create a tree structured array
279 *
280 * @param &$list The flat array to convert to a tree structure
281 * @param $parent Root node of the tree to create
282 * @return Tree structured array
283 *
284 */
285 public static function createTree(&$list, $parent){
286 $tree = array();
287 foreach ($parent as $k=>$l){
288 if(isset($list[$l['id']])){
289 $l['leaf'] = false;
290 $l['children'] = OMVModuleZFSUtil::createTree($list, $list[$l['id']]);
291 } else {
292 $l['leaf'] = true;
293 }
294 $tree[] = $l;
295 }
296 return $tree;
297 }
298
299 /**
300 * Get all Datasets as objects
301 *
302 * @return An array with all the Datasets
303 */
304 public static function getAllDatasets() {
305 $datasets = array();
306 $cmd = "zfs list -H -t filesystem -o name 2>&1";
307 OMVModuleZFSUtil::exec($cmd, $out, $res);
308 foreach ($out as $name) {
309 $ds = new OMVModuleZFSDataset($name);
310 array_push($datasets, $ds);
311 }
312 return $datasets;
313 }
314
315 /**
316 * Helper function to execute a command and throw an exception on error
317 * (requires stderr redirected to stdout for proper exception message).
318 *
319 * @param string $cmd Command to execute
320 * @param array &$out If provided will contain output in an array
321 * @param int &$res If provided will contain Exit status of the command
322 * @return string Last line of output when executing the command
323 * @throws OMVModuleZFSException
324 * @access public
325 */
326 public static function exec($cmd, &$out = null, &$res = null) {
327 $tmp = OMVUtil::exec($cmd, $out, $res);
328 if ($res) {
329 throw new OMVModuleZFSException(implode("\n", $out));
330 }
331 return $tmp;
332 }
333
334 }
335
336
337 ?>
This page took 0.093816 seconds and 4 git commands to generate.