source: mainline/uspace/lib/c/generic/vbd.c@ 78d50bd

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

VBD client API, liblabel API, pass partition creation/deletion through to VBD.

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