rbd.c (464444fcc161284ac0e743b99251debc297d5236) | rbd.c (2836284db603775af557e969d5a800efb0190324) |
---|---|
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. 9 * 10 * Contributions after 2012-01-13 are licensed under the terms of the 11 * GNU GPL, version 2 or (at your option) any later version. 12 */ 13 14#include "qemu/osdep.h" 15 | 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. 9 * 10 * Contributions after 2012-01-13 are licensed under the terms of the 11 * GNU GPL, version 2 or (at your option) any later version. 12 */ 13 14#include "qemu/osdep.h" 15 |
16#include <rbd/librbd.h> |
|
16#include "qapi/error.h" 17#include "qemu/error-report.h" 18#include "block/block_int.h" 19#include "crypto/secret.h" 20#include "qemu/cutils.h" 21#include "qapi/qmp/qstring.h" 22 | 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 |
23#include <rbd/librbd.h> 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 * 32 * devicename is the name of the rbd image. --- 282 unchanged lines hidden (view full) --- 315 }, 316 { 317 /* maps to 'id' in rados_create() */ 318 .name = "user", 319 .type = QEMU_OPT_STRING, 320 .help = "Rados id name", 321 }, 322 /* | 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 * 31 * devicename is the name of the rbd image. --- 282 unchanged lines hidden (view full) --- 314 }, 315 { 316 /* maps to 'id' in rados_create() */ 317 .name = "user", 318 .type = QEMU_OPT_STRING, 319 .help = "Rados id name", 320 }, 321 /* |
323 * server.* extracted manually, see qemu_rbd_array_opts() | 322 * server.* extracted manually, see qemu_rbd_mon_host() |
324 */ 325 { 326 .name = "password-secret", 327 .type = QEMU_OPT_STRING, 328 .help = "ID of secret providing the password", 329 }, 330 331 /* 332 * Keys for qemu_rbd_parse_filename(), not in the QAPI schema 333 */ 334 { 335 /* 336 * HACK: name starts with '=' so that qemu_opts_parse() 337 * can't set it 338 */ 339 .name = "=keyvalue-pairs", 340 .type = QEMU_OPT_STRING, 341 .help = "Legacy rados key/value option parameters", 342 }, | 323 */ 324 { 325 .name = "password-secret", 326 .type = QEMU_OPT_STRING, 327 .help = "ID of secret providing the password", 328 }, 329 330 /* 331 * Keys for qemu_rbd_parse_filename(), not in the QAPI schema 332 */ 333 { 334 /* 335 * HACK: name starts with '=' so that qemu_opts_parse() 336 * can't set it 337 */ 338 .name = "=keyvalue-pairs", 339 .type = QEMU_OPT_STRING, 340 .help = "Legacy rados key/value option parameters", 341 }, |
343 344 /* 345 * The remainder aren't option keys, but option sub-sub-keys, 346 * so that qemu_rbd_array_opts() can abuse runtime_opts for 347 * its own purposes 348 * TODO clean this up 349 */ 350 { 351 .name = "host", 352 .type = QEMU_OPT_STRING, 353 }, 354 { 355 .name = "port", 356 .type = QEMU_OPT_STRING, 357 }, | |
358 { /* end of list */ } 359 }, 360}; 361 362static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp) 363{ 364 Error *local_err = NULL; 365 int64_t bytes = 0; --- 134 unchanged lines hidden (view full) --- 500 qemu_vfree(acb->bounce); 501 } 502 503 acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); 504 505 qemu_aio_unref(acb); 506} 507 | 342 { /* end of list */ } 343 }, 344}; 345 346static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp) 347{ 348 Error *local_err = NULL; 349 int64_t bytes = 0; --- 134 unchanged lines hidden (view full) --- 484 qemu_vfree(acb->bounce); 485 } 486 487 acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); 488 489 qemu_aio_unref(acb); 490} 491 |
508#define RBD_MON_HOST 0 509 510static char *qemu_rbd_array_opts(QDict *options, const char *prefix, int type, 511 Error **errp) | 492static char *qemu_rbd_mon_host(QDict *options, Error **errp) |
512{ | 493{ |
513 int num_entries; 514 QemuOpts *opts = NULL; 515 QDict *sub_options; 516 const char *host; 517 const char *port; 518 char *str; 519 char *rados_str = NULL; 520 Error *local_err = NULL; | 494 const char **vals = g_new(const char *, qdict_size(options) + 1); 495 char keybuf[32]; 496 const char *host, *port; 497 char *rados_str; |
521 int i; 522 | 498 int i; 499 |
523 assert(type == RBD_MON_HOST); 524 525 num_entries = qdict_array_entries(options, prefix); 526 527 if (num_entries < 0) { 528 error_setg(errp, "Parse error on RBD QDict array"); 529 return NULL; 530 } 531 532 for (i = 0; i < num_entries; i++) { 533 char *strbuf = NULL; 534 const char *value; 535 char *rados_str_tmp; 536 537 str = g_strdup_printf("%s%d.", prefix, i); 538 qdict_extract_subqdict(options, &sub_options, str); 539 g_free(str); 540 541 opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); 542 qemu_opts_absorb_qdict(opts, sub_options, &local_err); 543 QDECREF(sub_options); 544 if (local_err) { 545 error_propagate(errp, local_err); 546 g_free(rados_str); | 500 for (i = 0;; i++) { 501 sprintf(keybuf, "server.%d.host", i); 502 host = qdict_get_try_str(options, keybuf); 503 qdict_del(options, keybuf); 504 sprintf(keybuf, "server.%d.port", i); 505 port = qdict_get_try_str(options, keybuf); 506 qdict_del(options, keybuf); 507 if (!host && !port) { 508 break; 509 } 510 if (!host) { 511 error_setg(errp, "Parameter server.%d.host is missing", i); |
547 rados_str = NULL; | 512 rados_str = NULL; |
548 goto exit; | 513 goto out; |
549 } 550 | 514 } 515 |
551 if (type == RBD_MON_HOST) { 552 host = qemu_opt_get(opts, "host"); 553 port = qemu_opt_get(opts, "port"); 554 555 value = host; 556 if (port) { 557 /* check for ipv6 */ 558 if (strchr(host, ':')) { 559 strbuf = g_strdup_printf("[%s]:%s", host, port); 560 } else { 561 strbuf = g_strdup_printf("%s:%s", host, port); 562 } 563 value = strbuf; 564 } else if (strchr(host, ':')) { 565 strbuf = g_strdup_printf("[%s]", host); 566 value = strbuf; 567 } | 516 if (strchr(host, ':')) { 517 vals[i] = port ? g_strdup_printf("[%s]:%s", host, port) 518 : g_strdup_printf("[%s]", host); |
568 } else { | 519 } else { |
569 abort(); | 520 vals[i] = port ? g_strdup_printf("%s:%s", host, port) 521 : g_strdup(host); |
570 } | 522 } |
571 572 /* each iteration in the for loop will build upon the string, and if 573 * rados_str is NULL then it is our first pass */ 574 if (rados_str) { 575 /* separate options with ';', as that is what rados_conf_set() 576 * requires */ 577 rados_str_tmp = rados_str; 578 rados_str = g_strdup_printf("%s;%s", rados_str_tmp, value); 579 g_free(rados_str_tmp); 580 } else { 581 rados_str = g_strdup(value); 582 } 583 584 g_free(strbuf); 585 qemu_opts_del(opts); 586 opts = NULL; | |
587 } | 523 } |
524 vals[i] = NULL; |
|
588 | 525 |
589exit: 590 qemu_opts_del(opts); | 526 rados_str = i ? g_strjoinv(";", (char **)vals) : NULL; 527out: 528 g_strfreev((char **)vals); |
591 return rados_str; 592} 593 594static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, 595 Error **errp) 596{ 597 BDRVRBDState *s = bs->opaque; 598 const char *pool, *snap, *conf, *clientname, *name, *keypairs; 599 const char *secretid; 600 QemuOpts *opts; 601 Error *local_err = NULL; 602 char *mon_host = NULL; 603 int r; 604 605 opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); 606 qemu_opts_absorb_qdict(opts, options, &local_err); 607 if (local_err) { 608 error_propagate(errp, local_err); | 529 return rados_str; 530} 531 532static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, 533 Error **errp) 534{ 535 BDRVRBDState *s = bs->opaque; 536 const char *pool, *snap, *conf, *clientname, *name, *keypairs; 537 const char *secretid; 538 QemuOpts *opts; 539 Error *local_err = NULL; 540 char *mon_host = NULL; 541 int r; 542 543 opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); 544 qemu_opts_absorb_qdict(opts, options, &local_err); 545 if (local_err) { 546 error_propagate(errp, local_err); |
609 qemu_opts_del(opts); 610 return -EINVAL; | 547 r = -EINVAL; 548 goto failed_opts; |
611 } 612 | 549 } 550 |
613 mon_host = qemu_rbd_array_opts(options, "server.", 614 RBD_MON_HOST, &local_err); | 551 mon_host = qemu_rbd_mon_host(options, &local_err); |
615 if (local_err) { 616 error_propagate(errp, local_err); 617 r = -EINVAL; 618 goto failed_opts; 619 } 620 621 secretid = qemu_opt_get(opts, "password-secret"); 622 --- 536 unchanged lines hidden --- | 552 if (local_err) { 553 error_propagate(errp, local_err); 554 r = -EINVAL; 555 goto failed_opts; 556 } 557 558 secretid = qemu_opt_get(opts, "password-secret"); 559 --- 536 unchanged lines hidden --- |