source: mainline/uspace/lib/c/generic/vbd.c@ c02d098

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c02d098 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: 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 libc
30 * @{
31 */
32/** @file Virtual Block Device client API
33 */
34
35#include <errno.h>
36#include <ipc/services.h>
37#include <ipc/vbd.h>
38#include <loc.h>
39#include <macros.h>
40#include <mem.h>
41#include <stdlib.h>
42#include <types/label.h>
43#include <vbd.h>
44
45int vbd_create(vbd_t **rvbd)
46{
47 vbd_t *vbd;
48 service_id_t vbd_svcid;
49 int rc;
50
51 vbd = calloc(1, sizeof(vbd_t));
52 if (vbd == NULL) {
53 rc = ENOMEM;
54 goto error;
55 }
56
57 rc = loc_service_get_id(SERVICE_NAME_VBD, &vbd_svcid,
58 IPC_FLAG_BLOCKING);
59 if (rc != EOK) {
60 rc = EIO;
61 goto error;
62 }
63
64 vbd->sess = loc_service_connect(EXCHANGE_SERIALIZE, vbd_svcid,
65 IPC_FLAG_BLOCKING);
66 if (vbd->sess == NULL) {
67 rc = EIO;
68 goto error;
69 }
70
71 *rvbd = vbd;
72 return EOK;
73error:
74 free(vbd);
75 return rc;
76}
77
78void vbd_destroy(vbd_t *vbd)
79{
80 if (vbd == NULL)
81 return;
82
83 async_hangup(vbd->sess);
84 free(vbd);
85}
86
87int vbd_disk_add(vbd_t *vbd, service_id_t disk_sid)
88{
89 async_exch_t *exch;
90
91 exch = async_exchange_begin(vbd->sess);
92 sysarg_t rc = async_req_1_0(exch, VBD_DISK_ADD, disk_sid);
93 async_exchange_end(exch);
94
95 return (int)rc;
96}
97
98int vbd_disk_remove(vbd_t *vbd, service_id_t disk_sid)
99{
100 async_exch_t *exch;
101
102 exch = async_exchange_begin(vbd->sess);
103 sysarg_t rc = async_req_1_0(exch, VBD_DISK_REMOVE, disk_sid);
104 async_exchange_end(exch);
105
106 return (int)rc;
107}
108
109/** Get disk information. */
110int vbd_disk_info(vbd_t *vbd, service_id_t sid, vbd_disk_info_t *vinfo)
111{
112 async_exch_t *exch;
113 sysarg_t retval;
114 ipc_call_t answer;
115
116 exch = async_exchange_begin(vbd->sess);
117 aid_t req = async_send_1(exch, VBD_DISK_INFO, sid, &answer);
118 int rc = async_data_read_start(exch, vinfo, sizeof(vbd_disk_info_t));
119 async_exchange_end(exch);
120
121 if (rc != EOK) {
122 async_forget(req);
123 return EIO;
124 }
125
126 async_wait_for(req, &retval);
127 if (retval != EOK)
128 return EIO;
129
130 return EOK;
131}
132
133int vbd_label_create(vbd_t *vbd, service_id_t sid, label_type_t ltype)
134{
135 async_exch_t *exch;
136 int retval;
137
138 exch = async_exchange_begin(vbd->sess);
139 retval = async_req_2_0(exch, VBD_LABEL_CREATE, sid, ltype);
140 async_exchange_end(exch);
141
142 if (retval != EOK)
143 return EIO;
144
145 return EOK;
146}
147
148int vbd_label_delete(vbd_t *vbd, service_id_t sid)
149{
150 async_exch_t *exch;
151 int retval;
152
153 exch = async_exchange_begin(vbd->sess);
154 retval = async_req_1_0(exch, VBD_LABEL_DELETE, sid);
155 async_exchange_end(exch);
156
157 if (retval != EOK)
158 return EIO;
159
160 return EOK;
161}
162
163/** Get list of IDs into a buffer of fixed size.
164 *
165 * @param vbd Virtual Block Device
166 * @param method IPC method
167 * @param arg1 First argument
168 * @param id_buf Buffer to store IDs
169 * @param buf_size Buffer size
170 * @param act_size Place to store actual size of complete data.
171 *
172 * @return EOK on success or negative error code.
173 */
174static int vbd_get_ids_once(vbd_t *vbd, sysarg_t method, sysarg_t arg1,
175 sysarg_t *id_buf, size_t buf_size, size_t *act_size)
176{
177 async_exch_t *exch = async_exchange_begin(vbd->sess);
178
179 ipc_call_t answer;
180 aid_t req = async_send_1(exch, method, arg1, &answer);
181 int rc = async_data_read_start(exch, id_buf, buf_size);
182
183 async_exchange_end(exch);
184
185 if (rc != EOK) {
186 async_forget(req);
187 return rc;
188 }
189
190 sysarg_t retval;
191 async_wait_for(req, &retval);
192
193 if (retval != EOK) {
194 return retval;
195 }
196
197 *act_size = IPC_GET_ARG1(answer);
198 return EOK;
199}
200
201/** Get list of IDs.
202 *
203 * Returns an allocated array of service IDs.
204 *
205 * @param vbd Virtual Block Device
206 * @param method IPC method
207 * @param arg1 IPC argument 1
208 * @param data Place to store pointer to array of IDs
209 * @param count Place to store number of IDs
210 * @return EOK on success or negative error code
211 */
212static int vbd_get_ids_internal(vbd_t *vbd, sysarg_t method, sysarg_t arg1,
213 sysarg_t **data, size_t *count)
214{
215 *data = NULL;
216 *count = 0;
217
218 size_t act_size = 0;
219 int rc = vbd_get_ids_once(vbd, method, arg1, NULL, 0, &act_size);
220 if (rc != EOK)
221 return rc;
222
223 size_t alloc_size = act_size;
224 service_id_t *ids = malloc(alloc_size);
225 if (ids == NULL)
226 return ENOMEM;
227
228 while (true) {
229 rc = vbd_get_ids_once(vbd, method, arg1, ids, alloc_size,
230 &act_size);
231 if (rc != EOK)
232 return rc;
233
234 if (act_size <= alloc_size)
235 break;
236
237 alloc_size = act_size;
238 ids = realloc(ids, alloc_size);
239 if (ids == NULL)
240 return ENOMEM;
241 }
242
243 *count = act_size / sizeof(service_id_t);
244 *data = ids;
245 return EOK;
246}
247
248/** Get list of disks as array of service IDs.
249 *
250 * @param vbd Virtual Block Device
251 * @param data Place to store pointer to array
252 * @param count Place to store length of array (number of entries)
253 *
254 * @return EOK on success or negative error code
255 */
256int vbd_label_get_parts(vbd_t *vbd, service_id_t disk,
257 service_id_t **data, size_t *count)
258{
259 return vbd_get_ids_internal(vbd, VBD_LABEL_GET_PARTS, disk,
260 data, count);
261}
262
263int vbd_part_get_info(vbd_t *vbd, vbd_part_id_t part, vbd_part_info_t *pinfo)
264{
265 async_exch_t *exch;
266 sysarg_t retval;
267 ipc_call_t answer;
268
269 exch = async_exchange_begin(vbd->sess);
270 aid_t req = async_send_1(exch, VBD_PART_GET_INFO, part, &answer);
271 int rc = async_data_read_start(exch, pinfo, sizeof(vbd_part_info_t));
272 async_exchange_end(exch);
273
274 if (rc != EOK) {
275 async_forget(req);
276 return EIO;
277 }
278
279 async_wait_for(req, &retval);
280 if (retval != EOK)
281 return EIO;
282
283 return EOK;
284}
285
286int vbd_part_create(vbd_t *vbd, service_id_t disk, vbd_part_spec_t *pspec,
287 vbd_part_id_t *rpart)
288{
289 async_exch_t *exch;
290 sysarg_t retval;
291 ipc_call_t answer;
292
293 exch = async_exchange_begin(vbd->sess);
294 aid_t req = async_send_1(exch, VBD_PART_CREATE, disk, &answer);
295 int rc = async_data_write_start(exch, pspec, sizeof(vbd_part_spec_t));
296 async_exchange_end(exch);
297
298 if (rc != EOK) {
299 async_forget(req);
300 return EIO;
301 }
302
303 async_wait_for(req, &retval);
304 if (retval != EOK)
305 return EIO;
306
307 *rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
308 return EOK;
309
310}
311
312int vbd_part_delete(vbd_t *vbd, vbd_part_id_t part)
313{
314 async_exch_t *exch;
315 int retval;
316
317 exch = async_exchange_begin(vbd->sess);
318 retval = async_req_1_0(exch, VBD_PART_DELETE, part);
319 async_exchange_end(exch);
320
321 if (retval != EOK)
322 return EIO;
323
324 return EOK;
325}
326
327void vbd_pspec_init(vbd_part_spec_t *pspec)
328{
329 memset(pspec, 0, sizeof(vbd_part_spec_t));
330}
331
332/** @}
333 */
Note: See TracBrowser for help on using the repository browser.