From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257697; cv=none; d=zohomail.com; s=zohoarc; b=TgD57zUwY+BQJ9QLXGa3o8Kq7h0X7GthVo3Zs0BQQr2eDOJQSVdAivDLongXsoKMvPKaBuwp8psPcnFeUGQSGP78hSZK8hWcgI8OPa4H7+GSjzaaswpzINDiJa+5Fk1+xuUxOo5NEncNz2VyI6aXjBjxUZ/dLXw2yCJBiTUVvoU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257697; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=tU+D5qhrusf9iihUbUkrDBbgiDeZHayU9NlBs9u0C84=; b=lnPAycfNrs8GCWX00K/glXK9+FqsDeX1TGhFNlJzT4wM7+mGH9JlcomqxnOcXA8Sg5kI1QfIT6Jj0BOjNcVyBdpplPk4Q38xFC3qlWUj+doCPUALUDSNE7EmrNvftQHxlOsBRdEPqztm31Swy7rDWjpuWNJoMzyWscUHSwyd8pM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257697948465.0657601839026; Thu, 21 Jan 2021 11:34:57 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-98-IAgUvsAAOqeMMcKuiwM-TA-1; Thu, 21 Jan 2021 14:34:51 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 08B10806665; Thu, 21 Jan 2021 19:34:46 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D75896E51D; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 984851809CA2; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYWwC023141 for ; Thu, 21 Jan 2021 14:34:33 -0500 Received: by smtp.corp.redhat.com (Postfix) id EFD7F10021AA; Thu, 21 Jan 2021 19:34:32 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 526C810023AE for ; Thu, 21 Jan 2021 19:34:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257694; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=tU+D5qhrusf9iihUbUkrDBbgiDeZHayU9NlBs9u0C84=; b=jAbPCLdLj08hFAvKj+WEBbPce1J292vJw+ZXbxLYXZno+vnFXTBHg9gJqq6RQJFoXZOmOT 8UarFY/MM0GXG9NKzA6Pnp4WaDo23UbsADlEDoZ3F0x57r/4kvC4h1mqvGwJWKEWrY/ayr eaOIAgGdF1jPyN/PZwvIEFaSP5cDBIk= X-MC-Unique: IAgUvsAAOqeMMcKuiwM-TA-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 01/13] src: add missing virstoragefile.h includes Date: Thu, 21 Jan 2021 20:34:15 +0100 Message-Id: <7a966daf23fdd9e196a1493b5dfb4cb2cf0d018c.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" These files are using functions from virstoragefile.h but are missing explicit include. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/locking/lock_driver_lockd.c | 1 + src/qemu/qemu_block.c | 1 + src/qemu/qemu_snapshot.c | 1 + src/security/virt-aa-helper.c | 1 + src/storage/storage_file_gluster.c | 1 + 5 files changed, 5 insertions(+) diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lock= d.c index d459c1668c..5ebefa48d0 100644 --- a/src/locking/lock_driver_lockd.c +++ b/src/locking/lock_driver_lockd.c @@ -33,6 +33,7 @@ #include "rpc/virnetclient.h" #include "lock_protocol.h" #include "configmake.h" +#include "virstoragefile.h" #include "virstring.h" #include "virutil.h" =20 diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index f9c6da2cee..c98094e746 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -25,6 +25,7 @@ #include "qemu_security.h" =20 #include "viralloc.h" +#include "virstoragefile.h" #include "virstring.h" #include "virlog.h" =20 diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index ee333c35bb..c2fa54f5ab 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -38,6 +38,7 @@ #include "locking/domain_lock.h" #include "libvirt_internal.h" #include "virxml.h" +#include "virstoragefile.h" #include "virstring.h" #include "virdomainsnapshotobjlist.h" #include "virqemu.h" diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 5a6f4a5f7d..18af175655 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -46,6 +46,7 @@ #include "virfile.h" #include "configmake.h" #include "virrandom.h" +#include "virstoragefile.h" #include "virstring.h" #include "virgettext.h" #include "virhostdev.h" diff --git a/src/storage/storage_file_gluster.c b/src/storage/storage_file_= gluster.c index c84af8a4e8..0fc6835f11 100644 --- a/src/storage/storage_file_gluster.c +++ b/src/storage/storage_file_gluster.c @@ -27,6 +27,7 @@ #include "viralloc.h" #include "virerror.h" #include "virlog.h" +#include "virstoragefile.h" #include "virstoragefilebackend.h" #include "virstring.h" =20 --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.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 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257699; cv=none; d=zohomail.com; s=zohoarc; b=DCylzZPyFZRjZXZ4jQqfSlNonjgBmniDWkobW2h6hqxVPGVq9hBMEXROPhbol+0J0mWE+yHTwmtEZkePCEyo6Myv2CXtghCWJLItFcb9j+GRJXCYD6NrbprhN1XfEon6qm3D4bwAnKiNs576bs6GP2t2VHUSSMiFg3h4gJ6QSTI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257699; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zGylw2ZYdueAqjzu4cBS8n5v8DzIlx7gPcWTCZVGT3M=; b=enKNgD5d33svDFf/t1JK4w355S8jMA8FTyuTkzTk604gSe/FtaJw7EyRxHHfrnenlFlxx764qaQNmd3pPx+vvuLPAwDa4lfCRYLFr4zcxTNAqweO5dZ+rYoSTK2HGXqFCl8y3mK3iu/KZnaYMcZ3BIVHKYmfUZ5U1EI0eQxkh7Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1611257699857953.3585471107984; Thu, 21 Jan 2021 11:34:59 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-17-xZQR3_T7NMiLthYGEOYpXA-1; Thu, 21 Jan 2021 14:34:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1B306B810B; Thu, 21 Jan 2021 19:34:49 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E7396100AE37; Thu, 21 Jan 2021 19:34:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AD6F750030; Thu, 21 Jan 2021 19:34:48 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYYpD023151 for ; Thu, 21 Jan 2021 14:34:34 -0500 Received: by smtp.corp.redhat.com (Postfix) id 484581002382; Thu, 21 Jan 2021 19:34:34 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 62D3C10021AA for ; Thu, 21 Jan 2021 19:34:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257698; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=zGylw2ZYdueAqjzu4cBS8n5v8DzIlx7gPcWTCZVGT3M=; b=RRYLNvnFt6jkEAb5UF9BQPBLkzvzcXj6Rz14WIRLjDZZV8SZP6ZwPzcVJChM6ZfA9Vy9Xc QcX/0oUxUui+wBPXnn6Rock4IJR22kuoPziDnRRTIJbNv7a4FJY86N3kFmnC+AX56eQXsL QSSSSHkSzOHXtNzlg1LR4q7uJ0eYCAc= X-MC-Unique: xZQR3_T7NMiLthYGEOYpXA-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 02/13] virstoragefile: properly include virstoragefile.h header Date: Thu, 21 Jan 2021 20:34:16 +0100 Message-Id: <5eb1be52fe9f96e15791d1358ae62f0e8340d77f.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" It was indirectly included by virstoragefilebackend.h. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/util/virstoragefile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 0d3c2af94f..17579126b0 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -20,7 +20,7 @@ */ =20 #include -#include "virstoragefilebackend.h" +#include "virstoragefile.h" =20 #include #include @@ -38,6 +38,7 @@ #include "virbuffer.h" #include "virjson.h" #include "virstorageencryption.h" +#include "virstoragefilebackend.h" #include "virsecret.h" #include "virutil.h" =20 --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.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 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257689; cv=none; d=zohomail.com; s=zohoarc; b=WNTVrnDXSl+iz89gM3CfIiQltT/nzsRH4jcXaRVvnndmaOVGi0yhwRs5OesjYD3kACnfh7dD7PH8yTRRTE+hJzhu/jmM4SSf1DhQMy682rDNIvfgmiOYX4dtuLrUu53KrvAQwgY8Bqz2/Ou1FgR4/4ZigKYSfBwrMPGdT9BHpZ8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257689; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=4T9bl01pcRo/xWsMyNbdhnkq4oK0HG/fDRpVj+ED6Z0=; b=cLgALXlM24Wvn+X2TF25LUV37xAaUqjWlQ+DEbnrvHF7rNkNO0N4juSo3ZLHGqWrqFh8uRN8j+uMP7iAdARuyaR5YAyguSidv8Kx6C9BrxxAfXJwf8MEByWbDVbLjMOxR7RyUodpjhoqqW6e7+x5LbaUF9K90mXx9CQ0ksNHG98= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1611257689278730.7117589568321; Thu, 21 Jan 2021 11:34:49 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-143-QVgkeSciN2-vws4SYO0HVw-1; Thu, 21 Jan 2021 14:34:45 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 848A5B8103; Thu, 21 Jan 2021 19:34:39 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1FD226E51B; Thu, 21 Jan 2021 19:34:38 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 578A24E58F; Thu, 21 Jan 2021 19:34:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYaMv023162 for ; Thu, 21 Jan 2021 14:34:36 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1A82410021AA; Thu, 21 Jan 2021 19:34:36 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id DDC4B1002382 for ; Thu, 21 Jan 2021 19:34:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257688; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=4T9bl01pcRo/xWsMyNbdhnkq4oK0HG/fDRpVj+ED6Z0=; b=AQ9rFqesYr+vgvX2K+RZ13+4ggegJXyxK1UhW5XGsEnH2zKqP+AmQo0qafBx8Md/PYd56L GSQYUeCobKCa9lQV80xWHPytxx5yUTSmj127i1vTdB3tN+lGQqPH3i83Z2mxP6+ICpg86K Voeu77E3e4zpChLfU9DHfy+I7bA2J0M= X-MC-Unique: QVgkeSciN2-vws4SYO0HVw-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 03/13] virstoragefile: change virStorageSource->drv to void pointer Date: Thu, 21 Jan 2021 20:34:17 +0100 Message-Id: <09d25fea078b7aa5ba56874cbe25c4ec7f4c1e17.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" This will allow following patches to move virStorageSource into conf directory and virStorageDriverData into a new storage_file directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/storage/storage_file_fs.c | 21 +++-- src/storage/storage_file_gluster.c | 31 +++++--- src/util/virstoragefile.c | 118 +++++++++++++++++++++-------- src/util/virstoragefile.h | 5 +- src/util/virstoragefilebackend.h | 2 + 5 files changed, 122 insertions(+), 55 deletions(-) diff --git a/src/storage/storage_file_fs.c b/src/storage/storage_file_fs.c index b379a8ca8e..5a44ef8c2d 100644 --- a/src/storage/storage_file_fs.c +++ b/src/storage/storage_file_fs.c @@ -51,7 +51,8 @@ struct _virStorageFileBackendFsPriv { static void virStorageFileBackendFileDeinit(virStorageSourcePtr src) { - virStorageFileBackendFsPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendFsPrivPtr priv =3D drv->priv; =20 VIR_DEBUG("deinitializing FS storage file %p (%s:%s)", src, virStorageTypeToString(virStorageSourceGetActualType(src)), @@ -66,16 +67,17 @@ virStorageFileBackendFileDeinit(virStorageSourcePtr src) static int virStorageFileBackendFileInit(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D src->drv; virStorageFileBackendFsPrivPtr priv =3D NULL; =20 VIR_DEBUG("initializing FS storage file %p (%s:%s)[%u:%u]", src, virStorageTypeToString(virStorageSourceGetActualType(src)), src->path, - (unsigned int)src->drv->uid, (unsigned int)src->drv->gid); + (unsigned int)drv->uid, (unsigned int)drv->gid); =20 priv =3D g_new0(virStorageFileBackendFsPriv, 1); =20 - src->drv->priv =3D priv; + drv->priv =3D priv; =20 return 0; } @@ -84,10 +86,11 @@ virStorageFileBackendFileInit(virStorageSourcePtr src) static int virStorageFileBackendFileCreate(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D src->drv; VIR_AUTOCLOSE fd =3D -1; =20 if ((fd =3D virFileOpenAs(src->path, O_WRONLY | O_TRUNC | O_CREAT, S_I= RUSR | S_IWUSR, - src->drv->uid, src->drv->gid, 0)) < 0) { + drv->uid, drv->gid, 0)) < 0) { errno =3D -fd; return -1; } @@ -117,11 +120,12 @@ virStorageFileBackendFileRead(virStorageSourcePtr src, size_t len, char **buf) { + virStorageDriverDataPtr drv =3D src->drv; ssize_t ret =3D -1; VIR_AUTOCLOSE fd =3D -1; =20 if ((fd =3D virFileOpenAs(src->path, O_RDONLY, 0, - src->drv->uid, src->drv->gid, 0)) < 0) { + drv->uid, drv->gid, 0)) < 0) { virReportSystemError(-fd, _("Failed to open file '%s'"), src->path); return -1; @@ -146,7 +150,8 @@ virStorageFileBackendFileRead(virStorageSourcePtr src, static const char * virStorageFileBackendFileGetUniqueIdentifier(virStorageSourcePtr src) { - virStorageFileBackendFsPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendFsPrivPtr priv =3D drv->priv; =20 if (!priv->canonpath) { if (!(priv->canonpath =3D virFileCanonicalizePath(src->path))) { @@ -164,8 +169,10 @@ static int virStorageFileBackendFileAccess(virStorageSourcePtr src, int mode) { + virStorageDriverDataPtr drv =3D src->drv; + return virFileAccessibleAs(src->path, mode, - src->drv->uid, src->drv->gid); + drv->uid, drv->gid); } =20 =20 diff --git a/src/storage/storage_file_gluster.c b/src/storage/storage_file_= gluster.c index 0fc6835f11..2560e10d37 100644 --- a/src/storage/storage_file_gluster.c +++ b/src/storage/storage_file_gluster.c @@ -47,7 +47,8 @@ struct _virStorageFileBackendGlusterPriv { static void virStorageFileBackendGlusterDeinit(virStorageSourcePtr src) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; =20 VIR_DEBUG("deinitializing gluster storage file %p (gluster://%s:%u/%s%= s)", src, src->hosts->name, src->hosts->port, src->volume, src->p= ath); @@ -57,7 +58,7 @@ virStorageFileBackendGlusterDeinit(virStorageSourcePtr sr= c) VIR_FREE(priv->canonpath); =20 VIR_FREE(priv); - src->drv->priv =3D NULL; + drv->priv =3D NULL; } =20 static int @@ -100,6 +101,7 @@ virStorageFileBackendGlusterInitServer(virStorageFileBa= ckendGlusterPrivPtr priv, static int virStorageFileBackendGlusterInit(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D src->drv; virStorageFileBackendGlusterPrivPtr priv =3D NULL; size_t i; =20 @@ -115,7 +117,7 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr sr= c) VIR_DEBUG("initializing gluster storage file %p " "(priv=3D'%p' volume=3D'%s' path=3D'%s') as [%u:%u]", src, priv, src->volume, src->path, - (unsigned int)src->drv->uid, (unsigned int)src->drv->gid); + (unsigned int)drv->uid, (unsigned int)drv->gid); =20 if (!(priv->vol =3D glfs_new(src->volume))) { virReportOOMError(); @@ -134,7 +136,7 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr sr= c) goto error; } =20 - src->drv->priv =3D priv; + drv->priv =3D priv; =20 return 0; =20 @@ -150,7 +152,8 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr sr= c) static int virStorageFileBackendGlusterCreate(virStorageSourcePtr src) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; glfs_fd_t *fd =3D NULL; =20 if (!(fd =3D glfs_creat(priv->vol, src->path, @@ -165,7 +168,8 @@ virStorageFileBackendGlusterCreate(virStorageSourcePtr = src) static int virStorageFileBackendGlusterUnlink(virStorageSourcePtr src) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; =20 return glfs_unlink(priv->vol, src->path); } @@ -175,7 +179,8 @@ static int virStorageFileBackendGlusterStat(virStorageSourcePtr src, struct stat *st) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; =20 return glfs_stat(priv->vol, src->path, st); } @@ -187,7 +192,8 @@ virStorageFileBackendGlusterRead(virStorageSourcePtr sr= c, size_t len, char **buf) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; glfs_fd_t *fd =3D NULL; ssize_t ret =3D -1; char *s; @@ -242,7 +248,8 @@ static int virStorageFileBackendGlusterAccess(virStorageSourcePtr src, int mode) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; =20 return glfs_access(priv->vol, src->path, mode); } @@ -295,7 +302,8 @@ virStorageFileBackendGlusterReadlinkCallback(const char= *path, static const char * virStorageFileBackendGlusterGetUniqueIdentifier(virStorageSourcePtr src) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; g_autofree char *filePath =3D NULL; =20 if (priv->canonpath) @@ -321,7 +329,8 @@ virStorageFileBackendGlusterChown(const virStorageSourc= e *src, uid_t uid, gid_t gid) { - virStorageFileBackendGlusterPrivPtr priv =3D src->drv->priv; + virStorageDriverDataPtr drv =3D src->drv; + virStorageFileBackendGlusterPrivPtr priv =3D drv->priv; =20 return glfs_chown(priv->vol, src->path, uid, gid); } diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 17579126b0..24b47fc788 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -4619,7 +4619,8 @@ virStorageFileGetBackendForSupportCheck(const virStor= ageSource *src, } =20 if (src->drv) { - *backend =3D src->drv->backend; + virStorageDriverDataPtr drv =3D src->drv; + *backend =3D drv->backend; return 1; } =20 @@ -4715,12 +4716,16 @@ virStorageFileSupportsCreate(const virStorageSource= *src) void virStorageFileDeinit(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D NULL; + if (!virStorageFileIsInitialized(src)) return; =20 - if (src->drv->backend && - src->drv->backend->backendDeinit) - src->drv->backend->backendDeinit(src); + drv =3D src->drv; + + if (drv->backend && + drv->backend->backendDeinit) + drv->backend->backendDeinit(src); =20 VIR_FREE(src->drv); } @@ -4744,26 +4749,28 @@ virStorageFileInitAs(virStorageSourcePtr src, uid_t uid, gid_t gid) { int actualType =3D virStorageSourceGetActualType(src); - src->drv =3D g_new0(virStorageDriverData, 1); + virStorageDriverDataPtr drv =3D g_new0(virStorageDriverData, 1); + + src->drv =3D drv; =20 if (uid =3D=3D (uid_t) -1) - src->drv->uid =3D geteuid(); + drv->uid =3D geteuid(); else - src->drv->uid =3D uid; + drv->uid =3D uid; =20 if (gid =3D=3D (gid_t) -1) - src->drv->gid =3D getegid(); + drv->gid =3D getegid(); else - src->drv->gid =3D gid; + drv->gid =3D gid; =20 if (virStorageFileBackendForType(actualType, src->protocol, true, - &src->drv->backend) < 0) + &drv->backend) < 0) goto error; =20 - if (src->drv->backend->backendInit && - src->drv->backend->backendInit(src) < 0) + if (drv->backend->backendInit && + drv->backend->backendInit(src) < 0) goto error; =20 return 0; @@ -4798,15 +4805,22 @@ virStorageFileInit(virStorageSourcePtr src) int virStorageFileCreate(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src) || - !src->drv->backend->storageFileCreate) { + if (!virStorageFileIsInitialized(src)) { errno =3D ENOSYS; return -2; } =20 - ret =3D src->drv->backend->storageFileCreate(src); + drv =3D src->drv; + + if (!drv->backend->storageFileCreate) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileCreate(src); =20 VIR_DEBUG("created storage file %p: ret=3D%d, errno=3D%d", src, ret, errno); @@ -4828,15 +4842,22 @@ virStorageFileCreate(virStorageSourcePtr src) int virStorageFileUnlink(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src) || - !src->drv->backend->storageFileUnlink) { + if (!virStorageFileIsInitialized(src)) { errno =3D ENOSYS; return -2; } =20 - ret =3D src->drv->backend->storageFileUnlink(src); + drv =3D src->drv; + + if (!drv->backend->storageFileUnlink) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileUnlink(src); =20 VIR_DEBUG("unlinked storage file %p: ret=3D%d, errno=3D%d", src, ret, errno); @@ -4858,15 +4879,22 @@ int virStorageFileStat(virStorageSourcePtr src, struct stat *st) { + virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src) || - !src->drv->backend->storageFileStat) { + if (!virStorageFileIsInitialized(src)) { errno =3D ENOSYS; return -2; } =20 - ret =3D src->drv->backend->storageFileStat(src, st); + drv =3D src->drv; + + if (!drv->backend->storageFileStat) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileStat(src, st); =20 VIR_DEBUG("stat of storage file %p: ret=3D%d, errno=3D%d", src, ret, errno); @@ -4893,6 +4921,7 @@ virStorageFileRead(virStorageSourcePtr src, size_t len, char **buf) { + virStorageDriverDataPtr drv =3D NULL; ssize_t ret; =20 if (!virStorageFileIsInitialized(src)) { @@ -4901,10 +4930,12 @@ virStorageFileRead(virStorageSourcePtr src, return -1; } =20 - if (!src->drv->backend->storageFileRead) + drv =3D src->drv; + + if (!drv->backend->storageFileRead) return -2; =20 - ret =3D src->drv->backend->storageFileRead(src, offset, len, buf); + ret =3D drv->backend->storageFileRead(src, offset, len, buf); =20 VIR_DEBUG("read '%zd' bytes from storage '%p' starting at offset '%zu'= ", ret, src, offset); @@ -4924,13 +4955,17 @@ virStorageFileRead(virStorageSourcePtr src, const char * virStorageFileGetUniqueIdentifier(virStorageSourcePtr src) { + virStorageDriverDataPtr drv =3D NULL; + if (!virStorageFileIsInitialized(src)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("storage file backend not initialized")); return NULL; } =20 - if (!src->drv->backend->storageFileGetUniqueIdentifier) { + drv =3D src->drv; + + if (!drv->backend->storageFileGetUniqueIdentifier) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unique storage file identifier not implemented f= or " "storage type %s (protocol: %s)'"), @@ -4939,7 +4974,7 @@ virStorageFileGetUniqueIdentifier(virStorageSourcePtr= src) return NULL; } =20 - return src->drv->backend->storageFileGetUniqueIdentifier(src); + return drv->backend->storageFileGetUniqueIdentifier(src); } =20 =20 @@ -4957,13 +4992,21 @@ int virStorageFileAccess(virStorageSourcePtr src, int mode) { - if (!virStorageFileIsInitialized(src) || - !src->drv->backend->storageFileAccess) { + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileAccess) { errno =3D ENOSYS; return -2; } =20 - return src->drv->backend->storageFileAccess(src, mode); + return drv->backend->storageFileAccess(src, mode); } =20 =20 @@ -4983,8 +5026,16 @@ virStorageFileChown(const virStorageSource *src, uid_t uid, gid_t gid) { - if (!virStorageFileIsInitialized(src) || - !src->drv->backend->storageFileChown) { + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileChown) { errno =3D ENOSYS; return -2; } @@ -4992,7 +5043,7 @@ virStorageFileChown(const virStorageSource *src, VIR_DEBUG("chown of storage file %p to %u:%u", src, (unsigned int)uid, (unsigned int)gid); =20 - return src->drv->backend->storageFileChown(src, uid, gid); + return drv->backend->storageFileChown(src, uid, gid); } =20 =20 @@ -5012,8 +5063,9 @@ virStorageFileReportBrokenChain(int errcode, virStorageSourcePtr parent) { if (src->drv) { - unsigned int access_user =3D src->drv->uid; - unsigned int access_group =3D src->drv->gid; + virStorageDriverDataPtr drv =3D src->drv; + unsigned int access_user =3D drv->uid; + unsigned int access_group =3D drv->gid; =20 if (src =3D=3D parent) { virReportSystemError(errcode, diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 5689c39092..1a722e1fa4 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -263,9 +263,6 @@ struct _virStorageSourceSlice { }; =20 =20 -typedef struct _virStorageDriverData virStorageDriverData; -typedef virStorageDriverData *virStorageDriverDataPtr; - typedef struct _virStorageSource virStorageSource; typedef virStorageSource *virStorageSourcePtr; =20 @@ -337,7 +334,7 @@ struct _virStorageSource { virStorageSourcePtr backingStore; =20 /* metadata for storage driver access to remote and local volumes */ - virStorageDriverDataPtr drv; + void *drv; =20 /* metadata about storage image which need separate fields */ /* Relative name by which this image was opened from its parent, or NU= LL diff --git a/src/util/virstoragefilebackend.h b/src/util/virstoragefileback= end.h index c7af77bf8f..43b36e95bc 100644 --- a/src/util/virstoragefilebackend.h +++ b/src/util/virstoragefilebackend.h @@ -28,6 +28,8 @@ typedef struct _virStorageFileBackend virStorageFileBackend; typedef virStorageFileBackend *virStorageFileBackendPtr; =20 +typedef struct _virStorageDriverData virStorageDriverData; +typedef virStorageDriverData *virStorageDriverDataPtr; struct _virStorageDriverData { virStorageFileBackendPtr backend; void *priv; --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.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 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257689; cv=none; d=zohomail.com; s=zohoarc; b=mtUFJ9tEKij/J4vKK02nssUNE9A5+FbwNYC9KLz26KQeV0TVfxXnFAYpWCzDoBw4E9pRktadgOo3DZC+wGT7vf20lK0f2Wb0g/JWZ78Le1hTio8doDcrxubZC9UVnKL0hMc4lEp9UBGhGsNEC4+UzRdYyq+apcmfm8/RB+pQVbc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257689; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Ry+lbY4XcDzrBDySXMhIB0S/VD9nSaB7Ir3ZZdlAhvM=; b=XRh9DA47+cIgA/HV9suqWwfRT4ZcIzFJ3rHgz5DXe5LiVCwcFd/lCKSZtglpKDCyzp1wk80yTseeVeOABE4cXYH/RMvYc53chSrK4UmzWce+LmyCAUKzyFapkRuDSNcV7pjJG0VS/YMAg3uFnlnfR1ysZVfk6DOB4whGmcMsdbs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1611257689316524.9644575357855; Thu, 21 Jan 2021 11:34:49 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-173-aAyA7K8cPdCJh5rx7HCk6Q-1; Thu, 21 Jan 2021 14:34:45 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 31840107ACE4; Thu, 21 Jan 2021 19:34:40 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 039E139A66; Thu, 21 Jan 2021 19:34:40 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id BC4E8180954D; Thu, 21 Jan 2021 19:34:39 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYbWV023170 for ; Thu, 21 Jan 2021 14:34:37 -0500 Received: by smtp.corp.redhat.com (Postfix) id AE3C410021AA; Thu, 21 Jan 2021 19:34:37 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id E737810023B9 for ; Thu, 21 Jan 2021 19:34:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257688; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=Ry+lbY4XcDzrBDySXMhIB0S/VD9nSaB7Ir3ZZdlAhvM=; b=SBN9EmWpjm9KBkEI9nVrLxCTY09P0ukbtKEjspes2ecw5CklLd8OGpMAxOUtEEt46lXXjm 8FKqkZDvPJ1tMMN7JDZmThaw4ybrwijcu9PnDgv7YW2aYGxKyZGo0QuqOccveA/AqS6TXx v8QX1X/7wXyQUzG2ucIwHBcMjRDYji4= X-MC-Unique: aAyA7K8cPdCJh5rx7HCk6Q-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 04/13] storage: move storage file sources to separate directory Date: Thu, 21 Jan 2021 20:34:18 +0100 Message-Id: <44c4b69ef5d0b88cf8ed0c8e6e812d31c5755ee2.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Introduce a new storage_file directory where we will keep storage file related code. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 4 +- src/meson.build | 1 + src/storage/meson.build | 30 +-------------- src/storage_file/meson.build | 38 +++++++++++++++++++ .../storage_file_fs.c | 0 .../storage_file_fs.h | 0 .../storage_file_gluster.c | 0 .../storage_file_gluster.h | 0 8 files changed, 43 insertions(+), 30 deletions(-) create mode 100644 src/storage_file/meson.build rename src/{storage =3D> storage_file}/storage_file_fs.c (100%) rename src/{storage =3D> storage_file}/storage_file_fs.h (100%) rename src/{storage =3D> storage_file}/storage_file_gluster.c (100%) rename src/{storage =3D> storage_file}/storage_file_gluster.h (100%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 14636d4b93..e9fc3991f1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -222,9 +222,9 @@ @SRCDIR@src/storage/storage_backend_vstorage.c @SRCDIR@src/storage/storage_backend_zfs.c @SRCDIR@src/storage/storage_driver.c -@SRCDIR@src/storage/storage_file_fs.c -@SRCDIR@src/storage/storage_file_gluster.c @SRCDIR@src/storage/storage_util.c +@SRCDIR@src/storage_file/storage_file_fs.c +@SRCDIR@src/storage_file/storage_file_gluster.c @SRCDIR@src/test/test_driver.c @SRCDIR@src/util/iohelper.c @SRCDIR@src/util/viralloc.c diff --git a/src/meson.build b/src/meson.build index 7c478219d6..3aa9498b98 100644 --- a/src/meson.build +++ b/src/meson.build @@ -266,6 +266,7 @@ subdir('nwfilter') subdir('secret') subdir('security') subdir('storage') +subdir('storage_file') =20 subdir('bhyve') subdir('esx') diff --git a/src/storage/meson.build b/src/storage/meson.build index b4cefe9a89..8537359e93 100644 --- a/src/storage/meson.build +++ b/src/storage/meson.build @@ -15,10 +15,6 @@ storage_backend_fs_sources =3D [ 'storage_backend_fs.c', ] =20 -stoarge_file_fs_sources =3D [ - 'storage_file_fs.c', -] - storage_backend_disk_sources =3D [ 'storage_backend_disk.c', ] @@ -31,10 +27,6 @@ storage_backend_gluster_sources =3D [ 'storage_backend_gluster.c', ] =20 -storage_file_gluster_sources =3D [ - 'storage_file_gluster.c', -] - storage_backend_iscsi_sources =3D [ 'storage_backend_iscsi.c', ] @@ -72,7 +64,6 @@ storage_backend_zfs_sources =3D [ ] =20 storage_backend_install_dir =3D libdir / 'libvirt' / 'storage-backend' -storage_file_install_dir =3D libdir / 'libvirt' / 'storage-file' =20 if conf.has('WITH_STORAGE') storage_driver_impl_lib =3D static_library( @@ -109,14 +100,6 @@ if conf.has('WITH_STORAGE') 'install_dir': storage_backend_install_dir, } =20 - virt_modules +=3D { - 'name': 'virt_storage_file_fs', - 'sources': [ - files(stoarge_file_fs_sources), - ], - 'install_dir': storage_file_install_dir, - } - virt_daemons +=3D { 'name': 'virtstoraged', 'c_args': [ @@ -181,17 +164,6 @@ if conf.has('WITH_STORAGE_GLUSTER') ], 'install_dir': storage_backend_install_dir, } - - virt_modules +=3D { - 'name': 'virt_storage_file_gluster', - 'sources': [ - files(storage_file_gluster_sources), - ], - 'deps': [ - glusterfs_dep, - ], - 'install_dir': storage_file_install_dir, - } endif =20 if conf.has('WITH_STORAGE_ISCSI') @@ -303,3 +275,5 @@ if conf.has('WITH_STORAGE_ZFS') 'install_dir': storage_backend_install_dir, } endif + +storage_inc_dir =3D include_directories('.') diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build new file mode 100644 index 0000000000..20eb0176fc --- /dev/null +++ b/src/storage_file/meson.build @@ -0,0 +1,38 @@ +stoarge_file_fs_sources =3D [ + 'storage_file_fs.c', +] + +storage_file_gluster_sources =3D [ + 'storage_file_gluster.c', +] + +storage_file_install_dir =3D libdir / 'libvirt' / 'storage-file' + +if conf.has('WITH_STORAGE') + virt_modules +=3D { + 'name': 'virt_storage_file_fs', + 'sources': [ + files(stoarge_file_fs_sources), + ], + 'include': [ + storage_inc_dir, + ], + 'install_dir': storage_file_install_dir, + } +endif + +if conf.has('WITH_STORAGE_GLUSTER') + virt_modules +=3D { + 'name': 'virt_storage_file_gluster', + 'sources': [ + files(storage_file_gluster_sources), + ], + 'include': [ + storage_inc_dir, + ], + 'deps': [ + glusterfs_dep, + ], + 'install_dir': storage_file_install_dir, + } +endif diff --git a/src/storage/storage_file_fs.c b/src/storage_file/storage_file_= fs.c similarity index 100% rename from src/storage/storage_file_fs.c rename to src/storage_file/storage_file_fs.c diff --git a/src/storage/storage_file_fs.h b/src/storage_file/storage_file_= fs.h similarity index 100% rename from src/storage/storage_file_fs.h rename to src/storage_file/storage_file_fs.h diff --git a/src/storage/storage_file_gluster.c b/src/storage_file/storage_= file_gluster.c similarity index 100% rename from src/storage/storage_file_gluster.c rename to src/storage_file/storage_file_gluster.c diff --git a/src/storage/storage_file_gluster.h b/src/storage_file/storage_= file_gluster.h similarity index 100% rename from src/storage/storage_file_gluster.h rename to src/storage_file/storage_file_gluster.h --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257698; cv=none; d=zohomail.com; s=zohoarc; b=M5HZQFFskDwQ57HHOHjCUBfXfZYJb/oHOmBwJ08fZ99Xqyv6Ai0q7i7eCnPttbLlEzq3Q9SIkCnwp7QJPRtPxJQBm5CMEKSxrNg4J1zmDMPmEW2jxp7r66IQmwSwFOvgoYz0Uf3qGYVutpyo2aV+im1YoBHIPVmYF9FACt+2ZxI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257698; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9REDTz7ZVx5ACs4J5pKa5IiX8O2nMTX9JXeCnn0B3UU=; b=UcLFyDGhHAVbKkGAE6PQK+iIeKvdi5vfRhJm/RU4GwHbBTvwESpqLvQQw3EcUhIZkHNSEF+NnAm/wJCZgg2LWqgKHFYu1vfSGiKrHxhWGUMjuGT2kEydMaL9e71y0gUaw0G/8IWfC6BPa385SnC3hmYVYxSSaxSvsjsQ2CLkgu8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257698373116.86962970485251; Thu, 21 Jan 2021 11:34:58 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-170-oXB_aWr2O7a35Jqf-Hhy_g-1; Thu, 21 Jan 2021 14:34:54 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0517910766BD; Thu, 21 Jan 2021 19:34:46 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D2E0C5D9DD; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 98B565002E; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYc9w023185 for ; Thu, 21 Jan 2021 14:34:38 -0500 Received: by smtp.corp.redhat.com (Postfix) id E878C10023AE; Thu, 21 Jan 2021 19:34:38 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 586FE10021AA for ; Thu, 21 Jan 2021 19:34:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257697; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=9REDTz7ZVx5ACs4J5pKa5IiX8O2nMTX9JXeCnn0B3UU=; b=KBVu+Hn6X6+vdVEmfJRYDOE9GXBJDApHSKpahHcC88dIBUe6B/jvRMMDdOYzB4G9EniNOW /HClV//wulyAXlSaixyropBKroTnZlbejB9YLIV1d6RDq5keAMYxqBoC3CvRUWG/bzF13e C354/isodb238IfaHkZlxM73PX2XZPI= X-MC-Unique: oXB_aWr2O7a35Jqf-Hhy_g-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 05/13] util: move virStorageSourceFindByNodeName into qemu_domain Date: Thu, 21 Jan 2021 20:34:19 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" It's only relevant for QEMU driver. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/libvirt_private.syms | 1 - src/qemu/qemu_domain.c | 38 ++++++++++++++++++++++++++++++++------ src/util/virstoragefile.c | 25 ------------------------- src/util/virstoragefile.h | 5 ----- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c325040b60..84b650cb86 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3175,7 +3175,6 @@ virStorageSourceChainHasManagedPR; virStorageSourceChainHasNVMe; virStorageSourceClear; virStorageSourceCopy; -virStorageSourceFindByNodeName; virStorageSourceGetActualType; virStorageSourceGetSecurityLabelDef; virStorageSourceHasBacking; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index dd79cfd9d9..966608882f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2582,6 +2582,32 @@ qemuDomainObjPrivateXMLParseBlockjobChain(xmlNodePtr= node, } =20 =20 +/** + * qemuDomainVirStorageSourceFindByNodeName: + * @top: backing chain top + * @nodeName: node name to find in backing chain + * + * Looks up the given storage source in the backing chain and returns the + * pointer to it. + * On failure NULL is returned and no error is reported. + */ +static virStorageSourcePtr +qemuDomainVirStorageSourceFindByNodeName(virStorageSourcePtr top, + const char *nodeName) +{ + virStorageSourcePtr tmp; + + for (tmp =3D top; virStorageSourceIsBacking(tmp); tmp =3D tmp->backing= Store) { + if ((tmp->nodeformat && STREQ(tmp->nodeformat, nodeName)) || + (tmp->nodestorage && STREQ(tmp->nodestorage, nodeName))) + return tmp; + } + + return NULL; +} + + + static void qemuDomainObjPrivateXMLParseBlockjobNodename(qemuBlockJobDataPtr job, const char *xpath, @@ -2596,15 +2622,15 @@ qemuDomainObjPrivateXMLParseBlockjobNodename(qemuBl= ockJobDataPtr job, return; =20 if (job->disk && - (*src =3D virStorageSourceFindByNodeName(job->disk->src, nodename)= )) + (*src =3D qemuDomainVirStorageSourceFindByNodeName(job->disk->src,= nodename))) return; =20 if (job->chain && - (*src =3D virStorageSourceFindByNodeName(job->chain, nodename))) + (*src =3D qemuDomainVirStorageSourceFindByNodeName(job->chain, nod= ename))) return; =20 if (job->mirrorChain && - (*src =3D virStorageSourceFindByNodeName(job->mirrorChain, nodenam= e))) + (*src =3D qemuDomainVirStorageSourceFindByNodeName(job->mirrorChai= n, nodename))) return; =20 /* the node was in the XML but was not found in the job definitions */ @@ -10028,11 +10054,11 @@ qemuDomainDiskLookupByNodename(virDomainDefPtr de= f, for (i =3D 0; i < def->ndisks; i++) { virDomainDiskDefPtr domdisk =3D def->disks[i]; =20 - if ((*src =3D virStorageSourceFindByNodeName(domdisk->src, nodenam= e))) + if ((*src =3D qemuDomainVirStorageSourceFindByNodeName(domdisk->sr= c, nodename))) return domdisk; =20 if (domdisk->mirror && - (*src =3D virStorageSourceFindByNodeName(domdisk->mirror, node= name))) + (*src =3D qemuDomainVirStorageSourceFindByNodeName(domdisk->mi= rror, nodename))) return domdisk; } =20 @@ -10041,7 +10067,7 @@ qemuDomainDiskLookupByNodename(virDomainDefPtr def, virDomainBackupDiskDefPtr backupdisk =3D backupdef->disks + i; =20 if (backupdisk->store && - (*src =3D virStorageSourceFindByNodeName(backupdisk->store= , nodename))) + (*src =3D qemuDomainVirStorageSourceFindByNodeName(backupd= isk->store, nodename))) return virDomainDiskByTarget(def, backupdisk->name); } } diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 24b47fc788..13a86f34e5 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -4445,31 +4445,6 @@ virStorageSourceIsRelative(virStorageSourcePtr src) } =20 =20 -/** - * virStorageSourceFindByNodeName: - * @top: backing chain top - * @nodeName: node name to find in backing chain - * - * Looks up the given storage source in the backing chain and returns the - * pointer to it. - * On failure NULL is returned and no error is reported. - */ -virStorageSourcePtr -virStorageSourceFindByNodeName(virStorageSourcePtr top, - const char *nodeName) -{ - virStorageSourcePtr tmp; - - for (tmp =3D top; virStorageSourceIsBacking(tmp); tmp =3D tmp->backing= Store) { - if ((tmp->nodeformat && STREQ(tmp->nodeformat, nodeName)) || - (tmp->nodestorage && STREQ(tmp->nodestorage, nodeName))) - return tmp; - } - - return NULL; -} - - static unsigned int virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol) { diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 1a722e1fa4..46da6a8a18 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -521,11 +521,6 @@ int virStorageSourceNewFromBackingAbsolute(const char = *path, =20 bool virStorageSourceIsRelative(virStorageSourcePtr src); =20 -virStorageSourcePtr -virStorageSourceFindByNodeName(virStorageSourcePtr top, - const char *nodeName) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - void virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) ATTRIBUTE_NONNULL(1); --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257773; cv=none; d=zohomail.com; s=zohoarc; b=eZqOdrxvEhv46iUC/DLpSEeAaJmfNhYO9aacbh7kQYsL/Es28cE0aFamTlA5V7yBVpWndbmsczU/rHGz4+7CFaJD9KuBGV5Obe08abPxDcNpxnXlISh2BujHKzOgVeYi5vyg6tZidlaDji66Z+HnE2JpjwkAA/Jbps8pfmfZPU4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257773; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1Y/FSLXYCh9NrgWfjlpq4mI8tvpQ2m+4/zsvz+1Gtzg=; b=f9zSm8hTEOTz/52ga2Ry0QcAbG9tRpOOIYTTHiznPc8117re3WVGG1V5j6jlNhAOFN4O4L39oKStplI22kfQIo2ghuH22zLCrC3HuPARERFoeqtxIfzF8O7xpo2j27Qzk8ZPpGoeM9D5iUvQI/ZF3XTwDRzj2IxTaxWcMWRlGUY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257773654715.6192740668532; Thu, 21 Jan 2021 11:36:13 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-17-fe3z9Kv6P12b-d0U7gS5vQ-1; Thu, 21 Jan 2021 14:34:55 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 20844B810C; Thu, 21 Jan 2021 19:34:49 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EBB0A2C318; Thu, 21 Jan 2021 19:34:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AAC7E1809CA7; Thu, 21 Jan 2021 19:34:48 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYeMn023196 for ; Thu, 21 Jan 2021 14:34:40 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6B42A1002382; Thu, 21 Jan 2021 19:34:40 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6B7B310021AA for ; Thu, 21 Jan 2021 19:34:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257772; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=1Y/FSLXYCh9NrgWfjlpq4mI8tvpQ2m+4/zsvz+1Gtzg=; b=aqf+4gV33CYnMp/Xd7fL0kAa/kXltHmfBEFaFikBpfV7kqwwBywYcLKXiwqF2Wrex7pecC tsMZMZdQElrfp3EPs64bTRV1Kd9y2YDo3+y2beu8bF9OPa2YvWejmf1LswI3SPJC73AcZ8 Uqmlzl+uanQWHrobfQqaBGkd8Y7em/k= X-MC-Unique: fe3z9Kv6P12b-d0U7gS5vQ-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 06/13] util: extract storage file probe code into virtstoragefileprobe.c Date: Thu, 21 Jan 2021 20:34:20 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" This code is not directly relevant to virStorageSource so move it to separate file. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 1 + src/libvirt_private.syms | 6 +- src/qemu/qemu_driver.c | 1 + src/storage/storage_backend_gluster.c | 1 + src/storage/storage_util.c | 1 + src/util/meson.build | 1 + src/util/virstoragefile.c | 939 +------------------------ src/util/virstoragefile.h | 11 - src/util/virstoragefileprobe.c | 967 ++++++++++++++++++++++++++ src/util/virstoragefileprobe.h | 44 ++ 10 files changed, 1026 insertions(+), 946 deletions(-) create mode 100644 src/util/virstoragefileprobe.c create mode 100644 src/util/virstoragefileprobe.h diff --git a/po/POTFILES.in b/po/POTFILES.in index e9fc3991f1..19eb15ada0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -306,6 +306,7 @@ @SRCDIR@src/util/virstorageencryption.c @SRCDIR@src/util/virstoragefile.c @SRCDIR@src/util/virstoragefilebackend.c +@SRCDIR@src/util/virstoragefileprobe.c @SRCDIR@src/util/virstring.c @SRCDIR@src/util/virsysinfo.c @SRCDIR@src/util/virsystemd.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 84b650cb86..2dfc7e32d5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3148,7 +3148,6 @@ virStorageFileInit; virStorageFileInitAs; virStorageFileParseBackingStoreStr; virStorageFileParseChainIndex; -virStorageFileProbeFormat; virStorageFileRead; virStorageFileReportBrokenChain; virStorageFileStat; @@ -3212,6 +3211,11 @@ virStorageTypeToString; virStorageFileBackendRegister; =20 =20 +# util/virstoragefileprobe.h +virStorageFileProbeFormat; +virStorageFileProbeGetMetadata; + + # util/virstring.h virSkipSpaces; virSkipSpacesAndBackslash; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 027617deef..34a8fbe233 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -83,6 +83,7 @@ #include "domain_nwfilter.h" #include "virhook.h" #include "virstoragefile.h" +#include "virstoragefileprobe.h" #include "virfile.h" #include "virfdstream.h" #include "configmake.h" diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index 6c99c270da..205a707a17 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -28,6 +28,7 @@ #include "viralloc.h" #include "virerror.h" #include "virlog.h" +#include "virstoragefileprobe.h" #include "virstring.h" #include "viruri.h" #include "storage_util.h" diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 2e2c7dc68a..4117127d65 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -62,6 +62,7 @@ #include "vircrypto.h" #include "viruuid.h" #include "virstoragefile.h" +#include "virstoragefileprobe.h" #include "storage_util.h" #include "virlog.h" #include "virfile.h" diff --git a/src/util/meson.build b/src/util/meson.build index 395e70fd38..9fb270fadd 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -91,6 +91,7 @@ util_sources =3D [ 'virstorageencryption.c', 'virstoragefile.c', 'virstoragefilebackend.c', + 'virstoragefileprobe.c', 'virstring.c', 'virsysinfo.c', 'virsystemd.c', diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 13a86f34e5..98a3222d09 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -22,8 +22,6 @@ #include #include "virstoragefile.h" =20 -#include -#include #include "viralloc.h" #include "virxml.h" #include "viruuid.h" @@ -32,13 +30,13 @@ #include "virfile.h" #include "vircommand.h" #include "virhash.h" -#include "virendian.h" #include "virstring.h" #include "viruri.h" #include "virbuffer.h" #include "virjson.h" #include "virstorageencryption.h" #include "virstoragefilebackend.h" +#include "virstoragefileprobe.h" #include "virsecret.h" #include "virutil.h" =20 @@ -113,650 +111,6 @@ VIR_ENUM_IMPL(virStorageAuth, "none", "chap", "ceph", ); =20 -enum lv_endian { - LV_LITTLE_ENDIAN =3D 1, /* 1234 */ - LV_BIG_ENDIAN /* 4321 */ -}; - -enum { - BACKING_STORE_OK, - BACKING_STORE_INVALID, - BACKING_STORE_ERROR, -}; - -#define FILE_TYPE_VERSIONS_LAST 3 - -struct FileEncryptionInfo { - int format; /* Encryption format to assign */ - - int magicOffset; /* Byte offset of the magic */ - const char *magic; /* Optional string of magic */ - - enum lv_endian endian; /* Endianness of file format */ - - int versionOffset; /* Byte offset from start of file - * where we find version number, - * -1 to always fail the version test, - * -2 to always pass the version test */ - int versionSize; /* Size in bytes of version data (0, 2, or 4) */ - int versionNumbers[FILE_TYPE_VERSIONS_LAST]; - /* Version numbers to validate. Zeroes are ignor= ed. */ - - int modeOffset; /* Byte offset of the format native encryption mode */ - char modeValue; /* Value expected at offset */ - - int payloadOffset; /* start offset of the volume data (in 512 byte sec= tors) */ -}; - -struct FileTypeInfo { - int magicOffset; /* Byte offset of the magic */ - const char *magic; /* Optional string of file magic - * to check at head of file */ - enum lv_endian endian; /* Endianness of file format */ - - int versionOffset; /* Byte offset from start of file - * where we find version number, - * -1 to always fail the version test, - * -2 to always pass the version test */ - int versionSize; /* Size in bytes of version data (0, 2, or 4) */ - int versionNumbers[FILE_TYPE_VERSIONS_LAST]; - /* Version numbers to validate. Zeroes are ignor= ed. */ - int sizeOffset; /* Byte offset from start of file - * where we find capacity info, - * -1 to use st_size as capacity */ - int sizeBytes; /* Number of bytes for size field */ - int sizeMultiplier; /* A scaling factor if size is not in bytes */ - /* Store a COW base image path (possibly relativ= e), - * or NULL if there is no COW base image, to RES; - * return BACKING_STORE_* */ - const struct FileEncryptionInfo *cryptInfo; /* Encryption info */ - int (*getBackingStore)(char **res, int *format, - const char *buf, size_t buf_size); - int (*getFeatures)(virBitmapPtr *features, int format, - char *buf, ssize_t len); -}; - - -static int cowGetBackingStore(char **, int *, - const char *, size_t); -static int qcowXGetBackingStore(char **, int *, - const char *, size_t); -static int qcow2GetFeatures(virBitmapPtr *features, int format, - char *buf, ssize_t len); -static int vmdk4GetBackingStore(char **, int *, - const char *, size_t); -static int -qedGetBackingStore(char **, int *, const char *, size_t); - -#define QCOWX_HDR_VERSION (4) -#define QCOWX_HDR_BACKING_FILE_OFFSET (QCOWX_HDR_VERSION+4) -#define QCOWX_HDR_BACKING_FILE_SIZE (QCOWX_HDR_BACKING_FILE_OFFSET+8) -#define QCOWX_HDR_IMAGE_SIZE (QCOWX_HDR_BACKING_FILE_SIZE+4+4) - -#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1+2) -#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8) - -#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8) -#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8) - -#define QCOW2_HDR_EXTENSION_END 0 -#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA - -#define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE) -#define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE= +8) -#define QCOW2v3_HDR_FEATURES_AUTOCLEAR (QCOW2v3_HDR_FEATURES_COMPATIBLE+8) - -/* The location of the header size [4 bytes] */ -#define QCOW2v3_HDR_SIZE (QCOW2_HDR_TOTAL_SIZE+8+8+8+4) - -#define QED_HDR_FEATURES_OFFSET (4+4+4+4) -#define QED_HDR_IMAGE_SIZE (QED_HDR_FEATURES_OFFSET+8+8+8+8) -#define QED_HDR_BACKING_FILE_OFFSET (QED_HDR_IMAGE_SIZE+8) -#define QED_HDR_BACKING_FILE_SIZE (QED_HDR_BACKING_FILE_OFFSET+4) -#define QED_F_BACKING_FILE 0x01 -#define QED_F_BACKING_FORMAT_NO_PROBE 0x04 - -#define PLOOP_IMAGE_SIZE_OFFSET 36 -#define PLOOP_SIZE_MULTIPLIER 512 - -#define LUKS_HDR_MAGIC_LEN 6 -#define LUKS_HDR_VERSION_LEN 2 -#define LUKS_HDR_CIPHER_NAME_LEN 32 -#define LUKS_HDR_CIPHER_MODE_LEN 32 -#define LUKS_HDR_HASH_SPEC_LEN 32 -#define LUKS_HDR_PAYLOAD_LEN 4 - -/* Format described by qemu commit id '3e308f20e' */ -#define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN -#define LUKS_HDR_PAYLOAD_OFFSET (LUKS_HDR_MAGIC_LEN+\ - LUKS_HDR_VERSION_LEN+\ - LUKS_HDR_CIPHER_NAME_LEN+\ - LUKS_HDR_CIPHER_MODE_LEN+\ - LUKS_HDR_HASH_SPEC_LEN) - -static struct FileEncryptionInfo const luksEncryptionInfo[] =3D { - { - .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_LUKS, - - /* Magic is 'L','U','K','S', 0xBA, 0xBE */ - .magicOffset =3D 0, - .magic =3D "\x4c\x55\x4b\x53\xba\xbe", - .endian =3D LV_BIG_ENDIAN, - - .versionOffset =3D LUKS_HDR_VERSION_OFFSET, - .versionSize =3D LUKS_HDR_VERSION_LEN, - .versionNumbers =3D {1}, - - .modeOffset =3D -1, - .modeValue =3D -1, - - .payloadOffset =3D LUKS_HDR_PAYLOAD_OFFSET, - }, - { 0 } -}; - -static struct FileEncryptionInfo const qcow1EncryptionInfo[] =3D { - { - .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, - - .magicOffset =3D 0, - .magic =3D NULL, - .endian =3D LV_BIG_ENDIAN, - - .versionOffset =3D -1, - .versionSize =3D 0, - .versionNumbers =3D {}, - - .modeOffset =3D QCOW1_HDR_CRYPT, - .modeValue =3D 1, - - .payloadOffset =3D -1, - }, - { 0 } -}; - -static struct FileEncryptionInfo const qcow2EncryptionInfo[] =3D { - { - .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, - - .magicOffset =3D 0, - .magic =3D NULL, - .endian =3D LV_BIG_ENDIAN, - - .versionOffset =3D -1, - .versionSize =3D 0, - .versionNumbers =3D {}, - - .modeOffset =3D QCOW2_HDR_CRYPT, - .modeValue =3D 1, - - .payloadOffset =3D -1, - }, - { - .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_LUKS, - - .magicOffset =3D 0, - .magic =3D NULL, - .endian =3D LV_BIG_ENDIAN, - - .versionOffset =3D -1, - .versionSize =3D 0, - .versionNumbers =3D {}, - - .modeOffset =3D QCOW2_HDR_CRYPT, - .modeValue =3D 2, - - .payloadOffset =3D -1, - }, - { 0 } -}; - -static struct FileTypeInfo const fileTypeInfo[] =3D { - [VIR_STORAGE_FILE_NONE] =3D { 0, NULL, LV_LITTLE_ENDIAN, - -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, - [VIR_STORAGE_FILE_RAW] =3D { 0, NULL, LV_LITTLE_ENDIAN, - -1, 0, {0}, 0, 0, 0, - luksEncryptionInfo, - NULL, NULL }, - [VIR_STORAGE_FILE_DIR] =3D { 0, NULL, LV_LITTLE_ENDIAN, - -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, - [VIR_STORAGE_FILE_BOCHS] =3D { - /*"Bochs Virtual HD Image", */ /* Untested */ - 0, NULL, - LV_LITTLE_ENDIAN, 64, 4, {0x20000}, - 32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL - }, - [VIR_STORAGE_FILE_CLOOP] =3D { - /* #!/bin/sh - #V2.0 Format - modprobe cloop file=3D$0 && mount -r -t iso9660 /dev/cloop $1 - */ /* Untested */ - 0, NULL, - LV_LITTLE_ENDIAN, -1, 0, {0}, - -1, 0, 0, NULL, NULL, NULL - }, - [VIR_STORAGE_FILE_DMG] =3D { - /* XXX QEMU says there's no magic for dmg, - * /usr/share/misc/magic lists double magic (both offsets - * would have to match) but then disables that check. */ - 0, NULL, - 0, -1, 0, {0}, - -1, 0, 0, NULL, NULL, NULL - }, - [VIR_STORAGE_FILE_ISO] =3D { - 32769, "CD001", - LV_LITTLE_ENDIAN, -2, 0, {0}, - -1, 0, 0, NULL, NULL, NULL - }, - [VIR_STORAGE_FILE_VPC] =3D { - 0, "conectix", - LV_BIG_ENDIAN, 12, 4, {0x10000}, - 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL - }, - /* TODO: add getBackingStore function */ - [VIR_STORAGE_FILE_VDI] =3D { - 64, "\x7f\x10\xda\xbe", - LV_LITTLE_ENDIAN, 68, 4, {0x00010001}, - 64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL}, - - /* Not direct file formats, but used for various drivers */ - [VIR_STORAGE_FILE_FAT] =3D { 0, NULL, LV_LITTLE_ENDIAN, - -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, - [VIR_STORAGE_FILE_VHD] =3D { 0, NULL, LV_LITTLE_ENDIAN, - -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, - [VIR_STORAGE_FILE_PLOOP] =3D { 0, "WithouFreSpacExt", LV_LITTLE_ENDIAN, - -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0, - PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL }, - - /* All formats with a backing store probe below here */ - [VIR_STORAGE_FILE_COW] =3D { - 0, "OOOM", - LV_BIG_ENDIAN, 4, 4, {2}, - 4+4+1024+4, 8, 1, NULL, cowGetBackingStore, NULL - }, - [VIR_STORAGE_FILE_QCOW] =3D { - 0, "QFI", - LV_BIG_ENDIAN, 4, 4, {1}, - QCOWX_HDR_IMAGE_SIZE, 8, 1, - qcow1EncryptionInfo, - qcowXGetBackingStore, NULL - }, - [VIR_STORAGE_FILE_QCOW2] =3D { - 0, "QFI", - LV_BIG_ENDIAN, 4, 4, {2, 3}, - QCOWX_HDR_IMAGE_SIZE, 8, 1, - qcow2EncryptionInfo, - qcowXGetBackingStore, - qcow2GetFeatures - }, - [VIR_STORAGE_FILE_QED] =3D { - /* https://wiki.qemu.org/Features/QED */ - 0, "QED", - LV_LITTLE_ENDIAN, -2, 0, {0}, - QED_HDR_IMAGE_SIZE, 8, 1, NULL, qedGetBackingStore, NULL - }, - [VIR_STORAGE_FILE_VMDK] =3D { - 0, "KDMV", - LV_LITTLE_ENDIAN, 4, 4, {1, 2, 3}, - 4+4+4, 8, 512, NULL, vmdk4GetBackingStore, NULL - }, -}; -G_STATIC_ASSERT(G_N_ELEMENTS(fileTypeInfo) =3D=3D VIR_STORAGE_FILE_LAST); - - -/* qcow2 compatible features in the order they appear on-disk */ -enum qcow2CompatibleFeature { - QCOW2_COMPATIBLE_FEATURE_LAZY_REFCOUNTS =3D 0, - - QCOW2_COMPATIBLE_FEATURE_LAST -}; - -/* conversion to virStorageFileFeature */ -static const int qcow2CompatibleFeatureArray[] =3D { - VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS, -}; -G_STATIC_ASSERT(G_N_ELEMENTS(qcow2CompatibleFeatureArray) =3D=3D - QCOW2_COMPATIBLE_FEATURE_LAST); - -static int -cowGetBackingStore(char **res, - int *format, - const char *buf, - size_t buf_size) -{ -#define COW_FILENAME_MAXLEN 1024 - *res =3D NULL; - *format =3D VIR_STORAGE_FILE_AUTO; - - if (buf_size < 4+4+ COW_FILENAME_MAXLEN) - return BACKING_STORE_INVALID; - if (buf[4+4] =3D=3D '\0') { /* cow_header_v2.backing_file[0] */ - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - - *res =3D g_strndup((const char *)buf + 4 + 4, COW_FILENAME_MAXLEN); - return BACKING_STORE_OK; -} - - -static int -qcow2GetExtensions(const char *buf, - size_t buf_size, - int *backingFormat) -{ - size_t offset; - size_t extension_start; - size_t extension_end; - int version =3D virReadBufInt32BE(buf + QCOWX_HDR_VERSION); - - if (version < 2) { - /* QCow1 doesn't have the extensions capability - * used to store backing format */ - return 0; - } - - if (version =3D=3D 2) - extension_start =3D QCOW2_HDR_TOTAL_SIZE; - else - extension_start =3D virReadBufInt32BE(buf + QCOW2v3_HDR_SIZE); - - /* - * Traditionally QCow2 files had a layout of - * - * [header] - * [backingStoreName] - * - * Although the backingStoreName typically followed - * the header immediately, this was not required by - * the format. By specifying a higher byte offset for - * the backing file offset in the header, it was - * possible to leave space between the header and - * start of backingStore. - * - * This hack is now used to store extensions to the - * qcow2 format: - * - * [header] - * [extensions] - * [backingStoreName] - * - * Thus the file region to search for extensions is - * between the end of the header (QCOW2_HDR_TOTAL_SIZE) - * and the start of the backingStoreName (offset) - * - * for qcow2 v3 images, the length of the header - * is stored at QCOW2v3_HDR_SIZE - */ - extension_end =3D virReadBufInt64BE(buf + QCOWX_HDR_BACKING_FILE_OFFSE= T); - if (extension_end > buf_size) - return -1; - - /* - * The extensions take format of - * - * int32: magic - * int32: length - * byte[length]: payload - * - * Unknown extensions can be ignored by skipping - * over "length" bytes in the data stream. - */ - offset =3D extension_start; - while (offset < (buf_size-8) && - offset < (extension_end-8)) { - unsigned int magic =3D virReadBufInt32BE(buf + offset); - unsigned int len =3D virReadBufInt32BE(buf + offset + 4); - - offset +=3D 8; - - if ((offset + len) < offset) - break; - - if ((offset + len) > buf_size) - break; - - switch (magic) { - case QCOW2_HDR_EXTENSION_BACKING_FORMAT: { - g_autofree char *tmp =3D NULL; - if (!backingFormat) - break; - - tmp =3D g_new0(char, len + 1); - memcpy(tmp, buf + offset, len); - tmp[len] =3D '\0'; - - *backingFormat =3D virStorageFileFormatTypeFromString(tmp); - if (*backingFormat <=3D VIR_STORAGE_FILE_NONE) - return -1; - break; - } - - case QCOW2_HDR_EXTENSION_END: - return 0; - } - - offset +=3D len; - } - - return 0; -} - - -static int -qcowXGetBackingStore(char **res, - int *format, - const char *buf, - size_t buf_size) -{ - unsigned long long offset; - unsigned int size; - - *res =3D NULL; - *format =3D VIR_STORAGE_FILE_AUTO; - - if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4) - return BACKING_STORE_INVALID; - - offset =3D virReadBufInt64BE(buf + QCOWX_HDR_BACKING_FILE_OFFSET); - if (offset > buf_size) - return BACKING_STORE_INVALID; - - if (offset =3D=3D 0) { - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - - size =3D virReadBufInt32BE(buf + QCOWX_HDR_BACKING_FILE_SIZE); - if (size =3D=3D 0) { - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - if (size > 1023) - return BACKING_STORE_INVALID; - if (offset + size > buf_size || offset + size < offset) - return BACKING_STORE_INVALID; - *res =3D g_new0(char, size + 1); - memcpy(*res, buf + offset, size); - (*res)[size] =3D '\0'; - - if (qcow2GetExtensions(buf, buf_size, format) < 0) - return BACKING_STORE_INVALID; - - return BACKING_STORE_OK; -} - - -static int -vmdk4GetBackingStore(char **res, - int *format, - const char *buf, - size_t buf_size) -{ - static const char prefix[] =3D "parentFileNameHint=3D\""; - char *start, *end; - size_t len; - g_autofree char *desc =3D NULL; - - desc =3D g_new0(char, VIR_STORAGE_MAX_HEADER); - - *res =3D NULL; - /* - * Technically this should have been VMDK, since - * VMDK spec / VMware impl only support VMDK backed - * by VMDK. QEMU isn't following this though and - * does probing on VMDK backing files, hence we set - * AUTO - */ - *format =3D VIR_STORAGE_FILE_AUTO; - - if (buf_size <=3D 0x200) - return BACKING_STORE_INVALID; - - len =3D buf_size - 0x200; - if (len > VIR_STORAGE_MAX_HEADER) - len =3D VIR_STORAGE_MAX_HEADER; - memcpy(desc, buf + 0x200, len); - desc[len] =3D '\0'; - start =3D strstr(desc, prefix); - if (start =3D=3D NULL) { - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - start +=3D strlen(prefix); - end =3D strchr(start, '"'); - if (end =3D=3D NULL) - return BACKING_STORE_INVALID; - - if (end =3D=3D start) { - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - *end =3D '\0'; - *res =3D g_strdup(start); - - return BACKING_STORE_OK; -} - -static int -qedGetBackingStore(char **res, - int *format, - const char *buf, - size_t buf_size) -{ - unsigned long long flags; - unsigned long offset, size; - - *res =3D NULL; - /* Check if this image has a backing file */ - if (buf_size < QED_HDR_FEATURES_OFFSET+8) - return BACKING_STORE_INVALID; - flags =3D virReadBufInt64LE(buf + QED_HDR_FEATURES_OFFSET); - if (!(flags & QED_F_BACKING_FILE)) { - *format =3D VIR_STORAGE_FILE_NONE; - return BACKING_STORE_OK; - } - - /* Parse the backing file */ - if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8) - return BACKING_STORE_INVALID; - offset =3D virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_OFFSET); - if (offset > buf_size) - return BACKING_STORE_INVALID; - size =3D virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_SIZE); - if (size =3D=3D 0) - return BACKING_STORE_OK; - if (offset + size > buf_size || offset + size < offset) - return BACKING_STORE_INVALID; - *res =3D g_new0(char, size + 1); - memcpy(*res, buf + offset, size); - (*res)[size] =3D '\0'; - - if (flags & QED_F_BACKING_FORMAT_NO_PROBE) - *format =3D VIR_STORAGE_FILE_RAW; - else - *format =3D VIR_STORAGE_FILE_AUTO_SAFE; - - return BACKING_STORE_OK; -} - - -static bool -virStorageFileMatchesMagic(int magicOffset, - const char *magic, - char *buf, - size_t buflen) -{ - int mlen; - - if (magic =3D=3D NULL) - return false; - - /* Validate magic data */ - mlen =3D strlen(magic); - if (magicOffset + mlen > buflen) - return false; - - if (memcmp(buf + magicOffset, magic, mlen) !=3D 0) - return false; - - return true; -} - - -static bool -virStorageFileMatchesVersion(int versionOffset, - int versionSize, - const int *versionNumbers, - int endian, - char *buf, - size_t buflen) -{ - int version; - size_t i; - - /* Validate version number info */ - if (versionOffset =3D=3D -1) - return false; - - /* -2 =3D=3D non-versioned file format, so trivially match */ - if (versionOffset =3D=3D -2) - return true; - - /* A positive versionOffset, requires using a valid versionSize */ - if (versionSize !=3D 2 && versionSize !=3D 4) - return false; - - if ((versionOffset + versionSize) > buflen) - return false; - - if (endian =3D=3D LV_LITTLE_ENDIAN) { - if (versionSize =3D=3D 4) - version =3D virReadBufInt32LE(buf + - versionOffset); - else - version =3D virReadBufInt16LE(buf + - versionOffset); - } else { - if (versionSize =3D=3D 4) - version =3D virReadBufInt32BE(buf + - versionOffset); - else - version =3D virReadBufInt16BE(buf + - versionOffset); - } - - for (i =3D 0; - i < FILE_TYPE_VERSIONS_LAST && versionNumbers[i]; - i++) { - VIR_DEBUG("Compare detected version %d vs one of the expected vers= ions %d", - version, versionNumbers[i]); - if (version =3D=3D versionNumbers[i]) - return true; - } - - return false; -} =20 bool virStorageIsFile(const char *backing) @@ -792,289 +146,6 @@ virStorageIsRelative(const char *backing) } =20 =20 -static int -virStorageFileProbeFormatFromBuf(const char *path, - char *buf, - size_t buflen) -{ - int format =3D VIR_STORAGE_FILE_RAW; - size_t i; - int possibleFormat =3D VIR_STORAGE_FILE_RAW; - VIR_DEBUG("path=3D%s, buf=3D%p, buflen=3D%zu", path, buf, buflen); - - /* First check file magic */ - for (i =3D 0; i < VIR_STORAGE_FILE_LAST; i++) { - if (virStorageFileMatchesMagic(fileTypeInfo[i].magicOffset, - fileTypeInfo[i].magic, - buf, buflen)) { - if (!virStorageFileMatchesVersion(fileTypeInfo[i].versionOffse= t, - fileTypeInfo[i].versionSize, - fileTypeInfo[i].versionNumbe= rs, - fileTypeInfo[i].endian, - buf, buflen)) { - possibleFormat =3D i; - continue; - } - format =3D i; - goto cleanup; - } - } - - if (possibleFormat !=3D VIR_STORAGE_FILE_RAW) - VIR_WARN("File %s matches %s magic, but version is wrong. " - "Please report new version to libvir-list@redhat.com", - path, virStorageFileFormatTypeToString(possibleFormat)); - - cleanup: - VIR_DEBUG("format=3D%d", format); - return format; -} - - -static int -qcow2GetFeatures(virBitmapPtr *features, - int format, - char *buf, - ssize_t len) -{ - int version =3D -1; - virBitmapPtr feat =3D NULL; - uint64_t bits; - size_t i; - - version =3D virReadBufInt32BE(buf + fileTypeInfo[format].versionOffset= ); - - if (version =3D=3D 2) - return 0; - - if (len < QCOW2v3_HDR_SIZE) - return -1; - - feat =3D virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST); - - /* todo: check for incompatible or autoclear features? */ - bits =3D virReadBufInt64BE(buf + QCOW2v3_HDR_FEATURES_COMPATIBLE); - for (i =3D 0; i < QCOW2_COMPATIBLE_FEATURE_LAST; i++) { - if (bits & ((uint64_t) 1 << i)) - ignore_value(virBitmapSetBit(feat, qcow2CompatibleFeatureArray= [i])); - } - - *features =3D feat; - return 0; -} - - -static bool -virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info, - char *buf, - size_t len) -{ - if (!info->magic && info->modeOffset =3D=3D -1) - return false; /* Shouldn't happen - expect at least one */ - - if (info->magic) { - if (!virStorageFileMatchesMagic(info->magicOffset, - info->magic, - buf, len)) - return false; - - if (info->versionOffset !=3D -1 && - !virStorageFileMatchesVersion(info->versionOffset, - info->versionSize, - info->versionNumbers, - info->endian, - buf, len)) - return false; - - return true; - } else if (info->modeOffset !=3D -1) { - int crypt_format; - - if (info->modeOffset >=3D len) - return false; - - crypt_format =3D virReadBufInt32BE(buf + info->modeOffset); - if (crypt_format !=3D info->modeValue) - return false; - - return true; - } else { - return false; - } -} - - -static int -virStorageFileGetEncryptionPayloadOffset(const struct FileEncryptionInfo *= info, - char *buf) -{ - int payload_offset =3D -1; - - if (info->payloadOffset !=3D -1) { - if (info->endian =3D=3D LV_LITTLE_ENDIAN) - payload_offset =3D virReadBufInt32LE(buf + info->payloadOffset= ); - else - payload_offset =3D virReadBufInt32BE(buf + info->payloadOffset= ); - } - - return payload_offset; -} - - -/* Given a header in BUF with length LEN, as parsed from the storage file - * assuming it has the given FORMAT, populate information into META - * with information about the file and its backing store. Return format - * of the backing store as BACKING_FORMAT. PATH and FORMAT have to be - * pre-populated in META. - * - * Note that this function may be called repeatedly on @meta, so it must - * clean up any existing allocated memory which would be overwritten. - */ -static int -virStorageFileGetMetadataInternal(virStorageSourcePtr meta, - char *buf, - size_t len) -{ - int format; - size_t i; - - VIR_DEBUG("path=3D%s, buf=3D%p, len=3D%zu, meta->format=3D%d", - meta->path, buf, len, meta->format); - - if (meta->format =3D=3D VIR_STORAGE_FILE_AUTO) - meta->format =3D virStorageFileProbeFormatFromBuf(meta->path, buf,= len); - - if (meta->format <=3D VIR_STORAGE_FILE_NONE || - meta->format >=3D VIR_STORAGE_FILE_LAST) { - virReportSystemError(EINVAL, _("unknown storage file meta->format = %d"), - meta->format); - return -1; - } - - if (fileTypeInfo[meta->format].cryptInfo !=3D NULL) { - for (i =3D 0; fileTypeInfo[meta->format].cryptInfo[i].format !=3D = 0; i++) { - if (virStorageFileHasEncryptionFormat(&fileTypeInfo[meta->form= at].cryptInfo[i], - buf, len)) { - int expt_fmt =3D fileTypeInfo[meta->format].cryptInfo[i].f= ormat; - if (!meta->encryption) { - meta->encryption =3D g_new0(virStorageEncryption, 1); - meta->encryption->format =3D expt_fmt; - } else { - if (meta->encryption->format !=3D expt_fmt) { - virReportError(VIR_ERR_XML_ERROR, - _("encryption format %d doesn't mat= ch " - "expected format %d"), - meta->encryption->format, expt_fmt); - return -1; - } - } - meta->encryption->payload_offset =3D - virStorageFileGetEncryptionPayloadOffset(&fileTypeInfo= [meta->format].cryptInfo[i], buf); - } - } - } - - /* XXX we should consider moving virStorageBackendUpdateVolInfo - * code into this method, for non-magic files - */ - if (!fileTypeInfo[meta->format].magic) - return 0; - - /* Optionally extract capacity from file */ - if (fileTypeInfo[meta->format].sizeOffset !=3D -1) { - if ((fileTypeInfo[meta->format].sizeOffset + 8) > len) - return 0; - - if (fileTypeInfo[meta->format].endian =3D=3D LV_LITTLE_ENDIAN) - meta->capacity =3D virReadBufInt64LE(buf + - fileTypeInfo[meta->format].= sizeOffset); - else - meta->capacity =3D virReadBufInt64BE(buf + - fileTypeInfo[meta->format].= sizeOffset); - /* Avoid unlikely, but theoretically possible overflow */ - if (meta->capacity > (ULLONG_MAX / - fileTypeInfo[meta->format].sizeMultiplier)) - return 0; - meta->capacity *=3D fileTypeInfo[meta->format].sizeMultiplier; - } - - VIR_FREE(meta->backingStoreRaw); - if (fileTypeInfo[meta->format].getBackingStore !=3D NULL) { - int store =3D fileTypeInfo[meta->format].getBackingStore(&meta->ba= ckingStoreRaw, - &format, - buf, len); - meta->backingStoreRawFormat =3D format; - - if (store =3D=3D BACKING_STORE_INVALID) - return 0; - - if (store =3D=3D BACKING_STORE_ERROR) - return -1; - } - - virBitmapFree(meta->features); - meta->features =3D NULL; - if (fileTypeInfo[meta->format].getFeatures !=3D NULL && - fileTypeInfo[meta->format].getFeatures(&meta->features, meta->form= at, buf, len) < 0) - return -1; - - VIR_FREE(meta->compat); - if (meta->format =3D=3D VIR_STORAGE_FILE_QCOW2 && meta->features) - meta->compat =3D g_strdup("1.1"); - - return 0; -} - - -/** - * virStorageFileProbeFormat: - * - * Probe for the format of 'path', returning the detected - * disk format. - * - * Callers are advised never to trust the returned 'format' - * unless it is listed as VIR_STORAGE_FILE_RAW, since a - * malicious guest can turn a raw file into any other non-raw - * format at will. - * - * Best option: Don't use this function - */ -int -virStorageFileProbeFormat(const char *path, uid_t uid, gid_t gid) -{ - struct stat sb; - ssize_t len =3D VIR_STORAGE_MAX_HEADER; - VIR_AUTOCLOSE fd =3D -1; - g_autofree char *header =3D NULL; - - if ((fd =3D virFileOpenAs(path, O_RDONLY, 0, uid, gid, 0)) < 0) { - virReportSystemError(-fd, _("Failed to open file '%s'"), path); - return -1; - } - - if (fstat(fd, &sb) < 0) { - virReportSystemError(errno, _("cannot stat file '%s'"), path); - return -1; - } - - /* No header to probe for directories */ - if (S_ISDIR(sb.st_mode)) - return VIR_STORAGE_FILE_DIR; - - if (lseek(fd, 0, SEEK_SET) =3D=3D (off_t)-1) { - virReportSystemError(errno, _("cannot set to start of '%s'"), path= ); - return -1; - } - - if ((len =3D virFileReadHeaderFD(fd, len, &header)) < 0) { - virReportSystemError(errno, _("cannot read header '%s'"), path); - return -1; - } - - return virStorageFileProbeFormatFromBuf(path, header, len); -} - - static virStorageSourcePtr virStorageFileMetadataNew(const char *path, int format) @@ -1123,7 +194,7 @@ virStorageFileGetMetadataFromBuf(const char *path, if (!(ret =3D virStorageFileMetadataNew(path, format))) return NULL; =20 - if (virStorageFileGetMetadataInternal(ret, buf, len) < 0) { + if (virStorageFileProbeGetMetadata(ret, buf, len) < 0) { virObjectUnref(ret); return NULL; } @@ -1183,7 +254,7 @@ virStorageFileGetMetadataFromFD(const char *path, return NULL; } =20 - if (virStorageFileGetMetadataInternal(meta, buf, len) < 0) + if (virStorageFileProbeGetMetadata(meta, buf, len) < 0) return NULL; =20 if (S_ISREG(sb.st_mode)) @@ -5149,7 +4220,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr = src, &buf, &headerLen, cycle= ) < 0) return -1; =20 - if (virStorageFileGetMetadataInternal(src, buf, headerLen) < 0) + if (virStorageFileProbeGetMetadata(src, buf, headerLen) < 0) return -1; =20 /* If we probed the format we MUST ensure that nothing else than the c= urrent @@ -5292,7 +4363,7 @@ virStorageFileGetBackingStoreStr(virStorageSourcePtr = src, if (!(tmp =3D virStorageSourceCopy(src, false))) return -1; =20 - if (virStorageFileGetMetadataInternal(tmp, buf, headerLen) < 0) + if (virStorageFileProbeGetMetadata(tmp, buf, headerLen) < 0) return -1; =20 *backing =3D g_steal_pointer(&tmp->backingStoreRaw); diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 46da6a8a18..27ac6a493f 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -31,15 +31,6 @@ #include "virenum.h" #include "virpci.h" =20 -/* Minimum header size required to probe all known formats with - * virStorageFileProbeFormat, or obtain metadata from a known format. - * Rounded to multiple of 512 (ISO has a 5-byte magic at offset - * 32769). Some formats can be probed with fewer bytes. Although - * some formats theoretically permit metadata that can rely on offsets - * beyond this size, in practice that doesn't matter. */ -#define VIR_STORAGE_MAX_HEADER 0x8200 - - /* Types of disk backends (host resource). Comparable to the public * virStorageVolType, except we have an undetermined state, don't have * a netdir type, and add a volume type for reference through a @@ -401,8 +392,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObje= ctUnref); # define DEV_BSIZE 512 #endif =20 -int virStorageFileProbeFormat(const char *path, uid_t uid, gid_t gid); - virStorageSourcePtr virStorageFileGetMetadataFromFD(const char *path, int fd, int format); diff --git a/src/util/virstoragefileprobe.c b/src/util/virstoragefileprobe.c new file mode 100644 index 0000000000..bca098cd35 --- /dev/null +++ b/src/util/virstoragefileprobe.c @@ -0,0 +1,967 @@ +/* + * virstoragefileprobe.c: file utility functions for FS storage backend + * + * Copyright (C) 2007-2017 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include +#include +#include + +#include "internal.h" +#include "viralloc.h" +#include "virbitmap.h" +#include "virendian.h" +#include "virfile.h" +#include "virlog.h" +#include "virstoragefile.h" +#include "virstoragefileprobe.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("util.storagefileprobe"); + +enum lv_endian { + LV_LITTLE_ENDIAN =3D 1, /* 1234 */ + LV_BIG_ENDIAN /* 4321 */ +}; + +enum { + BACKING_STORE_OK, + BACKING_STORE_INVALID, + BACKING_STORE_ERROR, +}; + +#define FILE_TYPE_VERSIONS_LAST 3 + +struct FileEncryptionInfo { + int format; /* Encryption format to assign */ + + int magicOffset; /* Byte offset of the magic */ + const char *magic; /* Optional string of magic */ + + enum lv_endian endian; /* Endianness of file format */ + + int versionOffset; /* Byte offset from start of file + * where we find version number, + * -1 to always fail the version test, + * -2 to always pass the version test */ + int versionSize; /* Size in bytes of version data (0, 2, or 4) */ + int versionNumbers[FILE_TYPE_VERSIONS_LAST]; + /* Version numbers to validate. Zeroes are ignor= ed. */ + + int modeOffset; /* Byte offset of the format native encryption mode */ + char modeValue; /* Value expected at offset */ + + int payloadOffset; /* start offset of the volume data (in 512 byte sec= tors) */ +}; + +struct FileTypeInfo { + int magicOffset; /* Byte offset of the magic */ + const char *magic; /* Optional string of file magic + * to check at head of file */ + enum lv_endian endian; /* Endianness of file format */ + + int versionOffset; /* Byte offset from start of file + * where we find version number, + * -1 to always fail the version test, + * -2 to always pass the version test */ + int versionSize; /* Size in bytes of version data (0, 2, or 4) */ + int versionNumbers[FILE_TYPE_VERSIONS_LAST]; + /* Version numbers to validate. Zeroes are ignor= ed. */ + int sizeOffset; /* Byte offset from start of file + * where we find capacity info, + * -1 to use st_size as capacity */ + int sizeBytes; /* Number of bytes for size field */ + int sizeMultiplier; /* A scaling factor if size is not in bytes */ + /* Store a COW base image path (possibly relativ= e), + * or NULL if there is no COW base image, to RES; + * return BACKING_STORE_* */ + const struct FileEncryptionInfo *cryptInfo; /* Encryption info */ + int (*getBackingStore)(char **res, int *format, + const char *buf, size_t buf_size); + int (*getFeatures)(virBitmapPtr *features, int format, + char *buf, ssize_t len); +}; + + +static int cowGetBackingStore(char **, int *, + const char *, size_t); +static int qcowXGetBackingStore(char **, int *, + const char *, size_t); +static int qcow2GetFeatures(virBitmapPtr *features, int format, + char *buf, ssize_t len); +static int vmdk4GetBackingStore(char **, int *, + const char *, size_t); +static int +qedGetBackingStore(char **, int *, const char *, size_t); + +#define QCOWX_HDR_VERSION (4) +#define QCOWX_HDR_BACKING_FILE_OFFSET (QCOWX_HDR_VERSION+4) +#define QCOWX_HDR_BACKING_FILE_SIZE (QCOWX_HDR_BACKING_FILE_OFFSET+8) +#define QCOWX_HDR_IMAGE_SIZE (QCOWX_HDR_BACKING_FILE_SIZE+4+4) + +#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1+2) +#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8) + +#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8) +#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8) + +#define QCOW2_HDR_EXTENSION_END 0 +#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA + +#define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE) +#define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE= +8) +#define QCOW2v3_HDR_FEATURES_AUTOCLEAR (QCOW2v3_HDR_FEATURES_COMPATIBLE+8) + +/* The location of the header size [4 bytes] */ +#define QCOW2v3_HDR_SIZE (QCOW2_HDR_TOTAL_SIZE+8+8+8+4) + +#define QED_HDR_FEATURES_OFFSET (4+4+4+4) +#define QED_HDR_IMAGE_SIZE (QED_HDR_FEATURES_OFFSET+8+8+8+8) +#define QED_HDR_BACKING_FILE_OFFSET (QED_HDR_IMAGE_SIZE+8) +#define QED_HDR_BACKING_FILE_SIZE (QED_HDR_BACKING_FILE_OFFSET+4) +#define QED_F_BACKING_FILE 0x01 +#define QED_F_BACKING_FORMAT_NO_PROBE 0x04 + +#define PLOOP_IMAGE_SIZE_OFFSET 36 +#define PLOOP_SIZE_MULTIPLIER 512 + +#define LUKS_HDR_MAGIC_LEN 6 +#define LUKS_HDR_VERSION_LEN 2 +#define LUKS_HDR_CIPHER_NAME_LEN 32 +#define LUKS_HDR_CIPHER_MODE_LEN 32 +#define LUKS_HDR_HASH_SPEC_LEN 32 +#define LUKS_HDR_PAYLOAD_LEN 4 + +/* Format described by qemu commit id '3e308f20e' */ +#define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN +#define LUKS_HDR_PAYLOAD_OFFSET (LUKS_HDR_MAGIC_LEN+\ + LUKS_HDR_VERSION_LEN+\ + LUKS_HDR_CIPHER_NAME_LEN+\ + LUKS_HDR_CIPHER_MODE_LEN+\ + LUKS_HDR_HASH_SPEC_LEN) + +static struct FileEncryptionInfo const luksEncryptionInfo[] =3D { + { + .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_LUKS, + + /* Magic is 'L','U','K','S', 0xBA, 0xBE */ + .magicOffset =3D 0, + .magic =3D "\x4c\x55\x4b\x53\xba\xbe", + .endian =3D LV_BIG_ENDIAN, + + .versionOffset =3D LUKS_HDR_VERSION_OFFSET, + .versionSize =3D LUKS_HDR_VERSION_LEN, + .versionNumbers =3D {1}, + + .modeOffset =3D -1, + .modeValue =3D -1, + + .payloadOffset =3D LUKS_HDR_PAYLOAD_OFFSET, + }, + { 0 } +}; + +static struct FileEncryptionInfo const qcow1EncryptionInfo[] =3D { + { + .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, + + .magicOffset =3D 0, + .magic =3D NULL, + .endian =3D LV_BIG_ENDIAN, + + .versionOffset =3D -1, + .versionSize =3D 0, + .versionNumbers =3D {}, + + .modeOffset =3D QCOW1_HDR_CRYPT, + .modeValue =3D 1, + + .payloadOffset =3D -1, + }, + { 0 } +}; + +static struct FileEncryptionInfo const qcow2EncryptionInfo[] =3D { + { + .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, + + .magicOffset =3D 0, + .magic =3D NULL, + .endian =3D LV_BIG_ENDIAN, + + .versionOffset =3D -1, + .versionSize =3D 0, + .versionNumbers =3D {}, + + .modeOffset =3D QCOW2_HDR_CRYPT, + .modeValue =3D 1, + + .payloadOffset =3D -1, + }, + { + .format =3D VIR_STORAGE_ENCRYPTION_FORMAT_LUKS, + + .magicOffset =3D 0, + .magic =3D NULL, + .endian =3D LV_BIG_ENDIAN, + + .versionOffset =3D -1, + .versionSize =3D 0, + .versionNumbers =3D {}, + + .modeOffset =3D QCOW2_HDR_CRYPT, + .modeValue =3D 2, + + .payloadOffset =3D -1, + }, + { 0 } +}; + +static struct FileTypeInfo const fileTypeInfo[] =3D { + [VIR_STORAGE_FILE_NONE] =3D { 0, NULL, LV_LITTLE_ENDIAN, + -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, + [VIR_STORAGE_FILE_RAW] =3D { 0, NULL, LV_LITTLE_ENDIAN, + -1, 0, {0}, 0, 0, 0, + luksEncryptionInfo, + NULL, NULL }, + [VIR_STORAGE_FILE_DIR] =3D { 0, NULL, LV_LITTLE_ENDIAN, + -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, + [VIR_STORAGE_FILE_BOCHS] =3D { + /*"Bochs Virtual HD Image", */ /* Untested */ + 0, NULL, + LV_LITTLE_ENDIAN, 64, 4, {0x20000}, + 32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL + }, + [VIR_STORAGE_FILE_CLOOP] =3D { + /* #!/bin/sh + #V2.0 Format + modprobe cloop file=3D$0 && mount -r -t iso9660 /dev/cloop $1 + */ /* Untested */ + 0, NULL, + LV_LITTLE_ENDIAN, -1, 0, {0}, + -1, 0, 0, NULL, NULL, NULL + }, + [VIR_STORAGE_FILE_DMG] =3D { + /* XXX QEMU says there's no magic for dmg, + * /usr/share/misc/magic lists double magic (both offsets + * would have to match) but then disables that check. */ + 0, NULL, + 0, -1, 0, {0}, + -1, 0, 0, NULL, NULL, NULL + }, + [VIR_STORAGE_FILE_ISO] =3D { + 32769, "CD001", + LV_LITTLE_ENDIAN, -2, 0, {0}, + -1, 0, 0, NULL, NULL, NULL + }, + [VIR_STORAGE_FILE_VPC] =3D { + 0, "conectix", + LV_BIG_ENDIAN, 12, 4, {0x10000}, + 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL + }, + /* TODO: add getBackingStore function */ + [VIR_STORAGE_FILE_VDI] =3D { + 64, "\x7f\x10\xda\xbe", + LV_LITTLE_ENDIAN, 68, 4, {0x00010001}, + 64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL}, + + /* Not direct file formats, but used for various drivers */ + [VIR_STORAGE_FILE_FAT] =3D { 0, NULL, LV_LITTLE_ENDIAN, + -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, + [VIR_STORAGE_FILE_VHD] =3D { 0, NULL, LV_LITTLE_ENDIAN, + -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL }, + [VIR_STORAGE_FILE_PLOOP] =3D { 0, "WithouFreSpacExt", LV_LITTLE_ENDIAN, + -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0, + PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL }, + + /* All formats with a backing store probe below here */ + [VIR_STORAGE_FILE_COW] =3D { + 0, "OOOM", + LV_BIG_ENDIAN, 4, 4, {2}, + 4+4+1024+4, 8, 1, NULL, cowGetBackingStore, NULL + }, + [VIR_STORAGE_FILE_QCOW] =3D { + 0, "QFI", + LV_BIG_ENDIAN, 4, 4, {1}, + QCOWX_HDR_IMAGE_SIZE, 8, 1, + qcow1EncryptionInfo, + qcowXGetBackingStore, NULL + }, + [VIR_STORAGE_FILE_QCOW2] =3D { + 0, "QFI", + LV_BIG_ENDIAN, 4, 4, {2, 3}, + QCOWX_HDR_IMAGE_SIZE, 8, 1, + qcow2EncryptionInfo, + qcowXGetBackingStore, + qcow2GetFeatures + }, + [VIR_STORAGE_FILE_QED] =3D { + /* https://wiki.qemu.org/Features/QED */ + 0, "QED", + LV_LITTLE_ENDIAN, -2, 0, {0}, + QED_HDR_IMAGE_SIZE, 8, 1, NULL, qedGetBackingStore, NULL + }, + [VIR_STORAGE_FILE_VMDK] =3D { + 0, "KDMV", + LV_LITTLE_ENDIAN, 4, 4, {1, 2, 3}, + 4+4+4, 8, 512, NULL, vmdk4GetBackingStore, NULL + }, +}; +G_STATIC_ASSERT(G_N_ELEMENTS(fileTypeInfo) =3D=3D VIR_STORAGE_FILE_LAST); + + +/* qcow2 compatible features in the order they appear on-disk */ +enum qcow2CompatibleFeature { + QCOW2_COMPATIBLE_FEATURE_LAZY_REFCOUNTS =3D 0, + + QCOW2_COMPATIBLE_FEATURE_LAST +}; + +/* conversion to virStorageFileFeature */ +static const int qcow2CompatibleFeatureArray[] =3D { + VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS, +}; +G_STATIC_ASSERT(G_N_ELEMENTS(qcow2CompatibleFeatureArray) =3D=3D + QCOW2_COMPATIBLE_FEATURE_LAST); + +static int +cowGetBackingStore(char **res, + int *format, + const char *buf, + size_t buf_size) +{ +#define COW_FILENAME_MAXLEN 1024 + *res =3D NULL; + *format =3D VIR_STORAGE_FILE_AUTO; + + if (buf_size < 4+4+ COW_FILENAME_MAXLEN) + return BACKING_STORE_INVALID; + if (buf[4+4] =3D=3D '\0') { /* cow_header_v2.backing_file[0] */ + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + + *res =3D g_strndup((const char *)buf + 4 + 4, COW_FILENAME_MAXLEN); + return BACKING_STORE_OK; +} + + +static int +qcow2GetExtensions(const char *buf, + size_t buf_size, + int *backingFormat) +{ + size_t offset; + size_t extension_start; + size_t extension_end; + int version =3D virReadBufInt32BE(buf + QCOWX_HDR_VERSION); + + if (version < 2) { + /* QCow1 doesn't have the extensions capability + * used to store backing format */ + return 0; + } + + if (version =3D=3D 2) + extension_start =3D QCOW2_HDR_TOTAL_SIZE; + else + extension_start =3D virReadBufInt32BE(buf + QCOW2v3_HDR_SIZE); + + /* + * Traditionally QCow2 files had a layout of + * + * [header] + * [backingStoreName] + * + * Although the backingStoreName typically followed + * the header immediately, this was not required by + * the format. By specifying a higher byte offset for + * the backing file offset in the header, it was + * possible to leave space between the header and + * start of backingStore. + * + * This hack is now used to store extensions to the + * qcow2 format: + * + * [header] + * [extensions] + * [backingStoreName] + * + * Thus the file region to search for extensions is + * between the end of the header (QCOW2_HDR_TOTAL_SIZE) + * and the start of the backingStoreName (offset) + * + * for qcow2 v3 images, the length of the header + * is stored at QCOW2v3_HDR_SIZE + */ + extension_end =3D virReadBufInt64BE(buf + QCOWX_HDR_BACKING_FILE_OFFSE= T); + if (extension_end > buf_size) + return -1; + + /* + * The extensions take format of + * + * int32: magic + * int32: length + * byte[length]: payload + * + * Unknown extensions can be ignored by skipping + * over "length" bytes in the data stream. + */ + offset =3D extension_start; + while (offset < (buf_size-8) && + offset < (extension_end-8)) { + unsigned int magic =3D virReadBufInt32BE(buf + offset); + unsigned int len =3D virReadBufInt32BE(buf + offset + 4); + + offset +=3D 8; + + if ((offset + len) < offset) + break; + + if ((offset + len) > buf_size) + break; + + switch (magic) { + case QCOW2_HDR_EXTENSION_BACKING_FORMAT: { + g_autofree char *tmp =3D NULL; + if (!backingFormat) + break; + + tmp =3D g_new0(char, len + 1); + memcpy(tmp, buf + offset, len); + tmp[len] =3D '\0'; + + *backingFormat =3D virStorageFileFormatTypeFromString(tmp); + if (*backingFormat <=3D VIR_STORAGE_FILE_NONE) + return -1; + break; + } + + case QCOW2_HDR_EXTENSION_END: + return 0; + } + + offset +=3D len; + } + + return 0; +} + + +static int +qcowXGetBackingStore(char **res, + int *format, + const char *buf, + size_t buf_size) +{ + unsigned long long offset; + unsigned int size; + + *res =3D NULL; + *format =3D VIR_STORAGE_FILE_AUTO; + + if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4) + return BACKING_STORE_INVALID; + + offset =3D virReadBufInt64BE(buf + QCOWX_HDR_BACKING_FILE_OFFSET); + if (offset > buf_size) + return BACKING_STORE_INVALID; + + if (offset =3D=3D 0) { + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + + size =3D virReadBufInt32BE(buf + QCOWX_HDR_BACKING_FILE_SIZE); + if (size =3D=3D 0) { + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + if (size > 1023) + return BACKING_STORE_INVALID; + if (offset + size > buf_size || offset + size < offset) + return BACKING_STORE_INVALID; + *res =3D g_new0(char, size + 1); + memcpy(*res, buf + offset, size); + (*res)[size] =3D '\0'; + + if (qcow2GetExtensions(buf, buf_size, format) < 0) + return BACKING_STORE_INVALID; + + return BACKING_STORE_OK; +} + + +static int +vmdk4GetBackingStore(char **res, + int *format, + const char *buf, + size_t buf_size) +{ + static const char prefix[] =3D "parentFileNameHint=3D\""; + char *start, *end; + size_t len; + g_autofree char *desc =3D NULL; + + desc =3D g_new0(char, VIR_STORAGE_MAX_HEADER); + + *res =3D NULL; + /* + * Technically this should have been VMDK, since + * VMDK spec / VMware impl only support VMDK backed + * by VMDK. QEMU isn't following this though and + * does probing on VMDK backing files, hence we set + * AUTO + */ + *format =3D VIR_STORAGE_FILE_AUTO; + + if (buf_size <=3D 0x200) + return BACKING_STORE_INVALID; + + len =3D buf_size - 0x200; + if (len > VIR_STORAGE_MAX_HEADER) + len =3D VIR_STORAGE_MAX_HEADER; + memcpy(desc, buf + 0x200, len); + desc[len] =3D '\0'; + start =3D strstr(desc, prefix); + if (start =3D=3D NULL) { + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + start +=3D strlen(prefix); + end =3D strchr(start, '"'); + if (end =3D=3D NULL) + return BACKING_STORE_INVALID; + + if (end =3D=3D start) { + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + *end =3D '\0'; + *res =3D g_strdup(start); + + return BACKING_STORE_OK; +} + +static int +qedGetBackingStore(char **res, + int *format, + const char *buf, + size_t buf_size) +{ + unsigned long long flags; + unsigned long offset, size; + + *res =3D NULL; + /* Check if this image has a backing file */ + if (buf_size < QED_HDR_FEATURES_OFFSET+8) + return BACKING_STORE_INVALID; + flags =3D virReadBufInt64LE(buf + QED_HDR_FEATURES_OFFSET); + if (!(flags & QED_F_BACKING_FILE)) { + *format =3D VIR_STORAGE_FILE_NONE; + return BACKING_STORE_OK; + } + + /* Parse the backing file */ + if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8) + return BACKING_STORE_INVALID; + offset =3D virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_OFFSET); + if (offset > buf_size) + return BACKING_STORE_INVALID; + size =3D virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_SIZE); + if (size =3D=3D 0) + return BACKING_STORE_OK; + if (offset + size > buf_size || offset + size < offset) + return BACKING_STORE_INVALID; + *res =3D g_new0(char, size + 1); + memcpy(*res, buf + offset, size); + (*res)[size] =3D '\0'; + + if (flags & QED_F_BACKING_FORMAT_NO_PROBE) + *format =3D VIR_STORAGE_FILE_RAW; + else + *format =3D VIR_STORAGE_FILE_AUTO_SAFE; + + return BACKING_STORE_OK; +} + + +static bool +virStorageFileMatchesMagic(int magicOffset, + const char *magic, + char *buf, + size_t buflen) +{ + int mlen; + + if (magic =3D=3D NULL) + return false; + + /* Validate magic data */ + mlen =3D strlen(magic); + if (magicOffset + mlen > buflen) + return false; + + if (memcmp(buf + magicOffset, magic, mlen) !=3D 0) + return false; + + return true; +} + + +static bool +virStorageFileMatchesVersion(int versionOffset, + int versionSize, + const int *versionNumbers, + int endian, + char *buf, + size_t buflen) +{ + int version; + size_t i; + + /* Validate version number info */ + if (versionOffset =3D=3D -1) + return false; + + /* -2 =3D=3D non-versioned file format, so trivially match */ + if (versionOffset =3D=3D -2) + return true; + + /* A positive versionOffset, requires using a valid versionSize */ + if (versionSize !=3D 2 && versionSize !=3D 4) + return false; + + if ((versionOffset + versionSize) > buflen) + return false; + + if (endian =3D=3D LV_LITTLE_ENDIAN) { + if (versionSize =3D=3D 4) + version =3D virReadBufInt32LE(buf + + versionOffset); + else + version =3D virReadBufInt16LE(buf + + versionOffset); + } else { + if (versionSize =3D=3D 4) + version =3D virReadBufInt32BE(buf + + versionOffset); + else + version =3D virReadBufInt16BE(buf + + versionOffset); + } + + for (i =3D 0; + i < FILE_TYPE_VERSIONS_LAST && versionNumbers[i]; + i++) { + VIR_DEBUG("Compare detected version %d vs one of the expected vers= ions %d", + version, versionNumbers[i]); + if (version =3D=3D versionNumbers[i]) + return true; + } + + return false; +} + + +static int +virStorageFileProbeFormatFromBuf(const char *path, + char *buf, + size_t buflen) +{ + int format =3D VIR_STORAGE_FILE_RAW; + size_t i; + int possibleFormat =3D VIR_STORAGE_FILE_RAW; + VIR_DEBUG("path=3D%s, buf=3D%p, buflen=3D%zu", path, buf, buflen); + + /* First check file magic */ + for (i =3D 0; i < VIR_STORAGE_FILE_LAST; i++) { + if (virStorageFileMatchesMagic(fileTypeInfo[i].magicOffset, + fileTypeInfo[i].magic, + buf, buflen)) { + if (!virStorageFileMatchesVersion(fileTypeInfo[i].versionOffse= t, + fileTypeInfo[i].versionSize, + fileTypeInfo[i].versionNumbe= rs, + fileTypeInfo[i].endian, + buf, buflen)) { + possibleFormat =3D i; + continue; + } + format =3D i; + goto cleanup; + } + } + + if (possibleFormat !=3D VIR_STORAGE_FILE_RAW) + VIR_WARN("File %s matches %s magic, but version is wrong. " + "Please report new version to libvir-list@redhat.com", + path, virStorageFileFormatTypeToString(possibleFormat)); + + cleanup: + VIR_DEBUG("format=3D%d", format); + return format; +} + + +static int +qcow2GetFeatures(virBitmapPtr *features, + int format, + char *buf, + ssize_t len) +{ + int version =3D -1; + virBitmapPtr feat =3D NULL; + uint64_t bits; + size_t i; + + version =3D virReadBufInt32BE(buf + fileTypeInfo[format].versionOffset= ); + + if (version =3D=3D 2) + return 0; + + if (len < QCOW2v3_HDR_SIZE) + return -1; + + feat =3D virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST); + + /* todo: check for incompatible or autoclear features? */ + bits =3D virReadBufInt64BE(buf + QCOW2v3_HDR_FEATURES_COMPATIBLE); + for (i =3D 0; i < QCOW2_COMPATIBLE_FEATURE_LAST; i++) { + if (bits & ((uint64_t) 1 << i)) + ignore_value(virBitmapSetBit(feat, qcow2CompatibleFeatureArray= [i])); + } + + *features =3D feat; + return 0; +} + + +static bool +virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info, + char *buf, + size_t len) +{ + if (!info->magic && info->modeOffset =3D=3D -1) + return false; /* Shouldn't happen - expect at least one */ + + if (info->magic) { + if (!virStorageFileMatchesMagic(info->magicOffset, + info->magic, + buf, len)) + return false; + + if (info->versionOffset !=3D -1 && + !virStorageFileMatchesVersion(info->versionOffset, + info->versionSize, + info->versionNumbers, + info->endian, + buf, len)) + return false; + + return true; + } else if (info->modeOffset !=3D -1) { + int crypt_format; + + if (info->modeOffset >=3D len) + return false; + + crypt_format =3D virReadBufInt32BE(buf + info->modeOffset); + if (crypt_format !=3D info->modeValue) + return false; + + return true; + } else { + return false; + } +} + + +static int +virStorageFileGetEncryptionPayloadOffset(const struct FileEncryptionInfo *= info, + char *buf) +{ + int payload_offset =3D -1; + + if (info->payloadOffset !=3D -1) { + if (info->endian =3D=3D LV_LITTLE_ENDIAN) + payload_offset =3D virReadBufInt32LE(buf + info->payloadOffset= ); + else + payload_offset =3D virReadBufInt32BE(buf + info->payloadOffset= ); + } + + return payload_offset; +} + + +/* Given a header in BUF with length LEN, as parsed from the storage file + * assuming it has the given FORMAT, populate information into META + * with information about the file and its backing store. Return format + * of the backing store as BACKING_FORMAT. PATH and FORMAT have to be + * pre-populated in META. + * + * Note that this function may be called repeatedly on @meta, so it must + * clean up any existing allocated memory which would be overwritten. + */ +int +virStorageFileProbeGetMetadata(virStorageSourcePtr meta, + char *buf, + size_t len) +{ + int format; + size_t i; + + VIR_DEBUG("path=3D%s, buf=3D%p, len=3D%zu, meta->format=3D%d", + meta->path, buf, len, meta->format); + + if (meta->format =3D=3D VIR_STORAGE_FILE_AUTO) + meta->format =3D virStorageFileProbeFormatFromBuf(meta->path, buf,= len); + + if (meta->format <=3D VIR_STORAGE_FILE_NONE || + meta->format >=3D VIR_STORAGE_FILE_LAST) { + virReportSystemError(EINVAL, _("unknown storage file meta->format = %d"), + meta->format); + return -1; + } + + if (fileTypeInfo[meta->format].cryptInfo !=3D NULL) { + for (i =3D 0; fileTypeInfo[meta->format].cryptInfo[i].format !=3D = 0; i++) { + if (virStorageFileHasEncryptionFormat(&fileTypeInfo[meta->form= at].cryptInfo[i], + buf, len)) { + int expt_fmt =3D fileTypeInfo[meta->format].cryptInfo[i].f= ormat; + if (!meta->encryption) { + meta->encryption =3D g_new0(virStorageEncryption, 1); + meta->encryption->format =3D expt_fmt; + } else { + if (meta->encryption->format !=3D expt_fmt) { + virReportError(VIR_ERR_XML_ERROR, + _("encryption format %d doesn't mat= ch " + "expected format %d"), + meta->encryption->format, expt_fmt); + return -1; + } + } + meta->encryption->payload_offset =3D + virStorageFileGetEncryptionPayloadOffset(&fileTypeInfo= [meta->format].cryptInfo[i], buf); + } + } + } + + /* XXX we should consider moving virStorageBackendUpdateVolInfo + * code into this method, for non-magic files + */ + if (!fileTypeInfo[meta->format].magic) + return 0; + + /* Optionally extract capacity from file */ + if (fileTypeInfo[meta->format].sizeOffset !=3D -1) { + if ((fileTypeInfo[meta->format].sizeOffset + 8) > len) + return 0; + + if (fileTypeInfo[meta->format].endian =3D=3D LV_LITTLE_ENDIAN) + meta->capacity =3D virReadBufInt64LE(buf + + fileTypeInfo[meta->format].= sizeOffset); + else + meta->capacity =3D virReadBufInt64BE(buf + + fileTypeInfo[meta->format].= sizeOffset); + /* Avoid unlikely, but theoretically possible overflow */ + if (meta->capacity > (ULLONG_MAX / + fileTypeInfo[meta->format].sizeMultiplier)) + return 0; + meta->capacity *=3D fileTypeInfo[meta->format].sizeMultiplier; + } + + VIR_FREE(meta->backingStoreRaw); + if (fileTypeInfo[meta->format].getBackingStore !=3D NULL) { + int store =3D fileTypeInfo[meta->format].getBackingStore(&meta->ba= ckingStoreRaw, + &format, + buf, len); + meta->backingStoreRawFormat =3D format; + + if (store =3D=3D BACKING_STORE_INVALID) + return 0; + + if (store =3D=3D BACKING_STORE_ERROR) + return -1; + } + + virBitmapFree(meta->features); + meta->features =3D NULL; + if (fileTypeInfo[meta->format].getFeatures !=3D NULL && + fileTypeInfo[meta->format].getFeatures(&meta->features, meta->form= at, buf, len) < 0) + return -1; + + VIR_FREE(meta->compat); + if (meta->format =3D=3D VIR_STORAGE_FILE_QCOW2 && meta->features) + meta->compat =3D g_strdup("1.1"); + + return 0; +} + + +/** + * virStorageFileProbeFormat: + * + * Probe for the format of 'path', returning the detected + * disk format. + * + * Callers are advised never to trust the returned 'format' + * unless it is listed as VIR_STORAGE_FILE_RAW, since a + * malicious guest can turn a raw file into any other non-raw + * format at will. + * + * Best option: Don't use this function + */ +int +virStorageFileProbeFormat(const char *path, uid_t uid, gid_t gid) +{ + struct stat sb; + ssize_t len =3D VIR_STORAGE_MAX_HEADER; + VIR_AUTOCLOSE fd =3D -1; + g_autofree char *header =3D NULL; + + if ((fd =3D virFileOpenAs(path, O_RDONLY, 0, uid, gid, 0)) < 0) { + virReportSystemError(-fd, _("Failed to open file '%s'"), path); + return -1; + } + + if (fstat(fd, &sb) < 0) { + virReportSystemError(errno, _("cannot stat file '%s'"), path); + return -1; + } + + /* No header to probe for directories */ + if (S_ISDIR(sb.st_mode)) + return VIR_STORAGE_FILE_DIR; + + if (lseek(fd, 0, SEEK_SET) =3D=3D (off_t)-1) { + virReportSystemError(errno, _("cannot set to start of '%s'"), path= ); + return -1; + } + + if ((len =3D virFileReadHeaderFD(fd, len, &header)) < 0) { + virReportSystemError(errno, _("cannot read header '%s'"), path); + return -1; + } + + return virStorageFileProbeFormatFromBuf(path, header, len); +} diff --git a/src/util/virstoragefileprobe.h b/src/util/virstoragefileprobe.h new file mode 100644 index 0000000000..2b94a4ae51 --- /dev/null +++ b/src/util/virstoragefileprobe.h @@ -0,0 +1,44 @@ +/* + * virstoragefileprobe.h: file utility functions for FS storage backend + * + * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include + +#include "virstoragefile.h" + +/* Minimum header size required to probe all known formats with + * virStorageFileProbeFormat, or obtain metadata from a known format. + * Rounded to multiple of 512 (ISO has a 5-byte magic at offset + * 32769). Some formats can be probed with fewer bytes. Although + * some formats theoretically permit metadata that can rely on offsets + * beyond this size, in practice that doesn't matter. */ +#define VIR_STORAGE_MAX_HEADER 0x8200 + +int +virStorageFileProbeGetMetadata(virStorageSourcePtr meta, + char *buf, + size_t len); + +int +virStorageFileProbeFormat(const char *path, + uid_t uid, + gid_t gid); --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.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 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257703; cv=none; d=zohomail.com; s=zohoarc; b=NkfoEcorDeo3mngfXGXah95wO2aDrE+mFLArxPJbKFVh5rRG44z+MEwEi7Fcyetz2NOFS12Pq4zTVyGlBC8oeR1CDmvEMaO7qwjvL9uiJ3CLeoEFLySa7fytq31yBcSf2JgOP+09AEnlNo11Eyo0w+VQxPOsUPIXNcLaxvJ/kmI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257703; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1g4IjR4VPzry3RkkaoNZWRotUGa5S1VvwnFbhV4nAHQ=; b=f+jUaYMstXQquODdq/UDwgPlkp33Bm9fMurU0V+mToCmLUaM96V+d35BCUoYazJP1dlVdCU2AlGczWtD6t7+24JKW0u2FXldOX9Pc6FmfPjC9LL/ZkLQapQ6I/B/GwrkWpBsS9xb1QSPgb8qYOTn+68mmZ/xL5k/ofwvcqkohaI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1611257703613791.7213988033004; Thu, 21 Jan 2021 11:35:03 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-203-dsm0zmWRMVCZ5yqyFoA4kQ-1; Thu, 21 Jan 2021 14:34:58 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 49B7F1842143; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 20F4A5D9E3; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D77721809CAC; Thu, 21 Jan 2021 19:34:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYgTt023209 for ; Thu, 21 Jan 2021 14:34:42 -0500 Received: by smtp.corp.redhat.com (Postfix) id 561C810021AA; Thu, 21 Jan 2021 19:34:42 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id D9FE710023AE for ; Thu, 21 Jan 2021 19:34:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257702; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=1g4IjR4VPzry3RkkaoNZWRotUGa5S1VvwnFbhV4nAHQ=; b=hAEBlUMfLsmUt+oSBO6+SLId0rLmJQIB58DkdEr6bwm6GHW3B5JC7AN2rKoBVb9NiHiuwR SzoAVKNmN3AobeF9qnyDCW1tK1dY+34TsJtNLfhHtOkW9we2kz0KOJqlXMLImIrMMfUY8J /LLdzrhDsyBD0j+eWGFD+LHBtFqCfOk= X-MC-Unique: dsm0zmWRMVCZ5yqyFoA4kQ-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 07/13] util: extract virStorageFile code into storage_source Date: Thu, 21 Jan 2021 20:34:21 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Up until now we had a runtime code and XML related code in the same source file inside util directory. This patch takes the runtime part and extracts it into the new storage_file directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 1 + src/libvirt_private.syms | 57 +- src/libxl/meson.build | 1 + src/libxl/xen_xl.c | 2 +- src/qemu/meson.build | 1 + src/qemu/qemu_backup.c | 1 + src/qemu/qemu_block.c | 1 + src/qemu/qemu_domain.c | 1 + src/qemu/qemu_driver.c | 1 + src/qemu/qemu_hotplug.c | 1 + src/qemu/qemu_process.c | 1 + src/qemu/qemu_snapshot.c | 1 + src/security/meson.build | 1 + src/security/virt-aa-helper.c | 2 +- src/storage/meson.build | 4 + src/storage/storage_backend_gluster.c | 1 + src/storage/storage_util.c | 1 + src/storage_file/meson.build | 18 + src/storage_file/storage_source.c | 2614 +++++++++++++++++++++++++ src/storage_file/storage_source.h | 148 ++ src/util/virstoragefile.c | 2573 ------------------------ src/util/virstoragefile.h | 75 - tests/meson.build | 4 +- tests/qemublocktest.c | 1 + tests/virstoragetest.c | 1 + 25 files changed, 2833 insertions(+), 2679 deletions(-) create mode 100644 src/storage_file/storage_source.c create mode 100644 src/storage_file/storage_source.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 19eb15ada0..1e47af987d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -225,6 +225,7 @@ @SRCDIR@src/storage/storage_util.c @SRCDIR@src/storage_file/storage_file_fs.c @SRCDIR@src/storage_file/storage_file_gluster.c +@SRCDIR@src/storage_file/storage_source.c @SRCDIR@src/test/test_driver.c @SRCDIR@src/util/iohelper.c @SRCDIR@src/util/viralloc.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2dfc7e32d5..67a863467d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1618,6 +1618,36 @@ virSecurityManagerVerify; virSecurityXATTRNamespaceDefined; =20 =20 +# storage_file/storage_source.h +virStorageFileAccess; +virStorageFileChainLookup; +virStorageFileChown; +virStorageFileCreate; +virStorageFileDeinit; +virStorageFileGetBackingStoreStr; +virStorageFileGetMetadata; +virStorageFileGetMetadataFromBuf; +virStorageFileGetMetadataFromFD; +virStorageFileGetRelativeBackingPath; +virStorageFileGetUniqueIdentifier; +virStorageFileInit; +virStorageFileInitAs; +virStorageFileRead; +virStorageFileReportBrokenChain; +virStorageFileStat; +virStorageFileSupportsAccess; +virStorageFileSupportsBackingChainTraversal; +virStorageFileSupportsCreate; +virStorageFileSupportsSecurityDriver; +virStorageFileUnlink; +virStorageSourceNewFromBacking; +virStorageSourceNewFromBackingAbsolute; +virStorageSourceParseRBDColonString; +virStorageSourceUpdateBackingSizes; +virStorageSourceUpdateCapacity; +virStorageSourceUpdatePhysicalSize; + + # util/glibcompat.h vir_g_canonicalize_filename; vir_g_fsync; @@ -3126,36 +3156,15 @@ virStorageAuthDefCopy; virStorageAuthDefFormat; virStorageAuthDefFree; virStorageAuthDefParse; -virStorageFileAccess; virStorageFileCanonicalizePath; -virStorageFileChainLookup; -virStorageFileChown; -virStorageFileCreate; -virStorageFileDeinit; virStorageFileFeatureTypeFromString; virStorageFileFeatureTypeToString; virStorageFileFormatTypeFromString; virStorageFileFormatTypeToString; -virStorageFileGetBackingStoreStr; -virStorageFileGetMetadata; -virStorageFileGetMetadataFromBuf; -virStorageFileGetMetadataFromFD; virStorageFileGetNPIVKey; -virStorageFileGetRelativeBackingPath; virStorageFileGetSCSIKey; -virStorageFileGetUniqueIdentifier; -virStorageFileInit; -virStorageFileInitAs; virStorageFileParseBackingStoreStr; virStorageFileParseChainIndex; -virStorageFileRead; -virStorageFileReportBrokenChain; -virStorageFileStat; -virStorageFileSupportsAccess; -virStorageFileSupportsBackingChainTraversal; -virStorageFileSupportsCreate; -virStorageFileSupportsSecurityDriver; -virStorageFileUnlink; virStorageIsFile; virStorageIsRelative; virStorageNetHostDefClear; @@ -3191,18 +3200,12 @@ virStorageSourceIsSameLocation; virStorageSourceNetCookiesValidate; virStorageSourceNetworkAssignDefaultPorts; virStorageSourceNew; -virStorageSourceNewFromBacking; -virStorageSourceNewFromBackingAbsolute; virStorageSourceNVMeDefFree; -virStorageSourceParseRBDColonString; virStorageSourcePoolDefFree; virStorageSourcePoolModeTypeFromString; virStorageSourcePoolModeTypeToString; virStorageSourcePrivateDataFormatRelPath; virStorageSourcePrivateDataParseRelPath; -virStorageSourceUpdateBackingSizes; -virStorageSourceUpdateCapacity; -virStorageSourceUpdatePhysicalSize; virStorageTypeFromString; virStorageTypeToString; =20 diff --git a/src/libxl/meson.build b/src/libxl/meson.build index 3bb6cc5f2e..783af6c667 100644 --- a/src/libxl/meson.build +++ b/src/libxl/meson.build @@ -27,6 +27,7 @@ if conf.has('WITH_LIBXL') include_directories: [ conf_inc_dir, hypervisor_inc_dir, + storage_file_inc_dir, ], ) =20 diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c index 17b93d0f5c..621ee63a99 100644 --- a/src/libxl/xen_xl.c +++ b/src/libxl/xen_xl.c @@ -29,7 +29,7 @@ #include "domain_conf.h" #include "viralloc.h" #include "virstring.h" -#include "virstoragefile.h" +#include "storage_source.h" #include "xen_xl.h" #include "libxl_capabilities.h" #include "libxl_conf.h" diff --git a/src/qemu/meson.build b/src/qemu/meson.build index 90640b03c6..7ab591d040 100644 --- a/src/qemu/meson.build +++ b/src/qemu/meson.build @@ -104,6 +104,7 @@ if conf.has('WITH_QEMU') include_directories: [ conf_inc_dir, hypervisor_inc_dir, + storage_file_inc_dir, ], ) =20 diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index c444f8aaba..72ca781d8b 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -29,6 +29,7 @@ #include "qemu_checkpoint.h" #include "qemu_command.h" =20 +#include "storage_source.h" #include "virerror.h" #include "virlog.h" #include "virbuffer.h" diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c98094e746..ca23466b22 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -24,6 +24,7 @@ #include "qemu_alias.h" #include "qemu_security.h" =20 +#include "storage_source.h" #include "viralloc.h" #include "virstoragefile.h" #include "virstring.h" diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 966608882f..165321858e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -52,6 +52,7 @@ #include "virtime.h" #include "virnetdevopenvswitch.h" #include "virstoragefile.h" +#include "storage_source.h" #include "virstring.h" #include "virthreadjob.h" #include "virprocess.h" diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 34a8fbe233..a5c2488f2c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -84,6 +84,7 @@ #include "virhook.h" #include "virstoragefile.h" #include "virstoragefileprobe.h" +#include "storage_source.h" #include "virfile.h" #include "virfdstream.h" #include "configmake.h" diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index d016fe09a4..f1fa5986e1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -53,6 +53,7 @@ #include "virnetdevmidonet.h" #include "device_conf.h" #include "virstoragefile.h" +#include "storage_source.h" #include "virstring.h" #include "virtime.h" #include "virqemu.h" diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 202d867289..14e1f5d962 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -95,6 +95,7 @@ #include "viridentity.h" #include "virthreadjob.h" #include "virutil.h" +#include "storage_source.h" =20 #define VIR_FROM_THIS VIR_FROM_QEMU =20 diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index c2fa54f5ab..994c7dc60b 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -42,6 +42,7 @@ #include "virstring.h" #include "virdomainsnapshotobjlist.h" #include "virqemu.h" +#include "storage_source.h" =20 #define VIR_FROM_THIS VIR_FROM_QEMU =20 diff --git a/src/security/meson.build b/src/security/meson.build index 4f876c03c2..416fec7900 100644 --- a/src/security/meson.build +++ b/src/security/meson.build @@ -48,6 +48,7 @@ if conf.has('WITH_LIBVIRTD') and conf.has('WITH_APPARMOR') conf_inc_dir, hypervisor_inc_dir, include_directories('.'), + include_directories('../storage_file'), ], } endif diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 18af175655..6525baf193 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -37,6 +37,7 @@ =20 #include "security_driver.h" #include "security_apparmor.h" +#include "storage_source.h" #include "domain_conf.h" #include "virxml.h" #include "viruuid.h" @@ -46,7 +47,6 @@ #include "virfile.h" #include "configmake.h" #include "virrandom.h" -#include "virstoragefile.h" #include "virstring.h" #include "virgettext.h" #include "virhostdev.h" diff --git a/src/storage/meson.build b/src/storage/meson.build index 8537359e93..153ff6f846 100644 --- a/src/storage/meson.build +++ b/src/storage/meson.build @@ -79,6 +79,7 @@ if conf.has('WITH_STORAGE') ], include_directories: [ conf_inc_dir, + include_directories('../storage_file'), ], ) =20 @@ -162,6 +163,9 @@ if conf.has('WITH_STORAGE_GLUSTER') 'deps': [ glusterfs_dep, ], + 'include': [ + include_directories('../storage_file'), + ], 'install_dir': storage_backend_install_dir, } endif diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index 205a707a17..782f8eb611 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -32,6 +32,7 @@ #include "virstring.h" #include "viruri.h" #include "storage_util.h" +#include "storage_source.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE =20 diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 4117127d65..d51fa2b4c0 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -64,6 +64,7 @@ #include "virstoragefile.h" #include "virstoragefileprobe.h" #include "storage_util.h" +#include "storage_source.h" #include "virlog.h" #include "virfile.h" #include "virjson.h" diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build index 20eb0176fc..bae018feac 100644 --- a/src/storage_file/meson.build +++ b/src/storage_file/meson.build @@ -1,3 +1,7 @@ +storage_file_sources =3D [ + 'storage_source.c', +] + stoarge_file_fs_sources =3D [ 'storage_file_fs.c', ] @@ -8,6 +12,18 @@ storage_file_gluster_sources =3D [ =20 storage_file_install_dir =3D libdir / 'libvirt' / 'storage-file' =20 +virt_storage_file_lib =3D static_library( + 'virt_storage_file', + [ + storage_file_sources, + ], + dependencies: [ + src_dep, + ], +) + +libvirt_libs +=3D virt_storage_file_lib + if conf.has('WITH_STORAGE') virt_modules +=3D { 'name': 'virt_storage_file_fs', @@ -36,3 +52,5 @@ if conf.has('WITH_STORAGE_GLUSTER') 'install_dir': storage_file_install_dir, } endif + +storage_file_inc_dir =3D include_directories('.') diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_s= ource.c new file mode 100644 index 0000000000..b5e0bc5040 --- /dev/null +++ b/src/storage_file/storage_source.c @@ -0,0 +1,2614 @@ +/* + * storage_source.c: file utility functions for FS storage backend + * + * Copyright (C) 2007-2017 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include +#include + +#include "internal.h" +#include "storage_source.h" +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virhash.h" +#include "virjson.h" +#include "virlog.h" +#include "virobject.h" +#include "virstoragefile.h" +#include "virstoragefilebackend.h" +#include "virstoragefileprobe.h" +#include "virstring.h" +#include "viruri.h" +#include "virutil.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("storage_source"); + + +static virStorageSourcePtr +virStorageFileMetadataNew(const char *path, + int format) +{ + g_autoptr(virStorageSource) def =3D virStorageSourceNew(); + + def->format =3D format; + def->type =3D VIR_STORAGE_TYPE_FILE; + + def->path =3D g_strdup(path); + + return g_steal_pointer(&def); +} + + +/** + * virStorageFileGetMetadataFromBuf: + * @path: name of file, for error messages + * @buf: header bytes from @path + * @len: length of @buf + * @format: format of the storage file + * + * Extract metadata about the storage volume with the specified image form= at. + * If image format is VIR_STORAGE_FILE_AUTO, it will probe to automatically + * identify the format. Does not recurse. + * + * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a format on a= file + * that might be raw if that file will then be passed to a guest, since a + * malicious guest can turn a raw file into any other non-raw format at wi= ll. + * + * If the 'backingStoreRawFormat' field of the returned structure is + * VIR_STORAGE_FILE_AUTO it indicates the image didn't specify an explicit + * format for its backing store. Callers are advised against probing for t= he + * backing store format in this case. + * + * Caller MUST free the result after use via virObjectUnref. + */ +virStorageSourcePtr +virStorageFileGetMetadataFromBuf(const char *path, + char *buf, + size_t len, + int format) +{ + virStorageSourcePtr ret =3D NULL; + + if (!(ret =3D virStorageFileMetadataNew(path, format))) + return NULL; + + if (virStorageFileProbeGetMetadata(ret, buf, len) < 0) { + virObjectUnref(ret); + return NULL; + } + + return ret; +} + + +/** + * virStorageFileGetMetadataFromFD: + * + * Extract metadata about the storage volume with the specified + * image format. If image format is VIR_STORAGE_FILE_AUTO, it + * will probe to automatically identify the format. Does not recurse. + * + * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a + * format, since a malicious guest can turn a raw file into any + * other non-raw format at will. + * + * Caller MUST free the result after use via virObjectUnref. + */ +virStorageSourcePtr +virStorageFileGetMetadataFromFD(const char *path, + int fd, + int format) + +{ + ssize_t len =3D VIR_STORAGE_MAX_HEADER; + struct stat sb; + g_autofree char *buf =3D NULL; + g_autoptr(virStorageSource) meta =3D NULL; + + if (fstat(fd, &sb) < 0) { + virReportSystemError(errno, + _("cannot stat file '%s'"), path); + return NULL; + } + + if (!(meta =3D virStorageFileMetadataNew(path, format))) + return NULL; + + if (S_ISDIR(sb.st_mode)) { + /* No header to probe for directories, but also no backing file. J= ust + * update the metadata.*/ + meta->type =3D VIR_STORAGE_TYPE_DIR; + meta->format =3D VIR_STORAGE_FILE_DIR; + return g_steal_pointer(&meta); + } + + if (lseek(fd, 0, SEEK_SET) =3D=3D (off_t)-1) { + virReportSystemError(errno, _("cannot seek to start of '%s'"), met= a->path); + return NULL; + } + + if ((len =3D virFileReadHeaderFD(fd, len, &buf)) < 0) { + virReportSystemError(errno, _("cannot read header '%s'"), meta->pa= th); + return NULL; + } + + if (virStorageFileProbeGetMetadata(meta, buf, len) < 0) + return NULL; + + if (S_ISREG(sb.st_mode)) + meta->type =3D VIR_STORAGE_TYPE_FILE; + else if (S_ISBLK(sb.st_mode)) + meta->type =3D VIR_STORAGE_TYPE_BLOCK; + + return g_steal_pointer(&meta); +} + + +/* Given a @chain, look for the backing store @name that is a backing file + * of @startFrom (or any member of @chain if @startFrom is NULL) and return + * that location within the chain. @chain must always point to the top of + * the chain. Pass NULL for @name and 0 for @idx to find the base of the + * chain. Pass nonzero @idx to find the backing source according to its + * position in the backing chain. If @parent is not NULL, set *@parent to + * the preferred name of the parent (or to NULL if @name matches the start + * of the chain). Since the results point within @chain, they must not be + * independently freed. Reports an error and returns NULL if @name is not + * found. + */ +virStorageSourcePtr +virStorageFileChainLookup(virStorageSourcePtr chain, + virStorageSourcePtr startFrom, + const char *name, + unsigned int idx, + virStorageSourcePtr *parent) +{ + virStorageSourcePtr prev; + const char *start =3D chain->path; + bool nameIsFile =3D virStorageIsFile(name); + + if (!parent) + parent =3D &prev; + *parent =3D NULL; + + if (startFrom) { + while (virStorageSourceIsBacking(chain) && + chain !=3D startFrom->backingStore) + chain =3D chain->backingStore; + + *parent =3D startFrom; + } + + while (virStorageSourceIsBacking(chain)) { + if (!name && !idx) { + if (!virStorageSourceHasBacking(chain)) + break; + } else if (idx) { + VIR_DEBUG("%u: %s", chain->id, chain->path); + if (idx =3D=3D chain->id) + break; + } else { + if (STREQ_NULLABLE(name, chain->relPath) || + STREQ_NULLABLE(name, chain->path)) + break; + + if (nameIsFile && virStorageSourceIsLocalStorage(chain)) { + g_autofree char *parentDir =3D NULL; + int result; + + if (*parent && virStorageSourceIsLocalStorage(*parent)) + parentDir =3D g_path_get_dirname((*parent)->path); + else + parentDir =3D g_strdup("."); + + result =3D virFileRelLinkPointsTo(parentDir, name, + chain->path); + + if (result < 0) + goto error; + + if (result > 0) + break; + } + } + *parent =3D chain; + chain =3D chain->backingStore; + } + + if (!virStorageSourceIsBacking(chain)) + goto error; + + return chain; + + error: + if (idx) { + virReportError(VIR_ERR_INVALID_ARG, + _("could not find backing store index %u in chain " + "for '%s'"), + idx, NULLSTR(start)); + } else if (name) { + if (startFrom) + virReportError(VIR_ERR_INVALID_ARG, + _("could not find image '%s' beneath '%s' in " + "chain for '%s'"), name, NULLSTR(startFrom->p= ath), + NULLSTR(start)); + else + virReportError(VIR_ERR_INVALID_ARG, + _("could not find image '%s' in chain for '%s'"= ), + name, NULLSTR(start)); + } else { + virReportError(VIR_ERR_INVALID_ARG, + _("could not find base image in chain for '%s'"), + NULLSTR(start)); + } + *parent =3D NULL; + return NULL; +} + + +static virStorageSourcePtr +virStorageSourceNewFromBackingRelative(virStorageSourcePtr parent, + const char *rel) +{ + g_autofree char *dirname =3D NULL; + g_autoptr(virStorageSource) def =3D virStorageSourceNew(); + + /* store relative name */ + def->relPath =3D g_strdup(rel); + + dirname =3D g_path_get_dirname(parent->path); + + if (STRNEQ(dirname, "/")) { + def->path =3D g_strdup_printf("%s/%s", dirname, rel); + } else { + def->path =3D g_strdup_printf("/%s", rel); + } + + if (virStorageSourceGetActualType(parent) =3D=3D VIR_STORAGE_TYPE_NETW= ORK) { + def->type =3D VIR_STORAGE_TYPE_NETWORK; + + /* copy the host network part */ + def->protocol =3D parent->protocol; + if (parent->nhosts) { + if (!(def->hosts =3D virStorageNetHostDefCopy(parent->nhosts, + parent->hosts))) + return NULL; + + def->nhosts =3D parent->nhosts; + } + + def->volume =3D g_strdup(parent->volume); + } else { + /* set the type to _FILE, the caller shall update it to the actual= type */ + def->type =3D VIR_STORAGE_TYPE_FILE; + } + + return g_steal_pointer(&def); +} + + +static int +virStorageSourceParseBackingURI(virStorageSourcePtr src, + const char *uristr) +{ + g_autoptr(virURI) uri =3D NULL; + const char *path =3D NULL; + g_auto(GStrv) scheme =3D NULL; + + if (!(uri =3D virURIParse(uristr))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse backing file location '%s'"), + uristr); + return -1; + } + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (!(scheme =3D virStringSplit(uri->scheme, "+", 2))) + return -1; + + if (!scheme[0] || + (src->protocol =3D virStorageNetProtocolTypeFromString(scheme[0]))= < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid backing protocol '%s'"), + NULLSTR(scheme[0])); + return -1; + } + + if (scheme[1] && + (src->hosts->transport =3D virStorageNetHostTransportTypeFromStrin= g(scheme[1])) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid protocol transport type '%s'"), + scheme[1]); + return -1; + } + + if (uri->query) { + if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTP || + src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS) { + src->query =3D g_strdup(uri->query); + } else { + /* handle socket stored as a query */ + if (STRPREFIX(uri->query, "socket=3D")) + src->hosts->socket =3D g_strdup(STRSKIP(uri->query, "socke= t=3D")); + } + } + + /* uri->path is NULL if the URI does not contain slash after host: + * transport://host:port */ + if (uri->path) + path =3D uri->path; + else + path =3D ""; + + /* possibly skip the leading slash */ + if (path[0] =3D=3D '/') + path++; + + /* NBD allows empty export name (path) */ + if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_NBD && + path[0] =3D=3D '\0') + path =3D NULL; + + src->path =3D g_strdup(path); + + if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_GLUSTER) { + char *tmp; + + if (!src->path) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("missing volume name and path for gluster vol= ume")); + return -1; + } + + if (!(tmp =3D strchr(src->path, '/')) || + tmp =3D=3D src->path) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing volume name or file name in " + "gluster source path '%s'"), src->path); + return -1; + } + + src->volume =3D src->path; + + src->path =3D g_strdup(tmp + 1); + + tmp[0] =3D '\0'; + } + + src->hosts->port =3D uri->port; + + src->hosts->name =3D g_strdup(uri->server); + + /* Libvirt doesn't handle inline authentication. Make the caller aware= . */ + if (uri->user) + return 1; + + return 0; +} + + +static int +virStorageSourceRBDAddHost(virStorageSourcePtr src, + char *hostport) +{ + char *port; + size_t skip; + g_auto(GStrv) parts =3D NULL; + + if (VIR_EXPAND_N(src->hosts, src->nhosts, 1) < 0) + return -1; + + if ((port =3D strchr(hostport, ']'))) { + /* ipv6, strip brackets */ + hostport +=3D 1; + skip =3D 3; + } else { + port =3D strstr(hostport, "\\:"); + skip =3D 2; + } + + if (port) { + *port =3D '\0'; + port +=3D skip; + if (virStringParsePort(port, &src->hosts[src->nhosts - 1].port) < = 0) + goto error; + } + + parts =3D virStringSplit(hostport, "\\:", 0); + if (!parts) + goto error; + src->hosts[src->nhosts-1].name =3D virStringListJoin((const char **)pa= rts, ":"); + if (!src->hosts[src->nhosts-1].name) + goto error; + + src->hosts[src->nhosts-1].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + src->hosts[src->nhosts-1].socket =3D NULL; + + return 0; + + error: + VIR_FREE(src->hosts[src->nhosts-1].name); + return -1; +} + + +int +virStorageSourceParseRBDColonString(const char *rbdstr, + virStorageSourcePtr src) +{ + char *p, *e, *next; + g_autofree char *options =3D NULL; + g_autoptr(virStorageAuthDef) authdef =3D NULL; + + /* optionally skip the "rbd:" prefix if provided */ + if (STRPREFIX(rbdstr, "rbd:")) + rbdstr +=3D strlen("rbd:"); + + src->path =3D g_strdup(rbdstr); + + p =3D strchr(src->path, ':'); + if (p) { + options =3D g_strdup(p + 1); + *p =3D '\0'; + } + + /* snapshot name */ + if ((p =3D strchr(src->path, '@'))) { + src->snapshot =3D g_strdup(p + 1); + *p =3D '\0'; + } + + /* pool vs. image name */ + if ((p =3D strchr(src->path, '/'))) { + src->volume =3D g_steal_pointer(&src->path); + src->path =3D g_strdup(p + 1); + *p =3D '\0'; + } + + /* options */ + if (!options) + return 0; /* all done */ + + p =3D options; + while (*p) { + /* find : delimiter or end of string */ + for (e =3D p; *e && *e !=3D ':'; ++e) { + if (*e =3D=3D '\\') { + e++; + if (*e =3D=3D '\0') + break; + } + } + if (*e =3D=3D '\0') { + next =3D e; /* last kv pair */ + } else { + next =3D e + 1; + *e =3D '\0'; + } + + if (STRPREFIX(p, "id=3D")) { + /* formulate authdef for src->auth */ + if (src->auth) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("duplicate 'id' found in '%s'"), src->pat= h); + return -1; + } + + authdef =3D g_new0(virStorageAuthDef, 1); + + authdef->username =3D g_strdup(p + strlen("id=3D")); + + authdef->secrettype =3D g_strdup(virSecretUsageTypeToString(VI= R_SECRET_USAGE_TYPE_CEPH)); + src->auth =3D g_steal_pointer(&authdef); + + /* Cannot formulate a secretType (eg, usage or uuid) given + * what is provided. + */ + } + if (STRPREFIX(p, "mon_host=3D")) { + char *h, *sep; + + h =3D p + strlen("mon_host=3D"); + while (h < e) { + for (sep =3D h; sep < e; ++sep) { + if (*sep =3D=3D '\\' && (sep[1] =3D=3D ',' || + sep[1] =3D=3D ';' || + sep[1] =3D=3D ' ')) { + *sep =3D '\0'; + sep +=3D 2; + break; + } + } + + if (virStorageSourceRBDAddHost(src, h) < 0) + return -1; + + h =3D sep; + } + } + + if (STRPREFIX(p, "conf=3D")) + src->configFile =3D g_strdup(p + strlen("conf=3D")); + + p =3D next; + } + return 0; +} + + +static int +virStorageSourceParseNBDColonString(const char *nbdstr, + virStorageSourcePtr src) +{ + g_autofree char *nbd =3D g_strdup(nbdstr); + char *export_name; + char *host_spec; + char *unixpath; + char *port; + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + /* We extract the parameters in a similar way qemu does it */ + + /* format: [] denotes optional sections, uppercase are variable strings + * nbd:unix:/PATH/TO/SOCKET[:exportname=3DEXPORTNAME] + * nbd:HOSTNAME:PORT[:exportname=3DEXPORTNAME] + */ + + /* first look for ':exportname=3D' and cut it off */ + if ((export_name =3D strstr(nbd, ":exportname=3D"))) { + src->path =3D g_strdup(export_name + strlen(":exportname=3D")); + export_name[0] =3D '\0'; + } + + /* Verify the prefix and contents. Note that we require a + * "host_spec" part to be present. */ + if (!(host_spec =3D STRSKIP(nbd, "nbd:")) || host_spec[0] =3D=3D '\0') + goto malformed; + + if ((unixpath =3D STRSKIP(host_spec, "unix:"))) { + src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; + + if (unixpath[0] =3D=3D '\0') + goto malformed; + + src->hosts->socket =3D g_strdup(unixpath); + } else { + src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + + if (host_spec[0] =3D=3D ':') { + /* no host given */ + goto malformed; + } else if (host_spec[0] =3D=3D '[') { + host_spec++; + /* IPv6 addr */ + if (!(port =3D strstr(host_spec, "]:"))) + goto malformed; + + port[0] =3D '\0'; + port +=3D 2; + + if (host_spec[0] =3D=3D '\0') + goto malformed; + } else { + if (!(port =3D strchr(host_spec, ':'))) + goto malformed; + + port[0] =3D '\0'; + port++; + } + + if (virStringParsePort(port, &src->hosts->port) < 0) + return -1; + + src->hosts->name =3D g_strdup(host_spec); + } + + return 0; + + malformed: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("malformed nbd string '%s'"), nbdstr); + return -1; +} + + +static int +virStorageSourceParseBackingColon(virStorageSourcePtr src, + const char *path) +{ + const char *p; + g_autofree char *protocol =3D NULL; + + if (!(p =3D strchr(path, ':'))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid backing protocol string '%s'"), + path); + return -1; + } + + protocol =3D g_strndup(path, p - path); + + if ((src->protocol =3D virStorageNetProtocolTypeFromString(protocol)) = < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid backing protocol '%s'"), + protocol); + return -1; + } + + switch ((virStorageNetProtocol) src->protocol) { + case VIR_STORAGE_NET_PROTOCOL_NBD: + if (virStorageSourceParseNBDColonString(path, src) < 0) + return -1; + break; + + case VIR_STORAGE_NET_PROTOCOL_RBD: + if (virStorageSourceParseRBDColonString(path, src) < 0) + return -1; + break; + + case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: + case VIR_STORAGE_NET_PROTOCOL_LAST: + case VIR_STORAGE_NET_PROTOCOL_NONE: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("backing store parser is not implemented for prot= ocol %s"), + protocol); + return -1; + + 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_SSH: + case VIR_STORAGE_NET_PROTOCOL_VXHS: + case VIR_STORAGE_NET_PROTOCOL_NFS: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("malformed backing store path for protocol %s"), + protocol); + return -1; + } + + return 0; +} + + +static int +virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr, + bool allowformat); + + +static int +virStorageSourceParseBackingJSONPath(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int type) +{ + const char *path; + + if (!(path =3D virJSONValueObjectGetString(json, "filename"))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'filename' field in JSON backing volume " + "definition")); + return -1; + } + + src->path =3D g_strdup(path); + + src->type =3D type; + return 0; +} + + +static int +virStorageSourceParseBackingJSONUriStr(virStorageSourcePtr src, + const char *uri, + int protocol) +{ + int rc; + + if ((rc =3D virStorageSourceParseBackingURI(src, uri)) < 0) + return -1; + + if (src->protocol !=3D protocol) { + virReportError(VIR_ERR_INVALID_ARG, + _("expected protocol '%s' but got '%s' in URI JSON = volume " + "definition"), + virStorageNetProtocolTypeToString(protocol), + virStorageNetProtocolTypeToString(src->protocol)); + return -1; + } + + return rc; +} + + +static int +virStorageSourceParseBackingJSONUriCookies(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr) +{ + const char *cookiestr; + g_auto(GStrv) cookies =3D NULL; + size_t ncookies =3D 0; + size_t i; + + if (!virJSONValueObjectHasKey(json, "cookie")) + return 0; + + if (!(cookiestr =3D virJSONValueObjectGetString(json, "cookie"))) { + virReportError(VIR_ERR_INVALID_ARG, + _("wrong format of 'cookie' field in backing store = definition '%s'"), + jsonstr); + return -1; + } + + if (!(cookies =3D virStringSplitCount(cookiestr, ";", 0, &ncookies))) + return -1; + + src->cookies =3D g_new0(virStorageNetCookieDefPtr, ncookies); + src->ncookies =3D ncookies; + + for (i =3D 0; i < ncookies; i++) { + char *cookiename =3D cookies[i]; + char *cookievalue; + + virSkipSpaces((const char **) &cookiename); + + if (!(cookievalue =3D strchr(cookiename, '=3D'))) { + virReportError(VIR_ERR_INVALID_ARG, + _("malformed http cookie '%s' in backing store = definition '%s'"), + cookies[i], jsonstr); + return -1; + } + + *cookievalue =3D '\0'; + cookievalue++; + + src->cookies[i] =3D g_new0(virStorageNetCookieDef, 1); + src->cookies[i]->name =3D g_strdup(cookiename); + src->cookies[i]->value =3D g_strdup(cookievalue); + } + + return 0; +} + + +static int +virStorageSourceParseBackingJSONUri(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr, + int protocol) +{ + const char *uri; + + if (!(uri =3D virJSONValueObjectGetString(json, "url"))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'url' in JSON backing volume definition"= )); + return -1; + } + + if (protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS || + protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_FTPS) { + if (virJSONValueObjectHasKey(json, "sslverify")) { + const char *tmpstr; + bool tmp; + + /* libguestfs still uses undocumented legacy value of 'off' */ + if ((tmpstr =3D virJSONValueObjectGetString(json, "sslverify")= ) && + STREQ(tmpstr, "off")) { + src->sslverify =3D VIR_TRISTATE_BOOL_NO; + } else { + if (virJSONValueObjectGetBoolean(json, "sslverify", &tmp) = < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("malformed 'sslverify' field in backi= ng store definition '%s'"), + jsonstr); + return -1; + } + + src->sslverify =3D virTristateBoolFromBool(tmp); + } + } + } + + if (protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS || + protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTP) { + if (virStorageSourceParseBackingJSONUriCookies(src, json, jsonstr)= < 0) + return -1; + } + + if (virJSONValueObjectHasKey(json, "readahead") && + virJSONValueObjectGetNumberUlong(json, "readahead", &src->readahea= d) < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("malformed 'readahead' field in backing store def= inition '%s'"), + jsonstr); + return -1; + } + + if (virJSONValueObjectHasKey(json, "timeout") && + virJSONValueObjectGetNumberUlong(json, "timeout", &src->timeout) <= 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("malformed 'timeout' field in backing store defin= ition '%s'"), + jsonstr); + return -1; + } + + return virStorageSourceParseBackingJSONUriStr(src, uri, protocol); +} + + +static int +virStorageSourceParseBackingJSONInetSocketAddress(virStorageNetHostDefPtr = host, + virJSONValuePtr json) +{ + const char *hostname; + const char *port; + + if (!json) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing remote server specification in JSON " + "backing volume definition")); + return -1; + } + + hostname =3D virJSONValueObjectGetString(json, "host"); + port =3D virJSONValueObjectGetString(json, "port"); + + if (!hostname) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing hostname for tcp backing server in " + "JSON backing volume definition")); + return -1; + } + + host->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + host->name =3D g_strdup(hostname); + + if (virStringParsePort(port, &host->port) < 0) + return -1; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONSocketAddress(virStorageNetHostDefPtr host, + virJSONValuePtr json) +{ + const char *type; + const char *socket; + + if (!json) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing remote server specification in JSON " + "backing volume definition")); + return -1; + } + + if (!(type =3D virJSONValueObjectGetString(json, "type"))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing socket address type in " + "JSON backing volume definition")); + return -1; + } + + if (STREQ(type, "tcp") || STREQ(type, "inet")) { + return virStorageSourceParseBackingJSONInetSocketAddress(host, jso= n); + + } else if (STREQ(type, "unix")) { + host->transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; + + socket =3D virJSONValueObjectGetString(json, "path"); + + /* check for old spelling for gluster protocol */ + if (!socket) + socket =3D virJSONValueObjectGetString(json, "socket"); + + if (!socket) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing socket path for udp backing server i= n " + "JSON backing volume definition")); + return -1; + } + + host->socket =3D g_strdup(socket); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("backing store protocol '%s' is not yet supported= "), + type); + return -1; + } + + return 0; +} + + +static int +virStorageSourceParseBackingJSONGluster(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *uri =3D virJSONValueObjectGetString(json, "filename"); + const char *volume =3D virJSONValueObjectGetString(json, "volume"); + const char *path =3D virJSONValueObjectGetString(json, "path"); + virJSONValuePtr server =3D virJSONValueObjectGetArray(json, "server"); + size_t nservers; + size_t i; + + /* legacy URI based syntax passed via 'filename' option */ + if (uri) + return virStorageSourceParseBackingJSONUriStr(src, uri, + VIR_STORAGE_NET_PROT= OCOL_GLUSTER); + + if (!volume || !path || !server) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'volume', 'path' or 'server' attribute i= n " + "JSON backing definition for gluster volume")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_GLUSTER; + + src->volume =3D g_strdup(volume); + src->path =3D g_strdup(path); + + nservers =3D virJSONValueArraySize(server); + if (nservers =3D=3D 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("at least 1 server is necessary in " + "JSON backing definition for gluster volume")); + + return -1; + } + + src->hosts =3D g_new0(virStorageNetHostDef, nservers); + src->nhosts =3D nservers; + + for (i =3D 0; i < nservers; i++) { + if (virStorageSourceParseBackingJSONSocketAddress(src->hosts + i, + virJSONValueArra= yGet(server, i)) < 0) + return -1; + } + + return 0; +} + + +static int +virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *transport =3D virJSONValueObjectGetString(json, "transport= "); + const char *portal =3D virJSONValueObjectGetString(json, "portal"); + const char *target =3D virJSONValueObjectGetString(json, "target"); + const char *lun =3D virJSONValueObjectGetStringOrNumber(json, "lun"); + const char *uri; + char *port; + + /* legacy URI based syntax passed via 'filename' option */ + if ((uri =3D virJSONValueObjectGetString(json, "filename"))) + return virStorageSourceParseBackingJSONUriStr(src, uri, + VIR_STORAGE_NET_PROT= OCOL_ISCSI); + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_ISCSI; + + if (!lun) + lun =3D "0"; + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (STRNEQ_NULLABLE(transport, "tcp")) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("only TCP transport is supported for iSCSI volume= s")); + return -1; + } + + src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + + if (!portal) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'portal' address in iSCSI backing defini= tion")); + return -1; + } + + if (!target) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'target' in iSCSI backing definition")); + return -1; + } + + src->hosts->name =3D g_strdup(portal); + + if ((port =3D strrchr(src->hosts->name, ':')) && + !strchr(port, ']')) { + if (virStringParsePort(port + 1, &src->hosts->port) < 0) + return -1; + + *port =3D '\0'; + } + + src->path =3D g_strdup_printf("%s/%s", target, lun); + + /* Libvirt doesn't handle inline authentication. Make the caller aware= . */ + if (virJSONValueObjectGetString(json, "user") || + virJSONValueObjectGetString(json, "password")) + return 1; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *path =3D virJSONValueObjectGetString(json, "path"); + const char *host =3D virJSONValueObjectGetString(json, "host"); + const char *port =3D virJSONValueObjectGetString(json, "port"); + const char *export =3D virJSONValueObjectGetString(json, "export"); + virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); + + if (!path && !host && !server) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing host specification of NBD server in JSON= " + "backing volume definition")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_NBD; + + src->path =3D g_strdup(export); + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (server) { + if (virStorageSourceParseBackingJSONSocketAddress(src->hosts, serv= er) < 0) + return -1; + } else { + if (path) { + src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; + src->hosts[0].socket =3D g_strdup(path); + } else { + src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + src->hosts[0].name =3D g_strdup(host); + + if (virStringParsePort(port, &src->hosts[0].port) < 0) + return -1; + } + } + + return 0; +} + + +static int +virStorageSourceParseBackingJSONSheepdog(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *filename; + const char *vdi =3D virJSONValueObjectGetString(json, "vdi"); + virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); + + /* legacy URI based syntax passed via 'filename' option */ + if ((filename =3D virJSONValueObjectGetString(json, "filename"))) { + if (strstr(filename, "://")) + return virStorageSourceParseBackingJSONUriStr(src, filename, + VIR_STORAGE_NET_= PROTOCOL_SHEEPDOG); + + /* libvirt doesn't implement a parser for the legacy non-URI synta= x */ + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing sheepdog URI in JSON backing volume defi= nition")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_SHEEPDOG; + + if (!vdi) { + virReportError(VIR_ERR_INVALID_ARG, "%s", _("missing sheepdog vdi = name")); + return -1; + } + + src->path =3D g_strdup(vdi); + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (virStorageSourceParseBackingJSONSocketAddress(src->hosts, server) = < 0) + return -1; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *path =3D virJSONValueObjectGetString(json, "path"); + const char *host =3D virJSONValueObjectGetString(json, "host"); + const char *port =3D virJSONValueObjectGetString(json, "port"); + const char *user =3D virJSONValueObjectGetString(json, "user"); + const char *host_key_check =3D virJSONValueObjectGetString(json, "host= _key_check"); + virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); + + if (!(host || server) || !path) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing host/server or path of SSH JSON backing " + "volume definition")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_SSH; + + src->path =3D g_strdup(path); + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (server) { + if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, + server) < 0) + return -1; + } else { + src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; + src->hosts[0].name =3D g_strdup(host); + + if (virStringParsePort(port, &src->hosts[0].port) < 0) + return -1; + } + + /* these two are parsed just to be passed back as we don't model them = yet */ + src->ssh_user =3D g_strdup(user); + if (STREQ_NULLABLE(host_key_check, "no")) + src->ssh_host_key_check_disabled =3D true; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *filename; + const char *pool =3D virJSONValueObjectGetString(json, "pool"); + const char *image =3D virJSONValueObjectGetString(json, "image"); + const char *conf =3D virJSONValueObjectGetString(json, "conf"); + const char *snapshot =3D virJSONValueObjectGetString(json, "snapshot"); + virJSONValuePtr servers =3D virJSONValueObjectGetArray(json, "server"); + size_t nservers; + size_t i; + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_RBD; + + /* legacy syntax passed via 'filename' option */ + if ((filename =3D virJSONValueObjectGetString(json, "filename"))) + return virStorageSourceParseRBDColonString(filename, src); + + if (!pool || !image) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing pool or image name in ceph backing volum= e " + "JSON specification")); + return -1; + } + + src->volume =3D g_strdup(pool); + src->path =3D g_strdup(image); + src->snapshot =3D g_strdup(snapshot); + src->configFile =3D g_strdup(conf); + + if (servers) { + nservers =3D virJSONValueArraySize(servers); + + src->hosts =3D g_new0(virStorageNetHostDef, nservers); + src->nhosts =3D nservers; + + for (i =3D 0; i < nservers; i++) { + if (virStorageSourceParseBackingJSONInetSocketAddress(src->hos= ts + i, + virJSONV= alueArrayGet(servers, i)) < 0) + return -1; + } + } + + return 0; +} + +static int +virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr, + int opaque G_GNUC_UNUSED) +{ + bool has_offset =3D virJSONValueObjectHasKey(json, "offset"); + bool has_size =3D virJSONValueObjectHasKey(json, "size"); + virJSONValuePtr file; + + if (has_offset || has_size) { + src->sliceStorage =3D g_new0(virStorageSourceSlice, 1); + + if (has_offset && + virJSONValueObjectGetNumberUlong(json, "offset", &src->sliceSt= orage->offset) < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("malformed 'offset' property of 'raw' driver"= )); + return -1; + } + + if (has_size && + virJSONValueObjectGetNumberUlong(json, "size", &src->sliceStor= age->size) < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("malformed 'size' property of 'raw' driver")); + return -1; + } + } + + /* 'raw' is a format driver so it can have protocol driver children */ + if (!(file =3D virJSONValueObjectGetObject(json, "file"))) { + virReportError(VIR_ERR_INVALID_ARG, + _("JSON backing volume definition '%s' lacks 'file'= object"), + jsonstr); + return -1; + } + + return virStorageSourceParseBackingJSONInternal(src, file, jsonstr, fa= lse); +} + + +static int +virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + const char *vdisk_id =3D virJSONValueObjectGetString(json, "vdisk-id"); + virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); + + if (!vdisk_id || !server) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'vdisk-id' or 'server' attribute in " + "JSON backing definition for VxHS volume")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_VXHS; + + src->path =3D g_strdup(vdisk_id); + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, + server) < 0) + return -1; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONNFS(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); + int uidStore =3D -1; + int gidStore =3D -1; + int gotUID =3D virJSONValueObjectGetNumberInt(json, "user", &uidStore); + int gotGID =3D virJSONValueObjectGetNumberInt(json, "group", &gidStore= ); + + if (!server) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'server' attribute in JSON backing defin= ition for NFS volume")); + return -1; + } + + if (gotUID < 0 || gotGID < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'user' or 'group' attribute in JSON back= ing definition for NFS volume")); + return -1; + } + + src->path =3D g_strdup(virJSONValueObjectGetString(json, "path")); + if (!src->path) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing 'path' attribute in JSON backing definit= ion for NFS volume")); + return -1; + } + + src->nfs_user =3D g_strdup_printf("+%d", uidStore); + src->nfs_group =3D g_strdup_printf("+%d", gidStore); + + src->type =3D VIR_STORAGE_TYPE_NETWORK; + src->protocol =3D VIR_STORAGE_NET_PROTOCOL_NFS; + + src->hosts =3D g_new0(virStorageNetHostDef, 1); + src->nhosts =3D 1; + + if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, + server) < 0) + return -1; + + return 0; +} + + +static int +virStorageSourceParseBackingJSONNVMe(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + g_autoptr(virStorageSourceNVMeDef) nvme =3D g_new0(virStorageSourceNVM= eDef, 1); + const char *device =3D virJSONValueObjectGetString(json, "device"); + + if (!device || virPCIDeviceAddressParse((char *) device, &nvme->pciAdd= r) < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'device' field of 'nvme' st= orage")); + return -1; + } + + if (virJSONValueObjectGetNumberUlong(json, "namespace", &nvme->namespc= ) < 0 || + nvme->namespc =3D=3D 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'namespace' field of 'nvme'= storage")); + return -1; + } + + src->type =3D VIR_STORAGE_TYPE_NVME; + src->nvme =3D g_steal_pointer(&nvme); + + return 0; +} + + +struct virStorageSourceJSONDriverParser { + const char *drvname; + bool formatdriver; + /** + * The callback gets a pre-allocated storage source @src and the JSON + * object to parse. The callback shall return -1 on error and report e= rror + * 0 on success and 1 in cases when the configuration itself is valid,= but + * can't be converted to libvirt's configuration (e.g. inline authenti= cation + * credentials are present). + */ + int (*func)(virStorageSourcePtr src, virJSONValuePtr json, const char = *jsonstr, int opaque); + int opaque; +}; + +static const struct virStorageSourceJSONDriverParser jsonParsers[] =3D { + {"file", false, virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE= _FILE}, + {"host_device", false, virStorageSourceParseBackingJSONPath, VIR_STORA= GE_TYPE_BLOCK}, + {"host_cdrom", false, virStorageSourceParseBackingJSONPath, VIR_STORAG= E_TYPE_BLOCK}, + {"http", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_HTTP}, + {"https", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_= PROTOCOL_HTTPS}, + {"ftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PR= OTOCOL_FTP}, + {"ftps", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_FTPS}, + {"tftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_TFTP}, + {"gluster", false, virStorageSourceParseBackingJSONGluster, 0}, + {"iscsi", false, virStorageSourceParseBackingJSONiSCSI, 0}, + {"nbd", false, virStorageSourceParseBackingJSONNbd, 0}, + {"sheepdog", false, virStorageSourceParseBackingJSONSheepdog, 0}, + {"ssh", false, virStorageSourceParseBackingJSONSSH, 0}, + {"rbd", false, virStorageSourceParseBackingJSONRBD, 0}, + {"raw", true, virStorageSourceParseBackingJSONRaw, 0}, + {"nfs", false, virStorageSourceParseBackingJSONNFS, 0}, + {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0}, + {"nvme", false, virStorageSourceParseBackingJSONNVMe, 0}, +}; + + + +static int +virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr, + bool allowformat) +{ + const char *drvname; + size_t i; + + if (!(drvname =3D virJSONValueObjectGetString(json, "driver"))) { + virReportError(VIR_ERR_INVALID_ARG, + _("JSON backing volume definition '%s' lacks driver= name"), + jsonstr); + return -1; + } + + for (i =3D 0; i < G_N_ELEMENTS(jsonParsers); i++) { + if (STRNEQ(drvname, jsonParsers[i].drvname)) + continue; + + if (jsonParsers[i].formatdriver && !allowformat) { + virReportError(VIR_ERR_INVALID_ARG, + _("JSON backing volume definition '%s' must not= have nested format drivers"), + jsonstr); + return -1; + } + + return jsonParsers[i].func(src, json, jsonstr, jsonParsers[i].opaq= ue); + } + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing parser implementation for JSON backing volum= e " + "driver '%s'"), drvname); + return -1; +} + + +static int +virStorageSourceParseBackingJSON(virStorageSourcePtr src, + const char *json) +{ + g_autoptr(virJSONValue) root =3D NULL; + g_autoptr(virJSONValue) deflattened =3D NULL; + virJSONValuePtr file =3D NULL; + + if (!(root =3D virJSONValueFromString(json))) + return -1; + + if (!(deflattened =3D virJSONValueObjectDeflatten(root))) + return -1; + + /* There are 2 possible syntaxes: + * 1) json:{"file":{"driver":...}} + * 2) json:{"driver":...} + * Remove the 'file' wrapper object in case 1. + */ + if (!virJSONValueObjectHasKey(deflattened, "driver")) + file =3D virJSONValueObjectGetObject(deflattened, "file"); + + if (!file) + file =3D deflattened; + + return virStorageSourceParseBackingJSONInternal(src, file, json, true); +} + + +/** + * virStorageSourceNewFromBackingAbsolute + * @path: string representing absolute location of a storage source + * @src: filled with virStorageSource object representing @path + * + * Returns 0 on success, 1 if we could parse all location data but @path + * specified other data unrepresentable by libvirt (e.g. inline authentica= tion). + * In both cases @src is filled. On error -1 is returned @src is NULL and = an + * error is reported. + */ +int +virStorageSourceNewFromBackingAbsolute(const char *path, + virStorageSourcePtr *src) +{ + const char *json; + const char *dirpath; + int rc =3D 0; + g_autoptr(virStorageSource) def =3D virStorageSourceNew(); + + *src =3D NULL; + + if (virStorageIsFile(path)) { + def->type =3D VIR_STORAGE_TYPE_FILE; + + def->path =3D g_strdup(path); + } else { + if ((dirpath =3D STRSKIP(path, "fat:"))) { + def->type =3D VIR_STORAGE_TYPE_DIR; + def->format =3D VIR_STORAGE_FILE_FAT; + def->path =3D g_strdup(dirpath); + *src =3D g_steal_pointer(&def); + return 0; + } + + def->type =3D VIR_STORAGE_TYPE_NETWORK; + + VIR_DEBUG("parsing backing store string: '%s'", path); + + /* handle URI formatted backing stores */ + if ((json =3D STRSKIP(path, "json:"))) + rc =3D virStorageSourceParseBackingJSON(def, json); + else if (strstr(path, "://")) + rc =3D virStorageSourceParseBackingURI(def, path); + else + rc =3D virStorageSourceParseBackingColon(def, path); + + if (rc < 0) + return -1; + + virStorageSourceNetworkAssignDefaultPorts(def); + + /* Some of the legacy parsers parse authentication data since they= are + * also used in other places. For backing store detection the + * authentication data would be invalid anyways, so we clear it */ + if (def->auth) { + virStorageAuthDefFree(def->auth); + def->auth =3D NULL; + } + } + + *src =3D g_steal_pointer(&def); + return rc; +} + + +/** + * virStorageSourceNewFromChild: + * @parent: storage source parent + * @child: returned child/backing store definition + * @parentRaw: raw child string (backingStoreRaw) + * + * Creates a storage source which describes the backing image of @parent a= nd + * fills it into @backing depending on the passed parentRaw (backingStoreR= aw) + * and other data. Note that for local storage this function accesses the = file + * to update the actual type of the child store. + * + * Returns 0 on success, 1 if we could parse all location data but the chi= ld + * store specification contained other data unrepresentable by libvirt (e.= g. + * inline authentication). + * In both cases @src is filled. On error -1 is returned @src is NULL and = an + * error is reported. + */ +static int +virStorageSourceNewFromChild(virStorageSourcePtr parent, + const char *parentRaw, + virStorageSourcePtr *child) +{ + struct stat st; + g_autoptr(virStorageSource) def =3D NULL; + int rc =3D 0; + + *child =3D NULL; + + if (virStorageIsRelative(parentRaw)) { + if (!(def =3D virStorageSourceNewFromBackingRelative(parent, paren= tRaw))) + return -1; + } else { + if ((rc =3D virStorageSourceNewFromBackingAbsolute(parentRaw, &def= )) < 0) + return -1; + } + + /* possibly update local type */ + if (def->type =3D=3D VIR_STORAGE_TYPE_FILE) { + if (stat(def->path, &st) =3D=3D 0) { + if (S_ISDIR(st.st_mode)) { + def->type =3D VIR_STORAGE_TYPE_DIR; + def->format =3D VIR_STORAGE_FILE_DIR; + } else if (S_ISBLK(st.st_mode)) { + def->type =3D VIR_STORAGE_TYPE_BLOCK; + } + } + } + + /* copy parent's labelling and other top level stuff */ + if (virStorageSourceInitChainElement(def, parent, true) < 0) + return -1; + + def->detected =3D true; + + *child =3D g_steal_pointer(&def); + return rc; +} + + +int +virStorageSourceNewFromBacking(virStorageSourcePtr parent, + virStorageSourcePtr *backing) +{ + int rc; + + if ((rc =3D virStorageSourceNewFromChild(parent, + parent->backingStoreRaw, + backing)) < 0) + return rc; + + (*backing)->format =3D parent->backingStoreRawFormat; + (*backing)->readonly =3D true; + return rc; +} + + +/** + * @src: disk source definition structure + * @fd: file descriptor + * @sb: stat buffer + * + * Updates src->physical depending on the actual type of storage being use= d. + * To be called for domain storage source reporting as the volume code does + * not set/use the 'type' field for the voldef->source.target + * + * Returns 0 on success, -1 on error. No libvirt errors are reported. + */ +int +virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, + int fd, + struct stat const *sb) +{ + off_t end; + virStorageType actual_type =3D virStorageSourceGetActualType(src); + + switch (actual_type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_NETWORK: + src->physical =3D sb->st_size; + break; + + case VIR_STORAGE_TYPE_BLOCK: + if ((end =3D lseek(fd, 0, SEEK_END)) =3D=3D (off_t) -1) + return -1; + + src->physical =3D end; + break; + + case VIR_STORAGE_TYPE_DIR: + src->physical =3D 0; + break; + + /* We shouldn't get VOLUME, but the switch requires all cases */ + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return -1; + } + + return 0; +} + + +/** + * @src: disk source definition structure + * @fd: file descriptor + * @sb: stat buffer + * + * Update the capacity, allocation, physical values for the storage @src + * Shared between the domain storage source for an inactive domain and the + * voldef source target as the result is not affected by the 'type' field. + * + * Returns 0 on success, -1 on error. + */ +int +virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, + int fd, + struct stat const *sb) +{ + /* Get info for normal formats */ + if (S_ISREG(sb->st_mode) || fd =3D=3D -1) { +#ifndef WIN32 + src->allocation =3D (unsigned long long)sb->st_blocks * + (unsigned long long)DEV_BSIZE; +#else + src->allocation =3D sb->st_size; +#endif + /* Regular files may be sparse, so logical size (capacity) is not = same + * as actual allocation above + */ + src->capacity =3D sb->st_size; + + /* Allocation tracks when the file is sparse, physical is the + * last offset of the file. */ + src->physical =3D sb->st_size; + } else if (S_ISDIR(sb->st_mode)) { + src->allocation =3D 0; + src->capacity =3D 0; + src->physical =3D 0; + } else if (fd >=3D 0) { + off_t end; + + /* XXX this is POSIX compliant, but doesn't work for CHAR files, + * only BLOCK. There is a Linux specific ioctl() for getting + * size of both CHAR / BLOCK devices we should check for in + * configure + * + * NB. Because we configure with AC_SYS_LARGEFILE, off_t + * should be 64 bits on all platforms. For block devices, we + * have to seek (safe even if someone else is writing) to + * determine physical size, and assume that allocation is the + * same as physical (but can refine that assumption later if + * qemu is still running). + */ + if ((end =3D lseek(fd, 0, SEEK_END)) =3D=3D (off_t)-1) { + virReportSystemError(errno, + _("failed to seek to end of %s"), src->pa= th); + return -1; + } + src->physical =3D end; + src->allocation =3D end; + src->capacity =3D end; + } + + return 0; +} + + +/** + * @src: disk source definition structure + * @buf: buffer to the storage file header + * @len: length of the storage file header + * + * Update the storage @src capacity. + * + * Returns 0 on success, -1 on error. + */ +int +virStorageSourceUpdateCapacity(virStorageSourcePtr src, + char *buf, + ssize_t len) +{ + int format =3D src->format; + g_autoptr(virStorageSource) meta =3D NULL; + + /* Raw files: capacity is physical size. For all other files: if + * the metadata has a capacity, use that, otherwise fall back to + * physical size. */ + if (format =3D=3D VIR_STORAGE_FILE_NONE) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no disk format for %s was specified"), + src->path); + return -1; + } + + if (format =3D=3D VIR_STORAGE_FILE_RAW && !src->encryption) { + src->capacity =3D src->physical; + } else if ((meta =3D virStorageFileGetMetadataFromBuf(src->path, buf, + len, format))) { + src->capacity =3D meta->capacity ? meta->capacity : src->physical; + if (src->encryption && meta->encryption) + src->encryption->payload_offset =3D meta->encryption->payload_= offset; + } else { + return -1; + } + + if (src->encryption && src->encryption->payload_offset !=3D -1) + src->capacity -=3D src->encryption->payload_offset * 512; + + return 0; +} + + +/** + * virStorageFileRemoveLastPathComponent: + * + * @path: Path string to remove the last component from + * + * Removes the last path component of a path. This function is designed to= be + * called on file paths only (no trailing slashes in @path). Caller is + * responsible to free the returned string. + */ +static char * +virStorageFileRemoveLastPathComponent(const char *path) +{ + char *ret; + + ret =3D g_strdup(NULLSTR_EMPTY(path)); + + virFileRemoveLastComponent(ret); + + return ret; +} + + +/* + * virStorageFileGetRelativeBackingPath: + * + * Resolve relative path to be written to the overlay of @top image when + * collapsing the backing chain between @top and @base. + * + * Returns 0 on success; 1 if backing chain isn't relative and -1 on error. + */ +int +virStorageFileGetRelativeBackingPath(virStorageSourcePtr top, + virStorageSourcePtr base, + char **relpath) +{ + virStorageSourcePtr next; + g_autofree char *tmp =3D NULL; + g_autofree char *path =3D NULL; + + *relpath =3D NULL; + + for (next =3D top; virStorageSourceIsBacking(next); next =3D next->bac= kingStore) { + if (!next->relPath) + return 1; + + if (!(tmp =3D virStorageFileRemoveLastPathComponent(path))) + return -1; + + VIR_FREE(path); + + path =3D g_strdup_printf("%s%s", tmp, next->relPath); + + VIR_FREE(tmp); + + if (next =3D=3D base) + break; + } + + if (next !=3D base) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to resolve relative backing name: " + "base image is not in backing chain")); + return -1; + } + + *relpath =3D g_steal_pointer(&path); + return 0; +} + + +static bool +virStorageFileIsInitialized(const virStorageSource *src) +{ + return src && src->drv; +} + + +/** + * virStorageFileGetBackendForSupportCheck: + * @src: storage source to check support for + * @backend: pointer to the storage backend for @src if it's supported + * + * Returns 0 if @src is not supported by any storage backend currently lin= ked + * 1 if it is supported and -1 on error with an error reported. + */ +static int +virStorageFileGetBackendForSupportCheck(const virStorageSource *src, + virStorageFileBackendPtr *backend) +{ + int actualType; + + + if (!src) { + *backend =3D NULL; + return 0; + } + + if (src->drv) { + virStorageDriverDataPtr drv =3D src->drv; + *backend =3D drv->backend; + return 1; + } + + actualType =3D virStorageSourceGetActualType(src); + + if (virStorageFileBackendForType(actualType, src->protocol, false, bac= kend) < 0) + return -1; + + if (!*backend) + return 0; + + return 1; +} + + +int +virStorageFileSupportsBackingChainTraversal(const virStorageSource *src) +{ + virStorageFileBackendPtr backend; + int rv; + + if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + return rv; + + return backend->storageFileGetUniqueIdentifier && + backend->storageFileRead && + backend->storageFileAccess ? 1 : 0; +} + + +/** + * virStorageFileSupportsSecurityDriver: + * + * @src: a storage file structure + * + * Check if a storage file supports operations needed by the security + * driver to perform labelling + */ +int +virStorageFileSupportsSecurityDriver(const virStorageSource *src) +{ + virStorageFileBackendPtr backend; + int rv; + + if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + return rv; + + return backend->storageFileChown ? 1 : 0; +} + + +/** + * virStorageFileSupportsAccess: + * + * @src: a storage file structure + * + * Check if a storage file supports checking if the storage source is acce= ssible + * for the given vm. + */ +int +virStorageFileSupportsAccess(const virStorageSource *src) +{ + virStorageFileBackendPtr backend; + int rv; + + if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + return rv; + + return backend->storageFileAccess ? 1 : 0; +} + + +/** + * virStorageFileSupportsCreate: + * @src: a storage file structure + * + * Check if the storage driver supports creating storage described by @src + * via virStorageFileCreate. + */ +int +virStorageFileSupportsCreate(const virStorageSource *src) +{ + virStorageFileBackendPtr backend; + int rv; + + if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + return rv; + + return backend->storageFileCreate ? 1 : 0; +} + + +void +virStorageFileDeinit(virStorageSourcePtr src) +{ + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) + return; + + drv =3D src->drv; + + if (drv->backend && + drv->backend->backendDeinit) + drv->backend->backendDeinit(src); + + VIR_FREE(src->drv); +} + + +/** + * virStorageFileInitAs: + * + * @src: storage source definition + * @uid: uid used to access the file, or -1 for current uid + * @gid: gid used to access the file, or -1 for current gid + * + * Initialize a storage source to be used with storage driver. Use the pro= vided + * uid and gid if possible for the operations. + * + * Returns 0 if the storage file was successfully initialized, -1 if the + * initialization failed. Libvirt error is reported. + */ +int +virStorageFileInitAs(virStorageSourcePtr src, + uid_t uid, gid_t gid) +{ + int actualType =3D virStorageSourceGetActualType(src); + virStorageDriverDataPtr drv =3D g_new0(virStorageDriverData, 1); + + src->drv =3D drv; + + if (uid =3D=3D (uid_t) -1) + drv->uid =3D geteuid(); + else + drv->uid =3D uid; + + if (gid =3D=3D (gid_t) -1) + drv->gid =3D getegid(); + else + drv->gid =3D gid; + + if (virStorageFileBackendForType(actualType, + src->protocol, + true, + &drv->backend) < 0) + goto error; + + if (drv->backend->backendInit && + drv->backend->backendInit(src) < 0) + goto error; + + return 0; + + error: + VIR_FREE(src->drv); + return -1; +} + + +/** + * virStorageFileInit: + * + * See virStorageFileInitAs. The file is initialized to be accessed by the + * current user. + */ +int +virStorageFileInit(virStorageSourcePtr src) +{ + return virStorageFileInitAs(src, -1, -1); +} + + +/** + * virStorageFileCreate: Creates an empty storage file via storage driver + * + * @src: file structure pointing to the file + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. + */ +int +virStorageFileCreate(virStorageSourcePtr src) +{ + virStorageDriverDataPtr drv =3D NULL; + int ret; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileCreate) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileCreate(src); + + VIR_DEBUG("created storage file %p: ret=3D%d, errno=3D%d", + src, ret, errno); + + return ret; +} + + +/** + * virStorageFileUnlink: Unlink storage file via storage driver + * + * @src: file structure pointing to the file + * + * Unlinks the file described by the @file structure. + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. + */ +int +virStorageFileUnlink(virStorageSourcePtr src) +{ + virStorageDriverDataPtr drv =3D NULL; + int ret; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileUnlink) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileUnlink(src); + + VIR_DEBUG("unlinked storage file %p: ret=3D%d, errno=3D%d", + src, ret, errno); + + return ret; +} + + +/** + * virStorageFileStat: returns stat struct of a file via storage driver + * + * @src: file structure pointing to the file + * @stat: stat structure to return data + * + * Returns 0 on success, -2 if the function isn't supported by the backend, + * -1 on other failure. Errno is set in case of failure. +*/ +int +virStorageFileStat(virStorageSourcePtr src, + struct stat *st) +{ + virStorageDriverDataPtr drv =3D NULL; + int ret; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileStat) { + errno =3D ENOSYS; + return -2; + } + + ret =3D drv->backend->storageFileStat(src, st); + + VIR_DEBUG("stat of storage file %p: ret=3D%d, errno=3D%d", + src, ret, errno); + + return ret; +} + + +/** + * virStorageFileRead: read bytes from a file into a buffer + * + * @src: file structure pointing to the file + * @offset: number of bytes to skip in the storage file + * @len: maximum number of bytes read from the storage file + * @buf: buffer to read the data into. (buffer shall be freed by caller) + * + * Returns the count of bytes read on success and -1 on failure, -2 if the + * function isn't supported by the backend. + * Libvirt error is reported on failure. + */ +ssize_t +virStorageFileRead(virStorageSourcePtr src, + size_t offset, + size_t len, + char **buf) +{ + virStorageDriverDataPtr drv =3D NULL; + ssize_t ret; + + if (!virStorageFileIsInitialized(src)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("storage file backend not initialized")); + return -1; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileRead) + return -2; + + ret =3D drv->backend->storageFileRead(src, offset, len, buf); + + VIR_DEBUG("read '%zd' bytes from storage '%p' starting at offset '%zu'= ", + ret, src, offset); + + return ret; +} + + +/* + * virStorageFileGetUniqueIdentifier: Get a unique string describing the v= olume + * + * @src: file structure pointing to the file + * + * Returns a string uniquely describing a single volume (canonical path). + * The string shall not be freed and is valid until the storage file is + * deinitialized. Returns NULL on error and sets a libvirt error code */ +const char * +virStorageFileGetUniqueIdentifier(virStorageSourcePtr src) +{ + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("storage file backend not initialized")); + return NULL; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileGetUniqueIdentifier) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unique storage file identifier not implemented f= or " + "storage type %s (protocol: %s)'"), + virStorageTypeToString(src->type), + virStorageNetProtocolTypeToString(src->protocol)); + return NULL; + } + + return drv->backend->storageFileGetUniqueIdentifier(src); +} + + +/** + * virStorageFileAccess: Check accessibility of a storage file + * + * @src: storage file to check access permissions + * @mode: accessibility check options (see man 2 access) + * + * Returns 0 on success, -1 on error and sets errno. No libvirt + * error is reported. Returns -2 if the operation isn't supported + * by libvirt storage backend. + */ +int +virStorageFileAccess(virStorageSourcePtr src, + int mode) +{ + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileAccess) { + errno =3D ENOSYS; + return -2; + } + + return drv->backend->storageFileAccess(src, mode); +} + + +/** + * virStorageFileChown: Change owner of a storage file + * + * @src: storage file to change owner of + * @uid: new owner id + * @gid: new group id + * + * Returns 0 on success, -1 on error and sets errno. No libvirt + * error is reported. Returns -2 if the operation isn't supported + * by libvirt storage backend. + */ +int +virStorageFileChown(const virStorageSource *src, + uid_t uid, + gid_t gid) +{ + virStorageDriverDataPtr drv =3D NULL; + + if (!virStorageFileIsInitialized(src)) { + errno =3D ENOSYS; + return -2; + } + + drv =3D src->drv; + + if (!drv->backend->storageFileChown) { + errno =3D ENOSYS; + return -2; + } + + VIR_DEBUG("chown of storage file %p to %u:%u", + src, (unsigned int)uid, (unsigned int)gid); + + return drv->backend->storageFileChown(src, uid, gid); +} + + +/** + * virStorageFileReportBrokenChain: + * + * @errcode: errno when accessing @src + * @src: inaccessible file in the backing chain of @parent + * @parent: root virStorageSource being checked + * + * Reports the correct error message if @src is missing in the backing cha= in + * for @parent. + */ +void +virStorageFileReportBrokenChain(int errcode, + virStorageSourcePtr src, + virStorageSourcePtr parent) +{ + if (src->drv) { + virStorageDriverDataPtr drv =3D src->drv; + unsigned int access_user =3D drv->uid; + unsigned int access_group =3D drv->gid; + + if (src =3D=3D parent) { + virReportSystemError(errcode, + _("Cannot access storage file '%s' " + "(as uid:%u, gid:%u)"), + src->path, access_user, access_group); + } else { + virReportSystemError(errcode, + _("Cannot access backing file '%s' " + "of storage file '%s' (as uid:%u, gid:%= u)"), + src->path, parent->path, access_user, acc= ess_group); + } + } else { + if (src =3D=3D parent) { + virReportSystemError(errcode, + _("Cannot access storage file '%s'"), + src->path); + } else { + virReportSystemError(errcode, + _("Cannot access backing file '%s' " + "of storage file '%s'"), + src->path, parent->path); + } + } +} + + +static int +virStorageFileGetMetadataRecurseReadHeader(virStorageSourcePtr src, + virStorageSourcePtr parent, + uid_t uid, + gid_t gid, + char **buf, + size_t *headerLen, + GHashTable *cycle) +{ + int ret =3D -1; + const char *uniqueName; + ssize_t len; + + if (virStorageFileInitAs(src, uid, gid) < 0) + return -1; + + if (virStorageFileAccess(src, F_OK) < 0) { + virStorageFileReportBrokenChain(errno, src, parent); + goto cleanup; + } + + if (!(uniqueName =3D virStorageFileGetUniqueIdentifier(src))) + goto cleanup; + + if (virHashHasEntry(cycle, uniqueName)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("backing store for %s (%s) is self-referential"), + NULLSTR(src->path), uniqueName); + goto cleanup; + } + + if (virHashAddEntry(cycle, uniqueName, NULL) < 0) + goto cleanup; + + if ((len =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, buf)) = < 0) + goto cleanup; + + *headerLen =3D len; + ret =3D 0; + + cleanup: + virStorageFileDeinit(src); + return ret; +} + + +/* Recursive workhorse for virStorageFileGetMetadata. */ +static int +virStorageFileGetMetadataRecurse(virStorageSourcePtr src, + virStorageSourcePtr parent, + uid_t uid, gid_t gid, + bool report_broken, + GHashTable *cycle, + unsigned int depth) +{ + virStorageFileFormat orig_format =3D src->format; + size_t headerLen; + int rv; + g_autofree char *buf =3D NULL; + g_autoptr(virStorageSource) backingStore =3D NULL; + + VIR_DEBUG("path=3D%s format=3D%d uid=3D%u gid=3D%u", + NULLSTR(src->path), src->format, + (unsigned int)uid, (unsigned int)gid); + + if (src->format =3D=3D VIR_STORAGE_FILE_AUTO_SAFE) + src->format =3D VIR_STORAGE_FILE_AUTO; + + /* exit if we can't load information about the current image */ + rv =3D virStorageFileSupportsBackingChainTraversal(src); + if (rv <=3D 0) { + if (orig_format =3D=3D VIR_STORAGE_FILE_AUTO) + return -2; + + return rv; + } + + if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid, + &buf, &headerLen, cycle= ) < 0) + return -1; + + if (virStorageFileProbeGetMetadata(src, buf, headerLen) < 0) + return -1; + + /* If we probed the format we MUST ensure that nothing else than the c= urrent + * image is considered for security labelling and/or recursion. */ + if (orig_format =3D=3D VIR_STORAGE_FILE_AUTO) { + if (src->backingStoreRaw) { + src->format =3D VIR_STORAGE_FILE_RAW; + VIR_FREE(src->backingStoreRaw); + return -2; + } + } + + if (src->backingStoreRaw) { + if ((rv =3D virStorageSourceNewFromBacking(src, &backingStore)) < = 0) + return -1; + + /* the backing file would not be usable for VM usage */ + if (rv =3D=3D 1) + return 0; + + if ((rv =3D virStorageFileGetMetadataRecurse(backingStore, parent, + uid, gid, + report_broken, + cycle, depth + 1)) < 0)= { + if (!report_broken) + return 0; + + if (rv =3D=3D -2) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("format of backing image '%s' of image '%= s' was not specified in the image metadata " + "(See https://libvirt.org/kbase/backing_c= hains.html for troubleshooting)"), + src->backingStoreRaw, NULLSTR(src->path)); + } + + return -1; + } + + backingStore->id =3D depth; + src->backingStore =3D g_steal_pointer(&backingStore); + } else { + /* add terminator */ + src->backingStore =3D virStorageSourceNew(); + } + + return 0; +} + + +/** + * virStorageFileGetMetadata: + * + * Extract metadata about the storage volume with the specified + * image format. If image format is VIR_STORAGE_FILE_AUTO, it + * will probe to automatically identify the format. Recurses through + * the entire chain. + * + * Open files using UID and GID (or pass -1 for the current user/group). + * Treat any backing files without explicit type as raw, unless ALLOW_PROB= E. + * + * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a + * format, since a malicious guest can turn a raw file into any + * other non-raw format at will. + * + * If @report_broken is true, the whole function fails with a possibly sane + * error instead of just returning a broken chain. Note that the inability= for + * libvirt to traverse a given source is not considered an error. + * + * Caller MUST free result after use via virObjectUnref. + */ +int +virStorageFileGetMetadata(virStorageSourcePtr src, + uid_t uid, gid_t gid, + bool report_broken) +{ + GHashTable *cycle =3D NULL; + virStorageType actualType =3D virStorageSourceGetActualType(src); + int ret =3D -1; + + VIR_DEBUG("path=3D%s format=3D%d uid=3D%u gid=3D%u report_broken=3D%d", + src->path, src->format, (unsigned int)uid, (unsigned int)gid, + report_broken); + + if (!(cycle =3D virHashNew(NULL))) + return -1; + + if (src->format <=3D VIR_STORAGE_FILE_NONE) { + if (actualType =3D=3D VIR_STORAGE_TYPE_DIR) + src->format =3D VIR_STORAGE_FILE_DIR; + else + src->format =3D VIR_STORAGE_FILE_RAW; + } + + ret =3D virStorageFileGetMetadataRecurse(src, src, uid, gid, + report_broken, cycle, 1); + + virHashFree(cycle); + return ret; +} + + +/** + * virStorageFileGetBackingStoreStr: + * @src: storage object + * + * Extracts the backing store string as stored in the storage volume descr= ibed + * by @src and returns it to the user. Caller is responsible for freeing i= t. + * In case when the string can't be retrieved or does not exist NULL is + * returned. + */ +int +virStorageFileGetBackingStoreStr(virStorageSourcePtr src, + char **backing) +{ + ssize_t headerLen; + int rv; + g_autofree char *buf =3D NULL; + g_autoptr(virStorageSource) tmp =3D NULL; + + *backing =3D NULL; + + /* exit if we can't load information about the current image */ + if (!virStorageFileSupportsBackingChainTraversal(src)) + return 0; + + rv =3D virStorageFileAccess(src, F_OK); + if (rv =3D=3D -2) + return 0; + if (rv < 0) { + virStorageFileReportBrokenChain(errno, src, src); + return -1; + } + + if ((headerLen =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, + &buf)) < 0) { + if (headerLen =3D=3D -2) + return 0; + return -1; + } + + if (!(tmp =3D virStorageSourceCopy(src, false))) + return -1; + + if (virStorageFileProbeGetMetadata(tmp, buf, headerLen) < 0) + return -1; + + *backing =3D g_steal_pointer(&tmp->backingStoreRaw); + return 0; +} diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_s= ource.h new file mode 100644 index 0000000000..23f56417a8 --- /dev/null +++ b/src/storage_file/storage_source.h @@ -0,0 +1,148 @@ +/* + * storage_source.h: file utility functions for FS storage backend + * + * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "virstoragefile.h" + +#ifndef DEV_BSIZE +# define DEV_BSIZE 512 +#endif + +virStorageSourcePtr +virStorageFileGetMetadataFromFD(const char *path, + int fd, + int format); + +virStorageSourcePtr +virStorageFileGetMetadataFromBuf(const char *path, + char *buf, + size_t len, + int format) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +virStorageSourcePtr +virStorageFileChainLookup(virStorageSourcePtr chain, + virStorageSourcePtr startFrom, + const char *name, + unsigned int idx, + virStorageSourcePtr *parent) + ATTRIBUTE_NONNULL(1); + +int +virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, + int fd, + struct stat const *sb); + +int +virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, + int fd, + struct stat const *sb); + +int +virStorageSourceUpdateCapacity(virStorageSourcePtr src, + char *buf, + ssize_t len); + +int +virStorageSourceNewFromBacking(virStorageSourcePtr parent, + virStorageSourcePtr *backing); + +int +virStorageSourceParseRBDColonString(const char *rbdstr, + virStorageSourcePtr src) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +int +virStorageFileGetRelativeBackingPath(virStorageSourcePtr top, + virStorageSourcePtr base, + char **relpath) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +int +virStorageSourceNewFromBackingAbsolute(const char *path, + virStorageSourcePtr *src); + +int +virStorageFileInit(virStorageSourcePtr src); + +int +virStorageFileInitAs(virStorageSourcePtr src, + uid_t uid, gid_t gid); + +void +virStorageFileDeinit(virStorageSourcePtr src); + +int +virStorageFileCreate(virStorageSourcePtr src); + +int +virStorageFileUnlink(virStorageSourcePtr src); + +int +virStorageFileStat(virStorageSourcePtr src, + struct stat *st); + +ssize_t +virStorageFileRead(virStorageSourcePtr src, + size_t offset, + size_t len, + char **buf); + +const char * +virStorageFileGetUniqueIdentifier(virStorageSourcePtr src); + +int +virStorageFileAccess(virStorageSourcePtr src, + int mode); + +int +virStorageFileChown(const virStorageSource *src, + uid_t uid, + gid_t gid); + +int +virStorageFileSupportsSecurityDriver(const virStorageSource *src); + +int +virStorageFileSupportsAccess(const virStorageSource *src); + +int +virStorageFileSupportsCreate(const virStorageSource *src); + +int +virStorageFileSupportsBackingChainTraversal(const virStorageSource *src); + +int +virStorageFileGetMetadata(virStorageSourcePtr src, + uid_t uid, gid_t gid, + bool report_broken) + ATTRIBUTE_NONNULL(1); + +int +virStorageFileGetBackingStoreStr(virStorageSourcePtr src, + char **backing) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void +virStorageFileReportBrokenChain(int errcode, + virStorageSourcePtr src, + virStorageSourcePtr parent); diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 98a3222d09..c70d5713de 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -31,14 +31,9 @@ #include "vircommand.h" #include "virhash.h" #include "virstring.h" -#include "viruri.h" #include "virbuffer.h" -#include "virjson.h" #include "virstorageencryption.h" -#include "virstoragefilebackend.h" -#include "virstoragefileprobe.h" #include "virsecret.h" -#include "virutil.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE =20 @@ -146,126 +141,6 @@ virStorageIsRelative(const char *backing) } =20 =20 -static virStorageSourcePtr -virStorageFileMetadataNew(const char *path, - int format) -{ - g_autoptr(virStorageSource) def =3D virStorageSourceNew(); - - def->format =3D format; - def->type =3D VIR_STORAGE_TYPE_FILE; - - def->path =3D g_strdup(path); - - return g_steal_pointer(&def); -} - - -/** - * virStorageFileGetMetadataFromBuf: - * @path: name of file, for error messages - * @buf: header bytes from @path - * @len: length of @buf - * @format: format of the storage file - * - * Extract metadata about the storage volume with the specified image form= at. - * If image format is VIR_STORAGE_FILE_AUTO, it will probe to automatically - * identify the format. Does not recurse. - * - * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a format on a= file - * that might be raw if that file will then be passed to a guest, since a - * malicious guest can turn a raw file into any other non-raw format at wi= ll. - * - * If the 'backingStoreRawFormat' field of the returned structure is - * VIR_STORAGE_FILE_AUTO it indicates the image didn't specify an explicit - * format for its backing store. Callers are advised against probing for t= he - * backing store format in this case. - * - * Caller MUST free the result after use via virObjectUnref. - */ -virStorageSourcePtr -virStorageFileGetMetadataFromBuf(const char *path, - char *buf, - size_t len, - int format) -{ - virStorageSourcePtr ret =3D NULL; - - if (!(ret =3D virStorageFileMetadataNew(path, format))) - return NULL; - - if (virStorageFileProbeGetMetadata(ret, buf, len) < 0) { - virObjectUnref(ret); - return NULL; - } - - return ret; -} - - -/** - * virStorageFileGetMetadataFromFD: - * - * Extract metadata about the storage volume with the specified - * image format. If image format is VIR_STORAGE_FILE_AUTO, it - * will probe to automatically identify the format. Does not recurse. - * - * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a - * format, since a malicious guest can turn a raw file into any - * other non-raw format at will. - * - * Caller MUST free the result after use via virObjectUnref. - */ -virStorageSourcePtr -virStorageFileGetMetadataFromFD(const char *path, - int fd, - int format) - -{ - ssize_t len =3D VIR_STORAGE_MAX_HEADER; - struct stat sb; - g_autofree char *buf =3D NULL; - g_autoptr(virStorageSource) meta =3D NULL; - - if (fstat(fd, &sb) < 0) { - virReportSystemError(errno, - _("cannot stat file '%s'"), path); - return NULL; - } - - if (!(meta =3D virStorageFileMetadataNew(path, format))) - return NULL; - - if (S_ISDIR(sb.st_mode)) { - /* No header to probe for directories, but also no backing file. J= ust - * update the metadata.*/ - meta->type =3D VIR_STORAGE_TYPE_DIR; - meta->format =3D VIR_STORAGE_FILE_DIR; - return g_steal_pointer(&meta); - } - - if (lseek(fd, 0, SEEK_SET) =3D=3D (off_t)-1) { - virReportSystemError(errno, _("cannot seek to start of '%s'"), met= a->path); - return NULL; - } - - if ((len =3D virFileReadHeaderFD(fd, len, &buf)) < 0) { - virReportSystemError(errno, _("cannot read header '%s'"), meta->pa= th); - return NULL; - } - - if (virStorageFileProbeGetMetadata(meta, buf, len) < 0) - return NULL; - - if (S_ISREG(sb.st_mode)) - meta->type =3D VIR_STORAGE_TYPE_FILE; - else if (S_ISBLK(sb.st_mode)) - meta->type =3D VIR_STORAGE_TYPE_BLOCK; - - return g_steal_pointer(&meta); -} - - #ifdef WITH_UDEV /* virStorageFileGetSCSIKey * @path: Path to the SCSI device @@ -503,107 +378,6 @@ virStorageSourceHasBacking(const virStorageSource *sr= c) } =20 =20 -/* Given a @chain, look for the backing store @name that is a backing file - * of @startFrom (or any member of @chain if @startFrom is NULL) and return - * that location within the chain. @chain must always point to the top of - * the chain. Pass NULL for @name and 0 for @idx to find the base of the - * chain. Pass nonzero @idx to find the backing source according to its - * position in the backing chain. If @parent is not NULL, set *@parent to - * the preferred name of the parent (or to NULL if @name matches the start - * of the chain). Since the results point within @chain, they must not be - * independently freed. Reports an error and returns NULL if @name is not - * found. - */ -virStorageSourcePtr -virStorageFileChainLookup(virStorageSourcePtr chain, - virStorageSourcePtr startFrom, - const char *name, - unsigned int idx, - virStorageSourcePtr *parent) -{ - virStorageSourcePtr prev; - const char *start =3D chain->path; - bool nameIsFile =3D virStorageIsFile(name); - - if (!parent) - parent =3D &prev; - *parent =3D NULL; - - if (startFrom) { - while (virStorageSourceIsBacking(chain) && - chain !=3D startFrom->backingStore) - chain =3D chain->backingStore; - - *parent =3D startFrom; - } - - while (virStorageSourceIsBacking(chain)) { - if (!name && !idx) { - if (!virStorageSourceHasBacking(chain)) - break; - } else if (idx) { - VIR_DEBUG("%u: %s", chain->id, chain->path); - if (idx =3D=3D chain->id) - break; - } else { - if (STREQ_NULLABLE(name, chain->relPath) || - STREQ_NULLABLE(name, chain->path)) - break; - - if (nameIsFile && virStorageSourceIsLocalStorage(chain)) { - g_autofree char *parentDir =3D NULL; - int result; - - if (*parent && virStorageSourceIsLocalStorage(*parent)) - parentDir =3D g_path_get_dirname((*parent)->path); - else - parentDir =3D g_strdup("."); - - result =3D virFileRelLinkPointsTo(parentDir, name, - chain->path); - - if (result < 0) - goto error; - - if (result > 0) - break; - } - } - *parent =3D chain; - chain =3D chain->backingStore; - } - - if (!virStorageSourceIsBacking(chain)) - goto error; - - return chain; - - error: - if (idx) { - virReportError(VIR_ERR_INVALID_ARG, - _("could not find backing store index %u in chain " - "for '%s'"), - idx, NULLSTR(start)); - } else if (name) { - if (startFrom) - virReportError(VIR_ERR_INVALID_ARG, - _("could not find image '%s' beneath '%s' in " - "chain for '%s'"), name, NULLSTR(startFrom->p= ath), - NULLSTR(start)); - else - virReportError(VIR_ERR_INVALID_ARG, - _("could not find image '%s' in chain for '%s'"= ), - name, NULLSTR(start)); - } else { - virReportError(VIR_ERR_INVALID_ARG, - _("could not find base image in chain for '%s'"), - NULLSTR(start)); - } - *parent =3D NULL; - return NULL; -} - - void virStorageNetHostDefClear(virStorageNetHostDefPtr def) { @@ -1660,1550 +1434,6 @@ virStorageSourceNew(void) } =20 =20 -static virStorageSourcePtr -virStorageSourceNewFromBackingRelative(virStorageSourcePtr parent, - const char *rel) -{ - g_autofree char *dirname =3D NULL; - g_autoptr(virStorageSource) def =3D virStorageSourceNew(); - - /* store relative name */ - def->relPath =3D g_strdup(rel); - - dirname =3D g_path_get_dirname(parent->path); - - if (STRNEQ(dirname, "/")) { - def->path =3D g_strdup_printf("%s/%s", dirname, rel); - } else { - def->path =3D g_strdup_printf("/%s", rel); - } - - if (virStorageSourceGetActualType(parent) =3D=3D VIR_STORAGE_TYPE_NETW= ORK) { - def->type =3D VIR_STORAGE_TYPE_NETWORK; - - /* copy the host network part */ - def->protocol =3D parent->protocol; - if (parent->nhosts) { - if (!(def->hosts =3D virStorageNetHostDefCopy(parent->nhosts, - parent->hosts))) - return NULL; - - def->nhosts =3D parent->nhosts; - } - - def->volume =3D g_strdup(parent->volume); - } else { - /* set the type to _FILE, the caller shall update it to the actual= type */ - def->type =3D VIR_STORAGE_TYPE_FILE; - } - - return g_steal_pointer(&def); -} - - -static int -virStorageSourceParseBackingURI(virStorageSourcePtr src, - const char *uristr) -{ - g_autoptr(virURI) uri =3D NULL; - const char *path =3D NULL; - g_auto(GStrv) scheme =3D NULL; - - if (!(uri =3D virURIParse(uristr))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("failed to parse backing file location '%s'"), - uristr); - return -1; - } - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (!(scheme =3D virStringSplit(uri->scheme, "+", 2))) - return -1; - - if (!scheme[0] || - (src->protocol =3D virStorageNetProtocolTypeFromString(scheme[0]))= < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid backing protocol '%s'"), - NULLSTR(scheme[0])); - return -1; - } - - if (scheme[1] && - (src->hosts->transport =3D virStorageNetHostTransportTypeFromStrin= g(scheme[1])) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid protocol transport type '%s'"), - scheme[1]); - return -1; - } - - if (uri->query) { - if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTP || - src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS) { - src->query =3D g_strdup(uri->query); - } else { - /* handle socket stored as a query */ - if (STRPREFIX(uri->query, "socket=3D")) - src->hosts->socket =3D g_strdup(STRSKIP(uri->query, "socke= t=3D")); - } - } - - /* uri->path is NULL if the URI does not contain slash after host: - * transport://host:port */ - if (uri->path) - path =3D uri->path; - else - path =3D ""; - - /* possibly skip the leading slash */ - if (path[0] =3D=3D '/') - path++; - - /* NBD allows empty export name (path) */ - if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_NBD && - path[0] =3D=3D '\0') - path =3D NULL; - - src->path =3D g_strdup(path); - - if (src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_GLUSTER) { - char *tmp; - - if (!src->path) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("missing volume name and path for gluster vol= ume")); - return -1; - } - - if (!(tmp =3D strchr(src->path, '/')) || - tmp =3D=3D src->path) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("missing volume name or file name in " - "gluster source path '%s'"), src->path); - return -1; - } - - src->volume =3D src->path; - - src->path =3D g_strdup(tmp + 1); - - tmp[0] =3D '\0'; - } - - src->hosts->port =3D uri->port; - - src->hosts->name =3D g_strdup(uri->server); - - /* Libvirt doesn't handle inline authentication. Make the caller aware= . */ - if (uri->user) - return 1; - - return 0; -} - - -static int -virStorageSourceRBDAddHost(virStorageSourcePtr src, - char *hostport) -{ - char *port; - size_t skip; - g_auto(GStrv) parts =3D NULL; - - if (VIR_EXPAND_N(src->hosts, src->nhosts, 1) < 0) - return -1; - - if ((port =3D strchr(hostport, ']'))) { - /* ipv6, strip brackets */ - hostport +=3D 1; - skip =3D 3; - } else { - port =3D strstr(hostport, "\\:"); - skip =3D 2; - } - - if (port) { - *port =3D '\0'; - port +=3D skip; - if (virStringParsePort(port, &src->hosts[src->nhosts - 1].port) < = 0) - goto error; - } - - parts =3D virStringSplit(hostport, "\\:", 0); - if (!parts) - goto error; - src->hosts[src->nhosts-1].name =3D virStringListJoin((const char **)pa= rts, ":"); - if (!src->hosts[src->nhosts-1].name) - goto error; - - src->hosts[src->nhosts-1].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - src->hosts[src->nhosts-1].socket =3D NULL; - - return 0; - - error: - VIR_FREE(src->hosts[src->nhosts-1].name); - return -1; -} - - -int -virStorageSourceParseRBDColonString(const char *rbdstr, - virStorageSourcePtr src) -{ - char *p, *e, *next; - g_autofree char *options =3D NULL; - g_autoptr(virStorageAuthDef) authdef =3D NULL; - - /* optionally skip the "rbd:" prefix if provided */ - if (STRPREFIX(rbdstr, "rbd:")) - rbdstr +=3D strlen("rbd:"); - - src->path =3D g_strdup(rbdstr); - - p =3D strchr(src->path, ':'); - if (p) { - options =3D g_strdup(p + 1); - *p =3D '\0'; - } - - /* snapshot name */ - if ((p =3D strchr(src->path, '@'))) { - src->snapshot =3D g_strdup(p + 1); - *p =3D '\0'; - } - - /* pool vs. image name */ - if ((p =3D strchr(src->path, '/'))) { - src->volume =3D g_steal_pointer(&src->path); - src->path =3D g_strdup(p + 1); - *p =3D '\0'; - } - - /* options */ - if (!options) - return 0; /* all done */ - - p =3D options; - while (*p) { - /* find : delimiter or end of string */ - for (e =3D p; *e && *e !=3D ':'; ++e) { - if (*e =3D=3D '\\') { - e++; - if (*e =3D=3D '\0') - break; - } - } - if (*e =3D=3D '\0') { - next =3D e; /* last kv pair */ - } else { - next =3D e + 1; - *e =3D '\0'; - } - - if (STRPREFIX(p, "id=3D")) { - /* formulate authdef for src->auth */ - if (src->auth) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("duplicate 'id' found in '%s'"), src->pat= h); - return -1; - } - - authdef =3D g_new0(virStorageAuthDef, 1); - - authdef->username =3D g_strdup(p + strlen("id=3D")); - - authdef->secrettype =3D g_strdup(virSecretUsageTypeToString(VI= R_SECRET_USAGE_TYPE_CEPH)); - src->auth =3D g_steal_pointer(&authdef); - - /* Cannot formulate a secretType (eg, usage or uuid) given - * what is provided. - */ - } - if (STRPREFIX(p, "mon_host=3D")) { - char *h, *sep; - - h =3D p + strlen("mon_host=3D"); - while (h < e) { - for (sep =3D h; sep < e; ++sep) { - if (*sep =3D=3D '\\' && (sep[1] =3D=3D ',' || - sep[1] =3D=3D ';' || - sep[1] =3D=3D ' ')) { - *sep =3D '\0'; - sep +=3D 2; - break; - } - } - - if (virStorageSourceRBDAddHost(src, h) < 0) - return -1; - - h =3D sep; - } - } - - if (STRPREFIX(p, "conf=3D")) - src->configFile =3D g_strdup(p + strlen("conf=3D")); - - p =3D next; - } - return 0; -} - - -static int -virStorageSourceParseNBDColonString(const char *nbdstr, - virStorageSourcePtr src) -{ - g_autofree char *nbd =3D g_strdup(nbdstr); - char *export_name; - char *host_spec; - char *unixpath; - char *port; - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - /* We extract the parameters in a similar way qemu does it */ - - /* format: [] denotes optional sections, uppercase are variable strings - * nbd:unix:/PATH/TO/SOCKET[:exportname=3DEXPORTNAME] - * nbd:HOSTNAME:PORT[:exportname=3DEXPORTNAME] - */ - - /* first look for ':exportname=3D' and cut it off */ - if ((export_name =3D strstr(nbd, ":exportname=3D"))) { - src->path =3D g_strdup(export_name + strlen(":exportname=3D")); - export_name[0] =3D '\0'; - } - - /* Verify the prefix and contents. Note that we require a - * "host_spec" part to be present. */ - if (!(host_spec =3D STRSKIP(nbd, "nbd:")) || host_spec[0] =3D=3D '\0') - goto malformed; - - if ((unixpath =3D STRSKIP(host_spec, "unix:"))) { - src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; - - if (unixpath[0] =3D=3D '\0') - goto malformed; - - src->hosts->socket =3D g_strdup(unixpath); - } else { - src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - - if (host_spec[0] =3D=3D ':') { - /* no host given */ - goto malformed; - } else if (host_spec[0] =3D=3D '[') { - host_spec++; - /* IPv6 addr */ - if (!(port =3D strstr(host_spec, "]:"))) - goto malformed; - - port[0] =3D '\0'; - port +=3D 2; - - if (host_spec[0] =3D=3D '\0') - goto malformed; - } else { - if (!(port =3D strchr(host_spec, ':'))) - goto malformed; - - port[0] =3D '\0'; - port++; - } - - if (virStringParsePort(port, &src->hosts->port) < 0) - return -1; - - src->hosts->name =3D g_strdup(host_spec); - } - - return 0; - - malformed: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("malformed nbd string '%s'"), nbdstr); - return -1; -} - - -static int -virStorageSourceParseBackingColon(virStorageSourcePtr src, - const char *path) -{ - const char *p; - g_autofree char *protocol =3D NULL; - - if (!(p =3D strchr(path, ':'))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid backing protocol string '%s'"), - path); - return -1; - } - - protocol =3D g_strndup(path, p - path); - - if ((src->protocol =3D virStorageNetProtocolTypeFromString(protocol)) = < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("invalid backing protocol '%s'"), - protocol); - return -1; - } - - switch ((virStorageNetProtocol) src->protocol) { - case VIR_STORAGE_NET_PROTOCOL_NBD: - if (virStorageSourceParseNBDColonString(path, src) < 0) - return -1; - break; - - case VIR_STORAGE_NET_PROTOCOL_RBD: - if (virStorageSourceParseRBDColonString(path, src) < 0) - return -1; - break; - - case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: - case VIR_STORAGE_NET_PROTOCOL_LAST: - case VIR_STORAGE_NET_PROTOCOL_NONE: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("backing store parser is not implemented for prot= ocol %s"), - protocol); - return -1; - - 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_SSH: - case VIR_STORAGE_NET_PROTOCOL_VXHS: - case VIR_STORAGE_NET_PROTOCOL_NFS: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("malformed backing store path for protocol %s"), - protocol); - return -1; - } - - return 0; -} - - -static int -virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr, - bool allowformat); - - -static int -virStorageSourceParseBackingJSONPath(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int type) -{ - const char *path; - - if (!(path =3D virJSONValueObjectGetString(json, "filename"))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'filename' field in JSON backing volume " - "definition")); - return -1; - } - - src->path =3D g_strdup(path); - - src->type =3D type; - return 0; -} - - -static int -virStorageSourceParseBackingJSONUriStr(virStorageSourcePtr src, - const char *uri, - int protocol) -{ - int rc; - - if ((rc =3D virStorageSourceParseBackingURI(src, uri)) < 0) - return -1; - - if (src->protocol !=3D protocol) { - virReportError(VIR_ERR_INVALID_ARG, - _("expected protocol '%s' but got '%s' in URI JSON = volume " - "definition"), - virStorageNetProtocolTypeToString(protocol), - virStorageNetProtocolTypeToString(src->protocol)); - return -1; - } - - return rc; -} - - -static int -virStorageSourceParseBackingJSONUriCookies(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr) -{ - const char *cookiestr; - g_auto(GStrv) cookies =3D NULL; - size_t ncookies =3D 0; - size_t i; - - if (!virJSONValueObjectHasKey(json, "cookie")) - return 0; - - if (!(cookiestr =3D virJSONValueObjectGetString(json, "cookie"))) { - virReportError(VIR_ERR_INVALID_ARG, - _("wrong format of 'cookie' field in backing store = definition '%s'"), - jsonstr); - return -1; - } - - if (!(cookies =3D virStringSplitCount(cookiestr, ";", 0, &ncookies))) - return -1; - - src->cookies =3D g_new0(virStorageNetCookieDefPtr, ncookies); - src->ncookies =3D ncookies; - - for (i =3D 0; i < ncookies; i++) { - char *cookiename =3D cookies[i]; - char *cookievalue; - - virSkipSpaces((const char **) &cookiename); - - if (!(cookievalue =3D strchr(cookiename, '=3D'))) { - virReportError(VIR_ERR_INVALID_ARG, - _("malformed http cookie '%s' in backing store = definition '%s'"), - cookies[i], jsonstr); - return -1; - } - - *cookievalue =3D '\0'; - cookievalue++; - - src->cookies[i] =3D g_new0(virStorageNetCookieDef, 1); - src->cookies[i]->name =3D g_strdup(cookiename); - src->cookies[i]->value =3D g_strdup(cookievalue); - } - - return 0; -} - - -static int -virStorageSourceParseBackingJSONUri(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr, - int protocol) -{ - const char *uri; - - if (!(uri =3D virJSONValueObjectGetString(json, "url"))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'url' in JSON backing volume definition"= )); - return -1; - } - - if (protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS || - protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_FTPS) { - if (virJSONValueObjectHasKey(json, "sslverify")) { - const char *tmpstr; - bool tmp; - - /* libguestfs still uses undocumented legacy value of 'off' */ - if ((tmpstr =3D virJSONValueObjectGetString(json, "sslverify")= ) && - STREQ(tmpstr, "off")) { - src->sslverify =3D VIR_TRISTATE_BOOL_NO; - } else { - if (virJSONValueObjectGetBoolean(json, "sslverify", &tmp) = < 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("malformed 'sslverify' field in backi= ng store definition '%s'"), - jsonstr); - return -1; - } - - src->sslverify =3D virTristateBoolFromBool(tmp); - } - } - } - - if (protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTPS || - protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_HTTP) { - if (virStorageSourceParseBackingJSONUriCookies(src, json, jsonstr)= < 0) - return -1; - } - - if (virJSONValueObjectHasKey(json, "readahead") && - virJSONValueObjectGetNumberUlong(json, "readahead", &src->readahea= d) < 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("malformed 'readahead' field in backing store def= inition '%s'"), - jsonstr); - return -1; - } - - if (virJSONValueObjectHasKey(json, "timeout") && - virJSONValueObjectGetNumberUlong(json, "timeout", &src->timeout) <= 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("malformed 'timeout' field in backing store defin= ition '%s'"), - jsonstr); - return -1; - } - - return virStorageSourceParseBackingJSONUriStr(src, uri, protocol); -} - - -static int -virStorageSourceParseBackingJSONInetSocketAddress(virStorageNetHostDefPtr = host, - virJSONValuePtr json) -{ - const char *hostname; - const char *port; - - if (!json) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing remote server specification in JSON " - "backing volume definition")); - return -1; - } - - hostname =3D virJSONValueObjectGetString(json, "host"); - port =3D virJSONValueObjectGetString(json, "port"); - - if (!hostname) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing hostname for tcp backing server in " - "JSON backing volume definition")); - return -1; - } - - host->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - host->name =3D g_strdup(hostname); - - if (virStringParsePort(port, &host->port) < 0) - return -1; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONSocketAddress(virStorageNetHostDefPtr host, - virJSONValuePtr json) -{ - const char *type; - const char *socket; - - if (!json) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing remote server specification in JSON " - "backing volume definition")); - return -1; - } - - if (!(type =3D virJSONValueObjectGetString(json, "type"))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing socket address type in " - "JSON backing volume definition")); - return -1; - } - - if (STREQ(type, "tcp") || STREQ(type, "inet")) { - return virStorageSourceParseBackingJSONInetSocketAddress(host, jso= n); - - } else if (STREQ(type, "unix")) { - host->transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; - - socket =3D virJSONValueObjectGetString(json, "path"); - - /* check for old spelling for gluster protocol */ - if (!socket) - socket =3D virJSONValueObjectGetString(json, "socket"); - - if (!socket) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing socket path for udp backing server i= n " - "JSON backing volume definition")); - return -1; - } - - host->socket =3D g_strdup(socket); - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("backing store protocol '%s' is not yet supported= "), - type); - return -1; - } - - return 0; -} - - -static int -virStorageSourceParseBackingJSONGluster(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *uri =3D virJSONValueObjectGetString(json, "filename"); - const char *volume =3D virJSONValueObjectGetString(json, "volume"); - const char *path =3D virJSONValueObjectGetString(json, "path"); - virJSONValuePtr server =3D virJSONValueObjectGetArray(json, "server"); - size_t nservers; - size_t i; - - /* legacy URI based syntax passed via 'filename' option */ - if (uri) - return virStorageSourceParseBackingJSONUriStr(src, uri, - VIR_STORAGE_NET_PROT= OCOL_GLUSTER); - - if (!volume || !path || !server) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'volume', 'path' or 'server' attribute i= n " - "JSON backing definition for gluster volume")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_GLUSTER; - - src->volume =3D g_strdup(volume); - src->path =3D g_strdup(path); - - nservers =3D virJSONValueArraySize(server); - if (nservers =3D=3D 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("at least 1 server is necessary in " - "JSON backing definition for gluster volume")); - - return -1; - } - - src->hosts =3D g_new0(virStorageNetHostDef, nservers); - src->nhosts =3D nservers; - - for (i =3D 0; i < nservers; i++) { - if (virStorageSourceParseBackingJSONSocketAddress(src->hosts + i, - virJSONValueArra= yGet(server, i)) < 0) - return -1; - } - - return 0; -} - - -static int -virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *transport =3D virJSONValueObjectGetString(json, "transport= "); - const char *portal =3D virJSONValueObjectGetString(json, "portal"); - const char *target =3D virJSONValueObjectGetString(json, "target"); - const char *lun =3D virJSONValueObjectGetStringOrNumber(json, "lun"); - const char *uri; - char *port; - - /* legacy URI based syntax passed via 'filename' option */ - if ((uri =3D virJSONValueObjectGetString(json, "filename"))) - return virStorageSourceParseBackingJSONUriStr(src, uri, - VIR_STORAGE_NET_PROT= OCOL_ISCSI); - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_ISCSI; - - if (!lun) - lun =3D "0"; - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (STRNEQ_NULLABLE(transport, "tcp")) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("only TCP transport is supported for iSCSI volume= s")); - return -1; - } - - src->hosts->transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - - if (!portal) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'portal' address in iSCSI backing defini= tion")); - return -1; - } - - if (!target) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'target' in iSCSI backing definition")); - return -1; - } - - src->hosts->name =3D g_strdup(portal); - - if ((port =3D strrchr(src->hosts->name, ':')) && - !strchr(port, ']')) { - if (virStringParsePort(port + 1, &src->hosts->port) < 0) - return -1; - - *port =3D '\0'; - } - - src->path =3D g_strdup_printf("%s/%s", target, lun); - - /* Libvirt doesn't handle inline authentication. Make the caller aware= . */ - if (virJSONValueObjectGetString(json, "user") || - virJSONValueObjectGetString(json, "password")) - return 1; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *path =3D virJSONValueObjectGetString(json, "path"); - const char *host =3D virJSONValueObjectGetString(json, "host"); - const char *port =3D virJSONValueObjectGetString(json, "port"); - const char *export =3D virJSONValueObjectGetString(json, "export"); - virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); - - if (!path && !host && !server) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing host specification of NBD server in JSON= " - "backing volume definition")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_NBD; - - src->path =3D g_strdup(export); - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (server) { - if (virStorageSourceParseBackingJSONSocketAddress(src->hosts, serv= er) < 0) - return -1; - } else { - if (path) { - src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_UNIX; - src->hosts[0].socket =3D g_strdup(path); - } else { - src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - src->hosts[0].name =3D g_strdup(host); - - if (virStringParsePort(port, &src->hosts[0].port) < 0) - return -1; - } - } - - return 0; -} - - -static int -virStorageSourceParseBackingJSONSheepdog(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *filename; - const char *vdi =3D virJSONValueObjectGetString(json, "vdi"); - virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); - - /* legacy URI based syntax passed via 'filename' option */ - if ((filename =3D virJSONValueObjectGetString(json, "filename"))) { - if (strstr(filename, "://")) - return virStorageSourceParseBackingJSONUriStr(src, filename, - VIR_STORAGE_NET_= PROTOCOL_SHEEPDOG); - - /* libvirt doesn't implement a parser for the legacy non-URI synta= x */ - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing sheepdog URI in JSON backing volume defi= nition")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_SHEEPDOG; - - if (!vdi) { - virReportError(VIR_ERR_INVALID_ARG, "%s", _("missing sheepdog vdi = name")); - return -1; - } - - src->path =3D g_strdup(vdi); - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (virStorageSourceParseBackingJSONSocketAddress(src->hosts, server) = < 0) - return -1; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *path =3D virJSONValueObjectGetString(json, "path"); - const char *host =3D virJSONValueObjectGetString(json, "host"); - const char *port =3D virJSONValueObjectGetString(json, "port"); - const char *user =3D virJSONValueObjectGetString(json, "user"); - const char *host_key_check =3D virJSONValueObjectGetString(json, "host= _key_check"); - virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); - - if (!(host || server) || !path) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing host/server or path of SSH JSON backing " - "volume definition")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_SSH; - - src->path =3D g_strdup(path); - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (server) { - if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, - server) < 0) - return -1; - } else { - src->hosts[0].transport =3D VIR_STORAGE_NET_HOST_TRANS_TCP; - src->hosts[0].name =3D g_strdup(host); - - if (virStringParsePort(port, &src->hosts[0].port) < 0) - return -1; - } - - /* these two are parsed just to be passed back as we don't model them = yet */ - src->ssh_user =3D g_strdup(user); - if (STREQ_NULLABLE(host_key_check, "no")) - src->ssh_host_key_check_disabled =3D true; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *filename; - const char *pool =3D virJSONValueObjectGetString(json, "pool"); - const char *image =3D virJSONValueObjectGetString(json, "image"); - const char *conf =3D virJSONValueObjectGetString(json, "conf"); - const char *snapshot =3D virJSONValueObjectGetString(json, "snapshot"); - virJSONValuePtr servers =3D virJSONValueObjectGetArray(json, "server"); - size_t nservers; - size_t i; - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_RBD; - - /* legacy syntax passed via 'filename' option */ - if ((filename =3D virJSONValueObjectGetString(json, "filename"))) - return virStorageSourceParseRBDColonString(filename, src); - - if (!pool || !image) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing pool or image name in ceph backing volum= e " - "JSON specification")); - return -1; - } - - src->volume =3D g_strdup(pool); - src->path =3D g_strdup(image); - src->snapshot =3D g_strdup(snapshot); - src->configFile =3D g_strdup(conf); - - if (servers) { - nservers =3D virJSONValueArraySize(servers); - - src->hosts =3D g_new0(virStorageNetHostDef, nservers); - src->nhosts =3D nservers; - - for (i =3D 0; i < nservers; i++) { - if (virStorageSourceParseBackingJSONInetSocketAddress(src->hos= ts + i, - virJSONV= alueArrayGet(servers, i)) < 0) - return -1; - } - } - - return 0; -} - -static int -virStorageSourceParseBackingJSONRaw(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr, - int opaque G_GNUC_UNUSED) -{ - bool has_offset =3D virJSONValueObjectHasKey(json, "offset"); - bool has_size =3D virJSONValueObjectHasKey(json, "size"); - virJSONValuePtr file; - - if (has_offset || has_size) { - src->sliceStorage =3D g_new0(virStorageSourceSlice, 1); - - if (has_offset && - virJSONValueObjectGetNumberUlong(json, "offset", &src->sliceSt= orage->offset) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("malformed 'offset' property of 'raw' driver"= )); - return -1; - } - - if (has_size && - virJSONValueObjectGetNumberUlong(json, "size", &src->sliceStor= age->size) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("malformed 'size' property of 'raw' driver")); - return -1; - } - } - - /* 'raw' is a format driver so it can have protocol driver children */ - if (!(file =3D virJSONValueObjectGetObject(json, "file"))) { - virReportError(VIR_ERR_INVALID_ARG, - _("JSON backing volume definition '%s' lacks 'file'= object"), - jsonstr); - return -1; - } - - return virStorageSourceParseBackingJSONInternal(src, file, jsonstr, fa= lse); -} - - -static int -virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - const char *vdisk_id =3D virJSONValueObjectGetString(json, "vdisk-id"); - virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); - - if (!vdisk_id || !server) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'vdisk-id' or 'server' attribute in " - "JSON backing definition for VxHS volume")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_VXHS; - - src->path =3D g_strdup(vdisk_id); - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, - server) < 0) - return -1; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONNFS(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - virJSONValuePtr server =3D virJSONValueObjectGetObject(json, "server"); - int uidStore =3D -1; - int gidStore =3D -1; - int gotUID =3D virJSONValueObjectGetNumberInt(json, "user", &uidStore); - int gotGID =3D virJSONValueObjectGetNumberInt(json, "group", &gidStore= ); - - if (!server) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'server' attribute in JSON backing defin= ition for NFS volume")); - return -1; - } - - if (gotUID < 0 || gotGID < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'user' or 'group' attribute in JSON back= ing definition for NFS volume")); - return -1; - } - - src->path =3D g_strdup(virJSONValueObjectGetString(json, "path")); - if (!src->path) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing 'path' attribute in JSON backing definit= ion for NFS volume")); - return -1; - } - - src->nfs_user =3D g_strdup_printf("+%d", uidStore); - src->nfs_group =3D g_strdup_printf("+%d", gidStore); - - src->type =3D VIR_STORAGE_TYPE_NETWORK; - src->protocol =3D VIR_STORAGE_NET_PROTOCOL_NFS; - - src->hosts =3D g_new0(virStorageNetHostDef, 1); - src->nhosts =3D 1; - - if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts, - server) < 0) - return -1; - - return 0; -} - - -static int -virStorageSourceParseBackingJSONNVMe(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr G_GNUC_UNUSED, - int opaque G_GNUC_UNUSED) -{ - g_autoptr(virStorageSourceNVMeDef) nvme =3D g_new0(virStorageSourceNVM= eDef, 1); - const char *device =3D virJSONValueObjectGetString(json, "device"); - - if (!device || virPCIDeviceAddressParse((char *) device, &nvme->pciAdd= r) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing or malformed 'device' field of 'nvme' st= orage")); - return -1; - } - - if (virJSONValueObjectGetNumberUlong(json, "namespace", &nvme->namespc= ) < 0 || - nvme->namespc =3D=3D 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("missing or malformed 'namespace' field of 'nvme'= storage")); - return -1; - } - - src->type =3D VIR_STORAGE_TYPE_NVME; - src->nvme =3D g_steal_pointer(&nvme); - - return 0; -} - - -struct virStorageSourceJSONDriverParser { - const char *drvname; - bool formatdriver; - /** - * The callback gets a pre-allocated storage source @src and the JSON - * object to parse. The callback shall return -1 on error and report e= rror - * 0 on success and 1 in cases when the configuration itself is valid,= but - * can't be converted to libvirt's configuration (e.g. inline authenti= cation - * credentials are present). - */ - int (*func)(virStorageSourcePtr src, virJSONValuePtr json, const char = *jsonstr, int opaque); - int opaque; -}; - -static const struct virStorageSourceJSONDriverParser jsonParsers[] =3D { - {"file", false, virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE= _FILE}, - {"host_device", false, virStorageSourceParseBackingJSONPath, VIR_STORA= GE_TYPE_BLOCK}, - {"host_cdrom", false, virStorageSourceParseBackingJSONPath, VIR_STORAG= E_TYPE_BLOCK}, - {"http", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_HTTP}, - {"https", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_= PROTOCOL_HTTPS}, - {"ftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PR= OTOCOL_FTP}, - {"ftps", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_FTPS}, - {"tftp", false, virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_P= ROTOCOL_TFTP}, - {"gluster", false, virStorageSourceParseBackingJSONGluster, 0}, - {"iscsi", false, virStorageSourceParseBackingJSONiSCSI, 0}, - {"nbd", false, virStorageSourceParseBackingJSONNbd, 0}, - {"sheepdog", false, virStorageSourceParseBackingJSONSheepdog, 0}, - {"ssh", false, virStorageSourceParseBackingJSONSSH, 0}, - {"rbd", false, virStorageSourceParseBackingJSONRBD, 0}, - {"raw", true, virStorageSourceParseBackingJSONRaw, 0}, - {"nfs", false, virStorageSourceParseBackingJSONNFS, 0}, - {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0}, - {"nvme", false, virStorageSourceParseBackingJSONNVMe, 0}, -}; - - - -static int -virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src, - virJSONValuePtr json, - const char *jsonstr, - bool allowformat) -{ - const char *drvname; - size_t i; - - if (!(drvname =3D virJSONValueObjectGetString(json, "driver"))) { - virReportError(VIR_ERR_INVALID_ARG, - _("JSON backing volume definition '%s' lacks driver= name"), - jsonstr); - return -1; - } - - for (i =3D 0; i < G_N_ELEMENTS(jsonParsers); i++) { - if (STRNEQ(drvname, jsonParsers[i].drvname)) - continue; - - if (jsonParsers[i].formatdriver && !allowformat) { - virReportError(VIR_ERR_INVALID_ARG, - _("JSON backing volume definition '%s' must not= have nested format drivers"), - jsonstr); - return -1; - } - - return jsonParsers[i].func(src, json, jsonstr, jsonParsers[i].opaq= ue); - } - - virReportError(VIR_ERR_INTERNAL_ERROR, - _("missing parser implementation for JSON backing volum= e " - "driver '%s'"), drvname); - return -1; -} - - -static int -virStorageSourceParseBackingJSON(virStorageSourcePtr src, - const char *json) -{ - g_autoptr(virJSONValue) root =3D NULL; - g_autoptr(virJSONValue) deflattened =3D NULL; - virJSONValuePtr file =3D NULL; - - if (!(root =3D virJSONValueFromString(json))) - return -1; - - if (!(deflattened =3D virJSONValueObjectDeflatten(root))) - return -1; - - /* There are 2 possible syntaxes: - * 1) json:{"file":{"driver":...}} - * 2) json:{"driver":...} - * Remove the 'file' wrapper object in case 1. - */ - if (!virJSONValueObjectHasKey(deflattened, "driver")) - file =3D virJSONValueObjectGetObject(deflattened, "file"); - - if (!file) - file =3D deflattened; - - return virStorageSourceParseBackingJSONInternal(src, file, json, true); -} - - -/** - * virStorageSourceNewFromBackingAbsolute - * @path: string representing absolute location of a storage source - * @src: filled with virStorageSource object representing @path - * - * Returns 0 on success, 1 if we could parse all location data but @path - * specified other data unrepresentable by libvirt (e.g. inline authentica= tion). - * In both cases @src is filled. On error -1 is returned @src is NULL and = an - * error is reported. - */ -int -virStorageSourceNewFromBackingAbsolute(const char *path, - virStorageSourcePtr *src) -{ - const char *json; - const char *dirpath; - int rc =3D 0; - g_autoptr(virStorageSource) def =3D virStorageSourceNew(); - - *src =3D NULL; - - if (virStorageIsFile(path)) { - def->type =3D VIR_STORAGE_TYPE_FILE; - - def->path =3D g_strdup(path); - } else { - if ((dirpath =3D STRSKIP(path, "fat:"))) { - def->type =3D VIR_STORAGE_TYPE_DIR; - def->format =3D VIR_STORAGE_FILE_FAT; - def->path =3D g_strdup(dirpath); - *src =3D g_steal_pointer(&def); - return 0; - } - - def->type =3D VIR_STORAGE_TYPE_NETWORK; - - VIR_DEBUG("parsing backing store string: '%s'", path); - - /* handle URI formatted backing stores */ - if ((json =3D STRSKIP(path, "json:"))) - rc =3D virStorageSourceParseBackingJSON(def, json); - else if (strstr(path, "://")) - rc =3D virStorageSourceParseBackingURI(def, path); - else - rc =3D virStorageSourceParseBackingColon(def, path); - - if (rc < 0) - return -1; - - virStorageSourceNetworkAssignDefaultPorts(def); - - /* Some of the legacy parsers parse authentication data since they= are - * also used in other places. For backing store detection the - * authentication data would be invalid anyways, so we clear it */ - if (def->auth) { - virStorageAuthDefFree(def->auth); - def->auth =3D NULL; - } - } - - *src =3D g_steal_pointer(&def); - return rc; -} - - -/** - * virStorageSourceNewFromChild: - * @parent: storage source parent - * @child: returned child/backing store definition - * @parentRaw: raw child string (backingStoreRaw) - * - * Creates a storage source which describes the backing image of @parent a= nd - * fills it into @backing depending on the passed parentRaw (backingStoreR= aw) - * and other data. Note that for local storage this function accesses the = file - * to update the actual type of the child store. - * - * Returns 0 on success, 1 if we could parse all location data but the chi= ld - * store specification contained other data unrepresentable by libvirt (e.= g. - * inline authentication). - * In both cases @src is filled. On error -1 is returned @src is NULL and = an - * error is reported. - */ -static int -virStorageSourceNewFromChild(virStorageSourcePtr parent, - const char *parentRaw, - virStorageSourcePtr *child) -{ - struct stat st; - g_autoptr(virStorageSource) def =3D NULL; - int rc =3D 0; - - *child =3D NULL; - - if (virStorageIsRelative(parentRaw)) { - if (!(def =3D virStorageSourceNewFromBackingRelative(parent, paren= tRaw))) - return -1; - } else { - if ((rc =3D virStorageSourceNewFromBackingAbsolute(parentRaw, &def= )) < 0) - return -1; - } - - /* possibly update local type */ - if (def->type =3D=3D VIR_STORAGE_TYPE_FILE) { - if (stat(def->path, &st) =3D=3D 0) { - if (S_ISDIR(st.st_mode)) { - def->type =3D VIR_STORAGE_TYPE_DIR; - def->format =3D VIR_STORAGE_FILE_DIR; - } else if (S_ISBLK(st.st_mode)) { - def->type =3D VIR_STORAGE_TYPE_BLOCK; - } - } - } - - /* copy parent's labelling and other top level stuff */ - if (virStorageSourceInitChainElement(def, parent, true) < 0) - return -1; - - def->detected =3D true; - - *child =3D g_steal_pointer(&def); - return rc; -} - - -int -virStorageSourceNewFromBacking(virStorageSourcePtr parent, - virStorageSourcePtr *backing) -{ - int rc; - - if ((rc =3D virStorageSourceNewFromChild(parent, - parent->backingStoreRaw, - backing)) < 0) - return rc; - - (*backing)->format =3D parent->backingStoreRawFormat; - (*backing)->readonly =3D true; - return rc; -} - - -/** - * @src: disk source definition structure - * @fd: file descriptor - * @sb: stat buffer - * - * Updates src->physical depending on the actual type of storage being use= d. - * To be called for domain storage source reporting as the volume code does - * not set/use the 'type' field for the voldef->source.target - * - * Returns 0 on success, -1 on error. No libvirt errors are reported. - */ -int -virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, - int fd, - struct stat const *sb) -{ - off_t end; - virStorageType actual_type =3D virStorageSourceGetActualType(src); - - switch (actual_type) { - case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_NETWORK: - src->physical =3D sb->st_size; - break; - - case VIR_STORAGE_TYPE_BLOCK: - if ((end =3D lseek(fd, 0, SEEK_END)) =3D=3D (off_t) -1) - return -1; - - src->physical =3D end; - break; - - case VIR_STORAGE_TYPE_DIR: - src->physical =3D 0; - break; - - /* We shouldn't get VOLUME, but the switch requires all cases */ - case VIR_STORAGE_TYPE_VOLUME: - case VIR_STORAGE_TYPE_NVME: - case VIR_STORAGE_TYPE_NONE: - case VIR_STORAGE_TYPE_LAST: - return -1; - } - - return 0; -} - - -/** - * @src: disk source definition structure - * @fd: file descriptor - * @sb: stat buffer - * - * Update the capacity, allocation, physical values for the storage @src - * Shared between the domain storage source for an inactive domain and the - * voldef source target as the result is not affected by the 'type' field. - * - * Returns 0 on success, -1 on error. - */ -int -virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, - int fd, - struct stat const *sb) -{ - /* Get info for normal formats */ - if (S_ISREG(sb->st_mode) || fd =3D=3D -1) { -#ifndef WIN32 - src->allocation =3D (unsigned long long)sb->st_blocks * - (unsigned long long)DEV_BSIZE; -#else - src->allocation =3D sb->st_size; -#endif - /* Regular files may be sparse, so logical size (capacity) is not = same - * as actual allocation above - */ - src->capacity =3D sb->st_size; - - /* Allocation tracks when the file is sparse, physical is the - * last offset of the file. */ - src->physical =3D sb->st_size; - } else if (S_ISDIR(sb->st_mode)) { - src->allocation =3D 0; - src->capacity =3D 0; - src->physical =3D 0; - } else if (fd >=3D 0) { - off_t end; - - /* XXX this is POSIX compliant, but doesn't work for CHAR files, - * only BLOCK. There is a Linux specific ioctl() for getting - * size of both CHAR / BLOCK devices we should check for in - * configure - * - * NB. Because we configure with AC_SYS_LARGEFILE, off_t - * should be 64 bits on all platforms. For block devices, we - * have to seek (safe even if someone else is writing) to - * determine physical size, and assume that allocation is the - * same as physical (but can refine that assumption later if - * qemu is still running). - */ - if ((end =3D lseek(fd, 0, SEEK_END)) =3D=3D (off_t)-1) { - virReportSystemError(errno, - _("failed to seek to end of %s"), src->pa= th); - return -1; - } - src->physical =3D end; - src->allocation =3D end; - src->capacity =3D end; - } - - return 0; -} - - -/** - * @src: disk source definition structure - * @buf: buffer to the storage file header - * @len: length of the storage file header - * - * Update the storage @src capacity. - * - * Returns 0 on success, -1 on error. - */ -int -virStorageSourceUpdateCapacity(virStorageSourcePtr src, - char *buf, - ssize_t len) -{ - int format =3D src->format; - g_autoptr(virStorageSource) meta =3D NULL; - - /* Raw files: capacity is physical size. For all other files: if - * the metadata has a capacity, use that, otherwise fall back to - * physical size. */ - if (format =3D=3D VIR_STORAGE_FILE_NONE) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("no disk format for %s was specified"), - src->path); - return -1; - } - - if (format =3D=3D VIR_STORAGE_FILE_RAW && !src->encryption) { - src->capacity =3D src->physical; - } else if ((meta =3D virStorageFileGetMetadataFromBuf(src->path, buf, - len, format))) { - src->capacity =3D meta->capacity ? meta->capacity : src->physical; - if (src->encryption && meta->encryption) - src->encryption->payload_offset =3D meta->encryption->payload_= offset; - } else { - return -1; - } - - if (src->encryption && src->encryption->payload_offset !=3D -1) - src->capacity -=3D src->encryption->payload_offset * 512; - - return 0; -} - - static char * virStorageFileCanonicalizeFormatPath(char **components, size_t ncomponents, @@ -3414,76 +1644,6 @@ virStorageFileCanonicalizePath(const char *path, } =20 =20 -/** - * virStorageFileRemoveLastPathComponent: - * - * @path: Path string to remove the last component from - * - * Removes the last path component of a path. This function is designed to= be - * called on file paths only (no trailing slashes in @path). Caller is - * responsible to free the returned string. - */ -static char * -virStorageFileRemoveLastPathComponent(const char *path) -{ - char *ret; - - ret =3D g_strdup(NULLSTR_EMPTY(path)); - - virFileRemoveLastComponent(ret); - - return ret; -} - - -/* - * virStorageFileGetRelativeBackingPath: - * - * Resolve relative path to be written to the overlay of @top image when - * collapsing the backing chain between @top and @base. - * - * Returns 0 on success; 1 if backing chain isn't relative and -1 on error. - */ -int -virStorageFileGetRelativeBackingPath(virStorageSourcePtr top, - virStorageSourcePtr base, - char **relpath) -{ - virStorageSourcePtr next; - g_autofree char *tmp =3D NULL; - g_autofree char *path =3D NULL; - - *relpath =3D NULL; - - for (next =3D top; virStorageSourceIsBacking(next); next =3D next->bac= kingStore) { - if (!next->relPath) - return 1; - - if (!(tmp =3D virStorageFileRemoveLastPathComponent(path))) - return -1; - - VIR_FREE(path); - - path =3D g_strdup_printf("%s%s", tmp, next->relPath); - - VIR_FREE(tmp); - - if (next =3D=3D base) - break; - } - - if (next !=3D base) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("failed to resolve relative backing name: " - "base image is not in backing chain")); - return -1; - } - - *relpath =3D g_steal_pointer(&path); - return 0; -} - - /** * virStorageSourceIsRelative: * @src: storage source to check @@ -3636,736 +1796,3 @@ virStorageSourceInitiatorClear(virStorageSourceInit= iatorDefPtr initiator) { VIR_FREE(initiator->iqn); } - -static bool -virStorageFileIsInitialized(const virStorageSource *src) -{ - return src && src->drv; -} - - -/** - * virStorageFileGetBackendForSupportCheck: - * @src: storage source to check support for - * @backend: pointer to the storage backend for @src if it's supported - * - * Returns 0 if @src is not supported by any storage backend currently lin= ked - * 1 if it is supported and -1 on error with an error reported. - */ -static int -virStorageFileGetBackendForSupportCheck(const virStorageSource *src, - virStorageFileBackendPtr *backend) -{ - int actualType; - - - if (!src) { - *backend =3D NULL; - return 0; - } - - if (src->drv) { - virStorageDriverDataPtr drv =3D src->drv; - *backend =3D drv->backend; - return 1; - } - - actualType =3D virStorageSourceGetActualType(src); - - if (virStorageFileBackendForType(actualType, src->protocol, false, bac= kend) < 0) - return -1; - - if (!*backend) - return 0; - - return 1; -} - - -int -virStorageFileSupportsBackingChainTraversal(const virStorageSource *src) -{ - virStorageFileBackendPtr backend; - int rv; - - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) - return rv; - - return backend->storageFileGetUniqueIdentifier && - backend->storageFileRead && - backend->storageFileAccess ? 1 : 0; -} - - -/** - * virStorageFileSupportsSecurityDriver: - * - * @src: a storage file structure - * - * Check if a storage file supports operations needed by the security - * driver to perform labelling - */ -int -virStorageFileSupportsSecurityDriver(const virStorageSource *src) -{ - virStorageFileBackendPtr backend; - int rv; - - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) - return rv; - - return backend->storageFileChown ? 1 : 0; -} - - -/** - * virStorageFileSupportsAccess: - * - * @src: a storage file structure - * - * Check if a storage file supports checking if the storage source is acce= ssible - * for the given vm. - */ -int -virStorageFileSupportsAccess(const virStorageSource *src) -{ - virStorageFileBackendPtr backend; - int rv; - - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) - return rv; - - return backend->storageFileAccess ? 1 : 0; -} - - -/** - * virStorageFileSupportsCreate: - * @src: a storage file structure - * - * Check if the storage driver supports creating storage described by @src - * via virStorageFileCreate. - */ -int -virStorageFileSupportsCreate(const virStorageSource *src) -{ - virStorageFileBackendPtr backend; - int rv; - - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) - return rv; - - return backend->storageFileCreate ? 1 : 0; -} - - -void -virStorageFileDeinit(virStorageSourcePtr src) -{ - virStorageDriverDataPtr drv =3D NULL; - - if (!virStorageFileIsInitialized(src)) - return; - - drv =3D src->drv; - - if (drv->backend && - drv->backend->backendDeinit) - drv->backend->backendDeinit(src); - - VIR_FREE(src->drv); -} - - -/** - * virStorageFileInitAs: - * - * @src: storage source definition - * @uid: uid used to access the file, or -1 for current uid - * @gid: gid used to access the file, or -1 for current gid - * - * Initialize a storage source to be used with storage driver. Use the pro= vided - * uid and gid if possible for the operations. - * - * Returns 0 if the storage file was successfully initialized, -1 if the - * initialization failed. Libvirt error is reported. - */ -int -virStorageFileInitAs(virStorageSourcePtr src, - uid_t uid, gid_t gid) -{ - int actualType =3D virStorageSourceGetActualType(src); - virStorageDriverDataPtr drv =3D g_new0(virStorageDriverData, 1); - - src->drv =3D drv; - - if (uid =3D=3D (uid_t) -1) - drv->uid =3D geteuid(); - else - drv->uid =3D uid; - - if (gid =3D=3D (gid_t) -1) - drv->gid =3D getegid(); - else - drv->gid =3D gid; - - if (virStorageFileBackendForType(actualType, - src->protocol, - true, - &drv->backend) < 0) - goto error; - - if (drv->backend->backendInit && - drv->backend->backendInit(src) < 0) - goto error; - - return 0; - - error: - VIR_FREE(src->drv); - return -1; -} - - -/** - * virStorageFileInit: - * - * See virStorageFileInitAs. The file is initialized to be accessed by the - * current user. - */ -int -virStorageFileInit(virStorageSourcePtr src) -{ - return virStorageFileInitAs(src, -1, -1); -} - - -/** - * virStorageFileCreate: Creates an empty storage file via storage driver - * - * @src: file structure pointing to the file - * - * Returns 0 on success, -2 if the function isn't supported by the backend, - * -1 on other failure. Errno is set in case of failure. - */ -int -virStorageFileCreate(virStorageSourcePtr src) -{ - virStorageDriverDataPtr drv =3D NULL; - int ret; - - if (!virStorageFileIsInitialized(src)) { - errno =3D ENOSYS; - return -2; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileCreate) { - errno =3D ENOSYS; - return -2; - } - - ret =3D drv->backend->storageFileCreate(src); - - VIR_DEBUG("created storage file %p: ret=3D%d, errno=3D%d", - src, ret, errno); - - return ret; -} - - -/** - * virStorageFileUnlink: Unlink storage file via storage driver - * - * @src: file structure pointing to the file - * - * Unlinks the file described by the @file structure. - * - * Returns 0 on success, -2 if the function isn't supported by the backend, - * -1 on other failure. Errno is set in case of failure. - */ -int -virStorageFileUnlink(virStorageSourcePtr src) -{ - virStorageDriverDataPtr drv =3D NULL; - int ret; - - if (!virStorageFileIsInitialized(src)) { - errno =3D ENOSYS; - return -2; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileUnlink) { - errno =3D ENOSYS; - return -2; - } - - ret =3D drv->backend->storageFileUnlink(src); - - VIR_DEBUG("unlinked storage file %p: ret=3D%d, errno=3D%d", - src, ret, errno); - - return ret; -} - - -/** - * virStorageFileStat: returns stat struct of a file via storage driver - * - * @src: file structure pointing to the file - * @stat: stat structure to return data - * - * Returns 0 on success, -2 if the function isn't supported by the backend, - * -1 on other failure. Errno is set in case of failure. -*/ -int -virStorageFileStat(virStorageSourcePtr src, - struct stat *st) -{ - virStorageDriverDataPtr drv =3D NULL; - int ret; - - if (!virStorageFileIsInitialized(src)) { - errno =3D ENOSYS; - return -2; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileStat) { - errno =3D ENOSYS; - return -2; - } - - ret =3D drv->backend->storageFileStat(src, st); - - VIR_DEBUG("stat of storage file %p: ret=3D%d, errno=3D%d", - src, ret, errno); - - return ret; -} - - -/** - * virStorageFileRead: read bytes from a file into a buffer - * - * @src: file structure pointing to the file - * @offset: number of bytes to skip in the storage file - * @len: maximum number of bytes read from the storage file - * @buf: buffer to read the data into. (buffer shall be freed by caller) - * - * Returns the count of bytes read on success and -1 on failure, -2 if the - * function isn't supported by the backend. - * Libvirt error is reported on failure. - */ -ssize_t -virStorageFileRead(virStorageSourcePtr src, - size_t offset, - size_t len, - char **buf) -{ - virStorageDriverDataPtr drv =3D NULL; - ssize_t ret; - - if (!virStorageFileIsInitialized(src)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("storage file backend not initialized")); - return -1; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileRead) - return -2; - - ret =3D drv->backend->storageFileRead(src, offset, len, buf); - - VIR_DEBUG("read '%zd' bytes from storage '%p' starting at offset '%zu'= ", - ret, src, offset); - - return ret; -} - - -/* - * virStorageFileGetUniqueIdentifier: Get a unique string describing the v= olume - * - * @src: file structure pointing to the file - * - * Returns a string uniquely describing a single volume (canonical path). - * The string shall not be freed and is valid until the storage file is - * deinitialized. Returns NULL on error and sets a libvirt error code */ -const char * -virStorageFileGetUniqueIdentifier(virStorageSourcePtr src) -{ - virStorageDriverDataPtr drv =3D NULL; - - if (!virStorageFileIsInitialized(src)) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("storage file backend not initialized")); - return NULL; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileGetUniqueIdentifier) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unique storage file identifier not implemented f= or " - "storage type %s (protocol: %s)'"), - virStorageTypeToString(src->type), - virStorageNetProtocolTypeToString(src->protocol)); - return NULL; - } - - return drv->backend->storageFileGetUniqueIdentifier(src); -} - - -/** - * virStorageFileAccess: Check accessibility of a storage file - * - * @src: storage file to check access permissions - * @mode: accessibility check options (see man 2 access) - * - * Returns 0 on success, -1 on error and sets errno. No libvirt - * error is reported. Returns -2 if the operation isn't supported - * by libvirt storage backend. - */ -int -virStorageFileAccess(virStorageSourcePtr src, - int mode) -{ - virStorageDriverDataPtr drv =3D NULL; - - if (!virStorageFileIsInitialized(src)) { - errno =3D ENOSYS; - return -2; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileAccess) { - errno =3D ENOSYS; - return -2; - } - - return drv->backend->storageFileAccess(src, mode); -} - - -/** - * virStorageFileChown: Change owner of a storage file - * - * @src: storage file to change owner of - * @uid: new owner id - * @gid: new group id - * - * Returns 0 on success, -1 on error and sets errno. No libvirt - * error is reported. Returns -2 if the operation isn't supported - * by libvirt storage backend. - */ -int -virStorageFileChown(const virStorageSource *src, - uid_t uid, - gid_t gid) -{ - virStorageDriverDataPtr drv =3D NULL; - - if (!virStorageFileIsInitialized(src)) { - errno =3D ENOSYS; - return -2; - } - - drv =3D src->drv; - - if (!drv->backend->storageFileChown) { - errno =3D ENOSYS; - return -2; - } - - VIR_DEBUG("chown of storage file %p to %u:%u", - src, (unsigned int)uid, (unsigned int)gid); - - return drv->backend->storageFileChown(src, uid, gid); -} - - -/** - * virStorageFileReportBrokenChain: - * - * @errcode: errno when accessing @src - * @src: inaccessible file in the backing chain of @parent - * @parent: root virStorageSource being checked - * - * Reports the correct error message if @src is missing in the backing cha= in - * for @parent. - */ -void -virStorageFileReportBrokenChain(int errcode, - virStorageSourcePtr src, - virStorageSourcePtr parent) -{ - if (src->drv) { - virStorageDriverDataPtr drv =3D src->drv; - unsigned int access_user =3D drv->uid; - unsigned int access_group =3D drv->gid; - - if (src =3D=3D parent) { - virReportSystemError(errcode, - _("Cannot access storage file '%s' " - "(as uid:%u, gid:%u)"), - src->path, access_user, access_group); - } else { - virReportSystemError(errcode, - _("Cannot access backing file '%s' " - "of storage file '%s' (as uid:%u, gid:%= u)"), - src->path, parent->path, access_user, acc= ess_group); - } - } else { - if (src =3D=3D parent) { - virReportSystemError(errcode, - _("Cannot access storage file '%s'"), - src->path); - } else { - virReportSystemError(errcode, - _("Cannot access backing file '%s' " - "of storage file '%s'"), - src->path, parent->path); - } - } -} - - -static int -virStorageFileGetMetadataRecurseReadHeader(virStorageSourcePtr src, - virStorageSourcePtr parent, - uid_t uid, - gid_t gid, - char **buf, - size_t *headerLen, - GHashTable *cycle) -{ - int ret =3D -1; - const char *uniqueName; - ssize_t len; - - if (virStorageFileInitAs(src, uid, gid) < 0) - return -1; - - if (virStorageFileAccess(src, F_OK) < 0) { - virStorageFileReportBrokenChain(errno, src, parent); - goto cleanup; - } - - if (!(uniqueName =3D virStorageFileGetUniqueIdentifier(src))) - goto cleanup; - - if (virHashHasEntry(cycle, uniqueName)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("backing store for %s (%s) is self-referential"), - NULLSTR(src->path), uniqueName); - goto cleanup; - } - - if (virHashAddEntry(cycle, uniqueName, NULL) < 0) - goto cleanup; - - if ((len =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, buf)) = < 0) - goto cleanup; - - *headerLen =3D len; - ret =3D 0; - - cleanup: - virStorageFileDeinit(src); - return ret; -} - - -/* Recursive workhorse for virStorageFileGetMetadata. */ -static int -virStorageFileGetMetadataRecurse(virStorageSourcePtr src, - virStorageSourcePtr parent, - uid_t uid, gid_t gid, - bool report_broken, - GHashTable *cycle, - unsigned int depth) -{ - virStorageFileFormat orig_format =3D src->format; - size_t headerLen; - int rv; - g_autofree char *buf =3D NULL; - g_autoptr(virStorageSource) backingStore =3D NULL; - - VIR_DEBUG("path=3D%s format=3D%d uid=3D%u gid=3D%u", - NULLSTR(src->path), src->format, - (unsigned int)uid, (unsigned int)gid); - - if (src->format =3D=3D VIR_STORAGE_FILE_AUTO_SAFE) - src->format =3D VIR_STORAGE_FILE_AUTO; - - /* exit if we can't load information about the current image */ - rv =3D virStorageFileSupportsBackingChainTraversal(src); - if (rv <=3D 0) { - if (orig_format =3D=3D VIR_STORAGE_FILE_AUTO) - return -2; - - return rv; - } - - if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid, - &buf, &headerLen, cycle= ) < 0) - return -1; - - if (virStorageFileProbeGetMetadata(src, buf, headerLen) < 0) - return -1; - - /* If we probed the format we MUST ensure that nothing else than the c= urrent - * image is considered for security labelling and/or recursion. */ - if (orig_format =3D=3D VIR_STORAGE_FILE_AUTO) { - if (src->backingStoreRaw) { - src->format =3D VIR_STORAGE_FILE_RAW; - VIR_FREE(src->backingStoreRaw); - return -2; - } - } - - if (src->backingStoreRaw) { - if ((rv =3D virStorageSourceNewFromBacking(src, &backingStore)) < = 0) - return -1; - - /* the backing file would not be usable for VM usage */ - if (rv =3D=3D 1) - return 0; - - if ((rv =3D virStorageFileGetMetadataRecurse(backingStore, parent, - uid, gid, - report_broken, - cycle, depth + 1)) < 0)= { - if (!report_broken) - return 0; - - if (rv =3D=3D -2) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("format of backing image '%s' of image '%= s' was not specified in the image metadata " - "(See https://libvirt.org/kbase/backing_c= hains.html for troubleshooting)"), - src->backingStoreRaw, NULLSTR(src->path)); - } - - return -1; - } - - backingStore->id =3D depth; - src->backingStore =3D g_steal_pointer(&backingStore); - } else { - /* add terminator */ - src->backingStore =3D virStorageSourceNew(); - } - - return 0; -} - - -/** - * virStorageFileGetMetadata: - * - * Extract metadata about the storage volume with the specified - * image format. If image format is VIR_STORAGE_FILE_AUTO, it - * will probe to automatically identify the format. Recurses through - * the entire chain. - * - * Open files using UID and GID (or pass -1 for the current user/group). - * Treat any backing files without explicit type as raw, unless ALLOW_PROB= E. - * - * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a - * format, since a malicious guest can turn a raw file into any - * other non-raw format at will. - * - * If @report_broken is true, the whole function fails with a possibly sane - * error instead of just returning a broken chain. Note that the inability= for - * libvirt to traverse a given source is not considered an error. - * - * Caller MUST free result after use via virObjectUnref. - */ -int -virStorageFileGetMetadata(virStorageSourcePtr src, - uid_t uid, gid_t gid, - bool report_broken) -{ - GHashTable *cycle =3D NULL; - virStorageType actualType =3D virStorageSourceGetActualType(src); - int ret =3D -1; - - VIR_DEBUG("path=3D%s format=3D%d uid=3D%u gid=3D%u report_broken=3D%d", - src->path, src->format, (unsigned int)uid, (unsigned int)gid, - report_broken); - - if (!(cycle =3D virHashNew(NULL))) - return -1; - - if (src->format <=3D VIR_STORAGE_FILE_NONE) { - if (actualType =3D=3D VIR_STORAGE_TYPE_DIR) - src->format =3D VIR_STORAGE_FILE_DIR; - else - src->format =3D VIR_STORAGE_FILE_RAW; - } - - ret =3D virStorageFileGetMetadataRecurse(src, src, uid, gid, - report_broken, cycle, 1); - - virHashFree(cycle); - return ret; -} - - -/** - * virStorageFileGetBackingStoreStr: - * @src: storage object - * - * Extracts the backing store string as stored in the storage volume descr= ibed - * by @src and returns it to the user. Caller is responsible for freeing i= t. - * In case when the string can't be retrieved or does not exist NULL is - * returned. - */ -int -virStorageFileGetBackingStoreStr(virStorageSourcePtr src, - char **backing) -{ - ssize_t headerLen; - int rv; - g_autofree char *buf =3D NULL; - g_autoptr(virStorageSource) tmp =3D NULL; - - *backing =3D NULL; - - /* exit if we can't load information about the current image */ - if (!virStorageFileSupportsBackingChainTraversal(src)) - return 0; - - rv =3D virStorageFileAccess(src, F_OK); - if (rv =3D=3D -2) - return 0; - if (rv < 0) { - virStorageFileReportBrokenChain(errno, src, src); - return -1; - } - - if ((headerLen =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, - &buf)) < 0) { - if (headerLen =3D=3D -2) - return 0; - return -1; - } - - if (!(tmp =3D virStorageSourceCopy(src, false))) - return -1; - - if (virStorageFileProbeGetMetadata(tmp, buf, headerLen) < 0) - return -1; - - *backing =3D g_steal_pointer(&tmp->backingStoreRaw); - return 0; -} diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 27ac6a493f..d6f194a7dd 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -388,18 +388,6 @@ struct _virStorageSource { G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref); =20 =20 -#ifndef DEV_BSIZE -# define DEV_BSIZE 512 -#endif - -virStorageSourcePtr virStorageFileGetMetadataFromFD(const char *path, - int fd, - int format); -virStorageSourcePtr virStorageFileGetMetadataFromBuf(const char *path, - char *buf, - size_t len, - int format) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int virStorageFileParseChainIndex(const char *diskTarget, const char *name, unsigned int *chainIndex) @@ -410,13 +398,6 @@ int virStorageFileParseBackingStoreStr(const char *str, unsigned int *chainIndex) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); =20 -virStorageSourcePtr virStorageFileChainLookup(virStorageSourcePtr chain, - virStorageSourcePtr startFro= m, - const char *name, - unsigned int idx, - virStorageSourcePtr *parent) - ATTRIBUTE_NONNULL(1); - bool virStorageIsFile(const char *path); bool virStorageIsRelative(const char *backing); =20 @@ -469,15 +450,6 @@ bool virStorageSourceIsEmpty(virStorageSourcePtr src); bool virStorageSourceIsBlockLocal(const virStorageSource *src); virStorageSourcePtr virStorageSourceNew(void); void virStorageSourceBackingStoreClear(virStorageSourcePtr def); -int virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, - int fd, struct stat const *sb); -int virStorageSourceUpdateBackingSizes(virStorageSourcePtr src, - int fd, struct stat const *sb); -int virStorageSourceUpdateCapacity(virStorageSourcePtr src, - char *buf, ssize_t len); - -int virStorageSourceNewFromBacking(virStorageSourcePtr parent, - virStorageSourcePtr *backing); =20 int virStorageSourceNetCookiesValidate(virStorageSourcePtr src); =20 @@ -488,10 +460,6 @@ bool virStorageSourceIsSameLocation(virStorageSourcePt= r a, virStorageSourcePtr b) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 -int virStorageSourceParseRBDColonString(const char *rbdstr, - virStorageSourcePtr src) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - typedef int (*virStorageFileSimplifyPathReadlinkCallback)(const char *path, char **link, @@ -500,14 +468,6 @@ char *virStorageFileCanonicalizePath(const char *path, virStorageFileSimplifyPathReadlinkCal= lback cb, void *cbdata); =20 -int virStorageFileGetRelativeBackingPath(virStorageSourcePtr from, - virStorageSourcePtr to, - char **relpath) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); - -int virStorageSourceNewFromBackingAbsolute(const char *path, - virStorageSourcePtr *src); - bool virStorageSourceIsRelative(virStorageSourcePtr src); =20 void @@ -542,39 +502,4 @@ virStorageSourceInitiatorCopy(virStorageSourceInitiato= rDefPtr dest, void virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator); =20 -int virStorageFileInit(virStorageSourcePtr src); -int virStorageFileInitAs(virStorageSourcePtr src, - uid_t uid, gid_t gid); -void virStorageFileDeinit(virStorageSourcePtr src); - -int virStorageFileCreate(virStorageSourcePtr src); -int virStorageFileUnlink(virStorageSourcePtr src); -int virStorageFileStat(virStorageSourcePtr src, - struct stat *stat); -ssize_t virStorageFileRead(virStorageSourcePtr src, - size_t offset, - size_t len, - char **buf); -const char *virStorageFileGetUniqueIdentifier(virStorageSourcePtr src); -int virStorageFileAccess(virStorageSourcePtr src, int mode); -int virStorageFileChown(const virStorageSource *src, uid_t uid, gid_t gid); - -int virStorageFileSupportsSecurityDriver(const virStorageSource *src); -int virStorageFileSupportsAccess(const virStorageSource *src); -int virStorageFileSupportsCreate(const virStorageSource *src); -int virStorageFileSupportsBackingChainTraversal(const virStorageSource *sr= c); - -int virStorageFileGetMetadata(virStorageSourcePtr src, - uid_t uid, gid_t gid, - bool report_broken) - ATTRIBUTE_NONNULL(1); - -int virStorageFileGetBackingStoreStr(virStorageSourcePtr src, - char **backing) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - -void virStorageFileReportBrokenChain(int errcode, - virStorageSourcePtr src, - virStorageSourcePtr parent); - G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageAuthDef, virStorageAuthDefFree); diff --git a/tests/meson.build b/tests/meson.build index 23255dd62a..0de0783839 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -442,7 +442,7 @@ endif if conf.has('WITH_QEMU') tests +=3D [ { 'name': 'qemuagenttest', 'link_with': [ test_qemu_driver_lib, test_u= tils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, - { 'name': 'qemublocktest', 'link_with': [ test_qemu_driver_lib, test_u= tils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, + { 'name': 'qemublocktest', 'include': [ storage_file_inc_dir ], 'link_= with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole':= [ test_utils_qemu_lib ] }, { 'name': 'qemucapabilitiestest', 'link_with': [ test_qemu_driver_lib,= test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, { 'name': 'qemucaps2xmltest', 'link_with': [ test_qemu_driver_lib ], '= link_whole': [ test_utils_qemu_lib ] }, { 'name': 'qemucommandutiltest', 'link_with': [ test_qemu_driver_lib, = test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] }, @@ -509,7 +509,7 @@ endif =20 if conf.has('WITH_STORAGE_FS') tests +=3D [ - { 'name': 'virstoragetest', 'link_with': [ storage_driver_impl_lib ] }, + { 'name': 'virstoragetest', 'include': [ storage_file_inc_dir ],'link_= with': [ storage_driver_impl_lib ] }, ] endif =20 diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index f86e9fd552..ddaf73359d 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -17,6 +17,7 @@ #include =20 =20 +#include "storage_source.h" #include "testutils.h" #include "testutilsqemu.h" #include "testutilsqemuschema.h" diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 86c7cd910c..5c2f211557 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -20,6 +20,7 @@ =20 #include =20 +#include "storage_source.h" #include "testutils.h" #include "vircommand.h" #include "virerror.h" --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257699; cv=none; d=zohomail.com; s=zohoarc; b=HrN7Jyfo2ZC7ZrBb1vc9gUdHTTY6HkdhGGbnSY6RgfNy1Ig2L1dZqSsfXa+LSREisC8e9NMX07afinmwBECBQYy+Oc1QMdLM10DRZ1sYCxrlcPtetmW+rj30QLZzwwLhqiYkdQcwTM2kqeMITofScgEMvhvj4BAl/dkLieyezMI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257699; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rFPSC4V6KYWkj1N2s/gh9iBhcsH4GOdiidvtWh2yVe4=; b=TJAe/hCbuBRAA8OmoGrLXdqnKGogQoNi6VaGMxvjMAxBVCs1qlsp/z10C18BOVoQJWJs7I2+rJI/LJvxL+w/LXIb46LXQknWhsQcf6/Eh9NyAldyyG2akFwQqFlDBmVHaEr53QyJtJMIaaV9MuaVINfgxImiGsuD8OjDOYumQ4I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257699179711.1932703072642; Thu, 21 Jan 2021 11:34:59 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-174-SUsaPf2cMvSLTkS_nKXcFg-1; Thu, 21 Jan 2021 14:34:54 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1C44110766BF; Thu, 21 Jan 2021 19:34:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EA55D61F55; Thu, 21 Jan 2021 19:34:46 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B0D8E1809CA3; Thu, 21 Jan 2021 19:34:46 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYhOA023215 for ; Thu, 21 Jan 2021 14:34:43 -0500 Received: by smtp.corp.redhat.com (Postfix) id CAB6110021AA; Thu, 21 Jan 2021 19:34:43 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id E256210023AE for ; Thu, 21 Jan 2021 19:34:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257697; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=rFPSC4V6KYWkj1N2s/gh9iBhcsH4GOdiidvtWh2yVe4=; b=fhHwj4DcB7tbzGRLoznIawF4eE3nD0fzeoYtpWggmAGt6gqZKfV9PVU2L5RbVy8OSkJT+M hz9TYEhiClTwzc2W9aqNJV/FYYbWJRiU6KBRXQjXy9y/iDzaa2Lh6KPm05wKiOL4unnNLL uDpM9qY0zBGSSvZs+jQbiME2Bb2wkDc= X-MC-Unique: SUsaPf2cMvSLTkS_nKXcFg-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 08/13] util: move virStorageFileBackend code into storage_file Date: Thu, 21 Jan 2021 20:34:22 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" It's used only by storage file code so it doesn't make sense to have it in util directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 2 +- src/libvirt_private.syms | 8 ++++---- src/storage_file/meson.build | 1 + .../storage_file_backend.c} | 4 ++-- .../storage_file_backend.h} | 2 +- src/storage_file/storage_file_fs.c | 2 +- src/storage_file/storage_file_gluster.c | 2 +- src/storage_file/storage_source.c | 2 +- src/util/meson.build | 1 - 9 files changed, 12 insertions(+), 12 deletions(-) rename src/{util/virstoragefilebackend.c =3D> storage_file/storage_file_ba= ckend.c} (97%) rename src/{util/virstoragefilebackend.h =3D> storage_file/storage_file_ba= ckend.h} (97%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 1e47af987d..4da22ede8f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -223,6 +223,7 @@ @SRCDIR@src/storage/storage_backend_zfs.c @SRCDIR@src/storage/storage_driver.c @SRCDIR@src/storage/storage_util.c +@SRCDIR@src/storage_file/storage_file_backend.c @SRCDIR@src/storage_file/storage_file_fs.c @SRCDIR@src/storage_file/storage_file_gluster.c @SRCDIR@src/storage_file/storage_source.c @@ -306,7 +307,6 @@ @SRCDIR@src/util/virsocketaddr.c @SRCDIR@src/util/virstorageencryption.c @SRCDIR@src/util/virstoragefile.c -@SRCDIR@src/util/virstoragefilebackend.c @SRCDIR@src/util/virstoragefileprobe.c @SRCDIR@src/util/virstring.c @SRCDIR@src/util/virsysinfo.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 67a863467d..e7af8f0599 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1618,6 +1618,10 @@ virSecurityManagerVerify; virSecurityXATTRNamespaceDefined; =20 =20 +# storage_file/storage_file_backend.h +virStorageFileBackendRegister; + + # storage_file/storage_source.h virStorageFileAccess; virStorageFileChainLookup; @@ -3210,10 +3214,6 @@ virStorageTypeFromString; virStorageTypeToString; =20 =20 -# util/virstoragefilebackend.h -virStorageFileBackendRegister; - - # util/virstoragefileprobe.h virStorageFileProbeFormat; virStorageFileProbeGetMetadata; diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build index bae018feac..bcd6f01906 100644 --- a/src/storage_file/meson.build +++ b/src/storage_file/meson.build @@ -1,5 +1,6 @@ storage_file_sources =3D [ 'storage_source.c', + 'storage_file_backend.c', ] =20 stoarge_file_fs_sources =3D [ diff --git a/src/util/virstoragefilebackend.c b/src/storage_file/storage_fi= le_backend.c similarity index 97% rename from src/util/virstoragefilebackend.c rename to src/storage_file/storage_file_backend.c index 55c62b0212..6e4b2f408b 100644 --- a/src/util/virstoragefilebackend.c +++ b/src/storage_file/storage_file_backend.c @@ -1,5 +1,5 @@ /* - * virstoragefilebackend.c: internal storage source backend contract + * storage_file_backend.c: internal storage source backend contract * * Copyright (C) 2007-2018 Red Hat, Inc. * Copyright (C) 2007-2008 Daniel P. Berrange @@ -27,7 +27,7 @@ #include "virerror.h" #include "viralloc.h" #include "internal.h" -#include "virstoragefilebackend.h" +#include "storage_file_backend.h" #include "virlog.h" #include "virmodule.h" #include "virfile.h" diff --git a/src/util/virstoragefilebackend.h b/src/storage_file/storage_fi= le_backend.h similarity index 97% rename from src/util/virstoragefilebackend.h rename to src/storage_file/storage_file_backend.h index 43b36e95bc..ad0f66212c 100644 --- a/src/util/virstoragefilebackend.h +++ b/src/storage_file/storage_file_backend.h @@ -1,5 +1,5 @@ /* - * virstoragefilebackend.h: internal storage source backend contract + * storage_file_backend.h: internal storage source backend contract * * Copyright (C) 2007-2018 Red Hat, Inc. * diff --git a/src/storage_file/storage_file_fs.c b/src/storage_file/storage_= file_fs.c index 5a44ef8c2d..1cc9233512 100644 --- a/src/storage_file/storage_file_fs.c +++ b/src/storage_file/storage_file_fs.c @@ -25,9 +25,9 @@ #include =20 #include "virerror.h" +#include "storage_file_backend.h" #include "storage_file_fs.h" #include "storage_util.h" -#include "virstoragefilebackend.h" #include "vircommand.h" #include "viralloc.h" #include "virfile.h" diff --git a/src/storage_file/storage_file_gluster.c b/src/storage_file/sto= rage_file_gluster.c index 2560e10d37..0828088c2c 100644 --- a/src/storage_file/storage_file_gluster.c +++ b/src/storage_file/storage_file_gluster.c @@ -23,12 +23,12 @@ =20 #include =20 +#include "storage_file_backend.h" #include "storage_file_gluster.h" #include "viralloc.h" #include "virerror.h" #include "virlog.h" #include "virstoragefile.h" -#include "virstoragefilebackend.h" #include "virstring.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_s= ource.c index b5e0bc5040..744d3e94fd 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -25,6 +25,7 @@ #include =20 #include "internal.h" +#include "storage_file_backend.h" #include "storage_source.h" #include "viralloc.h" #include "virerror.h" @@ -34,7 +35,6 @@ #include "virlog.h" #include "virobject.h" #include "virstoragefile.h" -#include "virstoragefilebackend.h" #include "virstoragefileprobe.h" #include "virstring.h" #include "viruri.h" diff --git a/src/util/meson.build b/src/util/meson.build index 9fb270fadd..64c0f9df6d 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -90,7 +90,6 @@ util_sources =3D [ 'virsocketaddr.c', 'virstorageencryption.c', 'virstoragefile.c', - 'virstoragefilebackend.c', 'virstoragefileprobe.c', 'virstring.c', 'virsysinfo.c', --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257705; cv=none; d=zohomail.com; s=zohoarc; b=QlKq4PD5I/V9fexHn54ymM7ZGZiY6jWJTofc0L1eCHyDHH049DWr+0GlxivvM77D6fh46JHMmqhCMNdo0LnrUxWO4BIrHTQe2ybkX8jIj8MQejEnS5uNsPBier9wK4lZ+fDPHPGuGj0Lv2YcMlYh51xfuQwOJZrO87rkzt8k5X4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257705; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0CIEmZzkbu2+CIl65DvpElj9Z7eb9GWtPdgd//ybFvE=; b=dK1hnFO7+hVUp4U50MOSCshlFxU5r39OcfAyWS8TfYU6227O9vPLpCYLn9HPf+wSTs9n197YOrdgQ/AasHL9tYCzIqWlHHbN2/h7hnMQuT/bd4y/iEkPAGERwyZH9du7o478+xx/DDQGLX3WDB++W0h3yQGPgTkqcnKLeYAq3xM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257705864998.9642784605117; Thu, 21 Jan 2021 11:35:05 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-142-wKHbNY06P_uHh_8WFVoaJA-1; Thu, 21 Jan 2021 14:35:01 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7771B8030AA; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5572260C6B; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 1E2D450034; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYjbh023230 for ; Thu, 21 Jan 2021 14:34:45 -0500 Received: by smtp.corp.redhat.com (Postfix) id 653781002382; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 63635100AE37 for ; Thu, 21 Jan 2021 19:34:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257704; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=0CIEmZzkbu2+CIl65DvpElj9Z7eb9GWtPdgd//ybFvE=; b=RTozUpdhUGpcT8pICkRMuNF6k3OYZ+YzA4lmBAZHEKvxABaLMoPgWZejL7cASZk2hKoAxk 6L+Y9viVmNzatooSMNPR+PgmgpvNeDwmBZFd7i49lIgjiNIDH862RLmV41J1fkyMrihc8c psmJ86cCmSE085yvZ8MccFrvh/nd2o0= X-MC-Unique: wKHbNY06P_uHh_8WFVoaJA-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 09/13] util: move virStorageFileProbe code into storage_file Date: Thu, 21 Jan 2021 20:34:23 +0100 Message-Id: <32a2d137ed58ef070a4b53afc69ad84a405812ee.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Same as virStorageFileBackend, it doesn't belong into util directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 2 +- src/libvirt_private.syms | 10 +++++----- src/qemu/qemu_driver.c | 2 +- src/storage/storage_backend_gluster.c | 2 +- src/storage/storage_util.c | 2 +- src/storage_file/meson.build | 1 + .../storage_file_probe.c} | 6 +++--- .../storage_file_probe.h} | 2 +- src/storage_file/storage_source.c | 2 +- src/util/meson.build | 1 - 10 files changed, 15 insertions(+), 15 deletions(-) rename src/{util/virstoragefileprobe.c =3D> storage_file/storage_file_prob= e.c} (99%) rename src/{util/virstoragefileprobe.h =3D> storage_file/storage_file_prob= e.h} (95%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 4da22ede8f..eeff3f9f2f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -226,6 +226,7 @@ @SRCDIR@src/storage_file/storage_file_backend.c @SRCDIR@src/storage_file/storage_file_fs.c @SRCDIR@src/storage_file/storage_file_gluster.c +@SRCDIR@src/storage_file/storage_file_probe.c @SRCDIR@src/storage_file/storage_source.c @SRCDIR@src/test/test_driver.c @SRCDIR@src/util/iohelper.c @@ -307,7 +308,6 @@ @SRCDIR@src/util/virsocketaddr.c @SRCDIR@src/util/virstorageencryption.c @SRCDIR@src/util/virstoragefile.c -@SRCDIR@src/util/virstoragefileprobe.c @SRCDIR@src/util/virstring.c @SRCDIR@src/util/virsysinfo.c @SRCDIR@src/util/virsystemd.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e7af8f0599..b49eee3750 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1622,6 +1622,11 @@ virSecurityXATTRNamespaceDefined; virStorageFileBackendRegister; =20 =20 +# storage_file/storage_file_probe.h +virStorageFileProbeFormat; +virStorageFileProbeGetMetadata; + + # storage_file/storage_source.h virStorageFileAccess; virStorageFileChainLookup; @@ -3214,11 +3219,6 @@ virStorageTypeFromString; virStorageTypeToString; =20 =20 -# util/virstoragefileprobe.h -virStorageFileProbeFormat; -virStorageFileProbeGetMetadata; - - # util/virstring.h virSkipSpaces; virSkipSpacesAndBackslash; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a5c2488f2c..5363af3f56 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -83,7 +83,7 @@ #include "domain_nwfilter.h" #include "virhook.h" #include "virstoragefile.h" -#include "virstoragefileprobe.h" +#include "storage_file_probe.h" #include "storage_source.h" #include "virfile.h" #include "virfdstream.h" diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index 782f8eb611..554c76ddb4 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -28,9 +28,9 @@ #include "viralloc.h" #include "virerror.h" #include "virlog.h" -#include "virstoragefileprobe.h" #include "virstring.h" #include "viruri.h" +#include "storage_file_probe.h" #include "storage_util.h" #include "storage_source.h" =20 diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index d51fa2b4c0..04f9a442f2 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -62,7 +62,7 @@ #include "vircrypto.h" #include "viruuid.h" #include "virstoragefile.h" -#include "virstoragefileprobe.h" +#include "storage_file_probe.h" #include "storage_util.h" #include "storage_source.h" #include "virlog.h" diff --git a/src/storage_file/meson.build b/src/storage_file/meson.build index bcd6f01906..eb9453e7b0 100644 --- a/src/storage_file/meson.build +++ b/src/storage_file/meson.build @@ -1,6 +1,7 @@ storage_file_sources =3D [ 'storage_source.c', 'storage_file_backend.c', + 'storage_file_probe.c', ] =20 stoarge_file_fs_sources =3D [ diff --git a/src/util/virstoragefileprobe.c b/src/storage_file/storage_file= _probe.c similarity index 99% rename from src/util/virstoragefileprobe.c rename to src/storage_file/storage_file_probe.c index bca098cd35..e5e1b272ac 100644 --- a/src/util/virstoragefileprobe.c +++ b/src/storage_file/storage_file_probe.c @@ -1,5 +1,5 @@ /* - * virstoragefileprobe.c: file utility functions for FS storage backend + * storage_file_probe.c: file utility functions for FS storage backend * * Copyright (C) 2007-2017 Red Hat, Inc. * Copyright (C) 2007-2008 Daniel P. Berrange @@ -26,17 +26,17 @@ #include =20 #include "internal.h" +#include "storage_file_probe.h" #include "viralloc.h" #include "virbitmap.h" #include "virendian.h" #include "virfile.h" #include "virlog.h" #include "virstoragefile.h" -#include "virstoragefileprobe.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE =20 -VIR_LOG_INIT("util.storagefileprobe"); +VIR_LOG_INIT("storage_file.storagefileprobe"); =20 enum lv_endian { LV_LITTLE_ENDIAN =3D 1, /* 1234 */ diff --git a/src/util/virstoragefileprobe.h b/src/storage_file/storage_file= _probe.h similarity index 95% rename from src/util/virstoragefileprobe.h rename to src/storage_file/storage_file_probe.h index 2b94a4ae51..c443c11606 100644 --- a/src/util/virstoragefileprobe.h +++ b/src/storage_file/storage_file_probe.h @@ -1,5 +1,5 @@ /* - * virstoragefileprobe.h: file utility functions for FS storage backend + * storage_file_probe.h: file utility functions for FS storage backend * * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc. * Copyright (C) 2007-2008 Daniel P. Berrange diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_s= ource.c index 744d3e94fd..d1e0aeb2c1 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -26,6 +26,7 @@ =20 #include "internal.h" #include "storage_file_backend.h" +#include "storage_file_probe.h" #include "storage_source.h" #include "viralloc.h" #include "virerror.h" @@ -35,7 +36,6 @@ #include "virlog.h" #include "virobject.h" #include "virstoragefile.h" -#include "virstoragefileprobe.h" #include "virstring.h" #include "viruri.h" #include "virutil.h" diff --git a/src/util/meson.build b/src/util/meson.build index 64c0f9df6d..b510f0ebe9 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -90,7 +90,6 @@ util_sources =3D [ 'virsocketaddr.c', 'virstorageencryption.c', 'virstoragefile.c', - 'virstoragefileprobe.c', 'virstring.c', 'virsysinfo.c', 'virsystemd.c', --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257702; cv=none; d=zohomail.com; s=zohoarc; b=TGZsgC+KXlqbvX5cwqibL+1GHVOaV3agL05I31IcwGfG1I8D2h31Efb8pfbU4zsEiDc7+lgMQYdZzyqJUOUXSxygWQT7mC/KkcAQFFZ97da8sgtf55qRR+qrZCM0iQ02AM8GfqxdWyBrMFdSFnVCTqXGVFawDQi8ocNeQzikOEw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257702; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=qCDNDOY+MDTpza/L0NaUuWcmIg9qHpgQZ01p+ANGwPY=; b=BD92Ugy7EjIhdd3+jTymzY0TphduDQNz+PZKnf/nlVP7Z5YJtkqrUiuveJK8ZUcSOGZqJJydLqppxrx4H6uLDhg5lZAWCduvG2O39kmaFwNeqdljnYw4QLWXGRyaKQEKvCTYzYuEVgSbtRkjSGg7y9LxorG3+EKIWi9b2ZWJ5rg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257702659659.9716188381109; Thu, 21 Jan 2021 11:35:02 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-572-9uwoUmwUOX--dvBh5hkQVg-1; Thu, 21 Jan 2021 14:34:57 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 281E68030AE; Thu, 21 Jan 2021 19:34:50 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F41B660C6B; Thu, 21 Jan 2021 19:34:49 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B84B31809CA9; Thu, 21 Jan 2021 19:34:49 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYlSF023255 for ; Thu, 21 Jan 2021 14:34:47 -0500 Received: by smtp.corp.redhat.com (Postfix) id 5530E10023B9; Thu, 21 Jan 2021 19:34:47 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id E76B710023AE for ; Thu, 21 Jan 2021 19:34:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257701; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=qCDNDOY+MDTpza/L0NaUuWcmIg9qHpgQZ01p+ANGwPY=; b=JOfRTL6qD8mUhECH73itsuvDw5w2uTy6Lo472cnnUnlpbGNtMgdeqNI86MSL+Vvsl1g5Hv Riw5Q7dtH93uqrQ6s7jAk/C4Fi/bQgKvUcB9ly10qpVpkfQ9wXr+ylyQV/RwJiga1dehn2 TMYRT8alOVKXO8MnBxe5pS/j721zkiE= X-MC-Unique: 9uwoUmwUOX--dvBh5hkQVg-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 10/13] util: move virStorageSource code into conf Date: Thu, 21 Jan 2021 20:34:24 +0100 Message-Id: <23e9464dc92d49a49eb8a3b5f9630de75bc9f427.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" The code handles XML bits and internal definition and should be in conf directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 1 + src/conf/backup_conf.c | 2 +- src/conf/checkpoint_conf.c | 2 +- src/conf/domain_conf.c | 2 +- src/conf/domain_conf.h | 4 +- src/conf/meson.build | 1 + src/conf/snapshot_conf.c | 2 +- src/conf/storage_conf.c | 2 +- src/conf/storage_conf.h | 2 +- src/conf/storage_source_conf.c | 1350 +++++++++++++++++++++++ src/conf/storage_source_conf.h | 537 +++++++++ src/esx/esx_storage_backend_iscsi.c | 2 +- src/esx/esx_storage_backend_vmfs.c | 2 +- src/libvirt_private.syms | 101 +- src/qemu/qemu_backup.c | 2 +- src/qemu/qemu_blockjob.c | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 1 + src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_migration.c | 2 +- src/storage/storage_backend.c | 2 +- src/storage/storage_util.c | 1 + src/storage_file/meson.build | 3 + src/storage_file/storage_file_backend.h | 2 +- src/storage_file/storage_file_probe.c | 2 +- src/storage_file/storage_file_probe.h | 2 +- src/storage_file/storage_source.h | 2 +- src/util/virstoragefile.c | 1308 +--------------------- src/util/virstoragefile.h | 456 +------- 29 files changed, 1968 insertions(+), 1831 deletions(-) create mode 100644 src/conf/storage_source_conf.c create mode 100644 src/conf/storage_source_conf.h diff --git a/po/POTFILES.in b/po/POTFILES.in index eeff3f9f2f..00100d7d73 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,6 +43,7 @@ @SRCDIR@src/conf/snapshot_conf.c @SRCDIR@src/conf/storage_adapter_conf.c @SRCDIR@src/conf/storage_conf.c +@SRCDIR@src/conf/storage_source_conf.c @SRCDIR@src/conf/virchrdev.c @SRCDIR@src/conf/virdomainmomentobjlist.c @SRCDIR@src/conf/virdomainobjlist.c diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c index 90ffcc51d1..ba58b2e322 100644 --- a/src/conf/backup_conf.c +++ b/src/conf/backup_conf.c @@ -26,7 +26,7 @@ #include "virlog.h" #include "viralloc.h" #include "backup_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virfile.h" #include "virerror.h" #include "virxml.h" diff --git a/src/conf/checkpoint_conf.c b/src/conf/checkpoint_conf.c index 7edc7daa12..16fb138a3e 100644 --- a/src/conf/checkpoint_conf.c +++ b/src/conf/checkpoint_conf.c @@ -30,7 +30,7 @@ #include "virlog.h" #include "viralloc.h" #include "checkpoint_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "viruuid.h" #include "virfile.h" #include "virerror.h" diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fcf332fe44..dab4f10326 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -43,7 +43,7 @@ #include "nwfilter_conf.h" #include "virnetworkportdef.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virfile.h" #include "virbitmap.h" #include "secret_conf.h" diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d514f6360f..f5d346ddf0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -48,7 +48,7 @@ #include "virobject.h" #include "device_conf.h" #include "virbitmap.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virseclabel.h" #include "virprocess.h" #include "virgic.h" @@ -359,7 +359,7 @@ struct _virDomainHostdevDef { =20 =20 /* Types of disk frontend (guest view). For backends (host view), see - * virStorageType in util/virstoragefile.h */ + * virStorageType in conf/storage_source_conf.h */ typedef enum { VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM, diff --git a/src/conf/meson.build b/src/conf/meson.build index 8ddcc9968d..9d4831b815 100644 --- a/src/conf/meson.build +++ b/src/conf/meson.build @@ -54,6 +54,7 @@ storage_conf_sources =3D [ 'storage_adapter_conf.c', 'storage_capabilities.c', 'storage_conf.c', + 'storage_source_conf.c', 'virstorageobj.c', ] =20 diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 673282be7a..0b78699589 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -38,7 +38,7 @@ #include "nwfilter_conf.h" #include "secret_conf.h" #include "snapshot_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "viruuid.h" #include "virfile.h" #include "virerror.h" diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0c50529ace..9aed602fd6 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -31,7 +31,7 @@ #include "node_device_conf.h" #include "storage_adapter_conf.h" #include "storage_conf.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" =20 #include "virxml.h" #include "viruuid.h" diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index ffd406e093..aeda2891d4 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -23,7 +23,7 @@ =20 #include "internal.h" #include "virstorageencryption.h" -#include "virstoragefile.h" +#include "storage_source_conf.h" #include "virbitmap.h" #include "virthread.h" #include "device_conf.h" diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c new file mode 100644 index 0000000000..dab5e855f5 --- /dev/null +++ b/src/conf/storage_source_conf.c @@ -0,0 +1,1350 @@ +/* + * storage_source_conf.c: file utility functions for FS storage backend + * + * Copyright (C) 2007-2017 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "storage_source_conf.h" + +#include "viralloc.h" +#include "virbuffer.h" +#include "virerror.h" +#include "virlog.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("conf.storage_source_conf"); + + +static virClassPtr virStorageSourceClass; + + +VIR_ENUM_IMPL(virStorage, + VIR_STORAGE_TYPE_LAST, + "none", + "file", + "block", + "dir", + "network", + "volume", + "nvme", +); + + +VIR_ENUM_IMPL(virStorageFileFormat, + VIR_STORAGE_FILE_LAST, + "none", + "raw", "dir", "bochs", + "cloop", "dmg", "iso", + "vpc", "vdi", + /* Not direct file formats, but used for various drivers */ + "fat", "vhd", "ploop", + /* Formats with backing file below here */ + "cow", "qcow", "qcow2", "qed", "vmdk", +); + + +VIR_ENUM_IMPL(virStorageFileFeature, + VIR_STORAGE_FILE_FEATURE_LAST, + "lazy_refcounts", +); + + +VIR_ENUM_IMPL(virStorageNetProtocol, + VIR_STORAGE_NET_PROTOCOL_LAST, + "none", + "nbd", + "rbd", + "sheepdog", + "gluster", + "iscsi", + "http", + "https", + "ftp", + "ftps", + "tftp", + "ssh", + "vxhs", + "nfs", +); + + +VIR_ENUM_IMPL(virStorageNetHostTransport, + VIR_STORAGE_NET_HOST_TRANS_LAST, + "tcp", + "unix", + "rdma", +); + + +VIR_ENUM_IMPL(virStorageSourcePoolMode, + VIR_STORAGE_SOURCE_POOL_MODE_LAST, + "default", + "host", + "direct", +); + + +VIR_ENUM_IMPL(virStorageAuth, + VIR_STORAGE_AUTH_TYPE_LAST, + "none", "chap", "ceph", +); + + +/** + * virStorageSourceIsBacking: + * @src: storage source + * + * Returns true if @src is a eligible backing store structure. Useful + * for iterators. + */ +bool +virStorageSourceIsBacking(const virStorageSource *src) +{ + return src && src->type !=3D VIR_STORAGE_TYPE_NONE; +} + +/** + * virStorageSourceHasBacking: + * @src: storage source + * + * Returns true if @src has backing store/chain. + */ +bool +virStorageSourceHasBacking(const virStorageSource *src) +{ + return virStorageSourceIsBacking(src) && src->backingStore && + src->backingStore->type !=3D VIR_STORAGE_TYPE_NONE; +} + + +void +virStorageNetHostDefClear(virStorageNetHostDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->name); + VIR_FREE(def->socket); +} + + +void +virStorageNetHostDefFree(size_t nhosts, + virStorageNetHostDefPtr hosts) +{ + size_t i; + + if (!hosts) + return; + + for (i =3D 0; i < nhosts; i++) + virStorageNetHostDefClear(&hosts[i]); + + VIR_FREE(hosts); +} + + +static void +virStoragePermsFree(virStoragePermsPtr def) +{ + if (!def) + return; + + VIR_FREE(def->label); + VIR_FREE(def); +} + + +virStorageNetHostDefPtr +virStorageNetHostDefCopy(size_t nhosts, + virStorageNetHostDefPtr hosts) +{ + virStorageNetHostDefPtr ret =3D NULL; + size_t i; + + ret =3D g_new0(virStorageNetHostDef, nhosts); + + for (i =3D 0; i < nhosts; i++) { + virStorageNetHostDefPtr src =3D &hosts[i]; + virStorageNetHostDefPtr dst =3D &ret[i]; + + dst->transport =3D src->transport; + dst->port =3D src->port; + + dst->name =3D g_strdup(src->name); + dst->socket =3D g_strdup(src->socket); + } + + return ret; +} + + +void +virStorageAuthDefFree(virStorageAuthDefPtr authdef) +{ + if (!authdef) + return; + + VIR_FREE(authdef->username); + VIR_FREE(authdef->secrettype); + virSecretLookupDefClear(&authdef->seclookupdef); + VIR_FREE(authdef); +} + + +virStorageAuthDefPtr +virStorageAuthDefCopy(const virStorageAuthDef *src) +{ + g_autoptr(virStorageAuthDef) authdef =3D NULL; + + authdef =3D g_new0(virStorageAuthDef, 1); + + authdef->username =3D g_strdup(src->username); + /* Not present for storage pool, but used for disk source */ + authdef->secrettype =3D g_strdup(src->secrettype); + authdef->authType =3D src->authType; + + virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef); + + return g_steal_pointer(&authdef); +} + + +virStorageAuthDefPtr +virStorageAuthDefParse(xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + virStorageAuthDefPtr ret =3D NULL; + xmlNodePtr secretnode =3D NULL; + g_autoptr(virStorageAuthDef) authdef =3D NULL; + g_autofree char *authtype =3D NULL; + + ctxt->node =3D node; + + authdef =3D g_new0(virStorageAuthDef, 1); + + if (!(authdef->username =3D virXPathString("string(./@username)", ctxt= ))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing username for auth")); + goto cleanup; + } + + authdef->authType =3D VIR_STORAGE_AUTH_TYPE_NONE; + authtype =3D virXPathString("string(./@type)", ctxt); + if (authtype) { + /* Used by the storage pool instead of the secret type field + * to define whether chap or ceph being used + */ + if ((authdef->authType =3D virStorageAuthTypeFromString(authtype))= < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown auth type '%s'"), authtype); + goto cleanup; + } + } + + if (!(secretnode =3D virXPathNode("./secret ", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing element in auth")); + goto cleanup; + } + + /* Used by the domain disk xml parsing in order to ensure the + * secrettype =3D virXMLPropString(secretnode, "type"); + + if (virSecretLookupParseSecret(secretnode, &authdef->seclookupdef) < 0) + goto cleanup; + + ret =3D g_steal_pointer(&authdef); + + cleanup: + + return ret; +} + + +void +virStorageAuthDefFormat(virBufferPtr buf, + virStorageAuthDefPtr authdef) +{ + if (authdef->authType =3D=3D VIR_STORAGE_AUTH_TYPE_NONE) { + virBufferEscapeString(buf, "\n", authdef->us= ername); + } else { + virBufferAsprintf(buf, "authType)); + virBufferEscapeString(buf, "username=3D'%s'>\n", authdef->username= ); + } + + virBufferAdjustIndent(buf, 2); + virSecretLookupFormatSecret(buf, authdef->secrettype, + &authdef->seclookupdef); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + + +void +virStoragePRDefFree(virStoragePRDefPtr prd) +{ + if (!prd) + return; + + VIR_FREE(prd->path); + VIR_FREE(prd->mgralias); + VIR_FREE(prd); +} + + +virStoragePRDefPtr +virStoragePRDefParseXML(xmlXPathContextPtr ctxt) +{ + virStoragePRDefPtr prd; + virStoragePRDefPtr ret =3D NULL; + g_autofree char *managed =3D NULL; + g_autofree char *type =3D NULL; + g_autofree char *path =3D NULL; + g_autofree char *mode =3D NULL; + + prd =3D g_new0(virStoragePRDef, 1); + + if (!(managed =3D virXPathString("string(./@managed)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing @managed attribute for ")= ); + goto cleanup; + } + + if ((prd->managed =3D virTristateBoolTypeFromString(managed)) <=3D 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid value for 'managed': %s"), managed); + goto cleanup; + } + + type =3D virXPathString("string(./source[1]/@type)", ctxt); + path =3D virXPathString("string(./source[1]/@path)", ctxt); + mode =3D virXPathString("string(./source[1]/@mode)", ctxt); + + if (prd->managed =3D=3D VIR_TRISTATE_BOOL_NO || type || path || mode) { + if (!type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing connection type for "= )); + goto cleanup; + } + + if (!path) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing path for ")); + goto cleanup; + } + + if (!mode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing connection mode for "= )); + goto cleanup; + } + } + + if (type && STRNEQ(type, "unix")) { + virReportError(VIR_ERR_XML_ERROR, + _("unsupported connection type for := %s"), + type); + goto cleanup; + } + + if (mode && STRNEQ(mode, "client")) { + virReportError(VIR_ERR_XML_ERROR, + _("unsupported connection mode for := %s"), + mode); + goto cleanup; + } + + prd->path =3D g_steal_pointer(&path); + ret =3D g_steal_pointer(&prd); + + cleanup: + virStoragePRDefFree(prd); + return ret; +} + + +void +virStoragePRDefFormat(virBufferPtr buf, + virStoragePRDefPtr prd, + bool migratable) +{ + virBufferAsprintf(buf, "managed)); + if (prd->path && + (prd->managed =3D=3D VIR_TRISTATE_BOOL_NO || !migratable)) { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAddLit(buf, "path); + virBufferAddLit(buf, " mode=3D'client'/>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } +} + + +bool +virStoragePRDefIsEqual(virStoragePRDefPtr a, + virStoragePRDefPtr b) +{ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + if (a->managed !=3D b->managed || + STRNEQ_NULLABLE(a->path, b->path)) + return false; + + return true; +} + + +bool +virStoragePRDefIsManaged(virStoragePRDefPtr prd) +{ + return prd && prd->managed =3D=3D VIR_TRISTATE_BOOL_YES; +} + + +bool +virStorageSourceChainHasManagedPR(virStorageSourcePtr src) +{ + virStorageSourcePtr n; + + for (n =3D src; virStorageSourceIsBacking(n); n =3D n->backingStore) { + if (virStoragePRDefIsManaged(n->pr)) + return true; + } + + return false; +} + + +static virStoragePRDefPtr +virStoragePRDefCopy(virStoragePRDefPtr src) +{ + virStoragePRDefPtr copy =3D NULL; + virStoragePRDefPtr ret =3D NULL; + + copy =3D g_new0(virStoragePRDef, 1); + + copy->managed =3D src->managed; + + copy->path =3D g_strdup(src->path); + copy->mgralias =3D g_strdup(src->mgralias); + + ret =3D g_steal_pointer(©); + + virStoragePRDefFree(copy); + return ret; +} + + +static virStorageSourceNVMeDefPtr +virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src) +{ + virStorageSourceNVMeDefPtr ret =3D NULL; + + ret =3D g_new0(virStorageSourceNVMeDef, 1); + + ret->namespc =3D src->namespc; + ret->managed =3D src->managed; + virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr); + return ret; +} + + +static bool +virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a, + const virStorageSourceNVMeDef *b) +{ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + if (a->namespc !=3D b->namespc || + a->managed !=3D b->managed || + !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr)) + return false; + + return true; +} + + +void +virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def); +} + + +bool +virStorageSourceChainHasNVMe(const virStorageSource *src) +{ + const virStorageSource *n; + + for (n =3D src; virStorageSourceIsBacking(n); n =3D n->backingStore) { + if (n->type =3D=3D VIR_STORAGE_TYPE_NVME) + return true; + } + + return false; +} + + +virSecurityDeviceLabelDefPtr +virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, + const char *model) +{ + size_t i; + + for (i =3D 0; i < src->nseclabels; i++) { + if (STREQ_NULLABLE(src->seclabels[i]->model, model)) + return src->seclabels[i]; + } + + return NULL; +} + + +static void +virStorageSourceSeclabelsClear(virStorageSourcePtr def) +{ + size_t i; + + if (def->seclabels) { + for (i =3D 0; i < def->nseclabels; i++) + virSecurityDeviceLabelDefFree(def->seclabels[i]); + VIR_FREE(def->seclabels); + } +} + + +static int +virStorageSourceSeclabelsCopy(virStorageSourcePtr to, + const virStorageSource *from) +{ + size_t i; + + if (from->nseclabels =3D=3D 0) + return 0; + + to->seclabels =3D g_new0(virSecurityDeviceLabelDefPtr, from->nseclabel= s); + to->nseclabels =3D from->nseclabels; + + for (i =3D 0; i < to->nseclabels; i++) { + if (!(to->seclabels[i] =3D virSecurityDeviceLabelDefCopy(from->sec= labels[i]))) + goto error; + } + + return 0; + + error: + virStorageSourceSeclabelsClear(to); + return -1; +} + + +void +virStorageNetCookieDefFree(virStorageNetCookieDefPtr def) +{ + if (!def) + return; + + g_free(def->name); + g_free(def->value); + + g_free(def); +} + + +static void +virStorageSourceNetCookiesClear(virStorageSourcePtr src) +{ + size_t i; + + if (!src || !src->cookies) + return; + + for (i =3D 0; i < src->ncookies; i++) + virStorageNetCookieDefFree(src->cookies[i]); + + g_clear_pointer(&src->cookies, g_free); + src->ncookies =3D 0; +} + + +static void +virStorageSourceNetCookiesCopy(virStorageSourcePtr to, + const virStorageSource *from) +{ + size_t i; + + if (from->ncookies =3D=3D 0) + return; + + to->cookies =3D g_new0(virStorageNetCookieDefPtr, from->ncookies); + to->ncookies =3D from->ncookies; + + for (i =3D 0; i < from->ncookies; i++) { + to->cookies[i]->name =3D g_strdup(from->cookies[i]->name); + to->cookies[i]->value =3D g_strdup(from->cookies[i]->value); + } +} + + +/* see https://tools.ietf.org/html/rfc6265#section-4.1.1 */ +static const char virStorageSourceCookieValueInvalidChars[] =3D + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + " \",;\\"; + +/* in addition cookie name can't contain these */ +static const char virStorageSourceCookieNameInvalidChars[] =3D + "()<>@:/[]?=3D{}"; + +static int +virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def) +{ + g_autofree char *val =3D g_strdup(def->value); + const char *checkval =3D val; + size_t len =3D strlen(val); + + /* name must have at least 1 character */ + if (*(def->name) =3D=3D '\0') { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cookie name must not be empty")); + return -1; + } + + /* check invalid characters in name */ + if (virStringHasChars(def->name, virStorageSourceCookieValueInvalidCha= rs) || + virStringHasChars(def->name, virStorageSourceCookieNameInvalidChar= s)) { + virReportError(VIR_ERR_XML_ERROR, + _("cookie name '%s' contains invalid characters"), + def->name); + return -1; + } + + /* check for optional quotes around the cookie value string */ + if (val[0] =3D=3D '"') { + if (val[len - 1] !=3D '"') { + virReportError(VIR_ERR_XML_ERROR, + _("value of cookie '%s' contains invalid charac= ters"), + def->name); + return -1; + } + + val[len - 1] =3D '\0'; + checkval++; + } + + /* check invalid characters in value */ + if (virStringHasChars(checkval, virStorageSourceCookieValueInvalidChar= s)) { + virReportError(VIR_ERR_XML_ERROR, + _("value of cookie '%s' contains invalid characters= "), + def->name); + return -1; + } + + return 0; +} + + +int +virStorageSourceNetCookiesValidate(virStorageSourcePtr src) +{ + size_t i; + size_t j; + + for (i =3D 0; i < src->ncookies; i++) { + if (virStorageSourceNetCookieValidate(src->cookies[i]) < 0) + return -1; + + for (j =3D i + 1; j < src->ncookies; j++) { + if (STREQ(src->cookies[i]->name, src->cookies[j]->name)) { + virReportError(VIR_ERR_XML_ERROR, _("duplicate cookie '%s'= "), + src->cookies[i]->name); + return -1; + } + } + } + + return 0; +} + + +static virStorageTimestampsPtr +virStorageTimestampsCopy(const virStorageTimestamps *src) +{ + virStorageTimestampsPtr ret; + + ret =3D g_new0(virStorageTimestamps, 1); + + memcpy(ret, src, sizeof(*src)); + + return ret; +} + + +static virStoragePermsPtr +virStoragePermsCopy(const virStoragePerms *src) +{ + virStoragePermsPtr ret; + + ret =3D g_new0(virStoragePerms, 1); + + ret->mode =3D src->mode; + ret->uid =3D src->uid; + ret->gid =3D src->gid; + + ret->label =3D g_strdup(src->label); + + return ret; +} + + +static virStorageSourcePoolDefPtr +virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src) +{ + virStorageSourcePoolDefPtr ret; + + ret =3D g_new0(virStorageSourcePoolDef, 1); + + ret->voltype =3D src->voltype; + ret->pooltype =3D src->pooltype; + ret->actualtype =3D src->actualtype; + ret->mode =3D src->mode; + + ret->pool =3D g_strdup(src->pool); + ret->volume =3D g_strdup(src->volume); + + return ret; +} + + +static virStorageSourceSlicePtr +virStorageSourceSliceCopy(const virStorageSourceSlice *src) +{ + virStorageSourceSlicePtr ret =3D g_new0(virStorageSourceSlice, 1); + + ret->offset =3D src->offset; + ret->size =3D src->size; + ret->nodename =3D g_strdup(src->nodename); + + return ret; +} + + +static void +virStorageSourceSliceFree(virStorageSourceSlicePtr slice) +{ + if (!slice) + return; + + g_free(slice->nodename); + g_free(slice); +} + + +/** + * virStorageSourcePtr: + * + * Deep-copies a virStorageSource structure. If @backing chain is true + * then also copies the backing chain recursively, otherwise just + * the top element is copied. This function doesn't copy the + * storage driver access structure and thus the struct needs to be initial= ized + * separately. + */ +virStorageSourcePtr +virStorageSourceCopy(const virStorageSource *src, + bool backingChain) +{ + g_autoptr(virStorageSource) def =3D virStorageSourceNew(); + + def->id =3D src->id; + def->type =3D src->type; + def->protocol =3D src->protocol; + def->format =3D src->format; + def->capacity =3D src->capacity; + def->allocation =3D src->allocation; + def->has_allocation =3D src->has_allocation; + def->physical =3D src->physical; + def->readonly =3D src->readonly; + def->shared =3D src->shared; + def->haveTLS =3D src->haveTLS; + def->tlsFromConfig =3D src->tlsFromConfig; + def->detected =3D src->detected; + def->debugLevel =3D src->debugLevel; + def->debug =3D src->debug; + def->iomode =3D src->iomode; + def->cachemode =3D src->cachemode; + def->discard =3D src->discard; + def->detect_zeroes =3D src->detect_zeroes; + def->sslverify =3D src->sslverify; + def->readahead =3D src->readahead; + def->timeout =3D src->timeout; + def->metadataCacheMaxSize =3D src->metadataCacheMaxSize; + + /* storage driver metadata are not copied */ + def->drv =3D NULL; + + def->path =3D g_strdup(src->path); + def->volume =3D g_strdup(src->volume); + def->relPath =3D g_strdup(src->relPath); + def->backingStoreRaw =3D g_strdup(src->backingStoreRaw); + def->backingStoreRawFormat =3D src->backingStoreRawFormat; + def->snapshot =3D g_strdup(src->snapshot); + def->configFile =3D g_strdup(src->configFile); + def->nodeformat =3D g_strdup(src->nodeformat); + def->nodestorage =3D g_strdup(src->nodestorage); + def->compat =3D g_strdup(src->compat); + def->tlsAlias =3D g_strdup(src->tlsAlias); + def->tlsCertdir =3D g_strdup(src->tlsCertdir); + def->query =3D g_strdup(src->query); + + if (src->sliceStorage) + def->sliceStorage =3D virStorageSourceSliceCopy(src->sliceStorage); + + if (src->nhosts) { + if (!(def->hosts =3D virStorageNetHostDefCopy(src->nhosts, src->ho= sts))) + return NULL; + + def->nhosts =3D src->nhosts; + } + + virStorageSourceNetCookiesCopy(def, src); + + if (src->srcpool && + !(def->srcpool =3D virStorageSourcePoolDefCopy(src->srcpool))) + return NULL; + + if (src->features) + def->features =3D virBitmapNewCopy(src->features); + + if (src->encryption && + !(def->encryption =3D virStorageEncryptionCopy(src->encryption))) + return NULL; + + if (src->perms && + !(def->perms =3D virStoragePermsCopy(src->perms))) + return NULL; + + if (src->timestamps && + !(def->timestamps =3D virStorageTimestampsCopy(src->timestamps))) + return NULL; + + if (virStorageSourceSeclabelsCopy(def, src) < 0) + return NULL; + + if (src->auth && + !(def->auth =3D virStorageAuthDefCopy(src->auth))) + return NULL; + + if (src->pr && + !(def->pr =3D virStoragePRDefCopy(src->pr))) + return NULL; + + if (src->nvme) + def->nvme =3D virStorageSourceNVMeDefCopy(src->nvme); + + if (virStorageSourceInitiatorCopy(&def->initiator, &src->initiator) < = 0) + return NULL; + + if (backingChain && src->backingStore) { + if (!(def->backingStore =3D virStorageSourceCopy(src->backingStore, + true))) + return NULL; + } + + /* ssh config passthrough for libguestfs */ + def->ssh_host_key_check_disabled =3D src->ssh_host_key_check_disabled; + def->ssh_user =3D g_strdup(src->ssh_user); + + def->nfs_user =3D g_strdup(src->nfs_user); + def->nfs_group =3D g_strdup(src->nfs_group); + def->nfs_uid =3D src->nfs_uid; + def->nfs_gid =3D src->nfs_gid; + + return g_steal_pointer(&def); +} + + +/** + * virStorageSourceIsSameLocation: + * + * Returns true if the sources @a and @b point to the same storage locatio= n. + * This does not compare any other configuration option + */ +bool +virStorageSourceIsSameLocation(virStorageSourcePtr a, + virStorageSourcePtr b) +{ + size_t i; + + /* there are multiple possibilities to define an empty source */ + if (virStorageSourceIsEmpty(a) && + virStorageSourceIsEmpty(b)) + return true; + + if (virStorageSourceGetActualType(a) !=3D virStorageSourceGetActualTyp= e(b)) + return false; + + if (STRNEQ_NULLABLE(a->path, b->path) || + STRNEQ_NULLABLE(a->volume, b->volume) || + STRNEQ_NULLABLE(a->snapshot, b->snapshot)) + return false; + + if (a->type =3D=3D VIR_STORAGE_TYPE_NETWORK) { + if (a->protocol !=3D b->protocol || + a->nhosts !=3D b->nhosts) + return false; + + for (i =3D 0; i < a->nhosts; i++) { + if (a->hosts[i].transport !=3D b->hosts[i].transport || + a->hosts[i].port !=3D b->hosts[i].port || + STRNEQ_NULLABLE(a->hosts[i].name, b->hosts[i].name) || + STRNEQ_NULLABLE(a->hosts[i].socket, b->hosts[i].socket)) + return false; + } + } + + if (a->type =3D=3D VIR_STORAGE_TYPE_NVME && + !virStorageSourceNVMeDefIsEqual(a->nvme, b->nvme)) + return false; + + return true; +} + + +/** + * virStorageSourceInitChainElement: + * @newelem: New backing chain element disk source + * @old: Existing top level disk source + * @transferLabels: Transfer security labels. + * + * Transfers relevant information from the existing disk source to the new + * backing chain element if they weren't supplied so that labelling info + * and possibly other stuff is correct. + * + * If @transferLabels is true, security labels from the existing disk are = copied + * to the new disk. Otherwise the default domain imagelabel label will be = used. + * + * Returns 0 on success, -1 on error. + */ +int +virStorageSourceInitChainElement(virStorageSourcePtr newelem, + virStorageSourcePtr old, + bool transferLabels) +{ + if (transferLabels && + !newelem->seclabels && + virStorageSourceSeclabelsCopy(newelem, old) < 0) + return -1; + + newelem->shared =3D old->shared; + newelem->readonly =3D old->readonly; + + return 0; +} + + +void +virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->pool); + VIR_FREE(def->volume); + + VIR_FREE(def); +} + + +/** + * virStorageSourceGetActualType: + * @def: storage source definition + * + * Returns type of @def. In case when the type is VIR_STORAGE_TYPE_VOLUME + * and virDomainDiskTranslateSourcePool was called on @def the actual type + * of the storage volume is returned rather than VIR_STORAGE_TYPE_VOLUME. + */ +int +virStorageSourceGetActualType(const virStorageSource *def) +{ + if (def->type =3D=3D VIR_STORAGE_TYPE_VOLUME && + def->srcpool && + def->srcpool->actualtype !=3D VIR_STORAGE_TYPE_NONE) + return def->srcpool->actualtype; + + return def->type; +} + + +bool +virStorageSourceIsLocalStorage(const virStorageSource *src) +{ + virStorageType type =3D virStorageSourceGetActualType(src); + + switch (type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + return true; + + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + /* While NVMe disks are local, they are not accessible via src->pa= th. + * Therefore, we have to return false here. */ + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_LAST: + case VIR_STORAGE_TYPE_NONE: + return false; + } + + return false; +} + + +/** + * virStorageSourceIsEmpty: + * + * @src: disk source to check + * + * Returns true if the guest disk has no associated host storage source + * (such as an empty cdrom drive). + */ +bool +virStorageSourceIsEmpty(virStorageSourcePtr src) +{ + if (virStorageSourceIsLocalStorage(src) && !src->path) + return true; + + if (src->type =3D=3D VIR_STORAGE_TYPE_NONE) + return true; + + if (src->type =3D=3D VIR_STORAGE_TYPE_NETWORK && + src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_NONE) + return true; + + return false; +} + + +/** + * virStorageSourceIsBlockLocal: + * @src: disk source definition + * + * Returns true if @src describes a locally accessible block storage sourc= e. + * This includes block devices and host-mapped iSCSI volumes. + */ +bool +virStorageSourceIsBlockLocal(const virStorageSource *src) +{ + return virStorageSourceGetActualType(src) =3D=3D VIR_STORAGE_TYPE_BLOC= K; +} + + +/** + * virStorageSourceBackingStoreClear: + * + * @src: disk source to clear + * + * Clears information about backing store of the current storage file. + */ +void +virStorageSourceBackingStoreClear(virStorageSourcePtr def) +{ + if (!def) + return; + + VIR_FREE(def->relPath); + VIR_FREE(def->backingStoreRaw); + + /* recursively free backing chain */ + virObjectUnref(def->backingStore); + def->backingStore =3D NULL; +} + + +void +virStorageSourceClear(virStorageSourcePtr def) +{ + if (!def) + return; + + VIR_FREE(def->path); + VIR_FREE(def->volume); + VIR_FREE(def->snapshot); + VIR_FREE(def->configFile); + VIR_FREE(def->query); + virStorageSourceNetCookiesClear(def); + virStorageSourcePoolDefFree(def->srcpool); + virBitmapFree(def->features); + VIR_FREE(def->compat); + virStorageEncryptionFree(def->encryption); + virStoragePRDefFree(def->pr); + virStorageSourceNVMeDefFree(def->nvme); + virStorageSourceSeclabelsClear(def); + virStoragePermsFree(def->perms); + VIR_FREE(def->timestamps); + + virStorageSourceSliceFree(def->sliceStorage); + + virStorageNetHostDefFree(def->nhosts, def->hosts); + virStorageAuthDefFree(def->auth); + virObjectUnref(def->privateData); + + VIR_FREE(def->nodestorage); + VIR_FREE(def->nodeformat); + + virStorageSourceBackingStoreClear(def); + + VIR_FREE(def->tlsAlias); + VIR_FREE(def->tlsCertdir); + + VIR_FREE(def->ssh_user); + + VIR_FREE(def->nfs_user); + VIR_FREE(def->nfs_group); + + virStorageSourceInitiatorClear(&def->initiator); + + /* clear everything except the class header as the object APIs + * will break otherwise */ + memset((char *) def + sizeof(def->parent), 0, + sizeof(*def) - sizeof(def->parent)); +} + + +static void +virStorageSourceDispose(void *obj) +{ + virStorageSourcePtr src =3D obj; + + virStorageSourceClear(src); +} + + +static int +virStorageSourceOnceInit(void) +{ + if (!VIR_CLASS_NEW(virStorageSource, virClassForObject())) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virStorageSource); + + +virStorageSourcePtr +virStorageSourceNew(void) +{ + virStorageSourcePtr ret; + + if (virStorageSourceInitialize() < 0) + abort(); + + if (!(ret =3D virObjectNew(virStorageSourceClass))) + abort(); + + return ret; +} + + +/** + * virStorageSourceIsRelative: + * @src: storage source to check + * + * Returns true if given storage source definition is a relative path. + */ +bool +virStorageSourceIsRelative(virStorageSourcePtr src) +{ + virStorageType actual_type =3D virStorageSourceGetActualType(src); + + if (!src->path) + return false; + + switch (actual_type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + return src->path[0] !=3D '/'; + + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return false; + } + + return false; +} + + +static unsigned int +virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol) +{ + switch (protocol) { + case VIR_STORAGE_NET_PROTOCOL_HTTP: + return 80; + + case VIR_STORAGE_NET_PROTOCOL_HTTPS: + return 443; + + case VIR_STORAGE_NET_PROTOCOL_FTP: + return 21; + + case VIR_STORAGE_NET_PROTOCOL_FTPS: + return 990; + + case VIR_STORAGE_NET_PROTOCOL_TFTP: + return 69; + + case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: + return 7000; + + case VIR_STORAGE_NET_PROTOCOL_NBD: + return 10809; + + case VIR_STORAGE_NET_PROTOCOL_SSH: + return 22; + + case VIR_STORAGE_NET_PROTOCOL_ISCSI: + return 3260; + + case VIR_STORAGE_NET_PROTOCOL_GLUSTER: + return 24007; + + case VIR_STORAGE_NET_PROTOCOL_RBD: + /* we don't provide a default for RBD */ + return 0; + + case VIR_STORAGE_NET_PROTOCOL_VXHS: + return 9999; + + case VIR_STORAGE_NET_PROTOCOL_NFS: + /* Port is not supported by NFS, so no default is provided */ + return 0; + + case VIR_STORAGE_NET_PROTOCOL_LAST: + case VIR_STORAGE_NET_PROTOCOL_NONE: + return 0; + } + + return 0; +} + + +void +virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) +{ + size_t i; + + for (i =3D 0; i < src->nhosts; i++) { + if (src->hosts[i].transport =3D=3D VIR_STORAGE_NET_HOST_TRANS_TCP = && + src->hosts[i].port =3D=3D 0) + src->hosts[i].port =3D virStorageSourceNetworkDefaultPort(src-= >protocol); + } +} + + +int +virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, + virStorageSourcePtr src) +{ + src->relPath =3D virXPathString("string(./relPath)", ctxt); + return 0; +} + + +int +virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, + virBufferPtr buf) +{ + if (src->relPath) + virBufferEscapeString(buf, "%s\n", src->relPath= ); + + return 0; +} + + +void +virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, + virStorageSourceInitiatorDefPtr initiato= r) +{ + initiator->iqn =3D virXPathString("string(./initiator/iqn/@name)", ctx= t); +} + + +void +virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiat= or, + virBufferPtr buf) +{ + if (!initiator->iqn) + return; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferEscapeString(buf, "\n", initiator->iqn); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + + +int +virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, + const virStorageSourceInitiatorDef *src) +{ + dest->iqn =3D g_strdup(src->iqn); + return 0; +} + + +void +virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator) +{ + VIR_FREE(initiator->iqn); +} diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h new file mode 100644 index 0000000000..6f39ab4bd0 --- /dev/null +++ b/src/conf/storage_source_conf.h @@ -0,0 +1,537 @@ +/* + * storage_source_conf.h: file utility functions for FS storage backend + * + * Copyright (C) 2007-2009, 2012-2016 Red Hat, Inc. + * Copyright (C) 2007-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "virbitmap.h" +#include "virenum.h" +#include "virobject.h" +#include "virpci.h" +#include "virseclabel.h" +#include "virsecret.h" +#include "virstorageencryption.h" + +/* Types of disk backends (host resource). Comparable to the public + * virStorageVolType, except we have an undetermined state, don't have + * a netdir type, and add a volume type for reference through a + * storage pool. */ +typedef enum { + VIR_STORAGE_TYPE_NONE, + VIR_STORAGE_TYPE_FILE, + VIR_STORAGE_TYPE_BLOCK, + VIR_STORAGE_TYPE_DIR, + VIR_STORAGE_TYPE_NETWORK, + VIR_STORAGE_TYPE_VOLUME, + VIR_STORAGE_TYPE_NVME, + + VIR_STORAGE_TYPE_LAST +} virStorageType; + +VIR_ENUM_DECL(virStorage); + + +typedef enum { + VIR_STORAGE_FILE_AUTO_SAFE =3D -2, + VIR_STORAGE_FILE_AUTO =3D -1, + VIR_STORAGE_FILE_NONE =3D 0, + VIR_STORAGE_FILE_RAW, + VIR_STORAGE_FILE_DIR, + VIR_STORAGE_FILE_BOCHS, + VIR_STORAGE_FILE_CLOOP, + VIR_STORAGE_FILE_DMG, + VIR_STORAGE_FILE_ISO, + VIR_STORAGE_FILE_VPC, + VIR_STORAGE_FILE_VDI, + + /* Not direct file formats, but used for various drivers */ + VIR_STORAGE_FILE_FAT, + VIR_STORAGE_FILE_VHD, + VIR_STORAGE_FILE_PLOOP, + + /* Not a format, but a marker: all formats below this point have + * libvirt support for following a backing chain */ + VIR_STORAGE_FILE_BACKING, + + VIR_STORAGE_FILE_COW =3D VIR_STORAGE_FILE_BACKING, + VIR_STORAGE_FILE_QCOW, + VIR_STORAGE_FILE_QCOW2, + VIR_STORAGE_FILE_QED, + VIR_STORAGE_FILE_VMDK, + + VIR_STORAGE_FILE_LAST, +} virStorageFileFormat; + +VIR_ENUM_DECL(virStorageFileFormat); + + +typedef enum { + VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS =3D 0, + + VIR_STORAGE_FILE_FEATURE_LAST +} virStorageFileFeature; + +VIR_ENUM_DECL(virStorageFileFeature); + + +typedef struct _virStoragePerms virStoragePerms; +typedef virStoragePerms *virStoragePermsPtr; +struct _virStoragePerms { + mode_t mode; + uid_t uid; + gid_t gid; + char *label; +}; + + +typedef struct _virStorageTimestamps virStorageTimestamps; +typedef virStorageTimestamps *virStorageTimestampsPtr; +struct _virStorageTimestamps { + struct timespec atime; + struct timespec btime; /* birth time unknown if btime.tv_nsec =3D=3D -= 1 */ + struct timespec ctime; + struct timespec mtime; +}; + + +/* Information related to network storage */ +typedef enum { + VIR_STORAGE_NET_PROTOCOL_NONE, + VIR_STORAGE_NET_PROTOCOL_NBD, + VIR_STORAGE_NET_PROTOCOL_RBD, + VIR_STORAGE_NET_PROTOCOL_SHEEPDOG, + VIR_STORAGE_NET_PROTOCOL_GLUSTER, + VIR_STORAGE_NET_PROTOCOL_ISCSI, + VIR_STORAGE_NET_PROTOCOL_HTTP, + VIR_STORAGE_NET_PROTOCOL_HTTPS, + VIR_STORAGE_NET_PROTOCOL_FTP, + VIR_STORAGE_NET_PROTOCOL_FTPS, + VIR_STORAGE_NET_PROTOCOL_TFTP, + VIR_STORAGE_NET_PROTOCOL_SSH, + VIR_STORAGE_NET_PROTOCOL_VXHS, + VIR_STORAGE_NET_PROTOCOL_NFS, + + VIR_STORAGE_NET_PROTOCOL_LAST +} virStorageNetProtocol; + +VIR_ENUM_DECL(virStorageNetProtocol); + + +typedef enum { + VIR_STORAGE_NET_HOST_TRANS_TCP, + VIR_STORAGE_NET_HOST_TRANS_UNIX, + VIR_STORAGE_NET_HOST_TRANS_RDMA, + + VIR_STORAGE_NET_HOST_TRANS_LAST +} virStorageNetHostTransport; + +VIR_ENUM_DECL(virStorageNetHostTransport); + + +typedef struct _virStorageNetHostDef virStorageNetHostDef; +typedef virStorageNetHostDef *virStorageNetHostDefPtr; +struct _virStorageNetHostDef { + char *name; + unsigned int port; + int transport; /* virStorageNetHostTransport */ + char *socket; /* path to unix socket */ +}; + + +typedef struct _virStorageNetCookieDef virStorageNetCookieDef; +typedef virStorageNetCookieDef *virStorageNetCookieDefPtr; +struct _virStorageNetCookieDef { + char *name; + char *value; +}; + + +void +virStorageNetCookieDefFree(virStorageNetCookieDefPtr def); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageNetCookieDef, virStorageNetCookieD= efFree); + + +/* Information for a storage volume from a virStoragePool */ + +/* + * Used for volume "type" disk to indicate how to represent + * the disk source if the specified "pool" is of iscsi type. + */ +typedef enum { + VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT =3D 0, + + /* Use the path as it shows up on host, e.g. + * /dev/disk/by-path/ip-$ip-iscsi-$iqn:iscsi.iscsi-pool0-lun-1 + */ + VIR_STORAGE_SOURCE_POOL_MODE_HOST, + + /* Use the URI from the storage pool source element host attribute. E.= g. + * file=3Discsi://demo.org:6000/iqn.1992-01.com.example/1. + */ + VIR_STORAGE_SOURCE_POOL_MODE_DIRECT, + + VIR_STORAGE_SOURCE_POOL_MODE_LAST +} virStorageSourcePoolMode; + +VIR_ENUM_DECL(virStorageSourcePoolMode); + + +typedef struct _virStorageSourcePoolDef virStorageSourcePoolDef; +typedef virStorageSourcePoolDef *virStorageSourcePoolDefPtr; +struct _virStorageSourcePoolDef { + char *pool; /* pool name */ + char *volume; /* volume name */ + int voltype; /* virStorageVolType, internal only */ + int pooltype; /* virStoragePoolType from storage_conf.h, internal only= */ + int actualtype; /* virStorageType, internal only */ + int mode; /* virStorageSourcePoolMode, currently makes sense only for = iscsi pool */ +}; + + +typedef enum { + VIR_STORAGE_AUTH_TYPE_NONE, + VIR_STORAGE_AUTH_TYPE_CHAP, + VIR_STORAGE_AUTH_TYPE_CEPHX, + + VIR_STORAGE_AUTH_TYPE_LAST, +} virStorageAuthType; + +VIR_ENUM_DECL(virStorageAuth); + + +typedef struct _virStorageAuthDef virStorageAuthDef; +typedef virStorageAuthDef *virStorageAuthDefPtr; +struct _virStorageAuthDef { + char *username; + char *secrettype; /* =20 -#include "virstoragefile.h" +#include "storage_source_conf.h" =20 /* ------- virStorageFile backends ------------ */ typedef struct _virStorageFileBackend virStorageFileBackend; diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/stora= ge_file_probe.c index e5e1b272ac..29baa0596f 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -27,12 +27,12 @@ =20 #include "internal.h" #include "storage_file_probe.h" +#include "storage_source_conf.h" #include "viralloc.h" #include "virbitmap.h" #include "virendian.h" #include "virfile.h" #include "virlog.h" -#include "virstoragefile.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE =20 diff --git a/src/storage_file/storage_file_probe.h b/src/storage_file/stora= ge_file_probe.h index c443c11606..0d0ac38185 100644 --- a/src/storage_file/storage_file_probe.h +++ b/src/storage_file/storage_file_probe.h @@ -23,7 +23,7 @@ =20 #include =20 -#include "virstoragefile.h" +#include "storage_source_conf.h" =20 /* Minimum header size required to probe all known formats with * virStorageFileProbeFormat, or obtain metadata from a known format. diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_s= ource.h index 23f56417a8..5d6ad4606d 100644 --- a/src/storage_file/storage_source.h +++ b/src/storage_file/storage_source.h @@ -21,7 +21,7 @@ =20 #pragma once =20 -#include "virstoragefile.h" +#include "storage_source_conf.h" =20 #ifndef DEV_BSIZE # define DEV_BSIZE 512 diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index c70d5713de..85ccd9f52c 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -23,89 +23,19 @@ #include "virstoragefile.h" =20 #include "viralloc.h" -#include "virxml.h" #include "viruuid.h" #include "virerror.h" #include "virlog.h" -#include "virfile.h" #include "vircommand.h" #include "virhash.h" #include "virstring.h" #include "virbuffer.h" -#include "virstorageencryption.h" #include "virsecret.h" =20 #define VIR_FROM_THIS VIR_FROM_STORAGE =20 VIR_LOG_INIT("util.storagefile"); =20 -static virClassPtr virStorageSourceClass; - -VIR_ENUM_IMPL(virStorage, - VIR_STORAGE_TYPE_LAST, - "none", - "file", - "block", - "dir", - "network", - "volume", - "nvme", -); - -VIR_ENUM_IMPL(virStorageFileFormat, - VIR_STORAGE_FILE_LAST, - "none", - "raw", "dir", "bochs", - "cloop", "dmg", "iso", - "vpc", "vdi", - /* Not direct file formats, but used for various drivers */ - "fat", "vhd", "ploop", - /* Formats with backing file below here */ - "cow", "qcow", "qcow2", "qed", "vmdk", -); - -VIR_ENUM_IMPL(virStorageFileFeature, - VIR_STORAGE_FILE_FEATURE_LAST, - "lazy_refcounts", -); - -VIR_ENUM_IMPL(virStorageNetProtocol, - VIR_STORAGE_NET_PROTOCOL_LAST, - "none", - "nbd", - "rbd", - "sheepdog", - "gluster", - "iscsi", - "http", - "https", - "ftp", - "ftps", - "tftp", - "ssh", - "vxhs", - "nfs", -); - -VIR_ENUM_IMPL(virStorageNetHostTransport, - VIR_STORAGE_NET_HOST_TRANS_LAST, - "tcp", - "unix", - "rdma", -); - -VIR_ENUM_IMPL(virStorageSourcePoolMode, - VIR_STORAGE_SOURCE_POOL_MODE_LAST, - "default", - "host", - "direct", -); - -VIR_ENUM_IMPL(virStorageAuth, - VIR_STORAGE_AUTH_TYPE_LAST, - "none", "chap", "ceph", -); - =20 bool virStorageIsFile(const char *backing) @@ -278,6 +208,7 @@ int virStorageFileGetNPIVKey(const char *path G_GNUC_UN= USED, } #endif =20 + /** * virStorageFileParseBackingStoreStr: * @str: backing store specifier string to parse @@ -351,1089 +282,6 @@ virStorageFileParseChainIndex(const char *diskTarget, } =20 =20 -/** - * virStorageSourceIsBacking: - * @src: storage source - * - * Returns true if @src is a eligible backing store structure. Useful - * for iterators. - */ -bool -virStorageSourceIsBacking(const virStorageSource *src) -{ - return src && src->type !=3D VIR_STORAGE_TYPE_NONE; -} - -/** - * virStorageSourceHasBacking: - * @src: storage source - * - * Returns true if @src has backing store/chain. - */ -bool -virStorageSourceHasBacking(const virStorageSource *src) -{ - return virStorageSourceIsBacking(src) && src->backingStore && - src->backingStore->type !=3D VIR_STORAGE_TYPE_NONE; -} - - -void -virStorageNetHostDefClear(virStorageNetHostDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def->name); - VIR_FREE(def->socket); -} - - -void -virStorageNetHostDefFree(size_t nhosts, - virStorageNetHostDefPtr hosts) -{ - size_t i; - - if (!hosts) - return; - - for (i =3D 0; i < nhosts; i++) - virStorageNetHostDefClear(&hosts[i]); - - VIR_FREE(hosts); -} - - -static void -virStoragePermsFree(virStoragePermsPtr def) -{ - if (!def) - return; - - VIR_FREE(def->label); - VIR_FREE(def); -} - - -virStorageNetHostDefPtr -virStorageNetHostDefCopy(size_t nhosts, - virStorageNetHostDefPtr hosts) -{ - virStorageNetHostDefPtr ret =3D NULL; - size_t i; - - ret =3D g_new0(virStorageNetHostDef, nhosts); - - for (i =3D 0; i < nhosts; i++) { - virStorageNetHostDefPtr src =3D &hosts[i]; - virStorageNetHostDefPtr dst =3D &ret[i]; - - dst->transport =3D src->transport; - dst->port =3D src->port; - - dst->name =3D g_strdup(src->name); - dst->socket =3D g_strdup(src->socket); - } - - return ret; -} - - -void -virStorageAuthDefFree(virStorageAuthDefPtr authdef) -{ - if (!authdef) - return; - - VIR_FREE(authdef->username); - VIR_FREE(authdef->secrettype); - virSecretLookupDefClear(&authdef->seclookupdef); - VIR_FREE(authdef); -} - - -virStorageAuthDefPtr -virStorageAuthDefCopy(const virStorageAuthDef *src) -{ - g_autoptr(virStorageAuthDef) authdef =3D NULL; - - authdef =3D g_new0(virStorageAuthDef, 1); - - authdef->username =3D g_strdup(src->username); - /* Not present for storage pool, but used for disk source */ - authdef->secrettype =3D g_strdup(src->secrettype); - authdef->authType =3D src->authType; - - virSecretLookupDefCopy(&authdef->seclookupdef, &src->seclookupdef); - - return g_steal_pointer(&authdef); -} - - -virStorageAuthDefPtr -virStorageAuthDefParse(xmlNodePtr node, - xmlXPathContextPtr ctxt) -{ - VIR_XPATH_NODE_AUTORESTORE(ctxt) - virStorageAuthDefPtr ret =3D NULL; - xmlNodePtr secretnode =3D NULL; - g_autoptr(virStorageAuthDef) authdef =3D NULL; - g_autofree char *authtype =3D NULL; - - ctxt->node =3D node; - - authdef =3D g_new0(virStorageAuthDef, 1); - - if (!(authdef->username =3D virXPathString("string(./@username)", ctxt= ))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing username for auth")); - goto cleanup; - } - - authdef->authType =3D VIR_STORAGE_AUTH_TYPE_NONE; - authtype =3D virXPathString("string(./@type)", ctxt); - if (authtype) { - /* Used by the storage pool instead of the secret type field - * to define whether chap or ceph being used - */ - if ((authdef->authType =3D virStorageAuthTypeFromString(authtype))= < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown auth type '%s'"), authtype); - goto cleanup; - } - } - - if (!(secretnode =3D virXPathNode("./secret ", ctxt))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing element in auth")); - goto cleanup; - } - - /* Used by the domain disk xml parsing in order to ensure the - * secrettype =3D virXMLPropString(secretnode, "type"); - - if (virSecretLookupParseSecret(secretnode, &authdef->seclookupdef) < 0) - goto cleanup; - - ret =3D g_steal_pointer(&authdef); - - cleanup: - - return ret; -} - - -void -virStorageAuthDefFormat(virBufferPtr buf, - virStorageAuthDefPtr authdef) -{ - if (authdef->authType =3D=3D VIR_STORAGE_AUTH_TYPE_NONE) { - virBufferEscapeString(buf, "\n", authdef->us= ername); - } else { - virBufferAsprintf(buf, "authType)); - virBufferEscapeString(buf, "username=3D'%s'>\n", authdef->username= ); - } - - virBufferAdjustIndent(buf, 2); - virSecretLookupFormatSecret(buf, authdef->secrettype, - &authdef->seclookupdef); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "\n"); -} - - -void -virStoragePRDefFree(virStoragePRDefPtr prd) -{ - if (!prd) - return; - - VIR_FREE(prd->path); - VIR_FREE(prd->mgralias); - VIR_FREE(prd); -} - - -virStoragePRDefPtr -virStoragePRDefParseXML(xmlXPathContextPtr ctxt) -{ - virStoragePRDefPtr prd; - virStoragePRDefPtr ret =3D NULL; - g_autofree char *managed =3D NULL; - g_autofree char *type =3D NULL; - g_autofree char *path =3D NULL; - g_autofree char *mode =3D NULL; - - prd =3D g_new0(virStoragePRDef, 1); - - if (!(managed =3D virXPathString("string(./@managed)", ctxt))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing @managed attribute for ")= ); - goto cleanup; - } - - if ((prd->managed =3D virTristateBoolTypeFromString(managed)) <=3D 0) { - virReportError(VIR_ERR_XML_ERROR, - _("invalid value for 'managed': %s"), managed); - goto cleanup; - } - - type =3D virXPathString("string(./source[1]/@type)", ctxt); - path =3D virXPathString("string(./source[1]/@path)", ctxt); - mode =3D virXPathString("string(./source[1]/@mode)", ctxt); - - if (prd->managed =3D=3D VIR_TRISTATE_BOOL_NO || type || path || mode) { - if (!type) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing connection type for "= )); - goto cleanup; - } - - if (!path) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing path for ")); - goto cleanup; - } - - if (!mode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing connection mode for "= )); - goto cleanup; - } - } - - if (type && STRNEQ(type, "unix")) { - virReportError(VIR_ERR_XML_ERROR, - _("unsupported connection type for := %s"), - type); - goto cleanup; - } - - if (mode && STRNEQ(mode, "client")) { - virReportError(VIR_ERR_XML_ERROR, - _("unsupported connection mode for := %s"), - mode); - goto cleanup; - } - - prd->path =3D g_steal_pointer(&path); - ret =3D g_steal_pointer(&prd); - - cleanup: - virStoragePRDefFree(prd); - return ret; -} - - -void -virStoragePRDefFormat(virBufferPtr buf, - virStoragePRDefPtr prd, - bool migratable) -{ - virBufferAsprintf(buf, "managed)); - if (prd->path && - (prd->managed =3D=3D VIR_TRISTATE_BOOL_NO || !migratable)) { - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAddLit(buf, "path); - virBufferAddLit(buf, " mode=3D'client'/>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "\n"); - } else { - virBufferAddLit(buf, "/>\n"); - } -} - - -bool -virStoragePRDefIsEqual(virStoragePRDefPtr a, - virStoragePRDefPtr b) -{ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - if (a->managed !=3D b->managed || - STRNEQ_NULLABLE(a->path, b->path)) - return false; - - return true; -} - - -bool -virStoragePRDefIsManaged(virStoragePRDefPtr prd) -{ - return prd && prd->managed =3D=3D VIR_TRISTATE_BOOL_YES; -} - - -bool -virStorageSourceChainHasManagedPR(virStorageSourcePtr src) -{ - virStorageSourcePtr n; - - for (n =3D src; virStorageSourceIsBacking(n); n =3D n->backingStore) { - if (virStoragePRDefIsManaged(n->pr)) - return true; - } - - return false; -} - - -static virStoragePRDefPtr -virStoragePRDefCopy(virStoragePRDefPtr src) -{ - virStoragePRDefPtr copy =3D NULL; - virStoragePRDefPtr ret =3D NULL; - - copy =3D g_new0(virStoragePRDef, 1); - - copy->managed =3D src->managed; - - copy->path =3D g_strdup(src->path); - copy->mgralias =3D g_strdup(src->mgralias); - - ret =3D g_steal_pointer(©); - - virStoragePRDefFree(copy); - return ret; -} - - -static virStorageSourceNVMeDefPtr -virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src) -{ - virStorageSourceNVMeDefPtr ret =3D NULL; - - ret =3D g_new0(virStorageSourceNVMeDef, 1); - - ret->namespc =3D src->namespc; - ret->managed =3D src->managed; - virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr); - return ret; -} - - -static bool -virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a, - const virStorageSourceNVMeDef *b) -{ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - if (a->namespc !=3D b->namespc || - a->managed !=3D b->managed || - !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr)) - return false; - - return true; -} - - -void -virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def); -} - - -bool -virStorageSourceChainHasNVMe(const virStorageSource *src) -{ - const virStorageSource *n; - - for (n =3D src; virStorageSourceIsBacking(n); n =3D n->backingStore) { - if (n->type =3D=3D VIR_STORAGE_TYPE_NVME) - return true; - } - - return false; -} - - -virSecurityDeviceLabelDefPtr -virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src, - const char *model) -{ - size_t i; - - for (i =3D 0; i < src->nseclabels; i++) { - if (STREQ_NULLABLE(src->seclabels[i]->model, model)) - return src->seclabels[i]; - } - - return NULL; -} - - -static void -virStorageSourceSeclabelsClear(virStorageSourcePtr def) -{ - size_t i; - - if (def->seclabels) { - for (i =3D 0; i < def->nseclabels; i++) - virSecurityDeviceLabelDefFree(def->seclabels[i]); - VIR_FREE(def->seclabels); - } -} - - -static int -virStorageSourceSeclabelsCopy(virStorageSourcePtr to, - const virStorageSource *from) -{ - size_t i; - - if (from->nseclabels =3D=3D 0) - return 0; - - to->seclabels =3D g_new0(virSecurityDeviceLabelDefPtr, from->nseclabel= s); - to->nseclabels =3D from->nseclabels; - - for (i =3D 0; i < to->nseclabels; i++) { - if (!(to->seclabels[i] =3D virSecurityDeviceLabelDefCopy(from->sec= labels[i]))) - goto error; - } - - return 0; - - error: - virStorageSourceSeclabelsClear(to); - return -1; -} - - -void -virStorageNetCookieDefFree(virStorageNetCookieDefPtr def) -{ - if (!def) - return; - - g_free(def->name); - g_free(def->value); - - g_free(def); -} - - -static void -virStorageSourceNetCookiesClear(virStorageSourcePtr src) -{ - size_t i; - - if (!src || !src->cookies) - return; - - for (i =3D 0; i < src->ncookies; i++) - virStorageNetCookieDefFree(src->cookies[i]); - - g_clear_pointer(&src->cookies, g_free); - src->ncookies =3D 0; -} - - -static void -virStorageSourceNetCookiesCopy(virStorageSourcePtr to, - const virStorageSource *from) -{ - size_t i; - - if (from->ncookies =3D=3D 0) - return; - - to->cookies =3D g_new0(virStorageNetCookieDefPtr, from->ncookies); - to->ncookies =3D from->ncookies; - - for (i =3D 0; i < from->ncookies; i++) { - to->cookies[i]->name =3D g_strdup(from->cookies[i]->name); - to->cookies[i]->value =3D g_strdup(from->cookies[i]->value); - } -} - - -/* see https://tools.ietf.org/html/rfc6265#section-4.1.1 */ -static const char virStorageSourceCookieValueInvalidChars[] =3D - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" - " \",;\\"; - -/* in addition cookie name can't contain these */ -static const char virStorageSourceCookieNameInvalidChars[] =3D - "()<>@:/[]?=3D{}"; - -static int -virStorageSourceNetCookieValidate(virStorageNetCookieDefPtr def) -{ - g_autofree char *val =3D g_strdup(def->value); - const char *checkval =3D val; - size_t len =3D strlen(val); - - /* name must have at least 1 character */ - if (*(def->name) =3D=3D '\0') { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cookie name must not be empty")); - return -1; - } - - /* check invalid characters in name */ - if (virStringHasChars(def->name, virStorageSourceCookieValueInvalidCha= rs) || - virStringHasChars(def->name, virStorageSourceCookieNameInvalidChar= s)) { - virReportError(VIR_ERR_XML_ERROR, - _("cookie name '%s' contains invalid characters"), - def->name); - return -1; - } - - /* check for optional quotes around the cookie value string */ - if (val[0] =3D=3D '"') { - if (val[len - 1] !=3D '"') { - virReportError(VIR_ERR_XML_ERROR, - _("value of cookie '%s' contains invalid charac= ters"), - def->name); - return -1; - } - - val[len - 1] =3D '\0'; - checkval++; - } - - /* check invalid characters in value */ - if (virStringHasChars(checkval, virStorageSourceCookieValueInvalidChar= s)) { - virReportError(VIR_ERR_XML_ERROR, - _("value of cookie '%s' contains invalid characters= "), - def->name); - return -1; - } - - return 0; -} - - -int -virStorageSourceNetCookiesValidate(virStorageSourcePtr src) -{ - size_t i; - size_t j; - - for (i =3D 0; i < src->ncookies; i++) { - if (virStorageSourceNetCookieValidate(src->cookies[i]) < 0) - return -1; - - for (j =3D i + 1; j < src->ncookies; j++) { - if (STREQ(src->cookies[i]->name, src->cookies[j]->name)) { - virReportError(VIR_ERR_XML_ERROR, _("duplicate cookie '%s'= "), - src->cookies[i]->name); - return -1; - } - } - } - - return 0; -} - - -static virStorageTimestampsPtr -virStorageTimestampsCopy(const virStorageTimestamps *src) -{ - virStorageTimestampsPtr ret; - - ret =3D g_new0(virStorageTimestamps, 1); - - memcpy(ret, src, sizeof(*src)); - - return ret; -} - - -static virStoragePermsPtr -virStoragePermsCopy(const virStoragePerms *src) -{ - virStoragePermsPtr ret; - - ret =3D g_new0(virStoragePerms, 1); - - ret->mode =3D src->mode; - ret->uid =3D src->uid; - ret->gid =3D src->gid; - - ret->label =3D g_strdup(src->label); - - return ret; -} - - -static virStorageSourcePoolDefPtr -virStorageSourcePoolDefCopy(const virStorageSourcePoolDef *src) -{ - virStorageSourcePoolDefPtr ret; - - ret =3D g_new0(virStorageSourcePoolDef, 1); - - ret->voltype =3D src->voltype; - ret->pooltype =3D src->pooltype; - ret->actualtype =3D src->actualtype; - ret->mode =3D src->mode; - - ret->pool =3D g_strdup(src->pool); - ret->volume =3D g_strdup(src->volume); - - return ret; -} - - -static virStorageSourceSlicePtr -virStorageSourceSliceCopy(const virStorageSourceSlice *src) -{ - virStorageSourceSlicePtr ret =3D g_new0(virStorageSourceSlice, 1); - - ret->offset =3D src->offset; - ret->size =3D src->size; - ret->nodename =3D g_strdup(src->nodename); - - return ret; -} - - -static void -virStorageSourceSliceFree(virStorageSourceSlicePtr slice) -{ - if (!slice) - return; - - g_free(slice->nodename); - g_free(slice); -} - - -/** - * virStorageSourcePtr: - * - * Deep-copies a virStorageSource structure. If @backing chain is true - * then also copies the backing chain recursively, otherwise just - * the top element is copied. This function doesn't copy the - * storage driver access structure and thus the struct needs to be initial= ized - * separately. - */ -virStorageSourcePtr -virStorageSourceCopy(const virStorageSource *src, - bool backingChain) -{ - g_autoptr(virStorageSource) def =3D virStorageSourceNew(); - - def->id =3D src->id; - def->type =3D src->type; - def->protocol =3D src->protocol; - def->format =3D src->format; - def->capacity =3D src->capacity; - def->allocation =3D src->allocation; - def->has_allocation =3D src->has_allocation; - def->physical =3D src->physical; - def->readonly =3D src->readonly; - def->shared =3D src->shared; - def->haveTLS =3D src->haveTLS; - def->tlsFromConfig =3D src->tlsFromConfig; - def->detected =3D src->detected; - def->debugLevel =3D src->debugLevel; - def->debug =3D src->debug; - def->iomode =3D src->iomode; - def->cachemode =3D src->cachemode; - def->discard =3D src->discard; - def->detect_zeroes =3D src->detect_zeroes; - def->sslverify =3D src->sslverify; - def->readahead =3D src->readahead; - def->timeout =3D src->timeout; - def->metadataCacheMaxSize =3D src->metadataCacheMaxSize; - - /* storage driver metadata are not copied */ - def->drv =3D NULL; - - def->path =3D g_strdup(src->path); - def->volume =3D g_strdup(src->volume); - def->relPath =3D g_strdup(src->relPath); - def->backingStoreRaw =3D g_strdup(src->backingStoreRaw); - def->backingStoreRawFormat =3D src->backingStoreRawFormat; - def->snapshot =3D g_strdup(src->snapshot); - def->configFile =3D g_strdup(src->configFile); - def->nodeformat =3D g_strdup(src->nodeformat); - def->nodestorage =3D g_strdup(src->nodestorage); - def->compat =3D g_strdup(src->compat); - def->tlsAlias =3D g_strdup(src->tlsAlias); - def->tlsCertdir =3D g_strdup(src->tlsCertdir); - def->query =3D g_strdup(src->query); - - if (src->sliceStorage) - def->sliceStorage =3D virStorageSourceSliceCopy(src->sliceStorage); - - if (src->nhosts) { - if (!(def->hosts =3D virStorageNetHostDefCopy(src->nhosts, src->ho= sts))) - return NULL; - - def->nhosts =3D src->nhosts; - } - - virStorageSourceNetCookiesCopy(def, src); - - if (src->srcpool && - !(def->srcpool =3D virStorageSourcePoolDefCopy(src->srcpool))) - return NULL; - - if (src->features) - def->features =3D virBitmapNewCopy(src->features); - - if (src->encryption && - !(def->encryption =3D virStorageEncryptionCopy(src->encryption))) - return NULL; - - if (src->perms && - !(def->perms =3D virStoragePermsCopy(src->perms))) - return NULL; - - if (src->timestamps && - !(def->timestamps =3D virStorageTimestampsCopy(src->timestamps))) - return NULL; - - if (virStorageSourceSeclabelsCopy(def, src) < 0) - return NULL; - - if (src->auth && - !(def->auth =3D virStorageAuthDefCopy(src->auth))) - return NULL; - - if (src->pr && - !(def->pr =3D virStoragePRDefCopy(src->pr))) - return NULL; - - if (src->nvme) - def->nvme =3D virStorageSourceNVMeDefCopy(src->nvme); - - if (virStorageSourceInitiatorCopy(&def->initiator, &src->initiator) < = 0) - return NULL; - - if (backingChain && src->backingStore) { - if (!(def->backingStore =3D virStorageSourceCopy(src->backingStore, - true))) - return NULL; - } - - /* ssh config passthrough for libguestfs */ - def->ssh_host_key_check_disabled =3D src->ssh_host_key_check_disabled; - def->ssh_user =3D g_strdup(src->ssh_user); - - def->nfs_user =3D g_strdup(src->nfs_user); - def->nfs_group =3D g_strdup(src->nfs_group); - def->nfs_uid =3D src->nfs_uid; - def->nfs_gid =3D src->nfs_gid; - - return g_steal_pointer(&def); -} - - -/** - * virStorageSourceIsSameLocation: - * - * Returns true if the sources @a and @b point to the same storage locatio= n. - * This does not compare any other configuration option - */ -bool -virStorageSourceIsSameLocation(virStorageSourcePtr a, - virStorageSourcePtr b) -{ - size_t i; - - /* there are multiple possibilities to define an empty source */ - if (virStorageSourceIsEmpty(a) && - virStorageSourceIsEmpty(b)) - return true; - - if (virStorageSourceGetActualType(a) !=3D virStorageSourceGetActualTyp= e(b)) - return false; - - if (STRNEQ_NULLABLE(a->path, b->path) || - STRNEQ_NULLABLE(a->volume, b->volume) || - STRNEQ_NULLABLE(a->snapshot, b->snapshot)) - return false; - - if (a->type =3D=3D VIR_STORAGE_TYPE_NETWORK) { - if (a->protocol !=3D b->protocol || - a->nhosts !=3D b->nhosts) - return false; - - for (i =3D 0; i < a->nhosts; i++) { - if (a->hosts[i].transport !=3D b->hosts[i].transport || - a->hosts[i].port !=3D b->hosts[i].port || - STRNEQ_NULLABLE(a->hosts[i].name, b->hosts[i].name) || - STRNEQ_NULLABLE(a->hosts[i].socket, b->hosts[i].socket)) - return false; - } - } - - if (a->type =3D=3D VIR_STORAGE_TYPE_NVME && - !virStorageSourceNVMeDefIsEqual(a->nvme, b->nvme)) - return false; - - return true; -} - - -/** - * virStorageSourceInitChainElement: - * @newelem: New backing chain element disk source - * @old: Existing top level disk source - * @transferLabels: Transfer security labels. - * - * Transfers relevant information from the existing disk source to the new - * backing chain element if they weren't supplied so that labelling info - * and possibly other stuff is correct. - * - * If @transferLabels is true, security labels from the existing disk are = copied - * to the new disk. Otherwise the default domain imagelabel label will be = used. - * - * Returns 0 on success, -1 on error. - */ -int -virStorageSourceInitChainElement(virStorageSourcePtr newelem, - virStorageSourcePtr old, - bool transferLabels) -{ - if (transferLabels && - !newelem->seclabels && - virStorageSourceSeclabelsCopy(newelem, old) < 0) - return -1; - - newelem->shared =3D old->shared; - newelem->readonly =3D old->readonly; - - return 0; -} - - -void -virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def) -{ - if (!def) - return; - - VIR_FREE(def->pool); - VIR_FREE(def->volume); - - VIR_FREE(def); -} - - -/** - * virStorageSourceGetActualType: - * @def: storage source definition - * - * Returns type of @def. In case when the type is VIR_STORAGE_TYPE_VOLUME - * and virDomainDiskTranslateSourcePool was called on @def the actual type - * of the storage volume is returned rather than VIR_STORAGE_TYPE_VOLUME. - */ -int -virStorageSourceGetActualType(const virStorageSource *def) -{ - if (def->type =3D=3D VIR_STORAGE_TYPE_VOLUME && - def->srcpool && - def->srcpool->actualtype !=3D VIR_STORAGE_TYPE_NONE) - return def->srcpool->actualtype; - - return def->type; -} - - -bool -virStorageSourceIsLocalStorage(const virStorageSource *src) -{ - virStorageType type =3D virStorageSourceGetActualType(src); - - switch (type) { - case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_BLOCK: - case VIR_STORAGE_TYPE_DIR: - return true; - - case VIR_STORAGE_TYPE_NETWORK: - case VIR_STORAGE_TYPE_VOLUME: - /* While NVMe disks are local, they are not accessible via src->pa= th. - * Therefore, we have to return false here. */ - case VIR_STORAGE_TYPE_NVME: - case VIR_STORAGE_TYPE_LAST: - case VIR_STORAGE_TYPE_NONE: - return false; - } - - return false; -} - - -/** - * virStorageSourceIsEmpty: - * - * @src: disk source to check - * - * Returns true if the guest disk has no associated host storage source - * (such as an empty cdrom drive). - */ -bool -virStorageSourceIsEmpty(virStorageSourcePtr src) -{ - if (virStorageSourceIsLocalStorage(src) && !src->path) - return true; - - if (src->type =3D=3D VIR_STORAGE_TYPE_NONE) - return true; - - if (src->type =3D=3D VIR_STORAGE_TYPE_NETWORK && - src->protocol =3D=3D VIR_STORAGE_NET_PROTOCOL_NONE) - return true; - - return false; -} - - -/** - * virStorageSourceIsBlockLocal: - * @src: disk source definition - * - * Returns true if @src describes a locally accessible block storage sourc= e. - * This includes block devices and host-mapped iSCSI volumes. - */ -bool -virStorageSourceIsBlockLocal(const virStorageSource *src) -{ - return virStorageSourceGetActualType(src) =3D=3D VIR_STORAGE_TYPE_BLOC= K; -} - - -/** - * virStorageSourceBackingStoreClear: - * - * @src: disk source to clear - * - * Clears information about backing store of the current storage file. - */ -void -virStorageSourceBackingStoreClear(virStorageSourcePtr def) -{ - if (!def) - return; - - VIR_FREE(def->relPath); - VIR_FREE(def->backingStoreRaw); - - /* recursively free backing chain */ - virObjectUnref(def->backingStore); - def->backingStore =3D NULL; -} - - -void -virStorageSourceClear(virStorageSourcePtr def) -{ - if (!def) - return; - - VIR_FREE(def->path); - VIR_FREE(def->volume); - VIR_FREE(def->snapshot); - VIR_FREE(def->configFile); - VIR_FREE(def->query); - virStorageSourceNetCookiesClear(def); - virStorageSourcePoolDefFree(def->srcpool); - virBitmapFree(def->features); - VIR_FREE(def->compat); - virStorageEncryptionFree(def->encryption); - virStoragePRDefFree(def->pr); - virStorageSourceNVMeDefFree(def->nvme); - virStorageSourceSeclabelsClear(def); - virStoragePermsFree(def->perms); - VIR_FREE(def->timestamps); - - virStorageSourceSliceFree(def->sliceStorage); - - virStorageNetHostDefFree(def->nhosts, def->hosts); - virStorageAuthDefFree(def->auth); - virObjectUnref(def->privateData); - - VIR_FREE(def->nodestorage); - VIR_FREE(def->nodeformat); - - virStorageSourceBackingStoreClear(def); - - VIR_FREE(def->tlsAlias); - VIR_FREE(def->tlsCertdir); - - VIR_FREE(def->ssh_user); - - VIR_FREE(def->nfs_user); - VIR_FREE(def->nfs_group); - - virStorageSourceInitiatorClear(&def->initiator); - - /* clear everything except the class header as the object APIs - * will break otherwise */ - memset((char *) def + sizeof(def->parent), 0, - sizeof(*def) - sizeof(def->parent)); -} - - -static void -virStorageSourceDispose(void *obj) -{ - virStorageSourcePtr src =3D obj; - - virStorageSourceClear(src); -} - - -static int -virStorageSourceOnceInit(void) -{ - if (!VIR_CLASS_NEW(virStorageSource, virClassForObject())) - return -1; - - return 0; -} - - -VIR_ONCE_GLOBAL_INIT(virStorageSource); - - -virStorageSourcePtr -virStorageSourceNew(void) -{ - virStorageSourcePtr ret; - - if (virStorageSourceInitialize() < 0) - abort(); - - if (!(ret =3D virObjectNew(virStorageSourceClass))) - abort(); - - return ret; -} - - static char * virStorageFileCanonicalizeFormatPath(char **components, size_t ncomponents, @@ -1642,157 +490,3 @@ virStorageFileCanonicalizePath(const char *path, =20 return ret; } - - -/** - * virStorageSourceIsRelative: - * @src: storage source to check - * - * Returns true if given storage source definition is a relative path. - */ -bool -virStorageSourceIsRelative(virStorageSourcePtr src) -{ - virStorageType actual_type =3D virStorageSourceGetActualType(src); - - if (!src->path) - return false; - - switch (actual_type) { - case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_BLOCK: - case VIR_STORAGE_TYPE_DIR: - return src->path[0] !=3D '/'; - - case VIR_STORAGE_TYPE_NETWORK: - case VIR_STORAGE_TYPE_VOLUME: - case VIR_STORAGE_TYPE_NVME: - case VIR_STORAGE_TYPE_NONE: - case VIR_STORAGE_TYPE_LAST: - return false; - } - - return false; -} - - -static unsigned int -virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol) -{ - switch (protocol) { - case VIR_STORAGE_NET_PROTOCOL_HTTP: - return 80; - - case VIR_STORAGE_NET_PROTOCOL_HTTPS: - return 443; - - case VIR_STORAGE_NET_PROTOCOL_FTP: - return 21; - - case VIR_STORAGE_NET_PROTOCOL_FTPS: - return 990; - - case VIR_STORAGE_NET_PROTOCOL_TFTP: - return 69; - - case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: - return 7000; - - case VIR_STORAGE_NET_PROTOCOL_NBD: - return 10809; - - case VIR_STORAGE_NET_PROTOCOL_SSH: - return 22; - - case VIR_STORAGE_NET_PROTOCOL_ISCSI: - return 3260; - - case VIR_STORAGE_NET_PROTOCOL_GLUSTER: - return 24007; - - case VIR_STORAGE_NET_PROTOCOL_RBD: - /* we don't provide a default for RBD */ - return 0; - - case VIR_STORAGE_NET_PROTOCOL_VXHS: - return 9999; - - case VIR_STORAGE_NET_PROTOCOL_NFS: - /* Port is not supported by NFS, so no default is provided */ - return 0; - - case VIR_STORAGE_NET_PROTOCOL_LAST: - case VIR_STORAGE_NET_PROTOCOL_NONE: - return 0; - } - - return 0; -} - - -void -virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src) -{ - size_t i; - - for (i =3D 0; i < src->nhosts; i++) { - if (src->hosts[i].transport =3D=3D VIR_STORAGE_NET_HOST_TRANS_TCP = && - src->hosts[i].port =3D=3D 0) - src->hosts[i].port =3D virStorageSourceNetworkDefaultPort(src-= >protocol); - } -} - - -int -virStorageSourcePrivateDataParseRelPath(xmlXPathContextPtr ctxt, - virStorageSourcePtr src) -{ - src->relPath =3D virXPathString("string(./relPath)", ctxt); - return 0; -} - - -int -virStorageSourcePrivateDataFormatRelPath(virStorageSourcePtr src, - virBufferPtr buf) -{ - if (src->relPath) - virBufferEscapeString(buf, "%s\n", src->relPath= ); - - return 0; -} - -void -virStorageSourceInitiatorParseXML(xmlXPathContextPtr ctxt, - virStorageSourceInitiatorDefPtr initiato= r) -{ - initiator->iqn =3D virXPathString("string(./initiator/iqn/@name)", ctx= t); -} - -void -virStorageSourceInitiatorFormatXML(virStorageSourceInitiatorDefPtr initiat= or, - virBufferPtr buf) -{ - if (!initiator->iqn) - return; - - virBufferAddLit(buf, "\n"); - virBufferAdjustIndent(buf, 2); - virBufferEscapeString(buf, "\n", initiator->iqn); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "\n"); -} - -int -virStorageSourceInitiatorCopy(virStorageSourceInitiatorDefPtr dest, - const virStorageSourceInitiatorDef *src) -{ - dest->iqn =3D g_strdup(src->iqn); - return 0; -} - -void -virStorageSourceInitiatorClear(virStorageSourceInitiatorDefPtr initiator) -{ - VIR_FREE(initiator->iqn); -} diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index d6f194a7dd..2c1a250f20 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -21,372 +21,7 @@ =20 #pragma once =20 -#include - -#include "virbitmap.h" -#include "virobject.h" -#include "virseclabel.h" -#include "virstorageencryption.h" -#include "virsecret.h" -#include "virenum.h" -#include "virpci.h" - -/* Types of disk backends (host resource). Comparable to the public - * virStorageVolType, except we have an undetermined state, don't have - * a netdir type, and add a volume type for reference through a - * storage pool. */ -typedef enum { - VIR_STORAGE_TYPE_NONE, - VIR_STORAGE_TYPE_FILE, - VIR_STORAGE_TYPE_BLOCK, - VIR_STORAGE_TYPE_DIR, - VIR_STORAGE_TYPE_NETWORK, - VIR_STORAGE_TYPE_VOLUME, - VIR_STORAGE_TYPE_NVME, - - VIR_STORAGE_TYPE_LAST -} virStorageType; - -VIR_ENUM_DECL(virStorage); - - -typedef enum { - VIR_STORAGE_FILE_AUTO_SAFE =3D -2, - VIR_STORAGE_FILE_AUTO =3D -1, - VIR_STORAGE_FILE_NONE =3D 0, - VIR_STORAGE_FILE_RAW, - VIR_STORAGE_FILE_DIR, - VIR_STORAGE_FILE_BOCHS, - VIR_STORAGE_FILE_CLOOP, - VIR_STORAGE_FILE_DMG, - VIR_STORAGE_FILE_ISO, - VIR_STORAGE_FILE_VPC, - VIR_STORAGE_FILE_VDI, - - /* Not direct file formats, but used for various drivers */ - VIR_STORAGE_FILE_FAT, - VIR_STORAGE_FILE_VHD, - VIR_STORAGE_FILE_PLOOP, - - /* Not a format, but a marker: all formats below this point have - * libvirt support for following a backing chain */ - VIR_STORAGE_FILE_BACKING, - - VIR_STORAGE_FILE_COW =3D VIR_STORAGE_FILE_BACKING, - VIR_STORAGE_FILE_QCOW, - VIR_STORAGE_FILE_QCOW2, - VIR_STORAGE_FILE_QED, - VIR_STORAGE_FILE_VMDK, - - VIR_STORAGE_FILE_LAST, -} virStorageFileFormat; - -VIR_ENUM_DECL(virStorageFileFormat); - -typedef enum { - VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS =3D 0, - - VIR_STORAGE_FILE_FEATURE_LAST -} virStorageFileFeature; - -VIR_ENUM_DECL(virStorageFileFeature); - -typedef struct _virStoragePerms virStoragePerms; -typedef virStoragePerms *virStoragePermsPtr; -struct _virStoragePerms { - mode_t mode; - uid_t uid; - gid_t gid; - char *label; -}; - - -typedef struct _virStorageTimestamps virStorageTimestamps; -typedef virStorageTimestamps *virStorageTimestampsPtr; -struct _virStorageTimestamps { - struct timespec atime; - struct timespec btime; /* birth time unknown if btime.tv_nsec =3D=3D -= 1 */ - struct timespec ctime; - struct timespec mtime; -}; - - -/* Information related to network storage */ -typedef enum { - VIR_STORAGE_NET_PROTOCOL_NONE, - VIR_STORAGE_NET_PROTOCOL_NBD, - VIR_STORAGE_NET_PROTOCOL_RBD, - VIR_STORAGE_NET_PROTOCOL_SHEEPDOG, - VIR_STORAGE_NET_PROTOCOL_GLUSTER, - VIR_STORAGE_NET_PROTOCOL_ISCSI, - VIR_STORAGE_NET_PROTOCOL_HTTP, - VIR_STORAGE_NET_PROTOCOL_HTTPS, - VIR_STORAGE_NET_PROTOCOL_FTP, - VIR_STORAGE_NET_PROTOCOL_FTPS, - VIR_STORAGE_NET_PROTOCOL_TFTP, - VIR_STORAGE_NET_PROTOCOL_SSH, - VIR_STORAGE_NET_PROTOCOL_VXHS, - VIR_STORAGE_NET_PROTOCOL_NFS, - - VIR_STORAGE_NET_PROTOCOL_LAST -} virStorageNetProtocol; - -VIR_ENUM_DECL(virStorageNetProtocol); - - -typedef enum { - VIR_STORAGE_NET_HOST_TRANS_TCP, - VIR_STORAGE_NET_HOST_TRANS_UNIX, - VIR_STORAGE_NET_HOST_TRANS_RDMA, - - VIR_STORAGE_NET_HOST_TRANS_LAST -} virStorageNetHostTransport; - -VIR_ENUM_DECL(virStorageNetHostTransport); - -typedef struct _virStorageNetHostDef virStorageNetHostDef; -typedef virStorageNetHostDef *virStorageNetHostDefPtr; -struct _virStorageNetHostDef { - char *name; - unsigned int port; - int transport; /* virStorageNetHostTransport */ - char *socket; /* path to unix socket */ -}; - -typedef struct _virStorageNetCookieDef virStorageNetCookieDef; -typedef virStorageNetCookieDef *virStorageNetCookieDefPtr; -struct _virStorageNetCookieDef { - char *name; - char *value; -}; - -void virStorageNetCookieDefFree(virStorageNetCookieDefPtr def); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageNetCookieDef, virStorageNetCookieD= efFree); - -/* Information for a storage volume from a virStoragePool */ - -/* - * Used for volume "type" disk to indicate how to represent - * the disk source if the specified "pool" is of iscsi type. - */ -typedef enum { - VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT =3D 0, - - /* Use the path as it shows up on host, e.g. - * /dev/disk/by-path/ip-$ip-iscsi-$iqn:iscsi.iscsi-pool0-lun-1 - */ - VIR_STORAGE_SOURCE_POOL_MODE_HOST, - - /* Use the URI from the storage pool source element host attribute. E.= g. - * file=3Discsi://demo.org:6000/iqn.1992-01.com.example/1. - */ - VIR_STORAGE_SOURCE_POOL_MODE_DIRECT, - - VIR_STORAGE_SOURCE_POOL_MODE_LAST -} virStorageSourcePoolMode; - -VIR_ENUM_DECL(virStorageSourcePoolMode); - -typedef struct _virStorageSourcePoolDef virStorageSourcePoolDef; -struct _virStorageSourcePoolDef { - char *pool; /* pool name */ - char *volume; /* volume name */ - int voltype; /* virStorageVolType, internal only */ - int pooltype; /* virStoragePoolType from storage_conf.h, internal only= */ - int actualtype; /* virStorageType, internal only */ - int mode; /* virStorageSourcePoolMode, currently makes sense only for = iscsi pool */ -}; -typedef virStorageSourcePoolDef *virStorageSourcePoolDefPtr; - - -typedef enum { - VIR_STORAGE_AUTH_TYPE_NONE, - VIR_STORAGE_AUTH_TYPE_CHAP, - VIR_STORAGE_AUTH_TYPE_CEPHX, - - VIR_STORAGE_AUTH_TYPE_LAST, -} virStorageAuthType; -VIR_ENUM_DECL(virStorageAuth); - -typedef struct _virStorageAuthDef virStorageAuthDef; -typedef virStorageAuthDef *virStorageAuthDefPtr; -struct _virStorageAuthDef { - char *username; - char *secrettype; /* (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257887838282.71230036536576; Thu, 21 Jan 2021 11:38:07 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-21-_MFIEsmtNIqcfkvIVbVtEQ-1; Thu, 21 Jan 2021 14:35:03 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 70369184214F; Thu, 21 Jan 2021 19:34:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4CEEC60C6C; Thu, 21 Jan 2021 19:34:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DB97F1809CAF; Thu, 21 Jan 2021 19:34:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYqSk023281 for ; Thu, 21 Jan 2021 14:34:52 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2F66E10023AE; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id C97E3100AE39 for ; Thu, 21 Jan 2021 19:34:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257886; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=pZEdEoFftAg72AwAj7w0MMDVos5P6Po4ipO80ioT/rU=; b=R1TRYL0yKg68/7FF1yQKRscrNET+jWKjcmP/raiwWI20ZD5PJiT85Njvv9Mw1L9IgzckRA 3/R0Q+Of4gttd4twOcfv8S+6tXDAM0H+6qjJc+6eXypkh+mfRc3tfmi6Kd9Jwkq77BV/Ob 7XnS8Fm27Q0grJ0MyvWpoRSUpZxcals= X-MC-Unique: _MFIEsmtNIqcfkvIVbVtEQ-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 11/13] util: move virStorageEncryption code into conf Date: Thu, 21 Jan 2021 20:34:25 +0100 Message-Id: <394f88f3a2081b3ad7bff93e74c1467fcf3116bd.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" The code handles XML bits and internal definition and should be in conf directory. Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- po/POTFILES.in | 2 +- src/conf/domain_conf.h | 2 +- src/conf/meson.build | 1 + src/conf/storage_conf.h | 2 +- .../storage_encryption_conf.c} | 4 ++-- .../storage_encryption_conf.h} | 2 +- src/conf/storage_source_conf.h | 2 +- src/libvirt_private.syms | 12 ++++++------ src/util/meson.build | 1 - 9 files changed, 14 insertions(+), 14 deletions(-) rename src/{util/virstorageencryption.c =3D> conf/storage_encryption_conf.= c} (99%) rename src/{util/virstorageencryption.h =3D> conf/storage_encryption_conf.= h} (98%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 00100d7d73..05bbe21462 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,6 +43,7 @@ @SRCDIR@src/conf/snapshot_conf.c @SRCDIR@src/conf/storage_adapter_conf.c @SRCDIR@src/conf/storage_conf.c +@SRCDIR@src/conf/storage_encryption_conf.c @SRCDIR@src/conf/storage_source_conf.c @SRCDIR@src/conf/virchrdev.c @SRCDIR@src/conf/virdomainmomentobjlist.c @@ -307,7 +308,6 @@ @SRCDIR@src/util/virscsivhost.c @SRCDIR@src/util/virsecret.c @SRCDIR@src/util/virsocketaddr.c -@SRCDIR@src/util/virstorageencryption.c @SRCDIR@src/util/virstoragefile.c @SRCDIR@src/util/virstring.c @SRCDIR@src/util/virsysinfo.c diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f5d346ddf0..95ad052891 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -29,7 +29,7 @@ #include "internal.h" #include "virconftypes.h" #include "capabilities.h" -#include "virstorageencryption.h" +#include "storage_encryption_conf.h" #include "cpu_conf.h" #include "virthread.h" #include "virhash.h" diff --git a/src/conf/meson.build b/src/conf/meson.build index 9d4831b815..bd35d87e0a 100644 --- a/src/conf/meson.build +++ b/src/conf/meson.build @@ -54,6 +54,7 @@ storage_conf_sources =3D [ 'storage_adapter_conf.c', 'storage_capabilities.c', 'storage_conf.c', + 'storage_encryption_conf.c', 'storage_source_conf.c', 'virstorageobj.c', ] diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index aeda2891d4..647eb847bf 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -22,7 +22,7 @@ #pragma once =20 #include "internal.h" -#include "virstorageencryption.h" +#include "storage_encryption_conf.h" #include "storage_source_conf.h" #include "virbitmap.h" #include "virthread.h" diff --git a/src/util/virstorageencryption.c b/src/conf/storage_encryption_= conf.c similarity index 99% rename from src/util/virstorageencryption.c rename to src/conf/storage_encryption_conf.c index c893f0babe..34ad5dffeb 100644 --- a/src/util/virstorageencryption.c +++ b/src/conf/storage_encryption_conf.c @@ -1,5 +1,5 @@ /* - * virstorageencryption.c: volume encryption information + * storage_encryption_conf.c: volume encryption information * * Copyright (C) 2009-2014 Red Hat, Inc. * @@ -27,7 +27,7 @@ =20 #include "virbuffer.h" #include "viralloc.h" -#include "virstorageencryption.h" +#include "storage_encryption_conf.h" #include "virxml.h" #include "virerror.h" #include "viruuid.h" diff --git a/src/util/virstorageencryption.h b/src/conf/storage_encryption_= conf.h similarity index 98% rename from src/util/virstorageencryption.h rename to src/conf/storage_encryption_conf.h index 352dd373d6..0799421763 100644 --- a/src/util/virstorageencryption.h +++ b/src/conf/storage_encryption_conf.h @@ -1,5 +1,5 @@ /* - * virstorageencryption.h: volume encryption information + * storage_encryption_conf.h: volume encryption information * * Copyright (C) 2009-2011, 2014 Red Hat, Inc. * diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h index 6f39ab4bd0..e66ccdedef 100644 --- a/src/conf/storage_source_conf.h +++ b/src/conf/storage_source_conf.h @@ -21,13 +21,13 @@ =20 #pragma once =20 +#include "storage_encryption_conf.h" #include "virbitmap.h" #include "virenum.h" #include "virobject.h" #include "virpci.h" #include "virseclabel.h" #include "virsecret.h" -#include "virstorageencryption.h" =20 /* Types of disk backends (host resource). Comparable to the public * virStorageVolType, except we have an undetermined state, don't have diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b13d0db209..e8fe8e6c12 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1047,6 +1047,12 @@ virStorageVolTypeFromString; virStorageVolTypeToString; =20 =20 +# conf/storage_encryption_conf.h +virStorageEncryptionFormat; +virStorageEncryptionFree; +virStorageEncryptionParseNode; + + # conf/storage_event.h virStoragePoolEventLifecycleNew; virStoragePoolEventRefreshNew; @@ -3206,12 +3212,6 @@ virSocketAddrSetIPv6AddrNetOrder; virSocketAddrSetPort; =20 =20 -# util/virstorageencryption.h -virStorageEncryptionFormat; -virStorageEncryptionFree; -virStorageEncryptionParseNode; - - # util/virstoragefile.h virStorageFileCanonicalizePath; virStorageFileGetNPIVKey; diff --git a/src/util/meson.build b/src/util/meson.build index b510f0ebe9..c077c5cc99 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -88,7 +88,6 @@ util_sources =3D [ 'virsecret.c', 'virsocket.c', 'virsocketaddr.c', - 'virstorageencryption.c', 'virstoragefile.c', 'virstring.c', 'virsysinfo.c', --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257770; cv=none; d=zohomail.com; s=zohoarc; b=O9OwqR+jOA17gyuOXOCem7/hfZjLUB3HzeVTOwPsmzAPqdVZFJKQAjKVIzrtaL+DsZuBQroNrnGZ59s9vCzHfnGVg/UP30fN/Mj63zC89dKTKqyzWy9TpEMTrBGk7Tbd3jbXoM/pzE4sZTCdrBooVuNnLdpFTGYlAh8Y8/TnEkU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257770; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=vJxCjVvb6Vrov1zsCaKFfvsCvfU5Js7/m4mB2B9o5sg=; b=YGurSmRPbakxz9sUas2y+bQFNZDQyodomlTtxnJFs44kK0DnZuW9uywsIIMwc41eFR6RY32XKcWlXqGJkdZXkiHIKPg5XhsviTr8PMYf5MFwP3pbPvNmObqhfz5kaHZjvtFIq4fTMFHzeskOQYvHSIel/xn+b3zSTZJ4Vxc3WYs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257770759278.68211718866644; Thu, 21 Jan 2021 11:36:10 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-519-KHwym60VON61aPpTX51avw-1; Thu, 21 Jan 2021 14:35:05 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AC37D1842149; Thu, 21 Jan 2021 19:34:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8813A5D9E3; Thu, 21 Jan 2021 19:34:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 4DD951809CB1; Thu, 21 Jan 2021 19:34:56 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYrsQ023286 for ; Thu, 21 Jan 2021 14:34:53 -0500 Received: by smtp.corp.redhat.com (Postfix) id 3E39110023AE; Thu, 21 Jan 2021 19:34:53 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A780100AE3F for ; Thu, 21 Jan 2021 19:34:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257769; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=vJxCjVvb6Vrov1zsCaKFfvsCvfU5Js7/m4mB2B9o5sg=; b=dXgNVSmrz6F+gwDctXp4y6YJfxqB6wJoRmM8JWZzVO/LMusf5WiocCvjDgIeJYTB0+zg23 ZPHoelolicHp6hBwvk7GU+pn7pioqecMt+KFU34afxlOSItJiajCoQyXl5hzvH1I+Hn/A5 Cr2cVmr2B1Wq9TRKjUTWxjdpobEDMKM= X-MC-Unique: KHwym60VON61aPpTX51avw-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 12/13] virstoragefile: use virStorageFile prefix for all functions Date: Thu, 21 Jan 2021 20:34:26 +0100 Message-Id: <28b9b89c6ae5556fdb8ae3f885cbc077651236f9.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/libvirt_private.syms | 4 ++-- src/qemu/qemu_block.c | 2 +- src/qemu/qemu_snapshot.c | 2 +- src/storage_file/storage_source.c | 6 +++--- src/util/virstoragefile.c | 6 +++--- src/util/virstoragefile.h | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e8fe8e6c12..088474d54b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3216,10 +3216,10 @@ virSocketAddrSetPort; virStorageFileCanonicalizePath; virStorageFileGetNPIVKey; virStorageFileGetSCSIKey; +virStorageFileIsFile; +virStorageFileIsRelative; virStorageFileParseBackingStoreStr; virStorageFileParseChainIndex; -virStorageIsFile; -virStorageIsRelative; =20 =20 # util/virstring.h diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index ca23466b22..fafa35071c 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3439,7 +3439,7 @@ qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, if (rc < 0) return rc; =20 - if (backingStoreStr && virStorageIsRelative(backingStoreStr)) + if (backingStoreStr && virStorageFileIsRelative(backingStoreStr)) n->backingStore->relPath =3D g_steal_pointer(&backingStoreStr); } =20 diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 994c7dc60b..699090ae40 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -1094,7 +1094,7 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm, if (virStorageFileGetBackingStoreStr(dd->src, &backingStor= eStr) < 0) return -1; if (backingStoreStr !=3D NULL) { - if (virStorageIsRelative(backingStoreStr)) + if (virStorageFileIsRelative(backingStoreStr)) dd->relPath =3D g_steal_pointer(&backingStoreStr); } } diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_s= ource.c index d1e0aeb2c1..ffc7fe8ea5 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -185,7 +185,7 @@ virStorageFileChainLookup(virStorageSourcePtr chain, { virStorageSourcePtr prev; const char *start =3D chain->path; - bool nameIsFile =3D virStorageIsFile(name); + bool nameIsFile =3D virStorageFileIsFile(name); =20 if (!parent) parent =3D &prev; @@ -1532,7 +1532,7 @@ virStorageSourceNewFromBackingAbsolute(const char *pa= th, =20 *src =3D NULL; =20 - if (virStorageIsFile(path)) { + if (virStorageFileIsFile(path)) { def->type =3D VIR_STORAGE_TYPE_FILE; =20 def->path =3D g_strdup(path); @@ -1604,7 +1604,7 @@ virStorageSourceNewFromChild(virStorageSourcePtr pare= nt, =20 *child =3D NULL; =20 - if (virStorageIsRelative(parentRaw)) { + if (virStorageFileIsRelative(parentRaw)) { if (!(def =3D virStorageSourceNewFromBackingRelative(parent, paren= tRaw))) return -1; } else { diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 85ccd9f52c..c9c735831d 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -38,7 +38,7 @@ VIR_LOG_INIT("util.storagefile"); =20 =20 bool -virStorageIsFile(const char *backing) +virStorageFileIsFile(const char *backing) { char *colon; char *slash; @@ -59,12 +59,12 @@ virStorageIsFile(const char *backing) =20 =20 bool -virStorageIsRelative(const char *backing) +virStorageFileIsRelative(const char *backing) { if (backing[0] =3D=3D '/') return false; =20 - if (!virStorageIsFile(backing)) + if (!virStorageFileIsFile(backing)) return false; =20 return true; diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 2c1a250f20..e56796ec95 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -33,8 +33,8 @@ int virStorageFileParseBackingStoreStr(const char *str, unsigned int *chainIndex) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); =20 -bool virStorageIsFile(const char *path); -bool virStorageIsRelative(const char *backing); +bool virStorageFileIsFile(const char *path); +bool virStorageFileIsRelative(const char *backing); =20 int virStorageFileGetSCSIKey(const char *path, char **key, --=20 2.29.2 From nobody Fri May 3 01:03:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.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 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1611257791; cv=none; d=zohomail.com; s=zohoarc; b=dUJOLUd8pU9pBp+TCH27ew1YL+xmIoCiCBZmjs5qC5ojhgyqZpToqkMFVA/tkxucuZNc5DrxeIEka4iK78Vw4og6NOnddeLddQiDo1NgyX/EZNPDIExzfsQmO2iD54KpHYRwEYY+5gmWtBEZ0VUA8JFqRF/CKuL09azcOxlHK9k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611257791; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=O4YI1EEst7ASM2nPbCotL+WvyY6JhbbLhX7WIfk9tp0=; b=CSSU73TUleXodlKNPQiQ4ejn9KBN0I4kD4LSPw+Xp8PcnbAjlwirMDjQaSZFPW3rUmSXUVr7NKfQSz609L4pMWoOxbo3axrGHfJCoPHclcXk2A+jXPS2rmrT/tEN+UHU/uiMmktBkhQr+RyqZfTzPw0TMbQPJyjM2i7jefFUimE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1611257791685579.0544190860344; Thu, 21 Jan 2021 11:36:31 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-257-Wtrd9L8COTmMZ4jiPi67_A-1; Thu, 21 Jan 2021 14:35:06 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 255948030B5; Thu, 21 Jan 2021 19:35:00 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A2A8F5D9E3; Thu, 21 Jan 2021 19:34:59 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 3C7C950036; Thu, 21 Jan 2021 19:34:59 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 10LJYspu023301 for ; Thu, 21 Jan 2021 14:34:54 -0500 Received: by smtp.corp.redhat.com (Postfix) id B764C10023B9; Thu, 21 Jan 2021 19:34:54 +0000 (UTC) Received: from antique-laptop.redhat.com (unknown [10.40.208.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id ACAEF100AE40 for ; Thu, 21 Jan 2021 19:34:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611257790; 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: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=O4YI1EEst7ASM2nPbCotL+WvyY6JhbbLhX7WIfk9tp0=; b=gCqoYP5IUrrxL+i22DPyrxe6pZtmkjWMT6CrSSbv4uexRaStqv3gPHRhKz/aOxuqRI8dXH qvifwpbRuNq6AgIXp8z/AQ/xqsU6ZarWXgmFkxUhmF7a1yEr3sP+hQ0fxxccXqBuPLrewU 2AFi1ONVs2hnvMbxrfIvTcNPZvsgTG4= X-MC-Unique: Wtrd9L8COTmMZ4jiPi67_A-1 From: Pavel Hrdina To: libvir-list@redhat.com Subject: [libvirt PATCH v2 13/13] storage_source: use virStorageSource prefix for all functions Date: Thu, 21 Jan 2021 20:34:27 +0100 Message-Id: <081d955537d3ff8ab37c5180e7f61bdcbfbe7147.1611257578.git.phrdina@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Signed-off-by: Pavel Hrdina Reviewed-by: Peter Krempa --- src/libvirt_private.syms | 42 ++--- src/qemu/qemu_backup.c | 8 +- src/qemu/qemu_block.c | 6 +- src/qemu/qemu_domain.c | 16 +- src/qemu/qemu_driver.c | 66 +++---- src/qemu/qemu_hotplug.c | 4 +- src/qemu/qemu_process.c | 4 +- src/qemu/qemu_snapshot.c | 20 +-- src/security/virt-aa-helper.c | 2 +- src/storage/storage_backend_gluster.c | 4 +- src/storage/storage_util.c | 6 +- src/storage_file/storage_source.c | 250 +++++++++++++------------- src/storage_file/storage_source.h | 90 +++++----- tests/virstoragetest.c | 18 +- 14 files changed, 268 insertions(+), 268 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 088474d54b..41fa8ae5ba 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1686,30 +1686,30 @@ virStorageFileProbeGetMetadata; =20 =20 # storage_file/storage_source.h -virStorageFileAccess; -virStorageFileChainLookup; -virStorageFileChown; -virStorageFileCreate; -virStorageFileDeinit; -virStorageFileGetBackingStoreStr; -virStorageFileGetMetadata; -virStorageFileGetMetadataFromBuf; -virStorageFileGetMetadataFromFD; -virStorageFileGetRelativeBackingPath; -virStorageFileGetUniqueIdentifier; -virStorageFileInit; -virStorageFileInitAs; -virStorageFileRead; -virStorageFileReportBrokenChain; -virStorageFileStat; -virStorageFileSupportsAccess; -virStorageFileSupportsBackingChainTraversal; -virStorageFileSupportsCreate; -virStorageFileSupportsSecurityDriver; -virStorageFileUnlink; +virStorageSourceAccess; +virStorageSourceChainLookup; +virStorageSourceChown; +virStorageSourceCreate; +virStorageSourceDeinit; +virStorageSourceGetBackingStoreStr; +virStorageSourceGetMetadata; +virStorageSourceGetMetadataFromBuf; +virStorageSourceGetMetadataFromFD; +virStorageSourceGetRelativeBackingPath; +virStorageSourceGetUniqueIdentifier; +virStorageSourceInit; +virStorageSourceInitAs; virStorageSourceNewFromBacking; virStorageSourceNewFromBackingAbsolute; virStorageSourceParseRBDColonString; +virStorageSourceRead; +virStorageSourceReportBrokenChain; +virStorageSourceStat; +virStorageSourceSupportsAccess; +virStorageSourceSupportsBackingChainTraversal; +virStorageSourceSupportsCreate; +virStorageSourceSupportsSecurityDriver; +virStorageSourceUnlink; virStorageSourceUpdateBackingSizes; virStorageSourceUpdateCapacity; virStorageSourceUpdatePhysicalSize; diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 4a07f6a5f4..423de9c719 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -135,7 +135,7 @@ qemuBackupDiskDataCleanupOne(virDomainObjPtr vm, } =20 if (dd->created) { - if (virStorageFileUnlink(dd->store) < 0) + if (virStorageSourceUnlink(dd->store) < 0) VIR_WARN("Unable to remove just-created %s", NULLSTR(dd->s= tore->path)); } =20 @@ -144,7 +144,7 @@ qemuBackupDiskDataCleanupOne(virDomainObjPtr vm, } =20 if (dd->initialized) - virStorageFileDeinit(dd->store); + virStorageSourceDeinit(dd->store); =20 if (dd->blockjob) qemuBlockJobStartupFinalize(vm, dd->blockjob); @@ -429,7 +429,7 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm, =20 if (!reuse_external && dd->store->type =3D=3D VIR_STORAGE_TYPE_FILE && - virStorageFileSupportsCreate(dd->store)) { + virStorageSourceSupportsCreate(dd->store)) { =20 if (virFileExists(dd->store->path)) { virReportError(VIR_ERR_INVALID_ARG, @@ -443,7 +443,7 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm, =20 dd->initialized =3D true; =20 - if (virStorageFileCreate(dd->store) < 0) { + if (virStorageSourceCreate(dd->store) < 0) { virReportSystemError(errno, _("failed to create image file '%s'"), NULLSTR(dd->store->path)); diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index fafa35071c..15019657e4 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3426,15 +3426,15 @@ qemuBlockUpdateRelativeBacking(virDomainObjPtr vm, if (n->backingStore->relPath) break; =20 - if (!virStorageFileSupportsBackingChainTraversal(n)) + if (!virStorageSourceSupportsBackingChainTraversal(n)) continue; =20 if (qemuDomainStorageFileInit(driver, vm, n, topsrc) < 0) return -1; =20 - rc =3D virStorageFileGetBackingStoreStr(n, &backingStoreStr); + rc =3D virStorageSourceGetBackingStoreStr(n, &backingStoreStr); =20 - virStorageFileDeinit(n); + virStorageSourceDeinit(n); =20 if (rc < 0) return rc; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 165321858e..0c078a9388 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7160,7 +7160,7 @@ qemuDomainStorageFileInit(virQEMUDriverPtr driver, =20 qemuDomainGetImageIds(cfg, vm, src, parent, &uid, &gid); =20 - if (virStorageFileInitAs(src, uid, gid) < 0) + if (virStorageSourceInitAs(src, uid, gid) < 0) return -1; =20 return 0; @@ -7298,7 +7298,7 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, =20 if (!virFileExists(disksrc->path)) { if (report_broken) - virStorageFileReportBrokenChain(errno, disksrc, disksrc); + virStorageSourceReportBrokenChain(errno, disksrc, disksrc); =20 return -1; } @@ -7322,7 +7322,7 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, /* skip to the end of the chain if there is any */ while (virStorageSourceHasBacking(src)) { if (report_broken) { - int rv =3D virStorageFileSupportsAccess(src); + int rv =3D virStorageSourceSupportsAccess(src); =20 if (rv < 0) return -1; @@ -7331,13 +7331,13 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr drive= r, if (qemuDomainStorageFileInit(driver, vm, src, disksrc) < = 0) return -1; =20 - if (virStorageFileAccess(src, F_OK) < 0) { - virStorageFileReportBrokenChain(errno, src, disksrc); - virStorageFileDeinit(src); + if (virStorageSourceAccess(src, F_OK) < 0) { + virStorageSourceReportBrokenChain(errno, src, disksrc); + virStorageSourceDeinit(src); return -1; } =20 - virStorageFileDeinit(src); + virStorageSourceDeinit(src); } } src =3D src->backingStore; @@ -7354,7 +7354,7 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, =20 qemuDomainGetImageIds(cfg, vm, src, disksrc, &uid, &gid); =20 - if (virStorageFileGetMetadata(src, uid, gid, report_broken) < 0) + if (virStorageSourceGetMetadata(src, uid, gid, report_broken) < 0) return -1; =20 for (n =3D src->backingStore; virStorageSourceIsBacking(n); n =3D n->b= ackingStore) { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8048c86632..ed966cf7e3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -253,20 +253,20 @@ qemuSecurityChownCallback(const virStorageSource *src, return 0; } =20 - if ((rv =3D virStorageFileSupportsSecurityDriver(src)) <=3D 0) + if ((rv =3D virStorageSourceSupportsSecurityDriver(src)) <=3D 0) return rv; =20 if (!(cpy =3D virStorageSourceCopy(src, false))) return -1; =20 /* src file init reports errors, return -2 on failure */ - if (virStorageFileInit(cpy) < 0) + if (virStorageSourceInit(cpy) < 0) return -2; =20 - ret =3D virStorageFileChown(cpy, uid, gid); + ret =3D virStorageSourceChown(cpy, uid, gid); =20 save_errno =3D errno; - virStorageFileDeinit(cpy); + virStorageSourceDeinit(cpy); errno =3D save_errno; =20 return ret; @@ -10620,7 +10620,7 @@ qemuDomainBlockPeek(virDomainPtr dom, if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL) < 0) goto cleanup; =20 - if ((nread =3D virStorageFileRead(disk->src, offset, size, &tmpbuf)) <= 0) { + if ((nread =3D virStorageSourceRead(disk->src, offset, size, &tmpbuf))= < 0) { if (nread =3D=3D -2) { virReportError(VIR_ERR_INTERNAL_ERROR, _("storage file reading is not supported for " @@ -10644,7 +10644,7 @@ qemuDomainBlockPeek(virDomainPtr dom, =20 cleanup: if (disk) - virStorageFileDeinit(disk->src); + virStorageSourceDeinit(disk->src); virDomainObjEndAPI(&vm); return ret; } @@ -10776,14 +10776,14 @@ qemuDomainStorageOpenStat(virQEMUDriverPtr driver, return -1; } } else { - if (skipInaccessible && virStorageFileSupportsBackingChainTraversa= l(src) <=3D 0) + if (skipInaccessible && virStorageSourceSupportsBackingChainTraver= sal(src) <=3D 0) return 0; =20 - if (virStorageFileInitAs(src, cfg->user, cfg->group) < 0) + if (virStorageSourceInitAs(src, cfg->user, cfg->group) < 0) return -1; =20 - if (virStorageFileStat(src, ret_sb) < 0) { - virStorageFileDeinit(src); + if (virStorageSourceStat(src, ret_sb) < 0) { + virStorageSourceDeinit(src); virReportSystemError(errno, _("failed to stat remote file '%s'= "), NULLSTR(src->path)); return -1; @@ -10808,7 +10808,7 @@ qemuDomainStorageCloseStat(virStorageSourcePtr src, if (virStorageSourceIsLocalStorage(src)) VIR_FORCE_CLOSE(*fd); else - virStorageFileDeinit(src); + virStorageSourceDeinit(src); } =20 =20 @@ -10908,7 +10908,7 @@ qemuStorageLimitsRefresh(virQEMUDriverPtr driver, goto cleanup; } } else { - if ((len =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, &b= uf)) < 0) + if ((len =3D virStorageSourceRead(src, 0, VIR_STORAGE_MAX_HEADER, = &buf)) < 0) goto cleanup; } =20 @@ -14449,8 +14449,8 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm, =20 if (base && (virStorageFileParseChainIndex(disk->dst, base, &baseIndex) < 0 || - !(baseSource =3D virStorageFileChainLookup(disk->src, disk->src, - base, baseIndex, NULL)))) + !(baseSource =3D virStorageSourceChainLookup(disk->src, disk->src, + base, baseIndex, NULL)= ))) goto endjob; =20 if (baseSource) { @@ -14466,9 +14466,9 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm, qemuBlockUpdateRelativeBacking(vm, disk->src, disk->src) <= 0) goto endjob; =20 - if (virStorageFileGetRelativeBackingPath(disk->src->backingSto= re, - baseSource, - &backingPath) < 0) + if (virStorageSourceGetRelativeBackingPath(disk->src->backingS= tore, + baseSource, + &backingPath) < 0) goto endjob; =20 if (!backingPath) { @@ -14839,7 +14839,7 @@ qemuDomainBlockCopyValidateMirror(virStorageSourceP= tr mirror, if (!virStorageSourceIsLocalStorage(mirror)) return 0; =20 - if (virStorageFileAccess(mirror, F_OK) < 0) { + if (virStorageSourceAccess(mirror, F_OK) < 0) { if (errno !=3D ENOENT) { virReportSystemError(errno, "%s", _("unable to verify existence of " @@ -14854,7 +14854,7 @@ qemuDomainBlockCopyValidateMirror(virStorageSourceP= tr mirror, return -1; } } else { - if (virStorageFileStat(mirror, &st) < 0) { + if (virStorageSourceStat(mirror, &st) < 0) { virReportSystemError(errno, _("unable to stat block copy target '%s'"= ), mirror->path); @@ -15058,9 +15058,9 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, goto endjob; } =20 - supports_access =3D virStorageFileSupportsAccess(mirror) =3D=3D 1; - supports_create =3D virStorageFileSupportsCreate(mirror) =3D=3D 1; - supports_detect =3D virStorageFileSupportsBackingChainTraversal(mirror= ) =3D=3D 1; + supports_access =3D virStorageSourceSupportsAccess(mirror) =3D=3D 1; + supports_create =3D virStorageSourceSupportsCreate(mirror) =3D=3D 1; + supports_detect =3D virStorageSourceSupportsBackingChainTraversal(mirr= or) =3D=3D 1; =20 if (supports_access || supports_create || supports_detect) { if (qemuDomainStorageFileInit(driver, vm, mirror, NULL) < 0) @@ -15104,7 +15104,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, * required so that libvirt can properly label the image for access by= qemu */ if (!existing) { if (supports_create) { - if (virStorageFileCreate(mirror) < 0) { + if (virStorageSourceCreate(mirror) < 0) { virReportSystemError(errno, "%s", _("failed to create copy= target")); goto endjob; } @@ -15247,7 +15247,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, =20 /* Update vm in place to match changes. */ need_unlink =3D false; - virStorageFileDeinit(mirror); + virStorageSourceDeinit(mirror); disk->mirror =3D g_steal_pointer(&mirror); disk->mirrorJob =3D VIR_DOMAIN_BLOCK_JOB_TYPE_COPY; qemuBlockJobStarted(job, vm); @@ -15266,9 +15266,9 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, if (need_revoke) qemuDomainStorageSourceChainAccessRevoke(driver, vm, mirror); } - if (need_unlink && virStorageFileUnlink(mirror) < 0) + if (need_unlink && virStorageSourceUnlink(mirror) < 0) VIR_WARN("%s", _("unable to remove just-created copy target")); - virStorageFileDeinit(mirror); + virStorageSourceDeinit(mirror); qemuDomainObjEndJob(driver, vm); qemuBlockJobStartupFinalize(vm, job); =20 @@ -15541,9 +15541,9 @@ qemuDomainBlockCommit(virDomainPtr dom, if (!top || STREQ(top, disk->dst)) topSource =3D disk->src; else if (virStorageFileParseChainIndex(disk->dst, top, &topIndex) < 0 = || - !(topSource =3D virStorageFileChainLookup(disk->src, NULL, - top, topIndex, - &top_parent))) + !(topSource =3D virStorageSourceChainLookup(disk->src, NULL, + top, topIndex, + &top_parent))) goto endjob; =20 if (topSource =3D=3D disk->src) { @@ -15576,8 +15576,8 @@ qemuDomainBlockCommit(virDomainPtr dom, if (!base && (flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)) baseSource =3D topSource->backingStore; else if (virStorageFileParseChainIndex(disk->dst, base, &baseIndex) < = 0 || - !(baseSource =3D virStorageFileChainLookup(disk->src, topSour= ce, - base, baseIndex, NUL= L))) + !(baseSource =3D virStorageSourceChainLookup(disk->src, topSo= urce, + base, baseIndex, N= ULL))) goto endjob; =20 if ((flags & VIR_DOMAIN_BLOCK_COMMIT_SHALLOW) && @@ -15611,8 +15611,8 @@ qemuDomainBlockCommit(virDomainPtr dom, qemuBlockUpdateRelativeBacking(vm, top_parent, disk->src) < 0) goto endjob; =20 - if (virStorageFileGetRelativeBackingPath(topSource, baseSource, - &backingPath) < 0) + if (virStorageSourceGetRelativeBackingPath(topSource, baseSource, + &backingPath) < 0) goto endjob; =20 if (!backingPath) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 99950a1360..882e5d2384 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4375,8 +4375,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, VIR_DEBUG("Removing transient overlay '%s' of disk '%s'", disk->src->path, disk->dst); if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL) >=3D 0)= { - virStorageFileUnlink(disk->src); - virStorageFileDeinit(disk->src); + virStorageSourceUnlink(disk->src); + virStorageSourceDeinit(disk->src); } } =20 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 14e1f5d962..f87a3c0f60 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7887,8 +7887,8 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_DEBUG("Removing transient overlay '%s' of disk '%s'", disk->src->path, disk->dst); if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL)= >=3D 0) { - virStorageFileUnlink(disk->src); - virStorageFileDeinit(disk->src); + virStorageSourceUnlink(disk->src); + virStorageSourceDeinit(disk->src); } } } diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 699090ae40..1c8b1a70f8 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -567,13 +567,13 @@ qemuSnapshotPrepareDiskExternal(virDomainObjPtr vm, } =20 if (virStorageSourceIsLocalStorage(snapdisk->src)) { - if (virStorageFileInit(snapdisk->src) < 0) + if (virStorageSourceInit(snapdisk->src) < 0) return -1; =20 - rc =3D virStorageFileStat(snapdisk->src, &st); + rc =3D virStorageSourceStat(snapdisk->src, &st); err =3D errno; =20 - virStorageFileDeinit(snapdisk->src); + virStorageSourceDeinit(snapdisk->src); =20 if (rc < 0) { if (err !=3D ENOENT) { @@ -867,13 +867,13 @@ qemuSnapshotDiskCleanup(qemuSnapshotDiskDataPtr data, } =20 if (data[i].created && - virStorageFileUnlink(data[i].src) < 0) { + virStorageSourceUnlink(data[i].src) < 0) { VIR_WARN("Unable to remove just-created %s", NULLSTR(data[i].src->path)); } =20 if (data[i].initialized) - virStorageFileDeinit(data[i].src); + virStorageSourceDeinit(data[i].src); =20 if (data[i].prepared) qemuDomainStorageSourceAccessRevoke(driver, vm, data[i].sr= c); @@ -1072,13 +1072,13 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm, return -1; } =20 - supportsCreate =3D virStorageFileSupportsCreate(dd->src); + supportsCreate =3D virStorageSourceSupportsCreate(dd->src); =20 /* relative backing store paths need to be updated so that relative * block commit still works. With blockdev we must update it when doing * commit anyways so it's skipped here */ if (!blockdev && - virStorageFileSupportsBackingChainTraversal(dd->src)) + virStorageSourceSupportsBackingChainTraversal(dd->src)) updateRelativeBacking =3D true; =20 if (supportsCreate || updateRelativeBacking) { @@ -1091,7 +1091,7 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm, if (updateRelativeBacking) { g_autofree char *backingStoreStr =3D NULL; =20 - if (virStorageFileGetBackingStoreStr(dd->src, &backingStor= eStr) < 0) + if (virStorageSourceGetBackingStoreStr(dd->src, &backingSt= oreStr) < 0) return -1; if (backingStoreStr !=3D NULL) { if (virStorageFileIsRelative(backingStoreStr)) @@ -1101,7 +1101,7 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm, } else { /* pre-create the image file so that we can label it before ha= nding it to qemu */ if (supportsCreate && dd->src->type !=3D VIR_STORAGE_TYPE_BLOC= K) { - if (virStorageFileCreate(dd->src) < 0) { + if (virStorageSourceCreate(dd->src) < 0) { virReportSystemError(errno, _("failed to create image = file '%s'"), NULLSTR(dd->src->path)); return -1; @@ -1251,7 +1251,7 @@ qemuSnapshotDiskUpdateSource(virDomainObjPtr vm, =20 /* storage driver access won'd be needed */ if (dd->initialized) - virStorageFileDeinit(dd->src); + virStorageSourceDeinit(dd->src); =20 if (qemuSecurityMoveImageMetadata(driver, vm, dd->disk->src, dd->src) = < 0) VIR_WARN("Unable to move disk metadata on vm %s", vm->def->name); diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 6525baf193..f71fe6f23b 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -939,7 +939,7 @@ get_files(vahControl * ctl) * so that the open could be re-tried as that user:group. */ if (!virStorageSourceHasBacking(disk->src)) - virStorageFileGetMetadata(disk->src, -1, -1, false); + virStorageSourceGetMetadata(disk->src, -1, -1, false); =20 /* XXX should handle open errors more careful than just ignoring = them. */ diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index 554c76ddb4..8de0cb8a6b 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -272,8 +272,8 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlu= sterStatePtr state, &header)) < 0) goto cleanup; =20 - if (!(meta =3D virStorageFileGetMetadataFromBuf(name, header, len, - VIR_STORAGE_FILE_AUTO))) + if (!(meta =3D virStorageSourceGetMetadataFromBuf(name, header, len, + VIR_STORAGE_FILE_AUTO)= )) goto cleanup; =20 if (meta->backingStoreRaw) { diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 10c04e1257..3d8de16341 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -3427,9 +3427,9 @@ storageBackendProbeTarget(virStorageSourcePtr target, } } =20 - if (!(meta =3D virStorageFileGetMetadataFromFD(target->path, - fd, - VIR_STORAGE_FILE_AUTO))) + if (!(meta =3D virStorageSourceGetMetadataFromFD(target->path, + fd, + VIR_STORAGE_FILE_AUTO))) return -1; =20 if (meta->backingStoreRaw) { diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_s= ource.c index ffc7fe8ea5..71bff1e55e 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -46,8 +46,8 @@ VIR_LOG_INIT("storage_source"); =20 =20 static virStorageSourcePtr -virStorageFileMetadataNew(const char *path, - int format) +virStorageSourceMetadataNew(const char *path, + int format) { g_autoptr(virStorageSource) def =3D virStorageSourceNew(); =20 @@ -61,7 +61,7 @@ virStorageFileMetadataNew(const char *path, =20 =20 /** - * virStorageFileGetMetadataFromBuf: + * virStorageSourceGetMetadataFromBuf: * @path: name of file, for error messages * @buf: header bytes from @path * @len: length of @buf @@ -83,14 +83,14 @@ virStorageFileMetadataNew(const char *path, * Caller MUST free the result after use via virObjectUnref. */ virStorageSourcePtr -virStorageFileGetMetadataFromBuf(const char *path, - char *buf, - size_t len, - int format) +virStorageSourceGetMetadataFromBuf(const char *path, + char *buf, + size_t len, + int format) { virStorageSourcePtr ret =3D NULL; =20 - if (!(ret =3D virStorageFileMetadataNew(path, format))) + if (!(ret =3D virStorageSourceMetadataNew(path, format))) return NULL; =20 if (virStorageFileProbeGetMetadata(ret, buf, len) < 0) { @@ -103,7 +103,7 @@ virStorageFileGetMetadataFromBuf(const char *path, =20 =20 /** - * virStorageFileGetMetadataFromFD: + * virStorageSourceGetMetadataFromFD: * * Extract metadata about the storage volume with the specified * image format. If image format is VIR_STORAGE_FILE_AUTO, it @@ -116,9 +116,9 @@ virStorageFileGetMetadataFromBuf(const char *path, * Caller MUST free the result after use via virObjectUnref. */ virStorageSourcePtr -virStorageFileGetMetadataFromFD(const char *path, - int fd, - int format) +virStorageSourceGetMetadataFromFD(const char *path, + int fd, + int format) =20 { ssize_t len =3D VIR_STORAGE_MAX_HEADER; @@ -132,7 +132,7 @@ virStorageFileGetMetadataFromFD(const char *path, return NULL; } =20 - if (!(meta =3D virStorageFileMetadataNew(path, format))) + if (!(meta =3D virStorageSourceMetadataNew(path, format))) return NULL; =20 if (S_ISDIR(sb.st_mode)) { @@ -177,11 +177,11 @@ virStorageFileGetMetadataFromFD(const char *path, * found. */ virStorageSourcePtr -virStorageFileChainLookup(virStorageSourcePtr chain, - virStorageSourcePtr startFrom, - const char *name, - unsigned int idx, - virStorageSourcePtr *parent) +virStorageSourceChainLookup(virStorageSourcePtr chain, + virStorageSourcePtr startFrom, + const char *name, + unsigned int idx, + virStorageSourcePtr *parent) { virStorageSourcePtr prev; const char *start =3D chain->path; @@ -1794,8 +1794,8 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr sr= c, =20 if (format =3D=3D VIR_STORAGE_FILE_RAW && !src->encryption) { src->capacity =3D src->physical; - } else if ((meta =3D virStorageFileGetMetadataFromBuf(src->path, buf, - len, format))) { + } else if ((meta =3D virStorageSourceGetMetadataFromBuf(src->path, buf, + len, format))) { src->capacity =3D meta->capacity ? meta->capacity : src->physical; if (src->encryption && meta->encryption) src->encryption->payload_offset =3D meta->encryption->payload_= offset; @@ -1811,7 +1811,7 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr sr= c, =20 =20 /** - * virStorageFileRemoveLastPathComponent: + * virStorageSourceRemoveLastPathComponent: * * @path: Path string to remove the last component from * @@ -1820,7 +1820,7 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr sr= c, * responsible to free the returned string. */ static char * -virStorageFileRemoveLastPathComponent(const char *path) +virStorageSourceRemoveLastPathComponent(const char *path) { char *ret; =20 @@ -1833,7 +1833,7 @@ virStorageFileRemoveLastPathComponent(const char *pat= h) =20 =20 /* - * virStorageFileGetRelativeBackingPath: + * virStorageSourceGetRelativeBackingPath: * * Resolve relative path to be written to the overlay of @top image when * collapsing the backing chain between @top and @base. @@ -1841,9 +1841,9 @@ virStorageFileRemoveLastPathComponent(const char *pat= h) * Returns 0 on success; 1 if backing chain isn't relative and -1 on error. */ int -virStorageFileGetRelativeBackingPath(virStorageSourcePtr top, - virStorageSourcePtr base, - char **relpath) +virStorageSourceGetRelativeBackingPath(virStorageSourcePtr top, + virStorageSourcePtr base, + char **relpath) { virStorageSourcePtr next; g_autofree char *tmp =3D NULL; @@ -1855,7 +1855,7 @@ virStorageFileGetRelativeBackingPath(virStorageSource= Ptr top, if (!next->relPath) return 1; =20 - if (!(tmp =3D virStorageFileRemoveLastPathComponent(path))) + if (!(tmp =3D virStorageSourceRemoveLastPathComponent(path))) return -1; =20 VIR_FREE(path); @@ -1881,14 +1881,14 @@ virStorageFileGetRelativeBackingPath(virStorageSour= cePtr top, =20 =20 static bool -virStorageFileIsInitialized(const virStorageSource *src) +virStorageSourceIsInitialized(const virStorageSource *src) { return src && src->drv; } =20 =20 /** - * virStorageFileGetBackendForSupportCheck: + * virStorageSourceGetBackendForSupportCheck: * @src: storage source to check support for * @backend: pointer to the storage backend for @src if it's supported * @@ -1896,8 +1896,8 @@ virStorageFileIsInitialized(const virStorageSource *s= rc) * 1 if it is supported and -1 on error with an error reported. */ static int -virStorageFileGetBackendForSupportCheck(const virStorageSource *src, - virStorageFileBackendPtr *backend) +virStorageSourceGetBackendForSupportCheck(const virStorageSource *src, + virStorageFileBackendPtr *backen= d) { int actualType; =20 @@ -1926,12 +1926,12 @@ virStorageFileGetBackendForSupportCheck(const virSt= orageSource *src, =20 =20 int -virStorageFileSupportsBackingChainTraversal(const virStorageSource *src) +virStorageSourceSupportsBackingChainTraversal(const virStorageSource *src) { virStorageFileBackendPtr backend; int rv; =20 - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + if ((rv =3D virStorageSourceGetBackendForSupportCheck(src, &backend)) = < 1) return rv; =20 return backend->storageFileGetUniqueIdentifier && @@ -1941,7 +1941,7 @@ virStorageFileSupportsBackingChainTraversal(const vir= StorageSource *src) =20 =20 /** - * virStorageFileSupportsSecurityDriver: + * virStorageSourceSupportsSecurityDriver: * * @src: a storage file structure * @@ -1949,12 +1949,12 @@ virStorageFileSupportsBackingChainTraversal(const v= irStorageSource *src) * driver to perform labelling */ int -virStorageFileSupportsSecurityDriver(const virStorageSource *src) +virStorageSourceSupportsSecurityDriver(const virStorageSource *src) { virStorageFileBackendPtr backend; int rv; =20 - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + if ((rv =3D virStorageSourceGetBackendForSupportCheck(src, &backend)) = < 1) return rv; =20 return backend->storageFileChown ? 1 : 0; @@ -1962,7 +1962,7 @@ virStorageFileSupportsSecurityDriver(const virStorage= Source *src) =20 =20 /** - * virStorageFileSupportsAccess: + * virStorageSourceSupportsAccess: * * @src: a storage file structure * @@ -1970,12 +1970,12 @@ virStorageFileSupportsSecurityDriver(const virStora= geSource *src) * for the given vm. */ int -virStorageFileSupportsAccess(const virStorageSource *src) +virStorageSourceSupportsAccess(const virStorageSource *src) { virStorageFileBackendPtr backend; int rv; =20 - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + if ((rv =3D virStorageSourceGetBackendForSupportCheck(src, &backend)) = < 1) return rv; =20 return backend->storageFileAccess ? 1 : 0; @@ -1983,19 +1983,19 @@ virStorageFileSupportsAccess(const virStorageSource= *src) =20 =20 /** - * virStorageFileSupportsCreate: + * virStorageSourceSupportsCreate: * @src: a storage file structure * * Check if the storage driver supports creating storage described by @src - * via virStorageFileCreate. + * via virStorageSourceCreate. */ int -virStorageFileSupportsCreate(const virStorageSource *src) +virStorageSourceSupportsCreate(const virStorageSource *src) { virStorageFileBackendPtr backend; int rv; =20 - if ((rv =3D virStorageFileGetBackendForSupportCheck(src, &backend)) < = 1) + if ((rv =3D virStorageSourceGetBackendForSupportCheck(src, &backend)) = < 1) return rv; =20 return backend->storageFileCreate ? 1 : 0; @@ -2003,11 +2003,11 @@ virStorageFileSupportsCreate(const virStorageSource= *src) =20 =20 void -virStorageFileDeinit(virStorageSourcePtr src) +virStorageSourceDeinit(virStorageSourcePtr src) { virStorageDriverDataPtr drv =3D NULL; =20 - if (!virStorageFileIsInitialized(src)) + if (!virStorageSourceIsInitialized(src)) return; =20 drv =3D src->drv; @@ -2021,7 +2021,7 @@ virStorageFileDeinit(virStorageSourcePtr src) =20 =20 /** - * virStorageFileInitAs: + * virStorageSourceInitAs: * * @src: storage source definition * @uid: uid used to access the file, or -1 for current uid @@ -2034,8 +2034,8 @@ virStorageFileDeinit(virStorageSourcePtr src) * initialization failed. Libvirt error is reported. */ int -virStorageFileInitAs(virStorageSourcePtr src, - uid_t uid, gid_t gid) +virStorageSourceInitAs(virStorageSourcePtr src, + uid_t uid, gid_t gid) { int actualType =3D virStorageSourceGetActualType(src); virStorageDriverDataPtr drv =3D g_new0(virStorageDriverData, 1); @@ -2071,20 +2071,20 @@ virStorageFileInitAs(virStorageSourcePtr src, =20 =20 /** - * virStorageFileInit: + * virStorageSourceInit: * - * See virStorageFileInitAs. The file is initialized to be accessed by the + * See virStorageSourceInitAs. The file is initialized to be accessed by t= he * current user. */ int -virStorageFileInit(virStorageSourcePtr src) +virStorageSourceInit(virStorageSourcePtr src) { - return virStorageFileInitAs(src, -1, -1); + return virStorageSourceInitAs(src, -1, -1); } =20 =20 /** - * virStorageFileCreate: Creates an empty storage file via storage driver + * virStorageSourceCreate: Creates an empty storage file via storage driver * * @src: file structure pointing to the file * @@ -2092,12 +2092,12 @@ virStorageFileInit(virStorageSourcePtr src) * -1 on other failure. Errno is set in case of failure. */ int -virStorageFileCreate(virStorageSourcePtr src) +virStorageSourceCreate(virStorageSourcePtr src) { virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { errno =3D ENOSYS; return -2; } @@ -2119,7 +2119,7 @@ virStorageFileCreate(virStorageSourcePtr src) =20 =20 /** - * virStorageFileUnlink: Unlink storage file via storage driver + * virStorageSourceUnlink: Unlink storage file via storage driver * * @src: file structure pointing to the file * @@ -2129,12 +2129,12 @@ virStorageFileCreate(virStorageSourcePtr src) * -1 on other failure. Errno is set in case of failure. */ int -virStorageFileUnlink(virStorageSourcePtr src) +virStorageSourceUnlink(virStorageSourcePtr src) { virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { errno =3D ENOSYS; return -2; } @@ -2156,7 +2156,7 @@ virStorageFileUnlink(virStorageSourcePtr src) =20 =20 /** - * virStorageFileStat: returns stat struct of a file via storage driver + * virStorageSourceStat: returns stat struct of a file via storage driver * * @src: file structure pointing to the file * @stat: stat structure to return data @@ -2165,13 +2165,13 @@ virStorageFileUnlink(virStorageSourcePtr src) * -1 on other failure. Errno is set in case of failure. */ int -virStorageFileStat(virStorageSourcePtr src, - struct stat *st) +virStorageSourceStat(virStorageSourcePtr src, + struct stat *st) { virStorageDriverDataPtr drv =3D NULL; int ret; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { errno =3D ENOSYS; return -2; } @@ -2193,7 +2193,7 @@ virStorageFileStat(virStorageSourcePtr src, =20 =20 /** - * virStorageFileRead: read bytes from a file into a buffer + * virStorageSourceRead: read bytes from a file into a buffer * * @src: file structure pointing to the file * @offset: number of bytes to skip in the storage file @@ -2205,15 +2205,15 @@ virStorageFileStat(virStorageSourcePtr src, * Libvirt error is reported on failure. */ ssize_t -virStorageFileRead(virStorageSourcePtr src, - size_t offset, - size_t len, - char **buf) +virStorageSourceRead(virStorageSourcePtr src, + size_t offset, + size_t len, + char **buf) { virStorageDriverDataPtr drv =3D NULL; ssize_t ret; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("storage file backend not initialized")); return -1; @@ -2234,7 +2234,7 @@ virStorageFileRead(virStorageSourcePtr src, =20 =20 /* - * virStorageFileGetUniqueIdentifier: Get a unique string describing the v= olume + * virStorageSourceGetUniqueIdentifier: Get a unique string describing the= volume * * @src: file structure pointing to the file * @@ -2242,11 +2242,11 @@ virStorageFileRead(virStorageSourcePtr src, * The string shall not be freed and is valid until the storage file is * deinitialized. Returns NULL on error and sets a libvirt error code */ const char * -virStorageFileGetUniqueIdentifier(virStorageSourcePtr src) +virStorageSourceGetUniqueIdentifier(virStorageSourcePtr src) { virStorageDriverDataPtr drv =3D NULL; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("storage file backend not initialized")); return NULL; @@ -2268,7 +2268,7 @@ virStorageFileGetUniqueIdentifier(virStorageSourcePtr= src) =20 =20 /** - * virStorageFileAccess: Check accessibility of a storage file + * virStorageSourceAccess: Check accessibility of a storage file * * @src: storage file to check access permissions * @mode: accessibility check options (see man 2 access) @@ -2278,12 +2278,12 @@ virStorageFileGetUniqueIdentifier(virStorageSourceP= tr src) * by libvirt storage backend. */ int -virStorageFileAccess(virStorageSourcePtr src, - int mode) +virStorageSourceAccess(virStorageSourcePtr src, + int mode) { virStorageDriverDataPtr drv =3D NULL; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { errno =3D ENOSYS; return -2; } @@ -2300,7 +2300,7 @@ virStorageFileAccess(virStorageSourcePtr src, =20 =20 /** - * virStorageFileChown: Change owner of a storage file + * virStorageSourceChown: Change owner of a storage file * * @src: storage file to change owner of * @uid: new owner id @@ -2311,13 +2311,13 @@ virStorageFileAccess(virStorageSourcePtr src, * by libvirt storage backend. */ int -virStorageFileChown(const virStorageSource *src, - uid_t uid, - gid_t gid) +virStorageSourceChown(const virStorageSource *src, + uid_t uid, + gid_t gid) { virStorageDriverDataPtr drv =3D NULL; =20 - if (!virStorageFileIsInitialized(src)) { + if (!virStorageSourceIsInitialized(src)) { errno =3D ENOSYS; return -2; } @@ -2337,7 +2337,7 @@ virStorageFileChown(const virStorageSource *src, =20 =20 /** - * virStorageFileReportBrokenChain: + * virStorageSourceReportBrokenChain: * * @errcode: errno when accessing @src * @src: inaccessible file in the backing chain of @parent @@ -2347,9 +2347,9 @@ virStorageFileChown(const virStorageSource *src, * for @parent. */ void -virStorageFileReportBrokenChain(int errcode, - virStorageSourcePtr src, - virStorageSourcePtr parent) +virStorageSourceReportBrokenChain(int errcode, + virStorageSourcePtr src, + virStorageSourcePtr parent) { if (src->drv) { virStorageDriverDataPtr drv =3D src->drv; @@ -2383,27 +2383,27 @@ virStorageFileReportBrokenChain(int errcode, =20 =20 static int -virStorageFileGetMetadataRecurseReadHeader(virStorageSourcePtr src, - virStorageSourcePtr parent, - uid_t uid, - gid_t gid, - char **buf, - size_t *headerLen, - GHashTable *cycle) +virStorageSourceGetMetadataRecurseReadHeader(virStorageSourcePtr src, + virStorageSourcePtr parent, + uid_t uid, + gid_t gid, + char **buf, + size_t *headerLen, + GHashTable *cycle) { int ret =3D -1; const char *uniqueName; ssize_t len; =20 - if (virStorageFileInitAs(src, uid, gid) < 0) + if (virStorageSourceInitAs(src, uid, gid) < 0) return -1; =20 - if (virStorageFileAccess(src, F_OK) < 0) { - virStorageFileReportBrokenChain(errno, src, parent); + if (virStorageSourceAccess(src, F_OK) < 0) { + virStorageSourceReportBrokenChain(errno, src, parent); goto cleanup; } =20 - if (!(uniqueName =3D virStorageFileGetUniqueIdentifier(src))) + if (!(uniqueName =3D virStorageSourceGetUniqueIdentifier(src))) goto cleanup; =20 if (virHashHasEntry(cycle, uniqueName)) { @@ -2416,26 +2416,26 @@ virStorageFileGetMetadataRecurseReadHeader(virStora= geSourcePtr src, if (virHashAddEntry(cycle, uniqueName, NULL) < 0) goto cleanup; =20 - if ((len =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, buf)) = < 0) + if ((len =3D virStorageSourceRead(src, 0, VIR_STORAGE_MAX_HEADER, buf)= ) < 0) goto cleanup; =20 *headerLen =3D len; ret =3D 0; =20 cleanup: - virStorageFileDeinit(src); + virStorageSourceDeinit(src); return ret; } =20 =20 -/* Recursive workhorse for virStorageFileGetMetadata. */ +/* Recursive workhorse for virStorageSourceGetMetadata. */ static int -virStorageFileGetMetadataRecurse(virStorageSourcePtr src, - virStorageSourcePtr parent, - uid_t uid, gid_t gid, - bool report_broken, - GHashTable *cycle, - unsigned int depth) +virStorageSourceGetMetadataRecurse(virStorageSourcePtr src, + virStorageSourcePtr parent, + uid_t uid, gid_t gid, + bool report_broken, + GHashTable *cycle, + unsigned int depth) { virStorageFileFormat orig_format =3D src->format; size_t headerLen; @@ -2451,7 +2451,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr = src, src->format =3D VIR_STORAGE_FILE_AUTO; =20 /* exit if we can't load information about the current image */ - rv =3D virStorageFileSupportsBackingChainTraversal(src); + rv =3D virStorageSourceSupportsBackingChainTraversal(src); if (rv <=3D 0) { if (orig_format =3D=3D VIR_STORAGE_FILE_AUTO) return -2; @@ -2459,8 +2459,8 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr = src, return rv; } =20 - if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid, - &buf, &headerLen, cycle= ) < 0) + if (virStorageSourceGetMetadataRecurseReadHeader(src, parent, uid, gid, + &buf, &headerLen, cyc= le) < 0) return -1; =20 if (virStorageFileProbeGetMetadata(src, buf, headerLen) < 0) @@ -2484,10 +2484,10 @@ virStorageFileGetMetadataRecurse(virStorageSourcePt= r src, if (rv =3D=3D 1) return 0; =20 - if ((rv =3D virStorageFileGetMetadataRecurse(backingStore, parent, - uid, gid, - report_broken, - cycle, depth + 1)) < 0)= { + if ((rv =3D virStorageSourceGetMetadataRecurse(backingStore, paren= t, + uid, gid, + report_broken, + cycle, depth + 1)) < = 0) { if (!report_broken) return 0; =20 @@ -2513,7 +2513,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr = src, =20 =20 /** - * virStorageFileGetMetadata: + * virStorageSourceGetMetadata: * * Extract metadata about the storage volume with the specified * image format. If image format is VIR_STORAGE_FILE_AUTO, it @@ -2534,9 +2534,9 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr = src, * Caller MUST free result after use via virObjectUnref. */ int -virStorageFileGetMetadata(virStorageSourcePtr src, - uid_t uid, gid_t gid, - bool report_broken) +virStorageSourceGetMetadata(virStorageSourcePtr src, + uid_t uid, gid_t gid, + bool report_broken) { GHashTable *cycle =3D NULL; virStorageType actualType =3D virStorageSourceGetActualType(src); @@ -2556,8 +2556,8 @@ virStorageFileGetMetadata(virStorageSourcePtr src, src->format =3D VIR_STORAGE_FILE_RAW; } =20 - ret =3D virStorageFileGetMetadataRecurse(src, src, uid, gid, - report_broken, cycle, 1); + ret =3D virStorageSourceGetMetadataRecurse(src, src, uid, gid, + report_broken, cycle, 1); =20 virHashFree(cycle); return ret; @@ -2565,7 +2565,7 @@ virStorageFileGetMetadata(virStorageSourcePtr src, =20 =20 /** - * virStorageFileGetBackingStoreStr: + * virStorageSourceGetBackingStoreStr: * @src: storage object * * Extracts the backing store string as stored in the storage volume descr= ibed @@ -2574,8 +2574,8 @@ virStorageFileGetMetadata(virStorageSourcePtr src, * returned. */ int -virStorageFileGetBackingStoreStr(virStorageSourcePtr src, - char **backing) +virStorageSourceGetBackingStoreStr(virStorageSourcePtr src, + char **backing) { ssize_t headerLen; int rv; @@ -2585,19 +2585,19 @@ virStorageFileGetBackingStoreStr(virStorageSourcePt= r src, *backing =3D NULL; =20 /* exit if we can't load information about the current image */ - if (!virStorageFileSupportsBackingChainTraversal(src)) + if (!virStorageSourceSupportsBackingChainTraversal(src)) return 0; =20 - rv =3D virStorageFileAccess(src, F_OK); + rv =3D virStorageSourceAccess(src, F_OK); if (rv =3D=3D -2) return 0; if (rv < 0) { - virStorageFileReportBrokenChain(errno, src, src); + virStorageSourceReportBrokenChain(errno, src, src); return -1; } =20 - if ((headerLen =3D virStorageFileRead(src, 0, VIR_STORAGE_MAX_HEADER, - &buf)) < 0) { + if ((headerLen =3D virStorageSourceRead(src, 0, VIR_STORAGE_MAX_HEADER, + &buf)) < 0) { if (headerLen =3D=3D -2) return 0; return -1; diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_s= ource.h index 5d6ad4606d..480333d37a 100644 --- a/src/storage_file/storage_source.h +++ b/src/storage_file/storage_source.h @@ -28,23 +28,23 @@ #endif =20 virStorageSourcePtr -virStorageFileGetMetadataFromFD(const char *path, - int fd, - int format); +virStorageSourceGetMetadataFromFD(const char *path, + int fd, + int format); =20 virStorageSourcePtr -virStorageFileGetMetadataFromBuf(const char *path, - char *buf, - size_t len, - int format) +virStorageSourceGetMetadataFromBuf(const char *path, + char *buf, + size_t len, + int format) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 virStorageSourcePtr -virStorageFileChainLookup(virStorageSourcePtr chain, - virStorageSourcePtr startFrom, - const char *name, - unsigned int idx, - virStorageSourcePtr *parent) +virStorageSourceChainLookup(virStorageSourcePtr chain, + virStorageSourcePtr startFrom, + const char *name, + unsigned int idx, + virStorageSourcePtr *parent) ATTRIBUTE_NONNULL(1); =20 int @@ -72,9 +72,9 @@ virStorageSourceParseRBDColonString(const char *rbdstr, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 int -virStorageFileGetRelativeBackingPath(virStorageSourcePtr top, - virStorageSourcePtr base, - char **relpath) +virStorageSourceGetRelativeBackingPath(virStorageSourcePtr top, + virStorageSourcePtr base, + char **relpath) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); =20 int @@ -82,67 +82,67 @@ virStorageSourceNewFromBackingAbsolute(const char *path, virStorageSourcePtr *src); =20 int -virStorageFileInit(virStorageSourcePtr src); +virStorageSourceInit(virStorageSourcePtr src); =20 int -virStorageFileInitAs(virStorageSourcePtr src, - uid_t uid, gid_t gid); +virStorageSourceInitAs(virStorageSourcePtr src, + uid_t uid, gid_t gid); =20 void -virStorageFileDeinit(virStorageSourcePtr src); +virStorageSourceDeinit(virStorageSourcePtr src); =20 int -virStorageFileCreate(virStorageSourcePtr src); +virStorageSourceCreate(virStorageSourcePtr src); =20 int -virStorageFileUnlink(virStorageSourcePtr src); +virStorageSourceUnlink(virStorageSourcePtr src); =20 int -virStorageFileStat(virStorageSourcePtr src, - struct stat *st); +virStorageSourceStat(virStorageSourcePtr src, + struct stat *st); =20 ssize_t -virStorageFileRead(virStorageSourcePtr src, - size_t offset, - size_t len, - char **buf); +virStorageSourceRead(virStorageSourcePtr src, + size_t offset, + size_t len, + char **buf); =20 const char * -virStorageFileGetUniqueIdentifier(virStorageSourcePtr src); +virStorageSourceGetUniqueIdentifier(virStorageSourcePtr src); =20 int -virStorageFileAccess(virStorageSourcePtr src, - int mode); +virStorageSourceAccess(virStorageSourcePtr src, + int mode); =20 int -virStorageFileChown(const virStorageSource *src, - uid_t uid, - gid_t gid); +virStorageSourceChown(const virStorageSource *src, + uid_t uid, + gid_t gid); =20 int -virStorageFileSupportsSecurityDriver(const virStorageSource *src); +virStorageSourceSupportsSecurityDriver(const virStorageSource *src); =20 int -virStorageFileSupportsAccess(const virStorageSource *src); +virStorageSourceSupportsAccess(const virStorageSource *src); =20 int -virStorageFileSupportsCreate(const virStorageSource *src); +virStorageSourceSupportsCreate(const virStorageSource *src); =20 int -virStorageFileSupportsBackingChainTraversal(const virStorageSource *src); +virStorageSourceSupportsBackingChainTraversal(const virStorageSource *src); =20 int -virStorageFileGetMetadata(virStorageSourcePtr src, - uid_t uid, gid_t gid, - bool report_broken) +virStorageSourceGetMetadata(virStorageSourcePtr src, + uid_t uid, gid_t gid, + bool report_broken) ATTRIBUTE_NONNULL(1); =20 int -virStorageFileGetBackingStoreStr(virStorageSourcePtr src, - char **backing) +virStorageSourceGetBackingStoreStr(virStorageSourcePtr src, + char **backing) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 void -virStorageFileReportBrokenChain(int errcode, - virStorageSourcePtr src, - virStorageSourcePtr parent); +virStorageSourceReportBrokenChain(int errcode, + virStorageSourcePtr src, + virStorageSourcePtr parent); diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 5c2f211557..0e168ce730 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -101,7 +101,7 @@ testStorageFileGetMetadata(const char *path, =20 def->path =3D g_strdup(path); =20 - if (virStorageFileGetMetadata(def, uid, gid, true) < 0) + if (virStorageSourceGetMetadata(def, uid, gid, true) < 0) return NULL; =20 return g_steal_pointer(&def); @@ -366,9 +366,9 @@ testStorageLookup(const void *args) } =20 /* Test twice to ensure optional parameter doesn't cause NULL deref. = */ - result =3D virStorageFileChainLookup(data->chain, data->from, - idx ? NULL : data->name, - idx, NULL); + result =3D virStorageSourceChainLookup(data->chain, data->from, + idx ? NULL : data->name, + idx, NULL); =20 if (!data->expResult) { if (virGetLastErrorCode() =3D=3D VIR_ERR_OK) { @@ -395,8 +395,8 @@ testStorageLookup(const void *args) ret =3D -1; } =20 - result =3D virStorageFileChainLookup(data->chain, data->from, - data->name, idx, &actualParent); + result =3D virStorageSourceChainLookup(data->chain, data->from, + data->name, idx, &actualParent); if (!data->expResult) virResetLastError(); =20 @@ -552,9 +552,9 @@ testPathRelative(const void *args) const struct testPathRelativeBacking *data =3D args; g_autofree char *actual =3D NULL; =20 - if (virStorageFileGetRelativeBackingPath(data->top, - data->base, - &actual) < 0) { + if (virStorageSourceGetRelativeBackingPath(data->top, + data->base, + &actual) < 0) { fprintf(stderr, "relative backing path resolution failed\n"); return -1; } --=20 2.29.2