From patchwork Mon Mar 28 23:15:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Durgin X-Patchwork-Id: 670312 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2SNIigC028317 for ; Mon, 28 Mar 2011 23:18:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932227Ab1C1XSn (ORCPT ); Mon, 28 Mar 2011 19:18:43 -0400 Received: from mail.hq.newdream.net ([66.33.206.127]:44689 "EHLO mail.hq.newdream.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932184Ab1C1XSm (ORCPT ); Mon, 28 Mar 2011 19:18:42 -0400 Received: from mail.hq.newdream.net (localhost [127.0.0.1]) by mail.hq.newdream.net (Postfix) with ESMTP id 4037BC065; Mon, 28 Mar 2011 16:18:42 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=dreamhost.com; h=from:to:cc :subject:date:message-id:in-reply-to:references:in-reply-to :references; q=dns; s=dreamhost.com; b=F1aJG2iFEpejBA6H1fG3fJv+z eaNq3LBttsWHI5EMW/FbUMwTFX8AI8z1eDw/0duHQUGG9qkgyybs6BGYVqYvwFV9 b3delWabhVyQsqPl4kzi9IB8UmPk1fqtzwwkMrWmSsSd0kjHCK81vqajanpD6ke3 za58fEj/LhA6rseNeI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=dreamhost.com; h=from:to :cc:subject:date:message-id:in-reply-to:references:in-reply-to :references; s=dreamhost.com; bh=yDfECsudCUUHB9y/CyZe9rvejQo=; b= gYJEj/fzPFKQbSAyx9IbavIcYDBCw5XaFUjOaiN6UyyrvplyondjwHMepoKaUc9W RxqC5v7w0+Dzzvb0iGk3pmaTwAwrKT4RJ+64L9h+d7BQMRI0h+cGR6KCFbqcEll/ FGUO5TfFoG4C0rR2Ck0elxcVZ92b6ahUiCA5/AElPJ4= Received: from pudgy.ops.newdream.net (ip-66-33-206-8.dreamhost.com [66.33.206.8]) by mail.hq.newdream.net (Postfix) with ESMTP id 3D05DC064; Mon, 28 Mar 2011 16:18:42 -0700 (PDT) From: Josh Durgin To: kvm@vger.kernel.org, qemu-devel@nongnu.org Cc: ceph-devel@vger.kernel.org Subject: [PATCH v2 2/2] rbd: allow configuration of rados from the rbd filename Date: Mon, 28 Mar 2011 16:15:58 -0700 Message-Id: <99252a76de350c8123eebfe4fc01fc6a1c9b2383.1301354138.git.josh.durgin@dreamhost.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <6f9466b6098b5159aca9c789f9fce45f409e684f.1301354138.git.josh.durgin@dreamhost.com> References: <6f9466b6098b5159aca9c789f9fce45f409e684f.1301354138.git.josh.durgin@dreamhost.com> In-Reply-To: <6f9466b6098b5159aca9c789f9fce45f409e684f.1301354138.git.josh.durgin@dreamhost.com> References: <6f9466b6098b5159aca9c789f9fce45f409e684f.1301354138.git.josh.durgin@dreamhost.com> Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 28 Mar 2011 23:18:44 +0000 (UTC) diff --git a/block/rbd.c b/block/rbd.c index cb76dd3..bc3323d 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -22,13 +22,17 @@ /* * When specifying the image filename use: * - * rbd:poolname/devicename + * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]] * * poolname must be the name of an existing rados pool * * devicename is the basename for all objects used to * emulate the raw device. * + * Each option given is used to configure rados, and may be + * any Ceph option, or "conf". The "conf" option specifies + * a Ceph configuration file to read. + * * Metadata information (image size, ...) is stored in an * object with the name "devicename.rbd". * @@ -121,7 +125,8 @@ static int qemu_rbd_next_tok(char *dst, int dst_len, static int qemu_rbd_parsename(const char *filename, char *pool, int pool_len, char *snap, int snap_len, - char *name, int name_len) + char *name, int name_len, + char *conf, int conf_len) { const char *start; char *p, *buf; @@ -133,28 +138,84 @@ static int qemu_rbd_parsename(const char *filename, buf = qemu_strdup(start); p = buf; + *snap = '\0'; + *conf = '\0'; ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); if (ret < 0 || !p) { ret = -EINVAL; goto done; } - ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); - if (ret < 0) { - goto done; + + if (strchr(p, '@')) { + ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); + if (ret < 0) { + goto done; + } + ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); + } else { + ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); } - if (!p) { - *snap = '\0'; + if (ret < 0 || !p) { goto done; } - ret = qemu_rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p); + ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p); done: qemu_free(buf); return ret; } +static int qemu_rbd_set_conf(rados_t cluster, const char *conf) +{ + char *p, *buf; + char name[RBD_MAX_CONF_NAME_SIZE]; + char value[RBD_MAX_CONF_VAL_SIZE]; + int ret = 0; + + buf = qemu_strdup(conf); + p = buf; + + while (p) { + ret = qemu_rbd_next_tok(name, sizeof(name), p, + '=', "conf option name", &p); + if (ret < 0) { + break; + } + + if (!p) { + error_report("conf option %s has no value", name); + ret = -EINVAL; + break; + } + + ret = qemu_rbd_next_tok(value, sizeof(value), p, + ':', "conf option value", &p); + if (ret < 0) { + break; + } + + if (strncmp(name, "conf", strlen("conf"))) { + ret = rados_conf_set(cluster, name, value); + if (ret < 0) { + error_report("invalid conf option %s", name); + ret = -EINVAL; + break; + } + } else { + ret = rados_conf_read_file(cluster, value); + if (ret < 0) { + error_report("error reading conf file %s", value); + break; + } + } + } + + qemu_free(buf); + return ret; +} + static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) { int64_t bytes = 0; @@ -163,6 +224,7 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) char pool[RBD_MAX_POOL_NAME_SIZE]; char name[RBD_MAX_IMAGE_NAME_SIZE]; char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; + char conf[RBD_MAX_CONF_SIZE]; char *snap = NULL; rados_t cluster; rados_ioctx_t io_ctx; @@ -170,7 +232,8 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), - name, sizeof(name)) < 0) { + name, sizeof(name), + conf, sizeof(conf)) < 0) { return -EINVAL; } if (snap_buf[0] != '\0') { @@ -203,8 +266,17 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) return -EIO; } - if (rados_conf_read_file(cluster, NULL) < 0) { - error_report("error reading config file"); + if (strstr(conf, "conf=") == NULL) { + if (rados_conf_read_file(cluster, NULL) < 0) { + error_report("error reading config file"); + rados_shutdown(cluster); + return -EIO; + } + } + + if (conf[0] != '\0' && + qemu_rbd_set_conf(cluster, conf) < 0) { + error_report("error setting config options"); rados_shutdown(cluster); return -EIO; } @@ -314,11 +386,13 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags) BDRVRBDState *s = bs->opaque; char pool[RBD_MAX_POOL_NAME_SIZE]; char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; + char conf[RBD_MAX_CONF_SIZE]; int r; if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), - s->name, sizeof(s->name)) < 0) { + s->name, sizeof(s->name), + conf, sizeof(conf)) < 0) { return -EINVAL; } s->snap = NULL; @@ -332,11 +406,22 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags) return r; } - r = rados_conf_read_file(s->cluster, NULL); - if (r < 0) { - error_report("error reading config file"); - rados_shutdown(s->cluster); - return r; + if (strstr(conf, "conf=") == NULL) { + r = rados_conf_read_file(s->cluster, NULL); + if (r < 0) { + error_report("error reading config file"); + rados_shutdown(s->cluster); + return r; + } + } + + if (conf[0] != '\0') { + r = qemu_rbd_set_conf(s->cluster, conf); + if (r < 0) { + error_report("error setting config options"); + rados_shutdown(s->cluster); + return r; + } } r = rados_connect(s->cluster);