source: mainline/uspace/lib/c/generic/vol.c@ 22fb7ab

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

Delegate disks to volsrv and labels to vbd.

  • Property mode set to 100644
File size: 5.8 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 Volume service API
33 */
34
35#include <errno.h>
36#include <ipc/services.h>
37#include <ipc/vol.h>
38#include <loc.h>
39#include <stdlib.h>
40#include <vol.h>
41
42/** Create Volume service session.
43 *
44 * @param rvol Place to store pointer to volume service session.
45 * @return EOK on success, ENOMEM if out of memory, EIO if service
46 * cannot be contacted.
47 */
48int vol_create(vol_t **rvol)
49{
50 vol_t *vol;
51 service_id_t vol_svcid;
52 int rc;
53
54 vol = calloc(1, sizeof(vol_t));
55 if (vol == NULL) {
56 rc = ENOMEM;
57 goto error;
58 }
59
60 rc = loc_service_get_id(SERVICE_NAME_VOLSRV, &vol_svcid, 0);
61 if (rc != EOK) {
62 rc = EIO;
63 goto error;
64 }
65
66 vol->sess = loc_service_connect(EXCHANGE_SERIALIZE, vol_svcid, 0);
67 if (vol->sess == NULL) {
68 rc = EIO;
69 goto error;
70 }
71
72 *rvol = vol;
73 return EOK;
74error:
75 free(vol);
76 return rc;
77}
78
79/** Destroy volume service session.
80 *
81 * @param vol Volume service session
82 */
83void vol_destroy(vol_t *vol)
84{
85 if (vol == NULL)
86 return;
87
88 async_hangup(vol->sess);
89 free(vol);
90}
91
92/** Get list of IDs into a buffer of fixed size.
93 *
94 * @param vol Volume service
95 * @param method IPC method
96 * @param arg1 First argument
97 * @param id_buf Buffer to store IDs
98 * @param buf_size Buffer size
99 * @param act_size Place to store actual size of complete data.
100 *
101 * @return EOK on success or negative error code.
102 */
103static int vol_get_ids_once(vol_t *vol, sysarg_t method, sysarg_t arg1,
104 sysarg_t *id_buf, size_t buf_size, size_t *act_size)
105{
106 async_exch_t *exch = async_exchange_begin(vol->sess);
107
108 ipc_call_t answer;
109 aid_t req = async_send_1(exch, method, arg1, &answer);
110 int rc = async_data_read_start(exch, id_buf, buf_size);
111
112 async_exchange_end(exch);
113
114 if (rc != EOK) {
115 async_forget(req);
116 return rc;
117 }
118
119 sysarg_t retval;
120 async_wait_for(req, &retval);
121
122 if (retval != EOK) {
123 return retval;
124 }
125
126 *act_size = IPC_GET_ARG1(answer);
127 return EOK;
128}
129
130/** Get list of IDs.
131 *
132 * Returns an allocated array of service IDs.
133 *
134 * @param vol Volume service
135 * @param method IPC method
136 * @param arg1 IPC argument 1
137 * @param data Place to store pointer to array of IDs
138 * @param count Place to store number of IDs
139 * @return EOK on success or negative error code
140 */
141static int vol_get_ids_internal(vol_t *vol, sysarg_t method, sysarg_t arg1,
142 sysarg_t **data, size_t *count)
143{
144 *data = NULL;
145 *count = 0;
146
147 size_t act_size = 0;
148 int rc = vol_get_ids_once(vol, method, arg1, NULL, 0, &act_size);
149 if (rc != EOK)
150 return rc;
151
152 size_t alloc_size = act_size;
153 service_id_t *ids = malloc(alloc_size);
154 if (ids == NULL)
155 return ENOMEM;
156
157 while (true) {
158 rc = vol_get_ids_once(vol, method, arg1, ids, alloc_size,
159 &act_size);
160 if (rc != EOK)
161 return rc;
162
163 if (act_size <= alloc_size)
164 break;
165
166 alloc_size = act_size;
167 ids = realloc(ids, alloc_size);
168 if (ids == NULL)
169 return ENOMEM;
170 }
171
172 *count = act_size / sizeof(service_id_t);
173 *data = ids;
174 return EOK;
175}
176
177/** Get list of disks as array of service IDs.
178 *
179 * @param vol Volume service
180 * @param data Place to store pointer to array
181 * @param count Place to store length of array (number of entries)
182 *
183 * @return EOK on success or negative error code
184 */
185int vol_get_disks(vol_t *vol, service_id_t **data, size_t *count)
186{
187 return vol_get_ids_internal(vol, VOL_GET_DISKS, 0, data, count);
188}
189
190/** Get disk information. */
191int vol_disk_info(vol_t *vol, service_id_t sid, vol_disk_info_t *vinfo)
192{
193 async_exch_t *exch;
194 sysarg_t dcnt, ltype;
195 int retval;
196
197 exch = async_exchange_begin(vol->sess);
198 retval = async_req_1_2(exch, VOL_DISK_INFO, sid, &dcnt, &ltype);
199 async_exchange_end(exch);
200
201 if (retval != EOK)
202 return EIO;
203
204 vinfo->dcnt = (label_disk_cnt_t)dcnt;
205 vinfo->ltype = (label_type_t)ltype;
206 return EOK;
207}
208
209/** Create new label. */
210int vol_label_create(vol_t *vol, service_id_t sid, label_type_t ltype)
211{
212 async_exch_t *exch;
213 int retval;
214
215 exch = async_exchange_begin(vol->sess);
216 retval = async_req_2_0(exch, VOL_LABEL_CREATE, sid, ltype);
217 async_exchange_end(exch);
218
219 if (retval != EOK)
220 return EIO;
221
222 return EOK;
223}
224
225/** Erase disk (to the extent where we will consider it not containing
226 * a label or file system. */
227int vol_disk_empty(vol_t *vol, service_id_t sid)
228{
229 async_exch_t *exch;
230 int retval;
231
232 exch = async_exchange_begin(vol->sess);
233 retval = async_req_1_0(exch, VOL_DISK_EMPTY, sid);
234 async_exchange_end(exch);
235
236 if (retval != EOK)
237 return EIO;
238
239 return EOK;
240}
241
242/** @}
243 */
Note: See TracBrowser for help on using the repository browser.