source: mainline/uspace/srv/volsrv/volsrv.c@ 2d78d88

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2d78d88 was 2d78d88, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Modifying mount point for a partition.

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup volsrv
30 * @{
31 */
32/**
33 * @file Volume service
34 */
35
36#include <async.h>
37#include <errno.h>
38#include <str_error.h>
39#include <io/log.h>
40#include <ipc/services.h>
41#include <ipc/vol.h>
42#include <loc.h>
43#include <macros.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <task.h>
47#include <types/vol.h>
48
49#include "mkfs.h"
50#include "part.h"
51#include "volume.h"
52
53#define NAME "volsrv"
54
55static void vol_client_conn(ipc_call_t *, void *);
56
57static errno_t vol_init(void)
58{
59 errno_t rc;
60 vol_volumes_t *volumes = NULL;
61 vol_parts_t *parts = NULL;
62
63 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_init()");
64
65 rc = vol_volumes_create(&volumes);
66 if (rc != EOK)
67 goto error;
68
69 rc = vol_parts_create(volumes, &parts);
70 if (rc != EOK)
71 goto error;
72
73 rc = vol_part_discovery_start(parts);
74 if (rc != EOK)
75 goto error;
76
77 async_set_fallback_port_handler(vol_client_conn, parts);
78
79 rc = loc_server_register(NAME);
80 if (rc != EOK) {
81 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
82 rc = EEXIST;
83 }
84
85 service_id_t sid;
86 rc = loc_service_register(SERVICE_NAME_VOLSRV, &sid);
87 if (rc != EOK) {
88 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
89 rc = EEXIST;
90 goto error;
91 }
92
93 return EOK;
94error:
95 vol_volumes_destroy(volumes);
96 vol_parts_destroy(parts);
97 return rc;
98}
99
100static void vol_get_parts_srv(vol_parts_t *parts, ipc_call_t *icall)
101{
102 ipc_call_t call;
103 size_t size;
104 size_t act_size;
105 errno_t rc;
106
107 if (!async_data_read_receive(&call, &size)) {
108 async_answer_0(&call, EREFUSED);
109 async_answer_0(icall, EREFUSED);
110 return;
111 }
112
113 service_id_t *id_buf = (service_id_t *) malloc(size);
114 if (id_buf == NULL) {
115 async_answer_0(&call, ENOMEM);
116 async_answer_0(icall, ENOMEM);
117 return;
118 }
119
120 rc = vol_part_get_ids(parts, id_buf, size, &act_size);
121 if (rc != EOK) {
122 async_answer_0(&call, rc);
123 async_answer_0(icall, rc);
124 return;
125 }
126
127 errno_t retval = async_data_read_finalize(&call, id_buf, size);
128 free(id_buf);
129
130 async_answer_1(icall, retval, act_size);
131}
132
133static void vol_part_add_srv(vol_parts_t *parts, ipc_call_t *icall)
134{
135 service_id_t sid;
136 errno_t rc;
137
138 sid = IPC_GET_ARG1(*icall);
139
140 rc = vol_part_add_part(parts, sid);
141 if (rc != EOK) {
142 async_answer_0(icall, rc);
143 return;
144 }
145
146 async_answer_0(icall, EOK);
147}
148
149static void vol_part_info_srv(vol_parts_t *parts, ipc_call_t *icall)
150{
151 service_id_t sid;
152 vol_part_t *part;
153 vol_part_info_t pinfo;
154 errno_t rc;
155
156 sid = IPC_GET_ARG1(*icall);
157 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
158 sid);
159 rc = vol_part_find_by_id_ref(parts, sid, &part);
160 if (rc != EOK) {
161 async_answer_0(icall, ENOENT);
162 return;
163 }
164
165 rc = vol_part_get_info(part, &pinfo);
166 if (rc != EOK) {
167 async_answer_0(icall, EIO);
168 goto error;
169 }
170
171 ipc_call_t call;
172 size_t size;
173 if (!async_data_read_receive(&call, &size)) {
174 async_answer_0(&call, EREFUSED);
175 async_answer_0(icall, EREFUSED);
176 goto error;
177 }
178
179 if (size != sizeof(vol_part_info_t)) {
180 async_answer_0(&call, EINVAL);
181 async_answer_0(icall, EINVAL);
182 goto error;
183 }
184
185 rc = async_data_read_finalize(&call, &pinfo,
186 min(size, sizeof(pinfo)));
187 if (rc != EOK) {
188 async_answer_0(&call, rc);
189 async_answer_0(icall, rc);
190 goto error;
191 }
192
193 async_answer_0(icall, EOK);
194error:
195 vol_part_del_ref(part);
196}
197
198static void vol_part_eject_srv(vol_parts_t *parts, ipc_call_t *icall)
199{
200 service_id_t sid;
201 vol_part_t *part;
202 errno_t rc;
203
204 sid = IPC_GET_ARG1(*icall);
205 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
206
207 rc = vol_part_find_by_id_ref(parts, sid, &part);
208 if (rc != EOK) {
209 async_answer_0(icall, ENOENT);
210 goto error;
211 }
212
213 rc = vol_part_eject_part(part);
214 if (rc != EOK) {
215 async_answer_0(icall, EIO);
216 goto error;
217 }
218
219 async_answer_0(icall, EOK);
220error:
221 vol_part_del_ref(part);
222}
223
224static void vol_part_empty_srv(vol_parts_t *parts, ipc_call_t *icall)
225{
226 service_id_t sid;
227 vol_part_t *part;
228 errno_t rc;
229
230 sid = IPC_GET_ARG1(*icall);
231 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
232
233 rc = vol_part_find_by_id_ref(parts, sid, &part);
234 if (rc != EOK) {
235 async_answer_0(icall, ENOENT);
236 return;
237 }
238
239 rc = vol_part_empty_part(part);
240 if (rc != EOK) {
241 async_answer_0(icall, EIO);
242 goto error;
243 }
244
245 async_answer_0(icall, EOK);
246error:
247 vol_part_del_ref(part);
248}
249
250static void vol_part_get_lsupp_srv(vol_parts_t *parts, ipc_call_t *icall)
251{
252 vol_fstype_t fstype;
253 vol_label_supp_t vlsupp;
254 errno_t rc;
255
256 fstype = IPC_GET_ARG1(*icall);
257 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
258 fstype);
259
260 volsrv_part_get_lsupp(fstype, &vlsupp);
261
262 ipc_call_t call;
263 size_t size;
264 if (!async_data_read_receive(&call, &size)) {
265 async_answer_0(&call, EREFUSED);
266 async_answer_0(icall, EREFUSED);
267 return;
268 }
269
270 if (size != sizeof(vol_label_supp_t)) {
271 async_answer_0(&call, EINVAL);
272 async_answer_0(icall, EINVAL);
273 return;
274 }
275
276 rc = async_data_read_finalize(&call, &vlsupp,
277 min(size, sizeof(vlsupp)));
278 if (rc != EOK) {
279 async_answer_0(&call, rc);
280 async_answer_0(icall, rc);
281 return;
282 }
283
284 async_answer_0(icall, EOK);
285}
286
287static void vol_part_mkfs_srv(vol_parts_t *parts, ipc_call_t *icall)
288{
289 service_id_t sid;
290 vol_part_t *part;
291 vol_fstype_t fstype;
292 char *label = NULL;
293 char *mountp = NULL;
294 errno_t rc;
295
296 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
297
298 sid = IPC_GET_ARG1(*icall);
299 fstype = IPC_GET_ARG2(*icall);
300
301 rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
302 0, NULL);
303 if (rc != EOK) {
304 async_answer_0(icall, rc);
305 goto error;
306 }
307
308 if (label != NULL) {
309 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: label='%s'",
310 label);
311 }
312
313 rc = async_data_write_accept((void **)&mountp, true, 0, VOL_MOUNTP_MAXLEN,
314 0, NULL);
315 if (rc != EOK) {
316 async_answer_0(icall, rc);
317 goto error;
318 }
319
320 if (mountp != NULL) {
321 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: mountp='%s'",
322 mountp);
323 }
324
325 rc = vol_part_find_by_id_ref(parts, sid, &part);
326 if (rc != EOK) {
327 async_answer_0(icall, ENOENT);
328 goto error;
329 }
330
331 rc = vol_part_mkfs_part(part, fstype, label, mountp);
332 if (rc != EOK) {
333 async_answer_0(icall, rc);
334 vol_part_del_ref(part);
335 goto error;
336 }
337
338 free(label);
339 free(mountp);
340 async_answer_0(icall, EOK);
341
342 return;
343error:
344 if (label != NULL)
345 free(label);
346 if (mountp != NULL)
347 free(mountp);
348}
349
350static void vol_part_set_mountp_srv(vol_parts_t *parts,
351 ipc_call_t *icall)
352{
353 service_id_t sid;
354 vol_part_t *part;
355 char *mountp;
356 errno_t rc;
357
358 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_set_mountp_srv()");
359
360 sid = IPC_GET_ARG1(*icall);
361
362 rc = async_data_write_accept((void **)&mountp, true, 0,
363 VOL_MOUNTP_MAXLEN, 0, NULL);
364 if (rc != EOK) {
365 async_answer_0(icall, rc);
366 return;
367 }
368
369 if (mountp != NULL) {
370 log_msg(LOG_DEFAULT, LVL_NOTE,
371 "vol_part_set_mountp_srv: mountp='%s'", mountp);
372 }
373
374 rc = vol_part_find_by_id_ref(parts, sid, &part);
375 if (rc != EOK) {
376 free(mountp);
377 async_answer_0(icall, ENOENT);
378 return;
379 }
380
381 rc = vol_part_set_mountp_part(part, mountp);
382 if (rc != EOK) {
383 free(mountp);
384 async_answer_0(icall, rc);
385 vol_part_del_ref(part);
386 return;
387 }
388
389 free(mountp);
390 async_answer_0(icall, EOK);
391}
392
393static void vol_client_conn(ipc_call_t *icall, void *arg)
394{
395 vol_parts_t *parts = (vol_parts_t *) arg;
396
397 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_client_conn()");
398
399 /* Accept the connection */
400 async_answer_0(icall, EOK);
401
402 while (true) {
403 ipc_call_t call;
404 async_get_call(&call);
405 sysarg_t method = IPC_GET_IMETHOD(call);
406
407 if (!method) {
408 /* The other side has hung up */
409 async_answer_0(&call, EOK);
410 return;
411 }
412
413 switch (method) {
414 case VOL_GET_PARTS:
415 vol_get_parts_srv(parts, &call);
416 break;
417 case VOL_PART_ADD:
418 vol_part_add_srv(parts, &call);
419 break;
420 case VOL_PART_INFO:
421 vol_part_info_srv(parts, &call);
422 break;
423 case VOL_PART_EJECT:
424 vol_part_eject_srv(parts, &call);
425 break;
426 case VOL_PART_EMPTY:
427 vol_part_empty_srv(parts, &call);
428 break;
429 case VOL_PART_LSUPP:
430 vol_part_get_lsupp_srv(parts, &call);
431 break;
432 case VOL_PART_MKFS:
433 vol_part_mkfs_srv(parts, &call);
434 break;
435 case VOL_PART_SET_MOUNTP:
436 vol_part_set_mountp_srv(parts, &call);
437 break;
438 default:
439 async_answer_0(&call, EINVAL);
440 }
441 }
442}
443
444int main(int argc, char *argv[])
445{
446 errno_t rc;
447
448 printf("%s: Volume service\n", NAME);
449
450 if (log_init(NAME) != EOK) {
451 printf(NAME ": Failed to initialize logging.\n");
452 return 1;
453 }
454
455 rc = vol_init();
456 if (rc != EOK)
457 return 1;
458
459 printf(NAME ": Accepting connections.\n");
460 task_retval(0);
461 async_manager();
462
463 return 0;
464}
465
466/** @}
467 */
Note: See TracBrowser for help on using the repository browser.