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 --- |