]> git.datanom.net - omvzfs.git/blob - gui/rpc/zfs.inc
Use /dev/disk/by-path as default for new pools as suggested by ZoL FAQ.
[omvzfs.git] / gui / rpc / zfs.inc
1 <?php
2
3 require_once("openmediavault/object.inc");
4 require_once("openmediavault/config.inc");
5 require_once("openmediavault/error.inc");
6 require_once("openmediavault/util.inc");
7 require_once("openmediavault/rpcservice.inc");
8 require_once("openmediavault/notify.inc");
9 require_once("zfs/Utils.php");
10 require_once("zfs/Dataset.php");
11 require_once("zfs/Snapshot.php");
12 require_once("zfs/Zvol.php");
13 require_once("zfs/Zpool.php");
14 require_once("zfs/NotifyListener.php");
15
16 class OMVRpcServiceZFS extends OMVRpcServiceAbstract {
17 public function getName() {
18 return "ZFS"; // RPC Service name. Same as in .js files
19 }
20
21 /* Initialize the RPC service. Different methods of the RPC service are declared here*/
22 public function initialize() {
23 $this->registerMethod("addPool");
24 $this->registerMethod("getObjectTree");
25 $this->registermethod("passParam");
26 $this->registermethod("addObject");
27 $this->registermethod("deleteObject");
28 $this->registermethod("getProperties");
29 $this->registermethod("setProperties");
30 $this->registermethod("inherit");
31 $this->registermethod("getSharedParams");
32 $this->registermethod("createShare");
33 }
34
35 public function addPool($params, $context) {
36 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
37 switch ($params['pooltype']) {
38 case "basic":
39 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSPLAIN;
40 break;
41 case "mirror":
42 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSMIRROR;
43 break;
44 case "raidz1":
45 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ1;
46 break;
47 case "raidz2":
48 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ2;
49 break;
50 case "raidz3":
51 $pooltype = OMVModuleZFSVdevType::OMVMODULEZFSRAIDZ3;
52 break;
53 default:
54 throw new OMVModuleZFSException("Incorrect pool type specified");
55 break;
56 }
57 //Check for user supplied options
58 $opts = "";
59 if ($params['force']) {
60 $opts .= "-f ";
61 }
62 if (strlen($params['mountpoint']) > 0) {
63 $opts .= "-m " . $params['mountpoint'] . " ";
64 }
65
66 //Use /dev/disk/by-path as deafult when creating new pools as suggested in ZoL FAQ.
67 $disks = preg_split("/[,;]/", $params['devices']);
68 if (file_exists("/dev/disk/by-path/")) {
69 $tmp_disks = array();
70 foreach ($disks as $disk) {
71 $tmp_disks[] = OMVModuleZFSUtil::getDiskPath($disk);
72 }
73 $disks = $tmp_disks;
74 }
75
76 $vdev = new OMVModuleZFSVdev($params['name'], $pooltype, $disks);
77 $pool = new OMVModuleZFSZpool($vdev, $opts);
78 //Ugly fix to solve the problem of blkid not displaying info on newly created pools
79 $pool->export();
80 $pool->import($pool->getName());
81 }
82
83 public function getObjectTree($params, $context) {
84 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
85 $objects = OMVModuleZFSUtil::getZFSFlatArray();
86 $new = array();
87 foreach ($objects as $a){
88 $new[$a['parentid']][] = $a;
89 }
90 $tree = OMVModuleZFSUtil::createTree($new, $new['root']);
91 OMVModuleZFSUtil::addMissingOMVMntEnt(); //Adds missing ZFS filesystems to the OMV core
92 return $tree;
93 }
94
95 public function passParam($params, $context) {
96 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
97 //$msg = "Key=" . $params['key'] . ";Value=" . $params['value'] . ";";
98 //throw new OMVModuleZFSException($msg);
99 return array($params['key'] => $params['value']);
100 }
101
102 public function addObject($params, $context) {
103 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
104 switch ($params['type']) {
105 case "filesystem":
106 $name = $params['path'] . "/" . $params['name'];
107 $tmp = new OMVModuleZFSDataset($name);
108 break;
109 case "snapshot":
110 $name = $params['path'] . "@" . $params['name'];
111 $tmp = new OMVModuleZFSSnapshot($name);
112 break;
113 case "volume":
114 $name = $params['path'] . "/" . $params['name'];
115 $tmp = new OMVModuleZFSZvol($name);
116 $tmp->create($params['size']);
117 break;
118 default:
119 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
120 break;
121 }
122 }
123
124 public function deleteObject($params, $context) {
125 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
126 switch ($params['type']) {
127 case "Filesystem":
128 case "Clone":
129 $name = $params['name'];
130 $tmp = new OMVModuleZFSDataset($name);
131 $tmp->destroy();
132 break;
133 case "Snapshot":
134 $name = $params['name'];
135 $tmp = new OMVModuleZFSSnapshot($name);
136 $tmp->destroy();
137 break;
138 case "Volume":
139 $name = $params['name'];
140 $tmp = new OMVModuleZFSZvol($name);
141 $tmp->destroy();
142 break;
143 case "Pool":
144 $name = $params['name'];
145 $tmp = new OMVModuleZFSZpool($name);
146 $tmp->destroy();
147 break;
148 default:
149 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
150 break;
151 }
152 }
153
154 public function getProperties($params, $context) {
155 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
156 $objects = array();
157 $name = $params['name'];
158 switch ($params['type']) {
159 case "Filesystem":
160 case "Clone":
161 $tmp = new OMVModuleZFSDataset($name);
162 break;
163 case "Snapshot":
164 $tmp = new OMVModuleZFSSnapshot($name);
165 break;
166 case "Volume":
167 $tmp = new OMVModuleZFSZvol($name);
168 break;
169 case "Pool":
170 $tmp = new OMVModuleZFSZpool($name);
171 break;
172 default:
173 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
174 break;
175 }
176 $properties = $tmp->getProperties();
177 foreach ($properties as $propertyk => $propertyv) {
178 if (!(strcmp($propertyv['source'], "-") == 0)) {
179 $objects[] = array('property' => $propertyk,
180 'value' => $propertyv['value'],
181 'source' => $propertyv['source'],
182 'modified' => "false");
183 }
184 }
185 return $objects;
186 }
187
188 public function setProperties($params, $context) {
189 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
190 $objects = array();
191 switch ($params['type']) {
192 case "Filesystem":
193 case "Clone":
194 $tmp = new OMVModuleZFSDataset($params['name']);
195 break;
196 case "Snapshot":
197 $tmp = new OMVModuleZFSSnapshot($params['name']);
198 break;
199 case "Volume":
200 $tmp = new OMVModuleZFSZvol($params['name']);
201 break;
202 case "Pool":
203 $tmp = new OMVModuleZFSZpool($params['name']);
204 break;
205 default:
206 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
207 break;
208 }
209 foreach ($params['properties'] as $property) {
210 $objects[$property['property']] = $property['value'];
211 }
212 $tmp->setProperties($objects);
213 }
214
215 public function inherit($params, $context) {
216 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
217 // Create a background process.
218 $bgStatusFilename = $this->createBgProcStatus();
219 $pid = $this->fork();
220 if($pid > 0) { // Parent process.
221 $this->initializeBgProcStatus($bgStatusFilename, $pid);
222 return $bgStatusFilename;
223 }
224 // Child process.
225 try {
226 $bgOutputFilename = $this->createBgProcOutput();
227 $this->updateBgProcStatus($bgStatusFilename, "outputfilename", $bgOutputFilename);
228 switch ($params['type']) {
229 case "Filesystem":
230 case "Clone":
231 $tmp = new OMVModuleZFSDataset($params['name']);
232 break;
233 case "Snapshot":
234 $tmp = new OMVModuleZFSSnapshot($params['name']);
235 break;
236 case "Volume":
237 $tmp = new OMVModuleZFSZvol($params['name']);
238 break;
239 case "Pool":
240 $tmp = new OMVModuleZFSZpool($params['name']);
241 break;
242 default:
243 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
244 break;
245 }
246 $tmp->inherit($params['property']);
247 $this->finalizeBgProcStatus($bgStatusFilename, $output);
248 exit(0);
249 } catch(Exception $e) {
250 $this->finalizeBgProcStatus($bgStatusFilename, "", $e);
251 exit(1);
252 }
253 }
254
255 public function getSharedParams($params, $context) {
256 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
257 $objects = array();
258 $ds = new OMVModuleZFSDataset($params['name']);
259 $mountpoint = $ds->getMountPoint();
260 return array(
261 "mountpoint" => $mountpoint,
262 "name" => $params['name'],
263 "type" => $params['type']);
264 }
265
266 public function createShare($params, $context) {
267 global $xmlConfig;
268 $this->validateMethodContext($context, array("role" => OMV_ROLE_ADMINISTRATOR));
269
270 //Get the UUID of the Pool
271 $poolname = OMVModuleZFSUtil::getPoolname($params['name']);
272 $pooluuid = OMVModuleZFSUtil::getUUIDbyName($poolname);
273
274 //Get the mntent object and fetch it's uuid.
275 $xpath = "//system/fstab/mntent[fsname=" . $pooluuid . "]";
276 $mountpoint = $xmlConfig->get($xpath);
277 $mntentref = $mountpoint['uuid'];
278
279 // Prepare the configuration object. Use the name of the shared
280 // folder as the relative directory name of the share.
281 switch ($params['type']) {
282 case "Filesystem":
283 $tmp = new OMVModuleZFSDataset($params['name']);
284 break;
285 case "Clone":
286 $tmp = new OMVModuleZFSDataset($params['name']);
287 break;
288 default:
289 throw new OMVModuleZFSException("Illegal type provided: " . $params['type']);
290 break;
291 }
292
293 $uuid = OMVUtil::uuid();
294 $pathName = $tmp->getMountPoint();
295 $subdirs = preg_split('/\//',$pathName);
296 $reldirpath = $subdirs[count($subdirs)-1];
297 $object = array(
298 "uuid" => $uuid,
299 "name" => $params['sharename'],
300 "comment" => $params['comment'],
301 "mntentref" => $mntentref,
302 "reldirpath" => $reldirpath
303 );
304
305 // Set the configuration object.
306 $success = FALSE;
307 // Check uniqueness. The share name must be global unique because
308 // the name is also used when exporting a shared folder via NFS for
309 // example.
310 $xpath = sprintf("//system/shares/sharedfolder[name='%s']",
311 $params['name']);
312 if(TRUE === $xmlConfig->exists($xpath)) {
313 throw new OMVException(OMVErrorMsg::E_CONFIG_OBJECT_UNIQUENESS,
314 gettext("A shared folder with the given name already exists"));
315 }
316
317 // Add empty list of privileges per default.
318 $object['privileges'] = array();
319
320 // Append object to configuration.
321 $success = $xmlConfig->set("//system/shares",
322 array("sharedfolder" => $object));
323 if(FALSE === $success) {
324 throw new OMVException(OMVErrorMsg::E_CONFIG_SET_OBJECT_FAILED);
325 }
326
327 // Append the file mode field to the notification object if set.
328 // Defaults to 775.
329 $object['mode'] = "775";
330 if(array_key_exists("mode", $params)) {
331 $object['mode'] = $params['mode'];
332 }
333
334 // Change group owner of directory to configured default group,
335 // e.g. 'users'.
336 if(FALSE === chgrp($pathName, $GLOBALS['OMV_USERMGMT_DEFAULT_GROUP'])) {
337 throw new OMVException(OMVErrorMsg::E_MISC_FAILURE,
338 sprintf("Failed to set file group to '%s' for '%s'",
339 $GLOBALS['OMV_USERMGMT_DEFAULT_GROUP'], $pathName));
340 }
341
342 // Set the setgid bit. Setting this permission means that all files
343 // created in the folder will inherit the group of the folder rather
344 // than the primary group of the user who creates the file.
345 $mode = fileperms($pathName) | 02000;
346 if(FALSE === chmod($pathName, $mode)) {
347 throw new OMVException(OMVErrorMsg::E_MISC_FAILURE,
348 sprintf("Failed to set file mode to '%o' for '%s'",
349 $mode, $pathName));
350 }
351
352 // Notify configuration changes.
353 $dispatcher = &OMVNotifyDispatcher::getInstance();
354 $dispatcher->notify(OMV_NOTIFY_CREATE,"org.openmediavault.system.shares.sharedfolder", $object);
355 // Return the configuration object.
356 return $object;
357 }
358
359 }
360
361 // Register the RPC service.
362 $rpcServiceMgr = &OMVRpcServiceMgr::getInstance(); // Get the "root" instance for the Services
363 $rpcServiceMgr->registerService(new OMVRpcServiceZFS()); // Register a new instance of the RPC service described above
364 ?>
365
This page took 0.254089 seconds and 6 git commands to generate.