source: mainline/uspace/srv/bd/vbd/vbd.c

Last change on this file was ca48672, checked in by Jiri Svoboda <jiri@…>, 5 weeks ago

loc_service_register() needs to take a port ID argument.

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