From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <f.ebner@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id B2FC06329E
 for <pve-devel@lists.proxmox.com>; Mon, 14 Feb 2022 12:03:03 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id B11AB218E4
 for <pve-devel@lists.proxmox.com>; Mon, 14 Feb 2022 12:03:03 +0100 (CET)
Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com
 [94.136.29.106])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by firstgate.proxmox.com (Proxmox) with ESMTPS id B7CA8218DB
 for <pve-devel@lists.proxmox.com>; Mon, 14 Feb 2022 12:03:02 +0100 (CET)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 8A19D4199C
 for <pve-devel@lists.proxmox.com>; Mon, 14 Feb 2022 12:03:02 +0100 (CET)
From: Fabian Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Date: Mon, 14 Feb 2022 12:02:52 +0100
Message-Id: <20220214110257.160945-1-f.ebner@proxmox.com>
X-Mailer: git-send-email 2.30.2
In-Reply-To: <20220211092435.84731-1-f.ebner@proxmox.com>
References: <20220211092435.84731-1-f.ebner@proxmox.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.134 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
 T_SCC_BODY_TEXT_LINE    -0.01 -
Subject: [pve-devel] [PATCH v2 qemu 4/4] vma: create: register all streams
 before entering coroutines
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Mon, 14 Feb 2022 11:03:03 -0000

Otherwise, the header might already get written by a coroutine and
registering further streams will fail after that.

Also adds a missing g_list_free call for the other GList that's used.

Reported in the community forum:
https://forum.proxmox.com/threads/104744/

Reproducer script (increase beyond 30 if the issue isn't triggered yet):
> #!/usr/bin/perl
>
> my $dir = "./vma-create-bug";
> mkdir $dir;
>
> my $archive_path = "$dir/vzdump-qemu-104-2202_02_02-00_00_00.vma";
> unlink $archive_path;
>
> my $cmd = "vma create $archive_path -v";
> for (my $i = 0; $i < 30; $i++) {
>   system("truncate -s 1M $dir/drive-virtio$i.img");
>   $cmd .= " drive-virtio$i=$dir/drive-virtio$i.img";
> }
> system($cmd);

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---

A late addition to v2.

 ...VE-Backup-add-vma-backup-format-code.patch | 24 +++++++++++++++----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch b/debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch
index d28065e..c4ed5bb 100644
--- a/debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch
+++ b/debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch
@@ -4,14 +4,16 @@ Date: Mon, 6 Apr 2020 12:16:57 +0200
 Subject: [PATCH] PVE-Backup: add vma backup format code
 
 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+[FE: create: register all streams before entering coroutines]
+Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
 ---
  block/meson.build |   2 +
  meson.build       |   5 +
  vma-reader.c      | 857 ++++++++++++++++++++++++++++++++++++++++++++++
  vma-writer.c      | 790 ++++++++++++++++++++++++++++++++++++++++++
- vma.c             | 839 +++++++++++++++++++++++++++++++++++++++++++++
+ vma.c             | 851 +++++++++++++++++++++++++++++++++++++++++++++
  vma.h             | 150 ++++++++
- 6 files changed, 2643 insertions(+)
+ 6 files changed, 2655 insertions(+)
  create mode 100644 vma-reader.c
  create mode 100644 vma-writer.c
  create mode 100644 vma.c
@@ -1714,10 +1716,10 @@ index 0000000000..11d8321ffd
 +}
 diff --git a/vma.c b/vma.c
 new file mode 100644
-index 0000000000..2eea2fc281
+index 0000000000..df542b7732
 --- /dev/null
 +++ b/vma.c
-@@ -0,0 +1,839 @@
+@@ -0,0 +1,851 @@
 +/*
 + * VMA: Virtual Machine Archive
 + *
@@ -2293,6 +2295,7 @@ index 0000000000..2eea2fc281
 +    int i, c;
 +    int verbose = 0;
 +    const char *archivename;
++    GList *backup_coroutines = NULL;
 +    GList *config_files = NULL;
 +
 +    for (;;) {
@@ -2381,7 +2384,9 @@ index 0000000000..2eea2fc281
 +        job->dev_id = dev_id;
 +
 +        Coroutine *co = qemu_coroutine_create(backup_run, job);
-+        qemu_coroutine_enter(co);
++        // Don't enter coroutine yet, because it might write the header before
++        // all streams can be registered.
++        backup_coroutines = g_list_append(backup_coroutines, co);
 +    }
 +
 +    VmaStatus vmastat;
@@ -2389,6 +2394,13 @@ index 0000000000..2eea2fc281
 +    int last_percent = -1;
 +
 +    if (devcount) {
++        GList *entry = backup_coroutines;
++        while (entry && entry->data) {
++            Coroutine *co = entry->data;
++            qemu_coroutine_enter(co);
++            entry = g_list_next(entry);
++        }
++
 +        while (1) {
 +            main_loop_wait(false);
 +            vma_writer_get_status(vmaw, &vmastat);
@@ -2453,6 +2465,8 @@ index 0000000000..2eea2fc281
 +        g_error("creating vma archive failed");
 +    }
 +
++    g_list_free(backup_coroutines);
++    g_list_free(config_files);
 +    vma_writer_destroy(vmaw);
 +    return 0;
 +}
-- 
2.30.2