From patchwork Tue Feb 16 21:45:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Fehlig X-Patchwork-Id: 8332581 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 08B4EC02AA for ; Tue, 16 Feb 2016 21:48:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EE46D202EC for ; Tue, 16 Feb 2016 21:48:34 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D2EEC202FE for ; Tue, 16 Feb 2016 21:48:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aVnRL-0001gR-0N; Tue, 16 Feb 2016 21:45:47 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aVnRK-0001fl-Dw for xen-devel@lists.xen.org; Tue, 16 Feb 2016 21:45:46 +0000 Received: from [85.158.137.68] by server-6.bemta-3.messagelabs.com id 47/4C-08479-98893C65; Tue, 16 Feb 2016 21:45:45 +0000 X-Env-Sender: jfehlig@suse.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1455659141!22829494!1 X-Originating-IP: [137.65.250.81] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17001 invoked from network); 16 Feb 2016 21:45:43 -0000 Received: from smtp2.provo.novell.com (HELO smtp2.provo.novell.com) (137.65.250.81) by server-12.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 16 Feb 2016 21:45:43 -0000 Received: from jfehlig2.provo.novell.com (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by smtp2.provo.novell.com with ESMTP (NOT encrypted); Tue, 16 Feb 2016 14:45:39 -0700 From: Jim Fehlig To: libvir-list@redhat.com Date: Tue, 16 Feb 2016 14:45:59 -0700 Message-Id: <1455659159-11931-5-git-send-email-jfehlig@suse.com> X-Mailer: git-send-email 2.6.1 In-Reply-To: <1455659159-11931-1-git-send-email-jfehlig@suse.com> References: <1455659159-11931-1-git-send-email-jfehlig@suse.com> Cc: Jim Fehlig , xen-devel@lists.xen.org Subject: [Xen-devel] [PATCH 4/4] libxl: add support for rbd qdisk X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP xl/libxl already supports qemu's network-based block backends such as nbd and rbd. libvirt has supported configuring such s for long time too. This patch adds support for rbd disks in the libxl driver by generating a rbd device URL from the virDomainDiskDef object. The URL is passed to libxl via the pdev_path field of libxl_device_disk struct. libxl then passes the URL to qemu for cosumption by the rbd backend. Signed-off-by: Jim Fehlig --- src/libxl/libxl_conf.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 48b77d2..5133299 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -46,6 +46,7 @@ #include "libxl_conf.h" #include "libxl_utils.h" #include "virstoragefile.h" +#include "base64.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -920,17 +921,206 @@ libxlDomainGetEmulatorType(const virDomainDef *def) return ret; } +static char * +libxlGetSecretString(virConnectPtr conn, + const char *scheme, + bool encoded, + virStorageAuthDefPtr authdef, + virSecretUsageType secretUsageType) +{ + size_t secret_size; + virSecretPtr sec = NULL; + char *secret = NULL; + char uuidStr[VIR_UUID_STRING_BUFLEN]; + + /* look up secret */ + switch (authdef->secretType) { + case VIR_STORAGE_SECRET_TYPE_UUID: + sec = virSecretLookupByUUID(conn, authdef->secret.uuid); + virUUIDFormat(authdef->secret.uuid, uuidStr); + break; + case VIR_STORAGE_SECRET_TYPE_USAGE: + sec = virSecretLookupByUsage(conn, secretUsageType, + authdef->secret.usage); + break; + } + + if (!sec) { + if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + virReportError(VIR_ERR_NO_SECRET, + _("%s no secret matches uuid '%s'"), + scheme, uuidStr); + } else { + virReportError(VIR_ERR_NO_SECRET, + _("%s no secret matches usage value '%s'"), + scheme, authdef->secret.usage); + } + goto cleanup; + } + + secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0, + VIR_SECRET_GET_VALUE_INTERNAL_CALL); + if (!secret) { + if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("could not get value of the secret for " + "username '%s' using uuid '%s'"), + authdef->username, uuidStr); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("could not get value of the secret for " + "username '%s' using usage value '%s'"), + authdef->username, authdef->secret.usage); + } + goto cleanup; + } + + if (encoded) { + char *base64 = NULL; + + base64_encode_alloc(secret, secret_size, &base64); + VIR_FREE(secret); + if (!base64) { + virReportOOMError(); + goto cleanup; + } + secret = base64; + } + + cleanup: + virObjectUnref(sec); + return secret; +} + +static char * +libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src, + const char *username, + const char *secret) +{ + char *ret = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t i; + + switch ((virStorageNetProtocol) src->protocol) { + case VIR_STORAGE_NET_PROTOCOL_NBD: + case VIR_STORAGE_NET_PROTOCOL_HTTP: + case VIR_STORAGE_NET_PROTOCOL_HTTPS: + case VIR_STORAGE_NET_PROTOCOL_FTP: + case VIR_STORAGE_NET_PROTOCOL_FTPS: + case VIR_STORAGE_NET_PROTOCOL_TFTP: + case VIR_STORAGE_NET_PROTOCOL_ISCSI: + case VIR_STORAGE_NET_PROTOCOL_GLUSTER: + case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: + case VIR_STORAGE_NET_PROTOCOL_LAST: + case VIR_STORAGE_NET_PROTOCOL_NONE: + virReportError(VIR_ERR_NO_SUPPORT, + _("Unsupported network block protocol '%s'"), + virStorageNetProtocolTypeToString(src->protocol)); + goto cleanup; + + case VIR_STORAGE_NET_PROTOCOL_RBD: + if (strchr(src->path, ':')) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("':' not allowed in RBD source volume name '%s'"), + src->path); + goto cleanup; + } + + virBufferStrcat(&buf, "rbd:", src->path, NULL); + + if (username) { + virBufferEscape(&buf, '\\', ":", ":id=%s", username); + virBufferEscape(&buf, '\\', ":", + ":key=%s:auth_supported=cephx\\;none", + secret); + } else { + virBufferAddLit(&buf, ":auth_supported=none"); + } + + if (src->nhosts > 0) { + virBufferAddLit(&buf, ":mon_host="); + for (i = 0; i < src->nhosts; i++) { + if (i) + virBufferAddLit(&buf, "\\;"); + + /* assume host containing : is ipv6 */ + if (strchr(src->hosts[i].name, ':')) + virBufferEscape(&buf, '\\', ":", "[%s]", + src->hosts[i].name); + else + virBufferAsprintf(&buf, "%s", src->hosts[i].name); + + if (src->hosts[i].port) + virBufferAsprintf(&buf, "\\:%s", src->hosts[i].port); + } + } + + if (src->configFile) + virBufferEscape(&buf, '\\', ":", ":conf=%s", src->configFile); + + if (virBufferCheckError(&buf) < 0) + goto cleanup; + + ret = virBufferContentAndReset(&buf); + break; + } + + cleanup: + virBufferFreeAndReset(&buf); + return ret; +} + +static int +libxlMakeNetworkDiskSrc(virStorageSourcePtr src, char **srcstr) +{ + virConnectPtr conn = NULL; + char *secret = NULL; + char *username = NULL; + int ret = -1; + + *srcstr = NULL; + if (src->auth && src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) { + const char *protocol = virStorageNetProtocolTypeToString(src->protocol); + + username = src->auth->username; + if (!(conn = virConnectOpen("xen:///system"))) + goto cleanup; + + if (!(secret = libxlGetSecretString(conn, + protocol, + true, + src->auth, + VIR_SECRET_USAGE_TYPE_CEPH))) + goto cleanup; + } + + if (!(*srcstr = libxlMakeNetworkDiskSrcStr(src, username, secret))) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(secret); + virObjectUnref(conn); + return ret; +} int libxlMakeDisk(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk) { const char *driver; int format; + int actual_type = virStorageSourceGetActualType(l_disk->src); libxl_device_disk_init(x_disk); - if (VIR_STRDUP(x_disk->pdev_path, virDomainDiskGetSource(l_disk)) < 0) + if (actual_type == VIR_STORAGE_TYPE_NETWORK) { + if (libxlMakeNetworkDiskSrc(l_disk->src, &x_disk->pdev_path) < 0) + return -1; + } else { + if (VIR_STRDUP(x_disk->pdev_path, virDomainDiskGetSource(l_disk)) < 0) return -1; + } if (VIR_STRDUP(x_disk->vdev, l_disk->dst) < 0) return -1;