source: mainline/uspace/srv/volsrv/volsrv.c@ da680b4b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since da680b4b was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 8.0 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
52#define NAME "volsrv"
53
54static void vol_client_conn(ipc_call_t *, void *);
55
56static errno_t vol_init(void)
57{
58 errno_t rc;
59 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_init()");
60
61 rc = vol_part_init();
62 if (rc != EOK)
63 return rc;
64
65 rc = vol_part_discovery_start();
66 if (rc != EOK)
67 return rc;
68
69 async_set_fallback_port_handler(vol_client_conn, NULL);
70
71 rc = loc_server_register(NAME);
72 if (rc != EOK) {
73 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
74 return EEXIST;
75 }
76
77 service_id_t sid;
78 rc = loc_service_register(SERVICE_NAME_VOLSRV, &sid);
79 if (rc != EOK) {
80 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
81 return EEXIST;
82 }
83
84 return EOK;
85}
86
87static void vol_get_parts_srv(ipc_call_t *icall)
88{
89 ipc_call_t call;
90 size_t size;
91 size_t act_size;
92 errno_t rc;
93
94 if (!async_data_read_receive(&call, &size)) {
95 async_answer_0(&call, EREFUSED);
96 async_answer_0(icall, EREFUSED);
97 return;
98 }
99
100 service_id_t *id_buf = (service_id_t *) malloc(size);
101 if (id_buf == NULL) {
102 async_answer_0(&call, ENOMEM);
103 async_answer_0(icall, ENOMEM);
104 return;
105 }
106
107 rc = vol_part_get_ids(id_buf, size, &act_size);
108 if (rc != EOK) {
109 async_answer_0(&call, rc);
110 async_answer_0(icall, rc);
111 return;
112 }
113
114 errno_t retval = async_data_read_finalize(&call, id_buf, size);
115 free(id_buf);
116
117 async_answer_1(icall, retval, act_size);
118}
119
120static void vol_part_add_srv(ipc_call_t *icall)
121{
122 service_id_t sid;
123 errno_t rc;
124
125 sid = IPC_GET_ARG1(*icall);
126
127 rc = vol_part_add(sid);
128 if (rc != EOK) {
129 async_answer_0(icall, rc);
130 return;
131 }
132
133 async_answer_0(icall, EOK);
134}
135
136static void vol_part_info_srv(ipc_call_t *icall)
137{
138 service_id_t sid;
139 vol_part_t *part;
140 vol_part_info_t pinfo;
141 errno_t rc;
142
143 sid = IPC_GET_ARG1(*icall);
144 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
145 sid);
146 rc = vol_part_find_by_id_ref(sid, &part);
147 if (rc != EOK) {
148 async_answer_0(icall, ENOENT);
149 return;
150 }
151
152 rc = vol_part_get_info(part, &pinfo);
153 if (rc != EOK) {
154 async_answer_0(icall, EIO);
155 goto error;
156 }
157
158 ipc_call_t call;
159 size_t size;
160 if (!async_data_read_receive(&call, &size)) {
161 async_answer_0(&call, EREFUSED);
162 async_answer_0(icall, EREFUSED);
163 goto error;
164 }
165
166 if (size != sizeof(vol_part_info_t)) {
167 async_answer_0(&call, EINVAL);
168 async_answer_0(icall, EINVAL);
169 goto error;
170 }
171
172 rc = async_data_read_finalize(&call, &pinfo,
173 min(size, sizeof(pinfo)));
174 if (rc != EOK) {
175 async_answer_0(&call, rc);
176 async_answer_0(icall, rc);
177 goto error;
178 }
179
180 async_answer_0(icall, EOK);
181error:
182 vol_part_del_ref(part);
183}
184
185static void vol_part_eject_srv(ipc_call_t *icall)
186{
187 service_id_t sid;
188 vol_part_t *part;
189 errno_t rc;
190
191 sid = IPC_GET_ARG1(*icall);
192 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
193
194 rc = vol_part_find_by_id_ref(sid, &part);
195 if (rc != EOK) {
196 async_answer_0(icall, ENOENT);
197 goto error;
198 }
199
200 rc = vol_part_eject_part(part);
201 if (rc != EOK) {
202 async_answer_0(icall, EIO);
203 goto error;
204 }
205
206 async_answer_0(icall, EOK);
207error:
208 vol_part_del_ref(part);
209}
210
211static void vol_part_empty_srv(ipc_call_t *icall)
212{
213 service_id_t sid;
214 vol_part_t *part;
215 errno_t rc;
216
217 sid = IPC_GET_ARG1(*icall);
218 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
219
220 rc = vol_part_find_by_id_ref(sid, &part);
221 if (rc != EOK) {
222 async_answer_0(icall, ENOENT);
223 return;
224 }
225
226 rc = vol_part_empty_part(part);
227 if (rc != EOK) {
228 async_answer_0(icall, EIO);
229 goto error;
230 }
231
232 async_answer_0(icall, EOK);
233error:
234 vol_part_del_ref(part);
235}
236
237static void vol_part_get_lsupp_srv(ipc_call_t *icall)
238{
239 vol_fstype_t fstype;
240 vol_label_supp_t vlsupp;
241 errno_t rc;
242
243 fstype = IPC_GET_ARG1(*icall);
244 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
245 fstype);
246
247 volsrv_part_get_lsupp(fstype, &vlsupp);
248
249 ipc_call_t call;
250 size_t size;
251 if (!async_data_read_receive(&call, &size)) {
252 async_answer_0(&call, EREFUSED);
253 async_answer_0(icall, EREFUSED);
254 return;
255 }
256
257 if (size != sizeof(vol_label_supp_t)) {
258 async_answer_0(&call, EINVAL);
259 async_answer_0(icall, EINVAL);
260 return;
261 }
262
263 rc = async_data_read_finalize(&call, &vlsupp,
264 min(size, sizeof(vlsupp)));
265 if (rc != EOK) {
266 async_answer_0(&call, rc);
267 async_answer_0(icall, rc);
268 return;
269 }
270
271 async_answer_0(icall, EOK);
272}
273
274
275static void vol_part_mkfs_srv(ipc_call_t *icall)
276{
277 service_id_t sid;
278 vol_part_t *part;
279 vol_fstype_t fstype;
280 char *label;
281 errno_t rc;
282
283 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
284
285 sid = IPC_GET_ARG1(*icall);
286 fstype = IPC_GET_ARG2(*icall);
287
288 rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
289 0, NULL);
290 if (rc != EOK) {
291 async_answer_0(icall, rc);
292 return;
293 }
294
295 if (label != NULL) {
296 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: label='%s'",
297 label);
298 }
299
300 rc = vol_part_find_by_id_ref(sid, &part);
301 if (rc != EOK) {
302 free(label);
303 async_answer_0(icall, ENOENT);
304 return;
305 }
306
307 rc = vol_part_mkfs_part(part, fstype, label);
308 if (rc != EOK) {
309 free(label);
310 async_answer_0(icall, rc);
311 vol_part_del_ref(part);
312 return;
313 }
314
315 free(label);
316 async_answer_0(icall, EOK);
317}
318
319static void vol_client_conn(ipc_call_t *icall, void *arg)
320{
321 log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_client_conn()");
322
323 /* Accept the connection */
324 async_answer_0(icall, EOK);
325
326 while (true) {
327 ipc_call_t call;
328 async_get_call(&call);
329 sysarg_t method = IPC_GET_IMETHOD(call);
330
331 if (!method) {
332 /* The other side has hung up */
333 async_answer_0(&call, EOK);
334 return;
335 }
336
337 switch (method) {
338 case VOL_GET_PARTS:
339 vol_get_parts_srv(&call);
340 break;
341 case VOL_PART_ADD:
342 vol_part_add_srv(&call);
343 break;
344 case VOL_PART_INFO:
345 vol_part_info_srv(&call);
346 break;
347 case VOL_PART_EJECT:
348 vol_part_eject_srv(&call);
349 break;
350 case VOL_PART_EMPTY:
351 vol_part_empty_srv(&call);
352 break;
353 case VOL_PART_LSUPP:
354 vol_part_get_lsupp_srv(&call);
355 break;
356 case VOL_PART_MKFS:
357 vol_part_mkfs_srv(&call);
358 break;
359 default:
360 async_answer_0(&call, EINVAL);
361 }
362 }
363}
364
365int main(int argc, char *argv[])
366{
367 errno_t rc;
368
369 printf("%s: Volume service\n", NAME);
370
371 if (log_init(NAME) != EOK) {
372 printf(NAME ": Failed to initialize logging.\n");
373 return 1;
374 }
375
376 rc = vol_init();
377 if (rc != EOK)
378 return 1;
379
380 printf(NAME ": Accepting connections.\n");
381 task_retval(0);
382 async_manager();
383
384 return 0;
385}
386
387/** @}
388 */
Note: See TracBrowser for help on using the repository browser.