--- monitor/hmp-cmds.c | 45 +++++++++++++++++++++++++++++++++----------- pve-backup.c | 26 +++++++++++++++++++++---- qapi/block-core.json | 9 +++++++-- 3 files changed, 63 insertions(+), 17 deletions(-)
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 7fd59b1c22..4f692c15a2 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -218,19 +218,42 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict) monitor_printf(mon, "End time: %s", ctime(&info->end_time)); } - int per = (info->has_total && info->total && - info->has_transferred && info->transferred) ? - (info->transferred * 100)/info->total : 0; - int zero_per = (info->has_total && info->total && - info->has_zero_bytes && info->zero_bytes) ? - (info->zero_bytes * 100)/info->total : 0; monitor_printf(mon, "Backup file: %s\n", info->backup_file); monitor_printf(mon, "Backup uuid: %s\n", info->uuid); - monitor_printf(mon, "Total size: %zd\n", info->total); - monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n", - info->transferred, per); - monitor_printf(mon, "Zero bytes: %zd (%d%%)\n", - info->zero_bytes, zero_per); + + if (!(info->has_total && info->total)) { + // this should not happen normally + monitor_printf(mon, "Total size: %d\n", 0); + } else { + bool incremental = false; + size_t total_or_dirty = info->total; + if (info->has_transferred) { + if (info->has_dirty && info->dirty) { + if (info->dirty < info->total) { + total_or_dirty = info->dirty; + incremental = true; + } + } + } + + int per = (info->transferred * 100)/total_or_dirty; + + monitor_printf(mon, "Backup mode: %s\n", incremental ? "incremental" : "full"); + + int zero_per = (info->has_zero_bytes && info->zero_bytes) ? + (info->zero_bytes * 100)/info->total : 0; + monitor_printf(mon, "Total size: %zd\n", info->total); + monitor_printf(mon, "Transferred bytes: %zd (%d%%)\n", + info->transferred, per); + monitor_printf(mon, "Zero bytes: %zd (%d%%)\n", + info->zero_bytes, zero_per); + + if (info->has_reused) { + int reused_per = (info->reused * 100)/total_or_dirty; + monitor_printf(mon, "Reused bytes: %zd (%d%%)\n", + info->reused, reused_per); + } + } } qapi_free_BackupStatus(info); diff --git a/pve-backup.c b/pve-backup.c index 1c4f6cf9e0..3a71270213 100644 --- a/pve-backup.c +++ b/pve-backup.c @@ -41,7 +41,9 @@ static struct PVEBackupState { uuid_t uuid; char uuid_str[37]; size_t total; + size_t dirty; size_t transferred; + size_t reused; size_t zero_bytes; } stat; int64_t speed; @@ -108,11 +110,12 @@ static bool pvebackup_error_or_canceled(void) return error_or_canceled; } -static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes) +static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes, size_t reused) { qemu_mutex_lock(&backup_state.stat.lock); backup_state.stat.zero_bytes += zero_bytes; backup_state.stat.transferred += transferred; + backup_state.stat.reused += reused; qemu_mutex_unlock(&backup_state.stat.lock); } @@ -151,7 +154,8 @@ pvebackup_co_dump_pbs_cb( pvebackup_propagate_error(local_err); return pbs_res; } else { - pvebackup_add_transfered_bytes(size, !buf ? size : 0); + size_t reused = (pbs_res == 0) ? size : 0; + pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused); } return size; @@ -211,11 +215,11 @@ pvebackup_co_dump_vma_cb( } else { if (remaining >= VMA_CLUSTER_SIZE) { assert(ret == VMA_CLUSTER_SIZE); - pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes); + pvebackup_add_transfered_bytes(VMA_CLUSTER_SIZE, zero_bytes, 0); remaining -= VMA_CLUSTER_SIZE; } else { assert(ret == remaining); - pvebackup_add_transfered_bytes(remaining, zero_bytes); + pvebackup_add_transfered_bytes(remaining, zero_bytes, 0); remaining = 0; } } @@ -650,6 +654,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) } size_t total = 0; + size_t dirty = 0; l = di_list; while (l) { @@ -731,11 +736,14 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) } /* mark entire bitmap as dirty to make full backup first */ bdrv_set_dirty_bitmap(bitmap, 0, di->size); + dirty += di->size; } else { use_incremental = true; + dirty += bdrv_get_dirty_count(bitmap); } di->bitmap = bitmap; } else if (bitmap != NULL) { + dirty += di->size; bdrv_release_dirty_bitmap(bitmap); } @@ -751,6 +759,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) di->dev_id = dev_id; } } else if (format == BACKUP_FORMAT_VMA) { + dirty = total; + vmaw = vma_writer_create(task->backup_file, uuid, &local_err); if (!vmaw) { if (local_err) { @@ -778,6 +788,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) } } } else if (format == BACKUP_FORMAT_DIR) { + dirty = total; + if (mkdir(task->backup_file, 0640) != 0) { error_setg_errno(task->errp, errno, "can't create directory '%s'\n", task->backup_file); @@ -850,8 +862,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque) char *uuid_str = g_strdup(backup_state.stat.uuid_str); backup_state.stat.total = total; + backup_state.stat.dirty = dirty; backup_state.stat.transferred = 0; backup_state.stat.zero_bytes = 0; + backup_state.stat.reused = 0; qemu_mutex_unlock(&backup_state.stat.lock); @@ -1009,10 +1023,14 @@ BackupStatus *qmp_query_backup(Error **errp) info->has_total = true; info->total = backup_state.stat.total; + info->has_dirty = true; + info->dirty = backup_state.stat.dirty; info->has_zero_bytes = true; info->zero_bytes = backup_state.stat.zero_bytes; info->has_transferred = true; info->transferred = backup_state.stat.transferred; + info->has_reused = true; + info->reused = backup_state.stat.reused; qemu_mutex_unlock(&backup_state.stat.lock); diff --git a/qapi/block-core.json b/qapi/block-core.json index f693bebdb4..8ffff7aaab 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -757,8 +757,13 @@ # # @total: total amount of bytes involved in the backup process # +# @dirty: with incremental mode, this is the amount of bytes involved +# in the backup process which are marked dirty. +# # @transferred: amount of bytes already backed up. # +# @reused: amount of bytes reused due to deduplication. +# # @zero-bytes: amount of 'zero' bytes detected. # # @start-time: time (epoch) when backup job started. @@ -771,8 +776,8 @@ # ## { 'struct': 'BackupStatus', - 'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int', - '*transferred': 'int', '*zero-bytes': 'int', + 'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int', '*dirty': 'int', + '*transferred': 'int', '*zero-bytes': 'int', '*reused': 'int', '*start-time': 'int', '*end-time': 'int', '*backup-file': 'str', '*uuid': 'str' } } -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel