From nobody Mon Sep 16 19:34:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1540496918748487.17420559588413; Thu, 25 Oct 2018 12:48:38 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E2997C0799B3; Thu, 25 Oct 2018 19:48:35 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B41A85D9C5; Thu, 25 Oct 2018 19:48:35 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6ACEA180B5B7; Thu, 25 Oct 2018 19:48:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w9PJLDE4027767 for ; Thu, 25 Oct 2018 15:21:13 -0400 Received: by smtp.corp.redhat.com (Postfix) id 38CDD62527; Thu, 25 Oct 2018 19:21:13 +0000 (UTC) Received: from red.redhat.com (ovpn-122-116.rdu2.redhat.com [10.10.122.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id A9F2960CD8; Thu, 25 Oct 2018 19:21:11 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Thu, 25 Oct 2018 20:20:16 +0100 Message-Id: <20181025192021.350438-16-eblake@redhat.com> In-Reply-To: <20181025192021.350438-1-eblake@redhat.com> References: <20181025192021.350438-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: amureini@redhat.com, derez@redhat.com, vsementsov@virtuozzo.com, ydary@redhat.com, nsoffer@redhat.com, jsnow@redhat.com Subject: [libvirt] [PATCH v3 15/20] backup: Add new qemu monitor interactions X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 25 Oct 2018 19:48:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Add some monitor commands to be used during backup/checkpoint operations: another facet to query-block for learning bitmap size; x-block-dirty-bitmap-enable, x-block-dirty-bitmap-merge, and block-dirty-bitmap-remove used when deleting a checkpoint; block-dirty-bitmap-add for performing incremental backup, and x-nbd-server-add-bitmap for exposing incremental backups over NBD. Signed-off-by: Eric Blake --- src/qemu/qemu_monitor.h | 16 +++ src/qemu/qemu_monitor_json.h | 18 +++ src/qemu/qemu_monitor.c | 68 +++++++++++ src/qemu/qemu_monitor_json.c | 215 +++++++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index b683d0f100..d321c8633f 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -28,6 +28,7 @@ # include "internal.h" # include "domain_conf.h" +# include "checkpoint_conf.h" # include "virbitmap.h" # include "virhash.h" # include "virjson.h" @@ -605,6 +606,9 @@ int qemuMonitorBlockStatsUpdateCapacity(qemuMonitorPtr = mon, int qemuMonitorBlockStatsUpdateCapacityBlockdev(qemuMonitorPtr mon, virHashTablePtr stats) ATTRIBUTE_NONNULL(2); +int qemuMonitorUpdateCheckpointSize(qemuMonitorPtr mon, + virDomainCheckpointDefPtr chk) + ATTRIBUTE_NONNULL(2); int qemuMonitorBlockResize(qemuMonitorPtr mon, const char *device, @@ -623,6 +627,15 @@ int qemuMonitorSetBalloon(qemuMonitorPtr mon, unsigned long long newmem); int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online); +int qemuMonitorAddBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); +int qemuMonitorEnableBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); +int qemuMonitorMergeBitmaps(qemuMonitorPtr mon, const char *node, + const char *dst, const char *src); +int qemuMonitorDeleteBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); + /* XXX should we pass the virDomainDiskDefPtr instead * and hide dev_name details inside monitor. Reconsider @@ -1076,6 +1089,9 @@ int qemuMonitorNBDServerAdd(qemuMonitorPtr mon, const char *deviceID, const char *export, bool writable); +int qemuMonitorNBDServerAddBitmap(qemuMonitorPtr mon, + const char *export, + const char *bitmap); int qemuMonitorNBDServerStop(qemuMonitorPtr); int qemuMonitorGetTPMModels(qemuMonitorPtr mon, char ***tpmmodels); diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index ac08bc21e0..8cf36b42cb 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -101,6 +101,9 @@ int qemuMonitorJSONBlockResize(qemuMonitorPtr mon, const char *nodename, unsigned long long size); +int qemuMonitorJSONUpdateCheckpointSize(qemuMonitorPtr mon, + virDomainCheckpointDefPtr chk); + int qemuMonitorJSONSetVNCPassword(qemuMonitorPtr mon, const char *password); int qemuMonitorJSONSetPassword(qemuMonitorPtr mon, @@ -470,6 +473,9 @@ int qemuMonitorJSONNBDServerAdd(qemuMonitorPtr mon, const char *deviceID, const char *export, bool writable); +int qemuMonitorJSONNBDServerAddBitmap(qemuMonitorPtr mon, + const char *export, + const char *bitmap); int qemuMonitorJSONNBDServerStop(qemuMonitorPtr mon); int qemuMonitorJSONGetTPMModels(qemuMonitorPtr mon, char ***tpmmodels) @@ -578,4 +584,16 @@ int qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon, virHashTablePtr info) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int qemuMonitorJSONAddBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); + +int qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); + +int qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon, const char *node, + const char *dst, const char *src); + +int qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 0c2e043fc9..2ed6762db8 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2322,6 +2322,17 @@ qemuMonitorBlockStatsUpdateCapacityBlockdev(qemuMoni= torPtr mon, return qemuMonitorJSONBlockStatsUpdateCapacityBlockdev(mon, stats); } +/* Updates "chk" to fill in size of the associated bitmap */ +int qemuMonitorUpdateCheckpointSize(qemuMonitorPtr mon, + virDomainCheckpointDefPtr chk) +{ + VIR_DEBUG("chk=3D%p", chk); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONUpdateCheckpointSize(mon, chk); +} + int qemuMonitorBlockResize(qemuMonitorPtr mon, const char *device, @@ -3936,6 +3947,19 @@ qemuMonitorNBDServerAdd(qemuMonitorPtr mon, } +int +qemuMonitorNBDServerAddBitmap(qemuMonitorPtr mon, + const char *export, + const char *bitmap) +{ + VIR_DEBUG("export=3D%s, bitmap=3D%s", export, bitmap); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONNBDServerAddBitmap(mon, export, bitmap); +} + + int qemuMonitorNBDServerStop(qemuMonitorPtr mon) { @@ -4429,3 +4453,47 @@ qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon, virHashFree(info); return ret; } + +int +qemuMonitorAddBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + VIR_DEBUG("node=3D%s bitmap=3D%s", node, bitmap); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONAddBitmap(mon, node, bitmap); +} + +int +qemuMonitorEnableBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + VIR_DEBUG("node=3D%s bitmap=3D%s", node, bitmap); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONEnableBitmap(mon, node, bitmap); +} + +int +qemuMonitorMergeBitmaps(qemuMonitorPtr mon, const char *node, + const char *dst, const char *src) +{ + VIR_DEBUG("node=3D%s dst=3D%s src=3D%s", node, dst, src); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONMergeBitmaps(mon, node, dst, src); +} + +int +qemuMonitorDeleteBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + VIR_DEBUG("node=3D%s bitmap=3D%s", node, bitmap); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONDeleteBitmap(mon, node, bitmap); +} diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 29d0395979..a700585243 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1008,6 +1008,8 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon, type =3D VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT; else if (STREQ(type_str, "mirror")) type =3D VIR_DOMAIN_BLOCK_JOB_TYPE_COPY; + else if (STREQ(type_str, "backup")) + type =3D VIR_DOMAIN_BLOCK_JOB_TYPE_BACKUP; switch ((virConnectDomainEventBlockJobStatus) event) { case VIR_DOMAIN_BLOCK_JOB_COMPLETED: @@ -2718,6 +2720,82 @@ int qemuMonitorJSONBlockResize(qemuMonitorPtr mon, return ret; } +int qemuMonitorJSONUpdateCheckpointSize(qemuMonitorPtr mon, + virDomainCheckpointDefPtr chk) +{ + int ret =3D -1; + size_t i, j; + virJSONValuePtr devices; + + if (!(devices =3D qemuMonitorJSONQueryBlock(mon))) + return -1; + + for (i =3D 0; i < virJSONValueArraySize(devices); i++) { + virJSONValuePtr dev =3D virJSONValueArrayGet(devices, i); + virJSONValuePtr inserted; + virJSONValuePtr bitmaps =3D NULL; + const char *node; + virDomainCheckpointDiskDefPtr disk; + + if (!(dev =3D qemuMonitorJSONGetBlockDev(devices, i))) + goto cleanup; + + if (!(inserted =3D virJSONValueObjectGetObject(dev, "inserted"))) + continue; + if (!(node =3D virJSONValueObjectGetString(inserted, "node-name"))= ) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-block device entry was not in expected= format")); + goto cleanup; + } + + for (j =3D 0; j < chk->ndisks; j++) { + disk =3D &chk->disks[j]; + if (disk->type !=3D VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP) + continue; + if (STREQ(disk->node, node)) + break; + } + if (j =3D=3D chk->ndisks) { + VIR_DEBUG("query-block did not find node %s", node); + continue; + } + if (!(bitmaps =3D virJSONValueObjectGetArray(dev, "dirty-bitmaps")= )) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("disk %s dirty bitmaps missing"), disk->name); + goto cleanup; + } + for (j =3D 0; j < virJSONValueArraySize(bitmaps); j++) { + virJSONValuePtr map =3D virJSONValueArrayGet(bitmaps, j); + const char *name; + + if (!(name =3D virJSONValueObjectGetString(map, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("dirty bitmaps entry was not in expected form= at")); + goto cleanup; + } + if (STRNEQ(name, disk->bitmap)) + continue; + if (virJSONValueObjectGetNumberUlong(map, "count", &disk->size= ) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid bitmap count")); + goto cleanup; + } + break; + } + if (j =3D=3D virJSONValueArraySize(bitmaps)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("disk %s dirty bitmap info missing"), disk->n= ame); + goto cleanup; + } + } + + ret =3D 0; + + cleanup: + virJSONValueFree(devices); + return ret; +} + int qemuMonitorJSONSetVNCPassword(qemuMonitorPtr mon, const char *password) { @@ -6754,6 +6832,34 @@ qemuMonitorJSONNBDServerAdd(qemuMonitorPtr mon, return ret; } +int +qemuMonitorJSONNBDServerAddBitmap(qemuMonitorPtr mon, + const char *export, + const char *bitmap) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("x-nbd-server-add-bitmap", + "s:name", export, + "s:bitmap", bitmap, + NULL))) + return ret; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + int qemuMonitorJSONNBDServerStop(qemuMonitorPtr mon) { @@ -8396,3 +8502,112 @@ qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon, return ret; } + +int +qemuMonitorJSONAddBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("block-dirty-bitmap-add", + "s:node", node, + "s:name", bitmap, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + +int +qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("x-block-dirty-bitmap-enable", + "s:node", node, + "s:name", bitmap, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + +int +qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon, const char *node, + const char *dst, const char *src) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("x-block-dirty-bitmap-merge", + "s:node", node, + "s:dst_name", dst, + "s:src_name", src, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + +int +qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon, const char *node, + const char *bitmap) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("block-dirty-bitmap-remove", + "s:node", node, + "s:name", bitmap, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} --=20 2.17.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list