From nobody Sat Nov 23 12:07:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1732119293; cv=none; d=zohomail.com; s=zohoarc; b=ausUYOklMAxYj2HZvENZCAt4lJnR9hPYOhMTW1mIstgxHA6D1YWkMC1HtJhZEmh9iUNskkpnOqUl5acfZrQ4Ay0POpGfvHsFQ0Vqz6RlOP35otbIdCmFfl5woD8T/6AGp1gZJgLhCMVjz8dawVOIaMBIY6hR3oUp0kQHT6EDgGo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1732119293; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=MsbdWh3Um0Uleml3lLsVNmNNsDWpUBsuYgVvtWhm50U=; b=OJmY+oXk2eKXo9xcOdupJlOqQ02cQIyguRIpViSG+T7yn3lSIVUQWXti6JYAQmXdTDwtwY3Ocj9KejLQx8gZKWnQpQH0bPSx+U4GW6cjpgm0lWqJFkNWN/T70CeY+YRpDtk9g+ijtJIyHAjZBTh9D7i+XymRiFdBWuAsUihNiHY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1732119293037600.802569923951; Wed, 20 Nov 2024 08:14:53 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id E4FCA1259; Wed, 20 Nov 2024 11:14:51 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 875411509; Wed, 20 Nov 2024 11:10:07 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id BF8671503; Wed, 20 Nov 2024 11:09:57 -0500 (EST) Received: from relay.virtuozzo.com (relay.virtuozzo.com [130.117.225.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 86DCE152E for ; Wed, 20 Nov 2024 11:09:45 -0500 (EST) Received: from [130.117.225.1] (helo=vz9-barybin-2.ch-qa.vzint.dev) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1tDn0a-0005yc-2a; Wed, 20 Nov 2024 16:52:48 +0100 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=h5X0VthHXVSExXaOkRL8dbOiTr+PpcPkeVRL7/eT8Sg=; b=pj2IagI9dFUk RSZP9LS8ht2g9pKHnDLhSegxMBUOCvBdX0hZ9d3/U1ifNZWKx2MAVQhcFrTpi7cZlUR/tJcthQq5M cZAfzPdnSmnGXEYyVhYzAEJyoiI+RUgIwn621d5Qu31Aji+vmSsYkh+SVnAzxhIsj63+t1tl5SsFM Sj9pZVpqshU0lVfRp6AfgfLKubzGBOgpzfjhtdrhBqtFd8CsDXsePHyGFs9AvMt/JkTt5E99FKxWA TfUVzJlTNfJWe9iQlJxMVbenQrJt0rc9ouO4bPhSpx67Dd9lvmF9Lk49NN2NYkWGq7EVShaVlytWL uH4XkYMwUyaoFSi8jQ5Bwg==; To: devel@lists.libvirt.org Subject: [PATCH 06/15] storage file: add qcow2 data-file path parsing from header Date: Wed, 20 Nov 2024 18:48:41 +0300 Message-ID: <20241120155229.1259-7-nikolai.barybin@virtuozzo.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20241120155229.1259-1-nikolai.barybin@virtuozzo.com> References: <20241120155229.1259-1-nikolai.barybin@virtuozzo.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: DVYAF7Y572XJNRNOOBLHDGIFETJEAEDF X-Message-ID-Hash: DVYAF7Y572XJNRNOOBLHDGIFETJEAEDF X-MailFrom: nikolai.barybin@virtuozzo.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: den@openvz.org, Nikolai Barybin X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: From: Nikolai Barybin via Devel Reply-To: Nikolai Barybin X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1732119295234116600 Content-Type: text/plain; charset="utf-8" In qcow2 header data file is represented by incompitible feature bit and its path is saved to header extension table. Thus, we implement here the logic similar to backing file probing. Signed-off-by: Nikolai Barybin Reviewed-by: Peter Krempa --- src/storage_file/storage_file_probe.c | 46 ++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/stora= ge_file_probe.c index ad14350edc..06868f5355 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -106,6 +106,7 @@ qcow2GetClusterSize(const char *buf, size_t buf_size); static int qcowXGetBackingStore(char **, int *, const char *, size_t); +static int qcow2GetDataFile(char **, virBitmap *, char *, size_t); static int qcow2GetFeatures(virBitmap **features, int format, char *buf, ssize_t len); static int vmdk4GetBackingStore(char **, int *, @@ -127,6 +128,7 @@ qedGetBackingStore(char **, int *, const char *, size_t= ); =20 #define QCOW2_HDR_EXTENSION_END 0 #define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA +#define QCOW2_HDR_EXTENSION_DATA_FILE_NAME 0x44415441 =20 #define QCOW2v3_HDR_FEATURES_INCOMPATIBLE (QCOW2_HDR_TOTAL_SIZE) #define QCOW2v3_HDR_FEATURES_COMPATIBLE (QCOW2v3_HDR_FEATURES_INCOMPATIBLE= +8) @@ -314,7 +316,7 @@ static struct FileTypeInfo const fileTypeInfo[] =3D { qcow2EncryptionInfo, qcow2GetClusterSize, qcowXGetBackingStore, - NULL, + qcow2GetDataFile, qcow2GetFeatures }, [VIR_STORAGE_FILE_QED] =3D { @@ -361,7 +363,7 @@ enum qcow2IncompatibleFeature { static const virStorageFileFeature qcow2IncompatibleFeatureArray[] =3D { VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DIRTY */ VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_CORRUPT */ - VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_DATA_FILE= */ + VIR_STORAGE_FILE_FEATURE_DATA_FILE, /* QCOW2_INCOMPATIBLE_FEATURE_DATA= _FILE */ VIR_STORAGE_FILE_FEATURE_LAST, /* QCOW2_INCOMPATIBLE_FEATURE_COMPRESSI= ON */ VIR_STORAGE_FILE_FEATURE_EXTENDED_L2, /* QCOW2_INCOMPATIBLE_FEATURE_EX= TL2 */ }; @@ -393,7 +395,8 @@ cowGetBackingStore(char **res, static int qcow2GetExtensions(const char *buf, size_t buf_size, - int *backingFormat) + int *backingFormat, + char **dataFilePath) { size_t offset; size_t extension_start; @@ -488,6 +491,15 @@ qcow2GetExtensions(const char *buf, break; } =20 + case QCOW2_HDR_EXTENSION_DATA_FILE_NAME: { + if (!dataFilePath) + break; + + *dataFilePath =3D g_new0(char, len + 1); + memcpy(*dataFilePath, buf + offset, len); + break; + } + case QCOW2_HDR_EXTENSION_END: return 0; } @@ -554,13 +566,33 @@ qcowXGetBackingStore(char **res, memcpy(*res, buf + offset, size); (*res)[size] =3D '\0'; =20 - if (qcow2GetExtensions(buf, buf_size, format) < 0) + if (qcow2GetExtensions(buf, buf_size, format, NULL) < 0) return 0; =20 return 0; } =20 =20 +static int +qcow2GetDataFile(char **res, + virBitmap *features, + char *buf, + size_t buf_size) +{ + *res =3D NULL; + + if (buf_size < QCOW2v3_HDR_FEATURES_INCOMPATIBLE + 8) + return 0; + + if (features && virBitmapIsBitSet(features, VIR_STORAGE_FILE_FEATURE_D= ATA_FILE)) { + if (qcow2GetExtensions(buf, buf_size, NULL, res) < 0) + return 0; + } + + return 0; +} + + static int vmdk4GetBackingStore(char **res, int *format, @@ -968,6 +1000,12 @@ virStorageFileProbeGetMetadata(virStorageSource *meta, fileTypeInfo[meta->format].getFeatures(&meta->features, meta->form= at, buf, len) < 0) return -1; =20 + VIR_FREE(meta->dataFileRaw); + if (fileTypeInfo[meta->format].getDataFile !=3D NULL) { + fileTypeInfo[meta->format].getDataFile(&meta->dataFileRaw, meta->f= eatures, + buf, len); + } + VIR_FREE(meta->compat); if (meta->format =3D=3D VIR_STORAGE_FILE_QCOW2 && meta->features) meta->compat =3D g_strdup("1.1"); --=20 2.43.5