rbd.c (aba0fb1e2e8a6b5c76c07a1d24c587d77154491d) rbd.c (e98c6961c82e25ff9051a31f17846404a64de6dd)
1/*
2 * QEMU Block driver for RADOS (Ceph)
3 *
4 * Copyright (C) 2010-2011 Christian Brunner <chb@muc.de>,
5 * Josh Durgin <josh.durgin@dreamhost.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2. See
8 * the COPYING file in the top-level directory.

--- 6 unchanged lines hidden (view full) ---

15
16#include <rbd/librbd.h>
17#include "qapi/error.h"
18#include "qemu/error-report.h"
19#include "block/block_int.h"
20#include "crypto/secret.h"
21#include "qemu/cutils.h"
22#include "qapi/qmp/qstring.h"
1/*
2 * QEMU Block driver for RADOS (Ceph)
3 *
4 * Copyright (C) 2010-2011 Christian Brunner <chb@muc.de>,
5 * Josh Durgin <josh.durgin@dreamhost.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2. See
8 * the COPYING file in the top-level directory.

--- 6 unchanged lines hidden (view full) ---

15
16#include <rbd/librbd.h>
17#include "qapi/error.h"
18#include "qemu/error-report.h"
19#include "block/block_int.h"
20#include "crypto/secret.h"
21#include "qemu/cutils.h"
22#include "qapi/qmp/qstring.h"
23#include "qapi/qmp/qjson.h"
23
24/*
25 * When specifying the image filename use:
26 *
27 * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]]
28 *
29 * poolname must be the name of an existing rados pool.
30 *

--- 99 unchanged lines hidden (view full) ---

130 }
131 *p = '\0';
132}
133
134static void qemu_rbd_parse_filename(const char *filename, QDict *options,
135 Error **errp)
136{
137 const char *start;
24
25/*
26 * When specifying the image filename use:
27 *
28 * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]]
29 *
30 * poolname must be the name of an existing rados pool.
31 *

--- 99 unchanged lines hidden (view full) ---

131 }
132 *p = '\0';
133}
134
135static void qemu_rbd_parse_filename(const char *filename, QDict *options,
136 Error **errp)
137{
138 const char *start;
138 char *p, *buf, *keypairs;
139 char *p, *buf;
140 QList *keypairs = NULL;
139 char *found_str;
141 char *found_str;
140 size_t max_keypair_size;
141
142 if (!strstart(filename, "rbd:", &start)) {
143 error_setg(errp, "File name must start with 'rbd:'");
144 return;
145 }
146
142
143 if (!strstart(filename, "rbd:", &start)) {
144 error_setg(errp, "File name must start with 'rbd:'");
145 return;
146 }
147
147 max_keypair_size = strlen(start) + 1;
148 buf = g_strdup(start);
148 buf = g_strdup(start);
149 keypairs = g_malloc0(max_keypair_size);
150 p = buf;
151
152 found_str = qemu_rbd_next_tok(p, '/', &p);
153 if (!p) {
154 error_setg(errp, "Pool name is required");
155 goto done;
156 }
157 qemu_rbd_unescape(found_str);

--- 31 unchanged lines hidden (view full) ---

189 value = qemu_rbd_next_tok(p, ':', &p);
190 qemu_rbd_unescape(value);
191
192 if (!strcmp(name, "conf")) {
193 qdict_put(options, "conf", qstring_from_str(value));
194 } else if (!strcmp(name, "id")) {
195 qdict_put(options, "user" , qstring_from_str(value));
196 } else {
149 p = buf;
150
151 found_str = qemu_rbd_next_tok(p, '/', &p);
152 if (!p) {
153 error_setg(errp, "Pool name is required");
154 goto done;
155 }
156 qemu_rbd_unescape(found_str);

--- 31 unchanged lines hidden (view full) ---

188 value = qemu_rbd_next_tok(p, ':', &p);
189 qemu_rbd_unescape(value);
190
191 if (!strcmp(name, "conf")) {
192 qdict_put(options, "conf", qstring_from_str(value));
193 } else if (!strcmp(name, "id")) {
194 qdict_put(options, "user" , qstring_from_str(value));
195 } else {
197 /* FIXME: This is pretty ugly, and not the right way to do this.
198 * These should be contained in a structure, and then
199 * passed explicitly as individual key/value pairs to
200 * rados. Consider this legacy code that needs to be
201 * updated. */
202 char *tmp = g_malloc0(max_keypair_size);
203 /* only use a delimiter if it is not the first keypair found */
204 /* These are sets of unknown key/value pairs we'll pass along
205 * to ceph */
206 if (keypairs[0]) {
207 snprintf(tmp, max_keypair_size, ":%s=%s", name, value);
208 pstrcat(keypairs, max_keypair_size, tmp);
209 } else {
210 snprintf(keypairs, max_keypair_size, "%s=%s", name, value);
196 /*
197 * We pass these internally to qemu_rbd_set_keypairs(), so
198 * we can get away with the simpler list of [ "key1",
199 * "value1", "key2", "value2" ] rather than a raw dict
200 * { "key1": "value1", "key2": "value2" } where we can't
201 * guarantee order, or even a more correct but complex
202 * [ { "key1": "value1" }, { "key2": "value2" } ]
203 */
204 if (!keypairs) {
205 keypairs = qlist_new();
211 }
206 }
212 g_free(tmp);
207 qlist_append(keypairs, qstring_from_str(name));
208 qlist_append(keypairs, qstring_from_str(value));
213 }
214 }
215
209 }
210 }
211
216 if (keypairs[0]) {
217 qdict_put(options, "=keyvalue-pairs", qstring_from_str(keypairs));
212 if (keypairs) {
213 qdict_put(options, "=keyvalue-pairs",
214 qobject_to_json(QOBJECT(keypairs)));
218 }
219
215 }
216
220
221done:
222 g_free(buf);
217done:
218 g_free(buf);
223 g_free(keypairs);
219 QDECREF(keypairs);
224 return;
225}
226
227
228static int qemu_rbd_set_auth(rados_t cluster, const char *secretid,
229 Error **errp)
230{
231 if (secretid == 0) {

--- 7 unchanged lines hidden (view full) ---

239 }
240
241 rados_conf_set(cluster, "key", secret);
242 g_free(secret);
243
244 return 0;
245}
246
220 return;
221}
222
223
224static int qemu_rbd_set_auth(rados_t cluster, const char *secretid,
225 Error **errp)
226{
227 if (secretid == 0) {

--- 7 unchanged lines hidden (view full) ---

235 }
236
237 rados_conf_set(cluster, "key", secret);
238 g_free(secret);
239
240 return 0;
241}
242
247static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs,
243static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs_json,
248 Error **errp)
249{
244 Error **errp)
245{
250 char *p, *buf;
251 char *name;
252 char *value;
246 QList *keypairs;
247 QString *name;
248 QString *value;
249 const char *key;
250 size_t remaining;
253 int ret = 0;
254
251 int ret = 0;
252
255 buf = g_strdup(keypairs);
256 p = buf;
253 if (!keypairs_json) {
254 return ret;
255 }
256 keypairs = qobject_to_qlist(qobject_from_json(keypairs_json,
257 &error_abort));
258 remaining = qlist_size(keypairs) / 2;
259 assert(remaining);
257
260
258 while (p) {
259 name = qemu_rbd_next_tok(p, '=', &p);
260 if (!p) {
261 error_setg(errp, "conf option %s has no value", name);
262 ret = -EINVAL;
263 break;
264 }
261 while (remaining--) {
262 name = qobject_to_qstring(qlist_pop(keypairs));
263 value = qobject_to_qstring(qlist_pop(keypairs));
264 assert(name && value);
265 key = qstring_get_str(name);
265
266
266 value = qemu_rbd_next_tok(p, ':', &p);
267
268 ret = rados_conf_set(cluster, name, value);
267 ret = rados_conf_set(cluster, key, qstring_get_str(value));
268 QDECREF(name);
269 QDECREF(value);
269 if (ret < 0) {
270 if (ret < 0) {
270 error_setg_errno(errp, -ret, "invalid conf option %s", name);
271 error_setg_errno(errp, -ret, "invalid conf option %s", key);
271 ret = -EINVAL;
272 break;
273 }
274 }
275
272 ret = -EINVAL;
273 break;
274 }
275 }
276
276 g_free(buf);
277 QDECREF(keypairs);
277 return ret;
278}
279
280static void qemu_rbd_memset(RADOSCB *rcb, int64_t offs)
281{
282 if (LIBRBD_USE_IOVEC) {
283 RBDAIOCB *acb = rcb->acb;
284 iov_memset(acb->qiov->iov, acb->qiov->niov, offs, 0,

--- 811 unchanged lines hidden ---
278 return ret;
279}
280
281static void qemu_rbd_memset(RADOSCB *rcb, int64_t offs)
282{
283 if (LIBRBD_USE_IOVEC) {
284 RBDAIOCB *acb = rcb->acb;
285 iov_memset(acb->qiov->iov, acb->qiov->niov, offs, 0,

--- 811 unchanged lines hidden ---