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