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

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

Most of extended (but not logical) partition support.

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