2021-03-03 12:56:02 +03:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Dietmar Maurer <dietmar@proxmox.com>
|
|
|
|
Date: Thu, 9 Jul 2020 12:53:08 +0200
|
|
|
|
Subject: [PATCH] PVE: various PBS fixes
|
|
|
|
|
|
|
|
pbs: fix crypt and compress parameters
|
|
|
|
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
|
|
|
|
|
|
|
PVE: handle PBS write callback with big blocks correctly
|
|
|
|
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
|
|
|
|
|
|
|
PVE: add zero block handling to PBS dump callback
|
|
|
|
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
2022-01-13 12:34:33 +03:00
|
|
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
2021-03-03 12:56:02 +03:00
|
|
|
---
|
|
|
|
block/monitor/block-hmp-cmds.c | 4 ++-
|
2022-06-22 16:47:34 +03:00
|
|
|
pve-backup.c | 57 +++++++++++++++++++++++++++-------
|
2021-03-03 12:56:02 +03:00
|
|
|
qapi/block-core.json | 6 ++++
|
2022-06-22 16:47:34 +03:00
|
|
|
3 files changed, 54 insertions(+), 13 deletions(-)
|
2021-03-03 12:56:02 +03:00
|
|
|
|
|
|
|
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
2022-12-14 17:16:32 +03:00
|
|
|
index 556af25861..a09f722fea 100644
|
2021-03-03 12:56:02 +03:00
|
|
|
--- a/block/monitor/block-hmp-cmds.c
|
|
|
|
+++ b/block/monitor/block-hmp-cmds.c
|
2021-10-11 14:55:34 +03:00
|
|
|
@@ -1042,7 +1042,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
|
2021-03-03 12:56:02 +03:00
|
|
|
false, NULL, // PBS fingerprint
|
|
|
|
false, NULL, // PBS backup-id
|
|
|
|
false, 0, // PBS backup-time
|
|
|
|
- false, false, // PBS incremental
|
|
|
|
+ false, false, // PBS use-dirty-bitmap
|
|
|
|
+ false, false, // PBS compress
|
|
|
|
+ false, false, // PBS encrypt
|
|
|
|
true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
|
|
|
|
false, NULL, false, NULL, !!devlist,
|
|
|
|
devlist, qdict_haskey(qdict, "speed"), speed, &error);
|
|
|
|
diff --git a/pve-backup.c b/pve-backup.c
|
2022-12-14 17:16:32 +03:00
|
|
|
index abd7062afe..e113ab61b9 100644
|
2021-03-03 12:56:02 +03:00
|
|
|
--- a/pve-backup.c
|
|
|
|
+++ b/pve-backup.c
|
|
|
|
@@ -8,6 +8,7 @@
|
|
|
|
#include "block/blockjob.h"
|
|
|
|
#include "qapi/qapi-commands-block.h"
|
|
|
|
#include "qapi/qmp/qerror.h"
|
|
|
|
+#include "qemu/cutils.h"
|
|
|
|
|
|
|
|
/* PVE backup state and related function */
|
|
|
|
|
|
|
|
@@ -67,6 +68,7 @@ opts_init(pvebackup_init);
|
|
|
|
typedef struct PVEBackupDevInfo {
|
|
|
|
BlockDriverState *bs;
|
|
|
|
size_t size;
|
|
|
|
+ uint64_t block_size;
|
|
|
|
uint8_t dev_id;
|
|
|
|
bool completed;
|
|
|
|
char targetfile[PATH_MAX];
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -137,10 +139,13 @@ pvebackup_co_dump_pbs_cb(
|
2021-03-03 12:56:02 +03:00
|
|
|
PVEBackupDevInfo *di = opaque;
|
|
|
|
|
|
|
|
assert(backup_state.pbs);
|
|
|
|
+ assert(buf);
|
|
|
|
|
|
|
|
Error *local_err = NULL;
|
|
|
|
int pbs_res = -1;
|
|
|
|
|
|
|
|
+ bool is_zero_block = size == di->block_size && buffer_is_zero(buf, size);
|
|
|
|
+
|
|
|
|
qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
|
|
|
|
|
|
|
|
// avoid deadlock if job is cancelled
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -149,17 +154,29 @@ pvebackup_co_dump_pbs_cb(
|
2021-03-03 12:56:02 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
- pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err);
|
2022-06-22 16:47:34 +03:00
|
|
|
- qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
|
2021-03-03 12:56:02 +03:00
|
|
|
+ uint64_t transferred = 0;
|
|
|
|
+ uint64_t reused = 0;
|
|
|
|
+ while (transferred < size) {
|
|
|
|
+ uint64_t left = size - transferred;
|
|
|
|
+ uint64_t to_transfer = left < di->block_size ? left : di->block_size;
|
2022-06-22 16:47:34 +03:00
|
|
|
|
|
|
|
- if (pbs_res < 0) {
|
|
|
|
- pvebackup_propagate_error(local_err);
|
|
|
|
- return pbs_res;
|
|
|
|
- } else {
|
|
|
|
- size_t reused = (pbs_res == 0) ? size : 0;
|
|
|
|
- pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused);
|
2021-03-03 12:56:02 +03:00
|
|
|
+ pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id,
|
|
|
|
+ is_zero_block ? NULL : buf + transferred, start + transferred,
|
|
|
|
+ to_transfer, &local_err);
|
|
|
|
+ transferred += to_transfer;
|
|
|
|
+
|
|
|
|
+ if (pbs_res < 0) {
|
|
|
|
+ pvebackup_propagate_error(local_err);
|
|
|
|
+ qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
|
|
|
|
+ return pbs_res;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ reused += pbs_res == 0 ? to_transfer : 0;
|
2022-06-22 16:47:34 +03:00
|
|
|
}
|
2022-01-13 12:34:33 +03:00
|
|
|
|
2022-06-22 16:47:34 +03:00
|
|
|
+ qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
|
|
|
|
+ pvebackup_add_transfered_bytes(size, is_zero_block ? size : 0, reused);
|
|
|
|
+
|
2021-03-03 12:56:02 +03:00
|
|
|
return size;
|
|
|
|
}
|
2022-06-22 16:47:34 +03:00
|
|
|
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -180,6 +197,7 @@ pvebackup_co_dump_vma_cb(
|
2021-03-03 12:56:02 +03:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
assert(backup_state.vmaw);
|
|
|
|
+ assert(buf);
|
|
|
|
|
|
|
|
uint64_t remaining = size;
|
|
|
|
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -206,9 +224,7 @@ pvebackup_co_dump_vma_cb(
|
2021-03-03 12:56:02 +03:00
|
|
|
qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
|
|
|
|
|
|
|
|
++cluster_num;
|
|
|
|
- if (buf) {
|
|
|
|
- buf += VMA_CLUSTER_SIZE;
|
|
|
|
- }
|
|
|
|
+ buf += VMA_CLUSTER_SIZE;
|
|
|
|
if (ret < 0) {
|
|
|
|
Error *local_err = NULL;
|
|
|
|
vma_writer_error_propagate(backup_state.vmaw, &local_err);
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -566,6 +582,10 @@ typedef struct QmpBackupTask {
|
2021-03-03 12:56:02 +03:00
|
|
|
const char *firewall_file;
|
|
|
|
bool has_devlist;
|
|
|
|
const char *devlist;
|
|
|
|
+ bool has_compress;
|
|
|
|
+ bool compress;
|
|
|
|
+ bool has_encrypt;
|
|
|
|
+ bool encrypt;
|
|
|
|
bool has_speed;
|
|
|
|
int64_t speed;
|
|
|
|
Error **errp;
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -689,6 +709,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
2021-03-03 12:56:02 +03:00
|
|
|
|
|
|
|
bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap;
|
|
|
|
|
|
|
|
+
|
|
|
|
char *pbs_err = NULL;
|
|
|
|
pbs = proxmox_backup_new(
|
|
|
|
task->backup_file,
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -698,8 +719,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
2021-03-03 12:56:02 +03:00
|
|
|
task->has_password ? task->password : NULL,
|
|
|
|
task->has_keyfile ? task->keyfile : NULL,
|
|
|
|
task->has_key_password ? task->key_password : NULL,
|
|
|
|
+ task->has_compress ? task->compress : true,
|
|
|
|
+ task->has_encrypt ? task->encrypt : task->has_keyfile,
|
|
|
|
task->has_fingerprint ? task->fingerprint : NULL,
|
|
|
|
- &pbs_err);
|
|
|
|
+ &pbs_err);
|
|
|
|
|
|
|
|
if (!pbs) {
|
|
|
|
error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -718,6 +741,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
|
2021-03-03 12:56:02 +03:00
|
|
|
PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
|
|
|
|
l = g_list_next(l);
|
|
|
|
|
|
|
|
+ di->block_size = dump_cb_block_size;
|
|
|
|
+
|
|
|
|
const char *devname = bdrv_get_device_name(di->bs);
|
|
|
|
|
|
|
|
BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -938,6 +963,8 @@ UuidInfo *qmp_backup(
|
2021-03-03 12:56:02 +03:00
|
|
|
bool has_backup_id, const char *backup_id,
|
|
|
|
bool has_backup_time, int64_t backup_time,
|
|
|
|
bool has_use_dirty_bitmap, bool use_dirty_bitmap,
|
|
|
|
+ bool has_compress, bool compress,
|
|
|
|
+ bool has_encrypt, bool encrypt,
|
|
|
|
bool has_format, BackupFormat format,
|
|
|
|
bool has_config_file, const char *config_file,
|
|
|
|
bool has_firewall_file, const char *firewall_file,
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -948,6 +975,8 @@ UuidInfo *qmp_backup(
|
2021-03-03 12:56:02 +03:00
|
|
|
.backup_file = backup_file,
|
|
|
|
.has_password = has_password,
|
|
|
|
.password = password,
|
|
|
|
+ .has_keyfile = has_keyfile,
|
|
|
|
+ .keyfile = keyfile,
|
|
|
|
.has_key_password = has_key_password,
|
|
|
|
.key_password = key_password,
|
|
|
|
.has_fingerprint = has_fingerprint,
|
2022-12-14 17:16:32 +03:00
|
|
|
@@ -958,6 +987,10 @@ UuidInfo *qmp_backup(
|
2021-03-03 12:56:02 +03:00
|
|
|
.backup_time = backup_time,
|
|
|
|
.has_use_dirty_bitmap = has_use_dirty_bitmap,
|
|
|
|
.use_dirty_bitmap = use_dirty_bitmap,
|
|
|
|
+ .has_compress = has_compress,
|
|
|
|
+ .compress = compress,
|
|
|
|
+ .has_encrypt = has_encrypt,
|
|
|
|
+ .encrypt = encrypt,
|
|
|
|
.has_format = has_format,
|
|
|
|
.format = format,
|
|
|
|
.has_config_file = has_config_file,
|
|
|
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
2022-12-14 17:16:32 +03:00
|
|
|
index 992e6c1e3f..5ac6276dc1 100644
|
2021-03-03 12:56:02 +03:00
|
|
|
--- a/qapi/block-core.json
|
|
|
|
+++ b/qapi/block-core.json
|
update submodule and patches to 7.1.0
Notable changes:
* The only big change is the switch to using a custom QIOChannel for
savevm-async, because the previously used QEMUFileOps was dropped.
Changes to the current implementation:
* Switch to vector based methods as required for an IO channel. For
short reads the passed-in IO vector is stuffed with zeroes at the
end, just to be sure.
* For reading: The documentation in include/io/channel.h states that
at least one byte should be read, so also error out when whe are
at the very end instead of returning 0.
* For reading: Fix off-by-one error when request goes beyond end.
The wrong code piece was:
if ((pos + size) > maxlen) {
size = maxlen - pos - 1;
}
Previously, the last byte would not be read. It's actually
possible to get a snapshot .raw file that has content all the way
up the final 512 byte (= BDRV_SECTOR_SIZE) boundary without any
trailing zero bytes (I wrote a script to do it).
Luckily, it didn't cause a real issue, because qemu_loadvm_state()
is not interested in the final (i.e. QEMU_VM_VMDESCRIPTION)
section. The buffer for reading it is simply freed up afterwards
and the function will assume that it read the whole section, even
if that's not the case.
* For writing: Make use of the generated blk_pwritev() wrapper
instead of manually wrapping the coroutine to simplify and save a
few lines.
* Adapt to changed interfaces for blk_{pread,pwrite}:
* a9262f551e ("block: Change blk_{pread,pwrite}() param order")
* 3b35d4542c ("block: Add a 'flags' param to blk_pread()")
* bf5b16fa40 ("block: Make blk_{pread,pwrite}() return 0 on success")
Those changes especially affected the qemu-img dd patches, because
the context also changed, but also some of our block drivers used
the functions.
* Drop qemu-common.h include: it got renamed after essentially
everything was moved to other headers. The only remaining user I
could find for things dropped from the header between 7.0 and 7.1
was qemu_get_vm_name() in the iscsi-initiatorname patch, but it
already includes the header to which the function was moved.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2022-10-14 15:07:13 +03:00
|
|
|
@@ -818,6 +818,10 @@
|
2021-03-03 12:56:02 +03:00
|
|
|
#
|
|
|
|
# @use-dirty-bitmap: use dirty bitmap to detect incremental changes since last job (optional for format 'pbs')
|
|
|
|
#
|
|
|
|
+# @compress: use compression (optional for format 'pbs', defaults to true)
|
|
|
|
+#
|
|
|
|
+# @encrypt: use encryption ((optional for format 'pbs', defaults to true if there is a keyfile)
|
|
|
|
+#
|
|
|
|
# Returns: the uuid of the backup job
|
|
|
|
#
|
|
|
|
##
|
update submodule and patches to 7.1.0
Notable changes:
* The only big change is the switch to using a custom QIOChannel for
savevm-async, because the previously used QEMUFileOps was dropped.
Changes to the current implementation:
* Switch to vector based methods as required for an IO channel. For
short reads the passed-in IO vector is stuffed with zeroes at the
end, just to be sure.
* For reading: The documentation in include/io/channel.h states that
at least one byte should be read, so also error out when whe are
at the very end instead of returning 0.
* For reading: Fix off-by-one error when request goes beyond end.
The wrong code piece was:
if ((pos + size) > maxlen) {
size = maxlen - pos - 1;
}
Previously, the last byte would not be read. It's actually
possible to get a snapshot .raw file that has content all the way
up the final 512 byte (= BDRV_SECTOR_SIZE) boundary without any
trailing zero bytes (I wrote a script to do it).
Luckily, it didn't cause a real issue, because qemu_loadvm_state()
is not interested in the final (i.e. QEMU_VM_VMDESCRIPTION)
section. The buffer for reading it is simply freed up afterwards
and the function will assume that it read the whole section, even
if that's not the case.
* For writing: Make use of the generated blk_pwritev() wrapper
instead of manually wrapping the coroutine to simplify and save a
few lines.
* Adapt to changed interfaces for blk_{pread,pwrite}:
* a9262f551e ("block: Change blk_{pread,pwrite}() param order")
* 3b35d4542c ("block: Add a 'flags' param to blk_pread()")
* bf5b16fa40 ("block: Make blk_{pread,pwrite}() return 0 on success")
Those changes especially affected the qemu-img dd patches, because
the context also changed, but also some of our block drivers used
the functions.
* Drop qemu-common.h include: it got renamed after essentially
everything was moved to other headers. The only remaining user I
could find for things dropped from the header between 7.0 and 7.1
was qemu_get_vm_name() in the iscsi-initiatorname patch, but it
already includes the header to which the function was moved.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
2022-10-14 15:07:13 +03:00
|
|
|
@@ -829,6 +833,8 @@
|
2021-03-03 12:56:02 +03:00
|
|
|
'*backup-id': 'str',
|
|
|
|
'*backup-time': 'int',
|
|
|
|
'*use-dirty-bitmap': 'bool',
|
|
|
|
+ '*compress': 'bool',
|
|
|
|
+ '*encrypt': 'bool',
|
|
|
|
'*format': 'BackupFormat',
|
|
|
|
'*config-file': 'str',
|
|
|
|
'*firewall-file': 'str',
|