]>
git.datanom.net - omvzfs.git/blob - src/Utils.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");
10 * Helper class for ZFS module
12 class OMVModuleZFSUtil
{
15 * Manages relocation of ZFS filesystem mountpoints in the OMV backend.
16 * Needed when the user changes mountpoint of a filesystem in the GUI.
19 public static function relocateFilesystem($name) {
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);
33 * Clears all ZFS labels on specified devices.
34 * Needed for blkid to display proper data.
37 public static function clearZFSLabel($disks) {
38 foreach ($disks as $disk) {
39 $cmd = "zpool labelclear /dev/" . $disk . "1";
40 OMVModuleZFSUtil
::exec($cmd,$out,$res);
46 * Return all disks in /dev/sdXX used by the pool
48 * @return array An array with all the disks
50 public static function getDevDisksByPool($name) {
51 $pool = new OMVModuleZFSZpool($name);
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)) {
61 $cmd = "ls -la /dev/disk/by-path/" . $vdisk;
63 OMVModuleZFSUtil
::exec($cmd,$out,$res);
64 if (count($out) === 1) {
65 if (preg_match('/^.*\/([a-z0-9]+)$/', $out[0], $match)) {
75 * Deletes all shared folders pointing to the specifc path
78 public static function deleteShares($name) {
80 $poolname = OMVModuleZFSUtil
::getPoolname($name);
81 $pooluuid = OMVModuleZFSUtil
::getUUIDbyName($poolname);
82 $ds = new OMVModuleZFSDataset($name);
83 $dir = $ds->getMountPoint();
84 $xpath = "//system/fstab/mntent[fsname='" . $pooluuid . "' and dir='" . $dir . "' and type='zfs']";
85 $mountpoint = $xmlConfig->get($xpath);
86 $mntentuuid = $mountpoint['uuid'];
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.");
96 $xmlConfig->delete($xpath);
97 $dispatcher = &OMVNotifyDispatcher
::getInstance();
98 $dispatcher->notify(OMV_NOTIFY_DELETE
,"org.openmediavault.system.shares.sharedfolder",$object);
102 * Get the relative path by complete path
104 * @return string Relative path of the complet path
106 public static function getReldirpath($path) {
107 $subdirs = preg_split('/\//',$path);
109 for ($i=2;$i<count($subdirs);$i++
) {
110 $reldirpath .= $subdirs[$i] . "/";
112 return(rtrim($reldirpath, "/"));
117 * Get /dev/disk/by-path from /dev/sdX
119 * @return string Disk identifier
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]);
133 * Get poolname from name of dataset/volume etc.
135 * @return string Name of the pool
137 public static function getPoolname($name) {
138 $tmp = preg_split('/[\/]+/', $name);
143 * Get UUID of ZFS pool by name
145 * @return string UUID of the pool
147 public static function getUUIDbyName($poolname) {
148 $cmd = "zpool get guid " . $poolname . " 2>&1";
149 OMVModuleZFSUtil
::exec($cmd, $out, $res);
151 $headers = preg_split('/[\s]+/', $out[0]);
152 for ($i=0; $i<count($headers); $i++
) {
153 if (strcmp($headers[$i], "VALUE") === 0) {
158 $line = preg_split('/[\s]+/', $out[1]);
159 return $line[$valuecol];
165 * Add any missing ZFS filesystems to the OMV backend
168 public static function addMissingOMVMntEnt() {
170 $cmd = "zfs list -H -o name -t filesystem";
171 OMVModuleZFSUtil
::exec($cmd, $out, $res);
172 foreach($out as $name) {
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();
183 "fsname" => $pooluuid,
186 "opts" => "rw,relatime,xattr,noacl",
191 $xmlConfig->set("//system/fstab",array("mntent" => $object));
199 * Get an array with all ZFS objects
201 * @return An array with all ZFS objects
203 public static function getZFSFlatArray() {
204 $prefix = "root/pool-";
206 $cmd = "zfs list -H -t all -o name,type 2>&1";
208 OMVModuleZFSUtil
::exec($cmd,$out,$res);
209 foreach ($out as $line) {
210 $parts = preg_split('/\t/',$line);
213 $subdirs = preg_split('/\//',$path);
219 if (strpos($path,'/') === false) {
221 $tmp = array('id'=>$prefix . $path,
225 'icon'=>'images/raid.png',
226 'expanded'=>$expanded,
228 $pool = new OMVModuleZFSZpool($path);
229 $tmp['size'] = $pool->getSize();
230 $tmp['used'] = $pool->getAttribute("allocated");
231 $tmp['available'] = $pool->getAttribute("free");
232 $tmp['mountpoint'] = $pool->getMountPoint();
233 $vdevs = $pool->getVdevs();
234 $vdev_type = $vdevs[0]->getType();
235 switch ($vdev_type) {
236 case OMVModuleZFSVdevType
::OMVMODULEZFSMIRROR
:
237 $pool_type = "Mirror";
239 case OMVModuleZFSVdevType
::OMVMODULEZFSPLAIN
:
240 $pool_type = "Basic";
242 case OMVModuleZFSVdevType
::OMVMODULEZFSRAIDZ1
:
243 $pool_type = "Raidz1";
245 case OMVModuleZFSVdevType
::OMVMODULEZFSRAIDZ2
:
246 $pool_type = "Raidz2";
248 case OMVModuleZFSVdevType
::OMVMODULEZFSRAIDZ3
:
249 $pool_type = "Raidz3";
252 $tmp['pool_type'] = $pool_type;
253 $tmp['nr_disks'] = count($vdevs[0]->getDisks());
254 array_push($objects,$tmp);
256 //This is a Filesystem
257 preg_match('/(.*)\/(.*)$/', $path, $result);
258 $tmp = array('id'=>$prefix . $path,
259 'parentid'=>$prefix . $result[1],
261 'icon'=>"images/filesystem.png",
263 'expanded'=>$expanded);
264 $ds = new OMVModuleZFSDataset($path);
265 if ($ds->isClone()) {
266 //This is a cloned Filesystem
267 $tmp['type'] = "Clone";
268 $tmp['origin'] = $ds->getOrigin();
270 //This is a standard Filesystem.
271 $tmp['type']= ucfirst($type);
273 $tmp['size'] = "n/a";
274 $used = $ds->getProperty("used");
275 $tmp['used'] = $used['value'];
276 $available = $ds->getProperty("available");
277 $tmp['available'] = $available['value'];
278 $tmp['mountpoint'] = $ds->getMountPoint();
279 $tmp['pool_type'] = "n/a";
280 $tmp['nr_disks'] = "n/a";
281 array_push($objects,$tmp);
286 preg_match('/(.*)\/(.*)$/', $path, $result);
287 $tmp = array('id'=>$prefix . $path,
288 'parentid'=>$prefix . $result[1],
290 'type'=>ucfirst($type),
291 'icon'=>"images/save.png",
293 'expanded'=>$expanded);
294 $vol = new OMVModuleZFSZvol();
295 $tmp['size'] = $vol->getSize();
296 $tmp['used'] = "n/a";
297 $tmp['available'] = "n/a";
298 $tmp['mountpoint'] = "n/a";
299 $tmp['pool_type'] = "n/a";
300 $tmp['nr_disks'] = "n/a";
301 array_push($objects,$tmp);
305 preg_match('/(.*)\@(.*)$/', $path, $result);
306 $subdirs = preg_split('/\//',$result[1]);
308 $tmp = array('id'=>$prefix . $path,
309 'parentid'=>$prefix . $result[1],
311 'type'=>ucfirst($type),
312 'icon'=>'images/zfs_snap.png',
314 'expanded'=>$expanded);
315 $tmp['size'] = "n/a";
316 $tmp['used'] = "n/a";
317 $tmp['available'] = "n/a";
318 $tmp['mountpoint'] = "n/a";
319 $tmp['pool_type'] = "n/a";
320 $tmp['nr_disks'] = "n/a";
321 array_push($objects,$tmp);
332 * Create a tree structured array
334 * @param &$list The flat array to convert to a tree structure
335 * @param $parent Root node of the tree to create
336 * @return Tree structured array
339 public static function createTree(&$list, $parent){
341 foreach ($parent as $k=>$l){
342 if(isset($list[$l['id']])){
344 $l['children'] = OMVModuleZFSUtil
::createTree($list, $list[$l['id']]);
354 * Get all Datasets as objects
356 * @return An array with all the Datasets
358 public static function getAllDatasets() {
360 $cmd = "zfs list -H -t filesystem -o name 2>&1";
361 OMVModuleZFSUtil
::exec($cmd, $out, $res);
362 foreach ($out as $name) {
363 $ds = new OMVModuleZFSDataset($name);
364 array_push($datasets, $ds);
370 * Helper function to execute a command and throw an exception on error
371 * (requires stderr redirected to stdout for proper exception message).
373 * @param string $cmd Command to execute
374 * @param array &$out If provided will contain output in an array
375 * @param int &$res If provided will contain Exit status of the command
376 * @return string Last line of output when executing the command
377 * @throws OMVModuleZFSException
380 public static function exec($cmd, &$out = null, &$res = null) {
381 $tmp = OMVUtil
::exec($cmd, $out, $res);
383 throw new OMVModuleZFSException(implode("\n", $out));
This page took 0.283712 seconds and 6 git commands to generate.