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