source: mainline/uspace/srv/bd/vbd/vbd.c@ 1626cd4

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

Propagate label and partition block ranges and other info up through the stack.

  • Property mode set to 100644
File size: 8.2 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 vbd
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>
40#include <ipc/vbd.h>
41#include <loc.h>
42#include <macros.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <task.h>
46
47#include "disk.h"
48#include "types/vbd.h"
49
50#define NAME "vbd"
51
52static void vbds_client_conn(ipc_callid_t, ipc_call_t *, void *);
53
54static service_id_t ctl_sid;
55
56static int vbds_init(void)
57{
58 int rc;
59 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_init()");
60
61 vbds_disks_init();
62
63 async_set_client_connection(vbds_client_conn);
64
65 rc = loc_server_register(NAME);
66 if (rc != EOK) {
67 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server (%d).", rc);
68 return EEXIST;
69 }
70
71 rc = loc_service_register(SERVICE_NAME_VBD, &ctl_sid);
72 if (rc != EOK) {
73 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
74 return EEXIST;
75 }
76
77 return EOK;
78}
79
80
81static void vbds_disk_add_srv(ipc_callid_t iid, ipc_call_t *icall)
82{
83 service_id_t disk_sid;
84 int rc;
85
86 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_disk_add_srv()");
87
88 disk_sid = IPC_GET_ARG1(*icall);
89 rc = vbds_disk_add(disk_sid);
90 async_answer_0(iid, (sysarg_t) rc);
91}
92
93static void vbds_disk_remove_srv(ipc_callid_t iid, ipc_call_t *icall)
94{
95 service_id_t disk_sid;
96 int rc;
97
98 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_disk_remove_srv()");
99
100 disk_sid = IPC_GET_ARG1(*icall);
101 rc = vbds_disk_remove(disk_sid);
102 async_answer_0(iid, (sysarg_t) rc);
103}
104
105static void vbds_disk_info_srv(ipc_callid_t iid, ipc_call_t *icall)
106{
107 service_id_t disk_sid;
108 vbds_disk_info_t dinfo;
109 int rc;
110
111 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_disk_info_srv()");
112
113 disk_sid = IPC_GET_ARG1(*icall);
114 rc = vbds_disk_info(disk_sid, &dinfo);
115 if (rc != EOK) {
116 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() call failed");
117 async_answer_0(iid, rc);
118 return;
119 }
120
121 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() data_read_receive");
122 ipc_callid_t callid;
123 size_t size;
124 if (!async_data_read_receive(&callid, &size)) {
125 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() failed");
126 async_answer_0(callid, EREFUSED);
127 async_answer_0(iid, EREFUSED);
128 return;
129 }
130
131 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() check size");
132 if (size != sizeof(vbds_disk_info_t)) {
133 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() wrong size");
134 async_answer_0(callid, EINVAL);
135 async_answer_0(iid, EINVAL);
136 return;
137 }
138
139 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() data_read_finalize");
140 rc = async_data_read_finalize(callid, &dinfo,
141 min(size, sizeof(dinfo)));
142 if (rc != EOK) {
143 async_answer_0(callid, rc);
144 async_answer_0(iid, rc);
145 return;
146 }
147
148 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() reply EOK");
149 async_answer_0(iid, EOK);
150}
151
152static void vbds_label_create_srv(ipc_callid_t iid, ipc_call_t *icall)
153{
154 service_id_t disk_sid;
155 label_type_t ltype;
156 int rc;
157
158 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_create_srv()");
159
160 disk_sid = IPC_GET_ARG1(*icall);
161 ltype = IPC_GET_ARG2(*icall);
162 rc = vbds_label_create(disk_sid, ltype);
163 async_answer_0(iid, (sysarg_t) rc);
164}
165
166static void vbds_label_delete_srv(ipc_callid_t iid, ipc_call_t *icall)
167{
168 service_id_t disk_sid;
169 int rc;
170
171 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_delete_srv()");
172
173 disk_sid = IPC_GET_ARG1(*icall);
174 rc = vbds_label_delete(disk_sid);
175 async_answer_0(iid, (sysarg_t) rc);
176}
177
178static void vbds_label_get_parts_srv(ipc_callid_t iid, ipc_call_t *icall)
179{
180 ipc_callid_t callid;
181 size_t size;
182 size_t act_size;
183 service_id_t sid;
184 int rc;
185
186 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_label_get_parts_srv()");
187
188 if (!async_data_read_receive(&callid, &size)) {
189 async_answer_0(callid, EREFUSED);
190 async_answer_0(iid, EREFUSED);
191 return;
192 }
193
194 sid = IPC_GET_ARG1(*icall);
195
196 category_id_t *id_buf = (category_id_t *) malloc(size);
197 if (id_buf == NULL) {
198 async_answer_0(callid, ENOMEM);
199 async_answer_0(iid, ENOMEM);
200 return;
201 }
202
203 rc = vbds_get_parts(sid, id_buf, size, &act_size);
204 if (rc != EOK) {
205 async_answer_0(callid, rc);
206 async_answer_0(iid, rc);
207 return;
208 }
209
210 sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
211 free(id_buf);
212
213 async_answer_1(iid, retval, act_size);
214}
215
216
217static void vbds_part_get_info_srv(ipc_callid_t iid, ipc_call_t *icall)
218{
219 vbds_part_id_t part;
220 vbds_part_info_t pinfo;
221 int rc;
222
223 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_get_info_srv()");
224
225 part = IPC_GET_ARG1(*icall);
226 rc = vbds_part_get_info(part, &pinfo);
227 async_answer_5(iid, (sysarg_t)rc, pinfo.index,
228 LOWER32(pinfo.block0), UPPER32(pinfo.block0),
229 LOWER32(pinfo.nblocks), UPPER32(pinfo.nblocks));
230}
231
232static void vbds_part_create_srv(ipc_callid_t iid, ipc_call_t *icall)
233{
234 service_id_t disk_sid;
235 vbds_part_id_t part;
236 int rc;
237
238 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_create_srv()");
239
240 disk_sid = IPC_GET_ARG1(*icall);
241 rc = vbds_part_create(disk_sid, &part);
242 async_answer_1(iid, (sysarg_t)rc, (sysarg_t)part);
243}
244
245static void vbds_part_delete_srv(ipc_callid_t iid, ipc_call_t *icall)
246{
247 vbds_part_id_t part;
248 int rc;
249
250 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_part_delete_srv()");
251
252 part = IPC_GET_ARG1(*icall);
253 rc = vbds_part_delete(part);
254 async_answer_0(iid, (sysarg_t) rc);
255}
256
257static void vbds_ctl_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
258{
259 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_client_conn()");
260
261 /* Accept the connection */
262 async_answer_0(iid, EOK);
263
264 while (true) {
265 ipc_call_t call;
266 ipc_callid_t callid = async_get_call(&call);
267 sysarg_t method = IPC_GET_IMETHOD(call);
268
269 if (!method) {
270 /* The other side has hung up */
271 async_answer_0(callid, EOK);
272 return;
273 }
274
275 switch (method) {
276 case VBD_DISK_ADD:
277 vbds_disk_add_srv(callid, &call);
278 break;
279 case VBD_DISK_REMOVE:
280 vbds_disk_remove_srv(callid, &call);
281 break;
282 case VBD_DISK_INFO:
283 vbds_disk_info_srv(callid, &call);
284 break;
285 case VBD_LABEL_CREATE:
286 vbds_label_create_srv(callid, &call);
287 break;
288 case VBD_LABEL_DELETE:
289 vbds_label_delete_srv(callid, &call);
290 break;
291 case VBD_LABEL_GET_PARTS:
292 vbds_label_get_parts_srv(callid, &call);
293 break;
294 case VBD_PART_GET_INFO:
295 vbds_part_get_info_srv(callid, &call);
296 break;
297 case VBD_PART_CREATE:
298 vbds_part_create_srv(callid, &call);
299 break;
300 case VBD_PART_DELETE:
301 vbds_part_delete_srv(callid, &call);
302 break;
303 default:
304 async_answer_0(callid, EINVAL);
305 }
306 }
307}
308
309static void vbds_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
310{
311 service_id_t sid;
312
313 log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_client_conn()");
314
315 sid = (service_id_t)IPC_GET_ARG1(*icall);
316
317 if (sid == ctl_sid)
318 vbds_ctl_conn(iid, icall, arg);
319 else
320 vbds_bd_conn(iid, icall, arg);
321}
322
323int main(int argc, char *argv[])
324{
325 int rc;
326
327 printf("%s: Virtual Block Device service\n", NAME);
328
329 if (log_init(NAME) != EOK) {
330 printf(NAME ": Failed to initialize logging.\n");
331 return 1;
332 }
333
334 rc = vbds_init();
335 if (rc != EOK)
336 return 1;
337
338 printf(NAME ": Accepting connections.\n");
339 task_retval(0);
340 async_manager();
341
342 return 0;
343}
344
345/** @}
346 */
Note: See TracBrowser for help on using the repository browser.