From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer 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 PVE: handle PBS write callback with big blocks correctly Signed-off-by: Stefan Reiter PVE: add zero block handling to PBS dump callback Signed-off-by: Stefan Reiter Signed-off-by: Thomas Lamprecht --- block/monitor/block-hmp-cmds.c | 4 ++- pve-backup.c | 59 ++++++++++++++++++++++++++-------- qapi/block-core.json | 6 ++++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 3fca3ce3e9..69254396d5 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -1042,7 +1042,9 @@ void hmp_backup(Monitor *mon, const QDict *qdict) 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 index 6cdbd40529..7527885251 100644 --- 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]; @@ -135,10 +137,13 @@ pvebackup_co_dump_pbs_cb( 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 @@ -147,16 +152,28 @@ pvebackup_co_dump_pbs_cb( return -1; } - pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err); + 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; + + 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; + } + qemu_co_mutex_unlock(&backup_state.dump_callback_mutex); - - 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); - } + pvebackup_add_transfered_bytes(size, is_zero_block ? size : 0, reused); return size; } @@ -178,6 +195,7 @@ pvebackup_co_dump_vma_cb( int ret = -1; assert(backup_state.vmaw); + assert(buf); uint64_t remaining = size; @@ -204,9 +222,7 @@ pvebackup_co_dump_vma_cb( 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); @@ -569,6 +585,10 @@ typedef struct QmpBackupTask { 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; @@ -692,6 +712,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) bool use_dirty_bitmap = task->has_use_dirty_bitmap && task->use_dirty_bitmap; + char *pbs_err = NULL; pbs = proxmox_backup_new( task->backup_file, @@ -701,8 +722,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) 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, @@ -721,6 +744,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) 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); @@ -941,6 +966,8 @@ UuidInfo *qmp_backup( 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, @@ -951,6 +978,8 @@ UuidInfo *qmp_backup( .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, @@ -961,6 +990,10 @@ UuidInfo *qmp_backup( .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 index a138ad08d4..a75f1b4687 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -777,6 +777,10 @@ # # @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 # ## @@ -788,6 +792,8 @@ '*backup-id': 'str', '*backup-time': 'int', '*use-dirty-bitmap': 'bool', + '*compress': 'bool', + '*encrypt': 'bool', '*format': 'BackupFormat', '*config-file': 'str', '*firewall-file': 'str',