From nobody Tue May 7 17:22:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1676372864; cv=none; d=zohomail.com; s=zohoarc; b=R6cE+KKgGLxrfz7pqD4NdhOLmsOWkd7oiKYd3lwhZFv/FLGESxUVaE72x5fySOTxKR3WXVfGV9H5J4F9MFKSgyY/Kwla89lhiOm0a5thiM0D08klCKyPc6Xhp1LFTn2K1v4Ub1PWB7M/l3+vBgDXweWI1zrz2fpL7yPfZHexml8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1676372864; h=Content-Type:Content-Transfer-Encoding:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=yt7ZD3pMeIGSk3GFoSgJS29wdM4wKFnHWE1AAdOqkNA=; b=lVa1JqUP4anAWEtH+TjvftS9r7oGjR9TIbtP04wunANnoQ3ZkOkIwZircK51pzvBLC5ivpmEWxr5hutIE5gpnoBtJJrjOS2mEx00ExhgtnPHAei9+HC6XTjnFzZDYDJpfHaBL0R4/kXNHidxihDPkHcEGsQQb6DwyLDveOzBgh8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1676372863701421.7592094307847; Tue, 14 Feb 2023 03:07:43 -0800 (PST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-212--NVYxrmfPWCKyjMXXhiwuQ-1; Tue, 14 Feb 2023 06:07:39 -0500 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 52B08858F09; Tue, 14 Feb 2023 11:07:36 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 33923492B1E; Tue, 14 Feb 2023 11:07:36 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 5CB3F19465B7; Tue, 14 Feb 2023 11:07:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 1E9ED1946586 for ; Tue, 14 Feb 2023 10:54:16 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 90A81492B04; Tue, 14 Feb 2023 10:54:16 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 89245492B03 for ; Tue, 14 Feb 2023 10:54:16 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 60CAB101A52E for ; Tue, 14 Feb 2023 10:54:16 +0000 (UTC) Received: from chinatelecom.cn (prt-mail.chinatelecom.cn [42.123.76.220]) by relay.mimecast.com with ESMTP id us-mta-636-lX2gGalbMXeMzhr4P-4V9A-1; Tue, 14 Feb 2023 05:54:13 -0500 Received: from clientip-106.120.101.58 (unknown [172.18.0.48]) by chinatelecom.cn (HERMES) with SMTP id 3E4E82800D5 for ; Tue, 14 Feb 2023 18:45:30 +0800 (CST) Received: from ([106.120.101.58]) by app0024 with ESMTP id 1c2992f931ec40839be63e258cc9bcd5 for libvir-list@redhat.com; Tue, 14 Feb 2023 18:45:34 CST DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676372862; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=yt7ZD3pMeIGSk3GFoSgJS29wdM4wKFnHWE1AAdOqkNA=; b=Vic3nBjJGo4T8h3DPxq+O8AtmqqMfril2usYB4Qr9yPuwCZuhiAbhDrKZLAqTedeymBFl8 ykb/1tfYT5q+nR7M/TVOCw5fOVIpkOQlFemOtK5LsltmDm7DRX6kIUxDMIfRBO2oRPLW0S 7KQ4hTqO4zf7w92EwvuUhyzu5Ox2gvo= X-MC-Unique: -NVYxrmfPWCKyjMXXhiwuQ-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: lX2gGalbMXeMzhr4P-4V9A-1 HMM_SOURCE_IP: 172.18.0.48:56960.814819757 HMM_ATTACHE_NUM: 0000 HMM_SOURCE_TYPE: SMTP X-189-SAVE-TO-SEND: 71117184@chinatelecom.cn X-Transaction-ID: 1c2992f931ec40839be63e258cc9bcd5 X-Real-From: guozh88@chinatelecom.cn X-Receive-IP: 106.120.101.58 X-MEDUSA-Status: 0 Date: Tue, 14 Feb 2023 18:45:31 +0800 From: Guozhonghua To: libvir-list Subject: [PATCH] feature: Ceph rbd create with data pool attributes set support. References: <2021083116095049963523@chinatelecom.cn>, , <202109061455554149503@chinatelecom.cn> X-Priority: 3 X-Has-Attach: no Mime-Version: 1.0 Message-ID: <2023021418453113543114@chinatelecom.cn> X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mailman-Approved-At: Tue, 14 Feb 2023 11:07:25 +0000 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1676372866857100001 Content-Type: text/plain; charset="utf-8" In some cases, we may use another pool to store the data and one pool to store the meta data of the rbd vol, so it is to use another interface to create the rbd vol, rbd_create4, required. This patch add the feature with xml configure is like as below: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rbd_pool =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Here we add one item rbdimageoption to set the attributions used when create rbd vol. If the option is not set, then the origin interface rbd_create is called as before. Signed-off-by: Guozhonghua --- =C2=A0src/conf/storage_conf.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 205 ++++= ++++++++++++++++++++++++++ =C2=A0src/conf/storage_conf.h =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A033= +++++ =C2=A0src/storage/storage_backend_rbd.c | 123 +++++++++++++++++- =C2=A03 files changed, 358 insertions(+), 3 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index f5a9636ce2..ac6c700ac1 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -461,6 +461,14 @@ virStoragePoolSourceDeviceClear(virStoragePoolSourceDe= vice *dev) =C2=A0} =C2=A0 =C2=A0 +void +virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option) +{ + =C2=A0 =C2=A0VIR_FREE(rbd_image_option->journal_pool); + =C2=A0 =C2=A0VIR_FREE(rbd_image_option->data_pool); +} + + =C2=A0void =C2=A0virStoragePoolSourceClear(virStoragePoolSource *source) =C2=A0{ @@ -484,6 +492,7 @@ virStoragePoolSourceClear(virStoragePoolSource *source) =C2=A0 =C2=A0 =C2=A0VIR_FREE(source->vendor); =C2=A0 =C2=A0 =C2=A0VIR_FREE(source->product); =C2=A0 =C2=A0 =C2=A0VIR_FREE(source->protocolVer); + =C2=A0 =C2=A0virRbdImageOptionClear(&source->rbdImageOptions); =C2=A0} =C2=A0 =C2=A0 @@ -514,6 +523,131 @@ virStoragePoolDefFree(virStoragePoolDef *def) =C2=A0} =C2=A0 =C2=A0 +int +virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 xmlNodePtr node, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 xmlXPathContextPtr ctxt) +{ + =C2=A0 =C2=A0VIR_XPATH_NODE_AUTORESTORE(ctxt) + =C2=A0 =C2=A0char *val =3D NULL; + + =C2=A0 =C2=A0ctxt->node =3D node; + + =C2=A0 =C2=A0rbd_image_option->format =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "format"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->format) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->feature =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "feature"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->feature) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->order =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "order"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->order) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->stripe_unit =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "stripeunit"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->stripe_unit) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->stripe_count =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "stripecount"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->stripe_count) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->journal_order =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "journalorder"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->journal_order) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->journal_splay_width =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "journalsplaywidth"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->journal_splay_width) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->journal_pool =3D virXMLPropString(node, "j= ournalpool"); + + =C2=A0 =C2=A0rbd_image_option->feature_set =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "featureset"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->feature_set) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->feature_clear =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "featureclear"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->feature_clear) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->data_pool =3D virXMLPropString(node, "data= pool"); + + =C2=A0 =C2=A0rbd_image_option->flatten =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "flatten"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->flatten) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->clone_format =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "cloneformat"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->clone_format) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_option->mirror_image_mode =3D -1; + =C2=A0 =C2=A0if ((val =3D virXMLPropString(node, "mirrorimagemode"))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStrToLong_l(val, NULL, 10, &rbd_image_o= ption->mirror_image_mode) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0return 0; +cleanup: + =C2=A0 =C2=A0VIR_FREE(val); + =C2=A0 =C2=A0return -1; +} + + + void + virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option) + { + =C2=A0 =C2=A0 rbd_image_option->format =3D -1; + =C2=A0 =C2=A0 rbd_image_option->feature =3D -1; + =C2=A0 =C2=A0 rbd_image_option->order =3D -1; + =C2=A0 =C2=A0 rbd_image_option->stripe_unit =3D -1; + =C2=A0 =C2=A0 rbd_image_option->stripe_count =3D -1; + =C2=A0 =C2=A0 rbd_image_option->journal_order =3D -1; + =C2=A0 =C2=A0 rbd_image_option->journal_splay_width =3D -1; + =C2=A0 =C2=A0 rbd_image_option->journal_pool =3D NULL; + =C2=A0 =C2=A0 rbd_image_option->feature_set =3D -1; + =C2=A0 =C2=A0 rbd_image_option->feature_clear =3D -1; + =C2=A0 =C2=A0 rbd_image_option->data_pool =3D NULL; + =C2=A0 =C2=A0 rbd_image_option->flatten =3D -1; + =C2=A0 =C2=A0 rbd_image_option->clone_format =3D -1; + =C2=A0 =C2=A0 rbd_image_option->mirror_image_mode =3D -1; + } + + =C2=A0static int =C2=A0virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 virStoragePoolSource *source, @@ -522,6 +656,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, =C2=A0{ =C2=A0 =C2=A0 =C2=A0xmlNodePtr authnode; =C2=A0 =C2=A0 =C2=A0xmlNodePtr adapternode; + =C2=A0 =C2=A0xmlNodePtr rbdimageoption; =C2=A0 =C2=A0 =C2=A0int nsource; =C2=A0 =C2=A0 =C2=A0size_t i; =C2=A0 =C2=A0 =C2=A0virStoragePoolOptions *options; @@ -633,6 +768,13 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0source->auth =3D g_steal_pointer(&authdef= ); =C2=A0 =C2=A0 =C2=A0} =C2=A0 + =C2=A0 =C2=A0if ((rbdimageoption =3D virXPathNode("./rbdimageoption", ctx= t))) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virRbdImageOptionParseXML(&source->rbdImag= eOptions, rbdimageoption, ctxt) < 0) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; + =C2=A0 =C2=A0} else { + =C2=A0 =C2=A0 =C2=A0 =C2=A0virRbdImageOptionDefaultSet(&source->rbdImageO= ptions); + =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0/* Option protocol version string (NFSvN) */ =C2=A0 =C2=A0 =C2=A0if ((source->protocolVer =3D virXPathString("string(./p= rotocol/@ver)", ctxt))) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((source->format !=3D VIR_STORAGE_POOL= _NETFS_NFS) && @@ -988,6 +1130,67 @@ virStoragePoolDefParse(const char *xmlStr, =C2=A0} =C2=A0 =C2=A0 +static void +virRbdImageOptionFormat(virBufferPtr buf, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 virRbdImageOptionsPtr rbdImageOptions) +{ + =C2=A0 // not set the rbd image options. + =C2=A0 if (rbdImageOptions->format < 0 && rbdImageOptions->feature < 0 &&= rbdImageOptions->order < 0 + =C2=A0 =C2=A0 =C2=A0 && rbdImageOptions->stripe_unit < 0 && rbdImageOptio= ns->stripe_count < 0 && rbdImageOptions->journal_order < 0 + =C2=A0 =C2=A0 =C2=A0 && rbdImageOptions->journal_splay_width < 0 && (rbdI= mageOptions->journal_pool !=3D NULL) && rbdImageOptions->feature_set < 0 + =C2=A0 =C2=A0 =C2=A0 && rbdImageOptions->feature_clear < 0 && (rbdImageOp= tions->data_pool !=3D NULL) && rbdImageOptions->flatten < 0 + =C2=A0 =C2=A0 =C2=A0 && rbdImageOptions->clone_format < 0 && rbdImageOpti= ons->mirror_image_mode < 0) + =C2=A0 return; + + =C2=A0 virBufferAsprintf(buf, "format >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " format=3D'%ld'", rbdImageOp= tions->format); + + =C2=A0 if (rbdImageOptions->feature >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " feature=3D'%ld'", rbdImageO= ptions->feature); + + =C2=A0 if (rbdImageOptions->order >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " order=3D'%ld'", rbdImageOpt= ions->order); + + =C2=A0 if (rbdImageOptions->stripe_unit >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " stripeunit=3D'%ld'", rbdIma= geOptions->stripe_unit); + + =C2=A0 if (rbdImageOptions->stripe_count >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " stripecount=3D'%ld'", rbdIm= ageOptions->stripe_count); + + =C2=A0 if (rbdImageOptions->journal_order >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " journalorder=3D'%ld'", rbdI= mageOptions->journal_order); + + =C2=A0 if (rbdImageOptions->journal_splay_width >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " journalsplaywidth=3D'%ld'",= rbdImageOptions->journal_splay_width); + + =C2=A0 if (rbdImageOptions->journal_pool) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " journalpool=3D'%s'", rbdIma= geOptions->journal_pool); + + =C2=A0 if (rbdImageOptions->feature_set >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " featureset=3D'%ld'", rbdIma= geOptions->feature_set); + + =C2=A0 if (rbdImageOptions->feature_clear >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " featureclear=3D'%ld'", rbdI= mageOptions->feature_clear); + + =C2=A0 if (rbdImageOptions->data_pool) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " datapool=3D'%s'", rbdImageO= ptions->data_pool); + + =C2=A0 if (rbdImageOptions->flatten >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " flatten=3D'%ld'", rbdImageO= ptions->flatten); + + =C2=A0 if (rbdImageOptions->clone_format >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " cloneformat=3D'%ld'", rbdIm= ageOptions->clone_format); + + =C2=A0 if (rbdImageOptions->mirror_image_mode >=3D 0) + =C2=A0 =C2=A0 =C2=A0 virBufferAsprintf(buf, " mirrorimagemode=3D'%ld'", r= bdImageOptions->mirror_image_mode); + + =C2=A0 virBufferAsprintf(buf, "/>\n"); +} + + + =C2=A0static int =C2=A0virStoragePoolSourceFormat(virBuffer *buf, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 virStoragePoolOptions *options, @@ -1066,6 +1269,8 @@ virStoragePoolSourceFormat(virBuffer *buf, =C2=A0 =C2=A0 =C2=A0virBufferEscapeString(buf, "\n", s= rc->vendor); =C2=A0 =C2=A0 =C2=A0virBufferEscapeString(buf, "\n", = src->product); =C2=A0 + =C2=A0 =C2=A0virRbdImageOptionFormat(buf, &src->rbdImageOptions); + =C2=A0 =C2=A0 =C2=A0virBufferAdjustIndent(buf, -2); =C2=A0 =C2=A0 =C2=A0virBufferAddLit(buf, "\n"); =C2=A0 =C2=A0 =C2=A0return 0; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index fc67957cfe..377ea1cfe2 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -175,6 +175,25 @@ struct _virStoragePoolFeatures { =C2=A0 =C2=A0 =C2=A0virTristateBool cow; =C2=A0}; =C2=A0 +typedef struct _virRbdImageOptions virRbdImageOptions; +typedef virRbdImageOptions *virRbdImageOptionsPtr; +struct _virRbdImageOptions { + =C2=A0 =C2=A0int64_t format; + =C2=A0 =C2=A0int64_t feature; + =C2=A0 =C2=A0int64_t order; + =C2=A0 =C2=A0int64_t stripe_unit; + =C2=A0 =C2=A0int64_t stripe_count; + =C2=A0 =C2=A0int64_t journal_order; + =C2=A0 =C2=A0int64_t journal_splay_width; + =C2=A0 =C2=A0char *journal_pool; + =C2=A0 =C2=A0int64_t feature_set; + =C2=A0 =C2=A0int64_t feature_clear; + =C2=A0 =C2=A0char *data_pool; + =C2=A0 =C2=A0int64_t flatten; + =C2=A0 =C2=A0int64_t clone_format; + =C2=A0 =C2=A0int64_t mirror_image_mode; +}; + =C2=A0 =C2=A0typedef struct _virStoragePoolSource virStoragePoolSource; =C2=A0struct _virStoragePoolSource { @@ -214,6 +233,9 @@ struct _virStoragePoolSource { =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Protocol version value for netfs */ =C2=A0 =C2=A0 =C2=A0char *protocolVer; + + =C2=A0 =C2=A0/* RBD Image Options definition. */ + =C2=A0 =C2=A0virRbdImageOptions rbdImageOptions; =C2=A0}; =C2=A0 =C2=A0typedef struct _virStoragePoolTarget virStoragePoolTarget; @@ -314,6 +336,9 @@ virStoragePoolSaveConfig(const char *configFile, =C2=A0void =C2=A0virStorageVolDefFree(virStorageVolDef *def); =C2=A0 +void +virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option); + =C2=A0void =C2=A0virStoragePoolSourceClear(virStoragePoolSource *source); =C2=A0 @@ -326,6 +351,14 @@ virStoragePoolSourceFree(virStoragePoolSource *source); =C2=A0void =C2=A0virStoragePoolDefFree(virStoragePoolDef *def); =C2=A0 +int +virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 xmlNodePtr node, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 xmlXPathContextPtr ctxt); + +void +virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option); + =C2=A0virStoragePoolSource * =C2=A0virStoragePoolDefParseSourceString(const char *srcSpec, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int pool_type); diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backen= d_rbd.c index 05b2c43f79..29c651cbcd 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -878,10 +878,127 @@ virStorageBackendRBDCreateVol(virStoragePoolObj *poo= l, =C2=A0} =C2=A0 =C2=A0static int virStorageBackendRBDCreateImage(rados_ioctx_t io, - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c= har *name, long capacity) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c= har *name, long capacity, virStoragePoolDefPtr def) =C2=A0{ =C2=A0 =C2=A0 =C2=A0int order =3D 0; - =C2=A0 =C2=A0return rbd_create(io, name, capacity, &order); + =C2=A0 =C2=A0int ret =3D -1; + =C2=A0 =C2=A0rbd_image_options_t image_options; + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.format < 0 && def->source.rb= dImageOptions.feature < 0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& def->source.rbdImageOptions.order < 0 && de= f->source.rbdImageOptions.stripe_unit < 0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& def->source.rbdImageOptions.stripe_count < = 0 && def->source.rbdImageOptions.journal_order < 0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& def->source.rbdImageOptions.journal_splay_w= idth < 0 && (def->source.rbdImageOptions.journal_pool !=3D NULL) + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& def->source.rbdImageOptions.feature_set < 0= && def->source.rbdImageOptions.feature_clear < 0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& (def->source.rbdImageOptions.data_pool !=3D= NULL) && def->source.rbdImageOptions.flatten < 0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& def->source.rbdImageOptions.clone_format < = 0 && def->source.rbdImageOptions.mirror_image_mode < 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Creating RBD image %s, without data= pool, with size %lu", name, capacity); + =C2=A0 =C2=A0 =C2=A0 =C2=A0return rbd_create(io, name, capacity, &order); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0rbd_image_options_create(&image_options); + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.format >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option format:%d, %lu= ", RBD_IMAGE_OPTION_FORMAT, def->source.rbdImageOptions.format); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_FORMAT, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbd= ImageOptions.format); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.feature >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option features:%d, %= lu", RBD_IMAGE_OPTION_FEATURES, def->source.rbdImageOptions.feature); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_FEATURES, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.feature); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.order >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option order:%d, %lu"= , RBD_IMAGE_OPTION_ORDER, def->source.rbdImageOptions.order); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_ORDER, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.order); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.stripe_unit >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option stripe_unit:%d= , %lu", RBD_IMAGE_OPTION_STRIPE_UNIT, def->source.rbdImageOptions.stripe_un= it); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_STRIPE_UNIT, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.stripe_unit); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.stripe_count >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option stipe_count:%d= , %lu", RBD_IMAGE_OPTION_STRIPE_COUNT, def->source.rbdImageOptions.stripe_c= ount); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_STRIPE_COUNT, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.stripe_count); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.journal_order >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option journal_order:= %d, %lu", RBD_IMAGE_OPTION_JOURNAL_ORDER, def->source.rbdImageOptions.journ= al_order); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_JOURNAL_ORDER, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.journal_order); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.journal_splay_width >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option journal_splay_= width:%d, %lu", RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH, def->source.rbdImageO= ptions.journal_splay_width); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_JOURNAL_SPLAY_W= IDTH, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.journal_splay_width); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.journal_pool !=3D NULL) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option journal_pool:%= d, %s", RBD_IMAGE_OPTION_JOURNAL_POOL, def->source.rbdImageOptions.journal_= pool); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_string(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_JOURNAL_POOL, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0def->source.rbdImageOptions.jour= nal_pool); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.feature_set >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option feature_set:%d= , %lu", RBD_IMAGE_OPTION_FEATURES_SET, def->source.rbdImageOptions.feature_= set); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_FEATURES_SET, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.feature_set); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.feature_clear >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option feature_clear:= %d, %lu", RBD_IMAGE_OPTION_FEATURES_CLEAR, def->source.rbdImageOptions.feat= ure_clear); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_FEATURES_CLEAR, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.feature_clear); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.data_pool !=3D NULL) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option data_pool:%d, = %s", RBD_IMAGE_OPTION_DATA_POOL, def->source.rbdImageOptions.data_pool); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_string(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_DATA_POOL, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0def->source.rbdImageOptions.data= _pool); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.flatten >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option flatten:%d, %l= u", RBD_IMAGE_OPTION_FLATTEN, def->source.rbdImageOptions.flatten); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_FLATTEN, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.flatten); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.clone_format >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option clone_format:%= d, %lu", RBD_IMAGE_OPTION_CLONE_FORMAT, def->source.rbdImageOptions.clone_f= ormat); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_CLONE_FORMAT, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.clone_format); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0if (def->source.rbdImageOptions.mirror_image_mode >=3D 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0VIR_DEBUG("Set rbd image option mirror_image_m= ode:%d, %lu", RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE, def->source.rbdImageOptio= ns.mirror_image_mode); + =C2=A0 =C2=A0 =C2=A0 =C2=A0rbd_image_options_set_uint64(image_options, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RBD_IMAGE_OPTION_MIRROR_IMAGE_MO= DE, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint64_t)def->source.rbdImageOp= tions.mirror_image_mode); + =C2=A0 =C2=A0} + + =C2=A0 =C2=A0ret =3D rbd_create4(io, name, capacity, image_options); + =C2=A0 =C2=A0VIR_DEBUG("Creating RBD image %s, with size:%lu, ret:%d", na= me, capacity, ret); + =C2=A0 =C2=A0rbd_image_options_destroy(image_options); + =C2=A0 =C2=A0return ret; =C2=A0} =C2=A0 =C2=A0static int @@ -920,7 +1037,7 @@ virStorageBackendRBDBuildVol(virStoragePoolObj *pool, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; =C2=A0 =C2=A0 =C2=A0 =C2=A0if (virStorageBackendRBDCreateImage(ptr->ioctx, vol->na= me, - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 vol->target.cap= acity) < 0) { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 vol->target.cap= acity, def) < 0) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0virReportSystemError(errno, _("failed to = create volume '%s/%s'"), =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 def->source.name, vol->name); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto cleanup; --=C2=A0 2.29.1.windows.1