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

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

Fdisk should be able to set volume label for newly created partitions.

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