source: mainline/uspace/srv/bd/vbd/vbd.c@ 5772aa1

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

VBD needs to empty a newly created partition before exposing it to the volume server.

  • Property mode set to 100644
File size: 9.8 KB
RevLine 
[1356f85a]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
[22fb7ab]29/** @addtogroup vbd
[1356f85a]30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <async.h>
37#include <errno.h>
38#include <io/log.h>
39#include <ipc/services.h>
[22fb7ab]40#include <ipc/vbd.h>
[5772aa1]41#include <label/label.h>
[1356f85a]42#include <loc.h>
[1626cd4]43#include <macros.h>
[1356f85a]44#include <stdio.h>
45#include <stdlib.h>
46#include <task.h>
[6a0d4ce2]47#include <vbd.h>
[1356f85a]48
[28ed0d95]49#include "disk.h"
[22fb7ab]50#include "types/vbd.h"
51
[1356f85a]52#define NAME "vbd"
53
[28ed0d95]54static void vbds_client_conn(ipc_callid_t, ipc_call_t *, void *);
[1356f85a]55
[78d50bd]56static service_id_t ctl_sid;
57
[28ed0d95]58static int vbds_init(void)
[1356f85a]59{
60 int rc;
[55f8c6e7]61 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_init()");
[1356f85a]62
[372df8f]63 rc = vbds_disks_init();
64 if (rc != EOK)
65 return rc;
66
[ff381a7]67 async_set_fallback_port_handler(vbds_client_conn, NULL);
[1356f85a]68
69 rc = loc_server_register(NAME);
70 if (rc != EOK) {
71 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server (%d).", rc);
72 return EEXIST;
73 }
74
[78d50bd]75 rc = loc_service_register(SERVICE_NAME_VBD, &ctl_sid);
[1356f85a]76 if (rc != EOK) {
77 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
78 return EEXIST;
79 }
80
[89204a23]81 rc = vbds_disk_discovery_start();
82 if (rc != EOK)
83 return rc;
84
[1356f85a]85 return EOK;
86}
87
[372df8f]88static void vbds_get_disks_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]89{
[372df8f]90 ipc_callid_t callid;
91 size_t size;
92 size_t act_size;
[28ed0d95]93 int rc;
[22fb7ab]94
[372df8f]95 if (!async_data_read_receive(&callid, &size)) {
96 async_answer_0(callid, EREFUSED);
97 async_answer_0(iid, EREFUSED);
98 return;
99 }
[28ed0d95]100
[372df8f]101 service_id_t *id_buf = (service_id_t *) malloc(size);
102 if (id_buf == NULL) {
103 async_answer_0(callid, ENOMEM);
104 async_answer_0(iid, ENOMEM);
105 return;
106 }
[22fb7ab]107
[372df8f]108 rc = vbds_disk_get_ids(id_buf, size, &act_size);
109 if (rc != EOK) {
[da3bc0e]110 free(id_buf);
[372df8f]111 async_answer_0(callid, rc);
112 async_answer_0(iid, rc);
113 return;
114 }
[28ed0d95]115
[372df8f]116 sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
117 free(id_buf);
[28ed0d95]118
[372df8f]119 async_answer_1(iid, retval, act_size);
[22fb7ab]120}
121
[28ed0d95]122static void vbds_disk_info_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]123{
[28ed0d95]124 service_id_t disk_sid;
[b7a4d06]125 vbd_disk_info_t dinfo;
[28ed0d95]126 int rc;
127
[55f8c6e7]128 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_disk_info_srv()");
[28ed0d95]129
130 disk_sid = IPC_GET_ARG1(*icall);
131 rc = vbds_disk_info(disk_sid, &dinfo);
[1626cd4]132 if (rc != EOK) {
133 async_answer_0(iid, rc);
134 return;
135 }
136
137 ipc_callid_t callid;
138 size_t size;
139 if (!async_data_read_receive(&callid, &size)) {
140 async_answer_0(callid, EREFUSED);
141 async_answer_0(iid, EREFUSED);
142 return;
143 }
144
[b7a4d06]145 if (size != sizeof(vbd_disk_info_t)) {
[1626cd4]146 async_answer_0(callid, EINVAL);
147 async_answer_0(iid, EINVAL);
148 return;
149 }
150
151 rc = async_data_read_finalize(callid, &dinfo,
152 min(size, sizeof(dinfo)));
153 if (rc != EOK) {
154 async_answer_0(callid, rc);
155 async_answer_0(iid, rc);
156 return;
157 }
158
159 async_answer_0(iid, EOK);
[22fb7ab]160}
161
[28ed0d95]162static void vbds_label_create_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]163{
164 service_id_t disk_sid;
[28ed0d95]165 label_type_t ltype;
[22fb7ab]166 int rc;
167
[55f8c6e7]168 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create_srv()");
[22fb7ab]169
170 disk_sid = IPC_GET_ARG1(*icall);
[28ed0d95]171 ltype = IPC_GET_ARG2(*icall);
172 rc = vbds_label_create(disk_sid, ltype);
[22fb7ab]173 async_answer_0(iid, (sysarg_t) rc);
174}
175
[28ed0d95]176static void vbds_label_delete_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]177{
178 service_id_t disk_sid;
179 int rc;
180
[55f8c6e7]181 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_delete_srv()");
[22fb7ab]182
183 disk_sid = IPC_GET_ARG1(*icall);
[28ed0d95]184 rc = vbds_label_delete(disk_sid);
[22fb7ab]185 async_answer_0(iid, (sysarg_t) rc);
186}
187
[28ed0d95]188static void vbds_label_get_parts_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]189{
[1626cd4]190 ipc_callid_t callid;
191 size_t size;
192 size_t act_size;
193 service_id_t sid;
194 int rc;
[28ed0d95]195
[55f8c6e7]196 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_get_parts_srv()");
[28ed0d95]197
[1626cd4]198 if (!async_data_read_receive(&callid, &size)) {
199 async_answer_0(callid, EREFUSED);
200 async_answer_0(iid, EREFUSED);
201 return;
202 }
203
204 sid = IPC_GET_ARG1(*icall);
205
206 category_id_t *id_buf = (category_id_t *) malloc(size);
207 if (id_buf == NULL) {
208 async_answer_0(callid, ENOMEM);
209 async_answer_0(iid, ENOMEM);
210 return;
211 }
212
213 rc = vbds_get_parts(sid, id_buf, size, &act_size);
214 if (rc != EOK) {
215 async_answer_0(callid, rc);
216 async_answer_0(iid, rc);
217 return;
218 }
219
220 sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
221 free(id_buf);
222
223 async_answer_1(iid, retval, act_size);
[28ed0d95]224}
225
226static void vbds_part_get_info_srv(ipc_callid_t iid, ipc_call_t *icall)
227{
228 vbds_part_id_t part;
[6a0d4ce2]229 vbd_part_info_t pinfo;
[22fb7ab]230 int rc;
231
[55f8c6e7]232 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_get_info_srv()");
[22fb7ab]233
[28ed0d95]234 part = IPC_GET_ARG1(*icall);
235 rc = vbds_part_get_info(part, &pinfo);
[b7a4d06]236 if (rc != EOK) {
237 async_answer_0(iid, rc);
238 return;
239 }
240
241 ipc_callid_t callid;
242 size_t size;
243 if (!async_data_read_receive(&callid, &size)) {
244 async_answer_0(callid, EREFUSED);
245 async_answer_0(iid, EREFUSED);
246 return;
247 }
248
249 if (size != sizeof(vbd_part_info_t)) {
250 async_answer_0(callid, EINVAL);
251 async_answer_0(iid, EINVAL);
252 return;
253 }
254
255 rc = async_data_read_finalize(callid, &pinfo,
256 min(size, sizeof(pinfo)));
257 if (rc != EOK) {
258 async_answer_0(callid, rc);
259 async_answer_0(iid, rc);
260 return;
261 }
262
263 async_answer_0(iid, EOK);
[22fb7ab]264}
265
[28ed0d95]266static void vbds_part_create_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]267{
268 service_id_t disk_sid;
[6bc542b]269 vbd_part_spec_t pspec;
[28ed0d95]270 vbds_part_id_t part;
[22fb7ab]271 int rc;
272
[55f8c6e7]273 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_create_srv()");
[22fb7ab]274
275 disk_sid = IPC_GET_ARG1(*icall);
[6bc542b]276
277 ipc_callid_t callid;
278 size_t size;
279 if (!async_data_write_receive(&callid, &size)) {
280 async_answer_0(callid, EREFUSED);
281 async_answer_0(iid, EREFUSED);
282 return;
283 }
284
285 if (size != sizeof(vbd_part_spec_t)) {
286 async_answer_0(callid, EINVAL);
287 async_answer_0(iid, EINVAL);
288 return;
289 }
290
291 rc = async_data_write_finalize(callid, &pspec, sizeof(vbd_part_spec_t));
292 if (rc != EOK) {
293 async_answer_0(callid, rc);
294 async_answer_0(iid, rc);
295 return;
296 }
297
298 rc = vbds_part_create(disk_sid, &pspec, &part);
299 if (rc != EOK) {
300 async_answer_0(iid, rc);
301 return;
302 }
303
[28ed0d95]304 async_answer_1(iid, (sysarg_t)rc, (sysarg_t)part);
[22fb7ab]305}
306
[28ed0d95]307static void vbds_part_delete_srv(ipc_callid_t iid, ipc_call_t *icall)
[22fb7ab]308{
[28ed0d95]309 vbds_part_id_t part;
[22fb7ab]310 int rc;
311
[55f8c6e7]312 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_delete_srv()");
[22fb7ab]313
[28ed0d95]314 part = IPC_GET_ARG1(*icall);
315 rc = vbds_part_delete(part);
[22fb7ab]316 async_answer_0(iid, (sysarg_t) rc);
317}
[1356f85a]318
[f57ccb5]319static void vbds_suggest_ptype_srv(ipc_callid_t iid, ipc_call_t *icall)
320{
321 service_id_t disk_sid;
322 label_ptype_t ptype;
323 label_pcnt_t pcnt;
324 int rc;
325
[55f8c6e7]326 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_suggest_ptype_srv()");
[f57ccb5]327
328 disk_sid = IPC_GET_ARG1(*icall);
329 pcnt = IPC_GET_ARG2(*icall);
330
331 rc = vbds_suggest_ptype(disk_sid, pcnt, &ptype);
332 if (rc != EOK) {
333 async_answer_0(iid, rc);
334 return;
335 }
336
337 ipc_callid_t callid;
338 size_t size;
339 if (!async_data_read_receive(&callid, &size)) {
340 async_answer_0(callid, EREFUSED);
341 async_answer_0(iid, EREFUSED);
342 return;
343 }
344
345 if (size != sizeof(label_ptype_t)) {
346 async_answer_0(callid, EINVAL);
347 async_answer_0(iid, EINVAL);
348 return;
349 }
350
351 rc = async_data_read_finalize(callid, &ptype, sizeof(label_ptype_t));
352 if (rc != EOK) {
353 async_answer_0(callid, rc);
354 async_answer_0(iid, rc);
355 return;
356 }
357
358 async_answer_0(iid, EOK);
359}
360
[78d50bd]361static void vbds_ctl_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
[1356f85a]362{
[55f8c6e7]363 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_client_conn()");
[1356f85a]364
365 /* Accept the connection */
366 async_answer_0(iid, EOK);
367
368 while (true) {
369 ipc_call_t call;
370 ipc_callid_t callid = async_get_call(&call);
371 sysarg_t method = IPC_GET_IMETHOD(call);
372
373 if (!method) {
374 /* The other side has hung up */
375 async_answer_0(callid, EOK);
376 return;
377 }
378
379 switch (method) {
[372df8f]380 case VBD_GET_DISKS:
381 vbds_get_disks_srv(callid, &call);
[22fb7ab]382 break;
383 case VBD_DISK_INFO:
[28ed0d95]384 vbds_disk_info_srv(callid, &call);
[22fb7ab]385 break;
386 case VBD_LABEL_CREATE:
[28ed0d95]387 vbds_label_create_srv(callid, &call);
[22fb7ab]388 break;
389 case VBD_LABEL_DELETE:
[28ed0d95]390 vbds_label_delete_srv(callid, &call);
391 break;
392 case VBD_LABEL_GET_PARTS:
393 vbds_label_get_parts_srv(callid, &call);
394 break;
395 case VBD_PART_GET_INFO:
396 vbds_part_get_info_srv(callid, &call);
397 break;
398 case VBD_PART_CREATE:
399 vbds_part_create_srv(callid, &call);
400 break;
401 case VBD_PART_DELETE:
402 vbds_part_delete_srv(callid, &call);
[22fb7ab]403 break;
[f57ccb5]404 case VBD_SUGGEST_PTYPE:
405 vbds_suggest_ptype_srv(callid, &call);
406 break;
[1356f85a]407 default:
408 async_answer_0(callid, EINVAL);
409 }
410 }
411}
412
[78d50bd]413static void vbds_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
414{
415 service_id_t sid;
416
[55f8c6e7]417 log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_client_conn()");
[78d50bd]418
[ff381a7]419 sid = (service_id_t)IPC_GET_ARG2(*icall);
[78d50bd]420
421 if (sid == ctl_sid)
422 vbds_ctl_conn(iid, icall, arg);
423 else
424 vbds_bd_conn(iid, icall, arg);
425}
426
[1356f85a]427int main(int argc, char *argv[])
428{
429 int rc;
430
431 printf("%s: Virtual Block Device service\n", NAME);
432
433 if (log_init(NAME) != EOK) {
434 printf(NAME ": Failed to initialize logging.\n");
435 return 1;
436 }
437
[28ed0d95]438 rc = vbds_init();
[1356f85a]439 if (rc != EOK)
440 return 1;
441
442 printf(NAME ": Accepting connections.\n");
443 task_retval(0);
444 async_manager();
445
446 return 0;
447}
448
449/** @}
450 */
Note: See TracBrowser for help on using the repository browser.