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