From nobody Mon Feb 9 22:39:17 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) client-ip=207.211.31.81; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1582624572; cv=none; d=zohomail.com; s=zohoarc; b=fme+MzdRu2GqNSjcns2DUlMR2/1Y2bCQ4RqSM4oewSIJA1aSyyzc4Vrg8BAiUSsHsAHto4YCaoiue3Uvo06PYKzQUPQ8FUNbsKsSoWDwluQW2zs0PzGcJJEyqqw0KQ51LeoyFbrYamqOp8JHslVcGEtZCeNs7qDtKCQpDbR9b78= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1582624572; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=428F2OhLzQ2JbcmNQ0IY6qK1s543Q2oY5i2u7T2ft/I=; b=MzHwhvqSPI1q/y09Dyh6VS7WSQ4O57FxpyTgEXbJfFzNcdJZPYun2uqAkAIACNj8tpwYQqNHi6NVoiz4X3RtKYtctTnBXiR3PP8zSpyys+iiHVolwNqFLriMdvaVSEptRc5d5wZqpB3Ut5m/deYR2tpyoW6F2d0iP8m6OOXGUn4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by mx.zohomail.com with SMTPS id 1582624572669963.2082455708463; Tue, 25 Feb 2020 01:56:12 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-11-1KSNev1BPqmmaq2OaZFUQw-1; Tue, 25 Feb 2020 04:56:09 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7ECC818C8C00; Tue, 25 Feb 2020 09:56:02 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 549EC8C06D; Tue, 25 Feb 2020 09:56:02 +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 EB8078B2D8; Tue, 25 Feb 2020 09:56:01 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 01P9txOQ027987 for ; Tue, 25 Feb 2020 04:55:59 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1B06892962; Tue, 25 Feb 2020 09:55:59 +0000 (UTC) Received: from localhost (unknown [10.48.0.127]) by smtp.corp.redhat.com (Postfix) with ESMTP id A601791840; Tue, 25 Feb 2020 09:55:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582624571; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=428F2OhLzQ2JbcmNQ0IY6qK1s543Q2oY5i2u7T2ft/I=; b=PjqKDlUVt/rlfMHp3LFZ64syBqbSIAwg3c3TDz1p47M7TxsUH9bt/4L4QXHcH9JbgrO7Yp 2OaqWeMDtADetDdOVLCENyTRl2jHa3zNYnKap2BjupcYjjCmMPn1p8wXn6ujpgf5pc//wZ Jo5pc8OAap8iZKzdTL4DoI5/1Qu1+mI= X-MC-Unique: 1KSNev1BPqmmaq2OaZFUQw-1 From: marcandre.lureau@redhat.com To: libvir-list@redhat.com Subject: [libvirt PATCH v2 7/9] qemu: add dbus-vmstate helper migration support Date: Tue, 25 Feb 2020 10:55:11 +0100 Message-Id: <20200225095513.969053-8-marcandre.lureau@redhat.com> In-Reply-To: <20200225095513.969053-1-marcandre.lureau@redhat.com> References: <20200225095513.969053-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: =?UTF-8?q?Michal=20Pr=C3=ADvozn=C3=ADk?= , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Helper processes may have their state migrated with QEMU data stream thanks to the QEMU "dbus-vmstate". libvirt maintains the list of helpers to be migrated. The "dbus-vmstate" is added when required, and given the list of helper Ids that must be migrated, on save & load sides. See also: https://git.qemu.org/?p=3Dqemu.git;a=3Dblob;f=3Ddocs/interop/dbus-vmstate.r= st Signed-off-by: Marc-Andr=C3=A9 Lureau --- src/qemu/qemu_alias.c | 7 +++ src/qemu/qemu_alias.h | 2 + src/qemu/qemu_command.c | 54 ++++++++++++++++++++++++ src/qemu/qemu_command.h | 3 ++ src/qemu/qemu_dbus.c | 14 ++++++ src/qemu/qemu_dbus.h | 4 ++ src/qemu/qemu_domain.c | 12 ++++++ src/qemu/qemu_domain.h | 5 +++ src/qemu/qemu_hotplug.c | 82 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_hotplug.h | 8 ++++ src/qemu/qemu_migration.c | 51 ++++++++++++++++++++++ src/qemu/qemu_monitor.c | 21 +++++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 15 +++++++ src/qemu/qemu_monitor_json.h | 5 +++ 15 files changed, 286 insertions(+) diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 61f8ce05c9..d2e1ce155e 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -840,3 +840,10 @@ qemuDomainGetUnmanagedPRAlias(const char *parentalias) =20 return ret; } + + +const char * +qemuDomainGetDBusVMStateAlias(void) +{ + return "dbus-vmstate0"; +} diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h index aaac09a1d1..e3492116c5 100644 --- a/src/qemu/qemu_alias.h +++ b/src/qemu/qemu_alias.h @@ -95,3 +95,5 @@ char *qemuAliasChardevFromDevAlias(const char *devAlias) const char *qemuDomainGetManagedPRAlias(void); =20 char *qemuDomainGetUnmanagedPRAlias(const char *parentalias); + +const char *qemuDomainGetDBusVMStateAlias(void); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7eec7b7577..4696fd715c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -24,6 +24,7 @@ #include "qemu_command.h" #include "qemu_hostdev.h" #include "qemu_capabilities.h" +#include "qemu_dbus.h" #include "qemu_interface.h" #include "qemu_alias.h" #include "qemu_security.h" @@ -9516,6 +9517,56 @@ qemuBuildPflashBlockdevCommandLine(virCommandPtr cmd, } =20 =20 +virJSONValuePtr +qemuBuildDBusVMStateInfoProps(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + virJSONValuePtr ret =3D NULL; + const char *alias =3D qemuDomainGetDBusVMStateAlias(); + g_autofree char *addr =3D qemuDBusGetAddress(driver, vm); + + if (!addr) + return NULL; + + qemuMonitorCreateObjectProps(&ret, + "dbus-vmstate", alias, + "s:addr", addr, NULL); + return ret; +} + + +static int +qemuBuildDBusVMStateCommandLine(virCommandPtr cmd, + virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props =3D NULL; + qemuDomainObjPrivatePtr priv =3D QEMU_DOMAIN_PRIVATE(vm); + + if (virStringListLength((const char **)priv->dbusVMStateIds) =3D=3D 0) + return 0; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) { + VIR_INFO("dbus-vmstate object is not supported by this QEMU binary= "); + return 0; + } + + if (!(props =3D qemuBuildDBusVMStateInfoProps(driver, vm))) + return -1; + + if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); + virCommandAddArgBuffer(cmd, &buf); + + priv->dbusVMState =3D true; + + return 0; +} + + /** * qemuBuildCommandLineValidate: * @@ -9747,6 +9798,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildMasterKeyCommandLine(cmd, priv) < 0) return NULL; =20 + if (qemuBuildDBusVMStateCommandLine(cmd, driver, vm) < 0) + return NULL; + if (qemuBuildManagedPRCommandLine(cmd, def, priv) < 0) return NULL; =20 diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index d4927d2191..bc3ba44fb3 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -59,6 +59,9 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr drive= r, virJSONValuePtr qemuBuildPRManagerInfoProps(virStorageSourcePtr src); virJSONValuePtr qemuBuildPRManagedManagerInfoProps(qemuDomainObjPrivatePtr= priv); =20 +virJSONValuePtr qemuBuildDBusVMStateInfoProps(virQEMUDriverPtr driver, + virDomainObjPtr vm); + /* Generate the object properties for a secret */ int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo, virJSONValuePtr *propsret); diff --git a/src/qemu/qemu_dbus.c b/src/qemu/qemu_dbus.c index 383efa0209..1bce6ffc69 100644 --- a/src/qemu/qemu_dbus.c +++ b/src/qemu/qemu_dbus.c @@ -280,3 +280,17 @@ qemuDBusStart(virQEMUDriverPtr driver, } return ret; } + + +int +qemuDBusVMStateAdd(virDomainObjPtr vm, const char *id) +{ + return virStringListAdd(&QEMU_DOMAIN_PRIVATE(vm)->dbusVMStateIds, id); +} + + +void +qemuDBusVMStateRemove(virDomainObjPtr vm, const char *id) +{ + virStringListRemove(&QEMU_DOMAIN_PRIVATE(vm)->dbusVMStateIds, id); +} diff --git a/src/qemu/qemu_dbus.h b/src/qemu/qemu_dbus.h index d6cb1bc84a..a96f19ac0d 100644 --- a/src/qemu/qemu_dbus.h +++ b/src/qemu/qemu_dbus.h @@ -31,3 +31,7 @@ int qemuDBusStart(virQEMUDriverPtr driver, =20 void qemuDBusStop(virQEMUDriverPtr driver, virDomainObjPtr vm); + +int qemuDBusVMStateAdd(virDomainObjPtr vm, const char *id); + +void qemuDBusVMStateRemove(virDomainObjPtr vm, const char *id); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 663938c9ff..07ba6ecf0e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2239,6 +2239,13 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePt= r priv) =20 /* reset node name allocator */ qemuDomainStorageIdReset(priv); + + priv->dbusDaemonRunning =3D false; + + virStringListFree(priv->dbusVMStateIds); + priv->dbusVMStateIds =3D NULL; + + priv->dbusVMState =3D false; } =20 =20 @@ -2885,6 +2892,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, if (priv->dbusDaemonRunning) virBufferAddLit(buf, "\n"); =20 + if (priv->dbusVMState) + virBufferAddLit(buf, "\n"); + if (priv->namespaces) { ssize_t ns =3D -1; =20 @@ -3639,6 +3649,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, =20 priv->dbusDaemonRunning =3D virXPathBoolean("boolean(./dbusDaemon)", c= txt) > 0; =20 + priv->dbusVMState =3D virXPathBoolean("boolean(./dbusVMState)", ctxt) = > 0; + if ((node =3D virXPathNode("./namespaces", ctxt))) { xmlNodePtr next; =20 diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 97e52b7a81..7804af4e04 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -419,6 +419,11 @@ struct _qemuDomainObjPrivate { virDomainBackupDefPtr backup; =20 bool dbusDaemonRunning; + + /* list of Ids to migrate */ + char **dbusVMStateIds; + /* true if -object dbus-vmstate was added */ + bool dbusVMState; }; =20 #define QEMU_DOMAIN_PRIVATE(vm) \ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5db03c4e9f..1a40a1dbcc 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -311,6 +311,88 @@ qemuDomainChangeMediaLegacy(virQEMUDriverPtr driver, } =20 =20 +/** + * qemuHotplugAttachDBusVMState: + * @driver: QEMU driver object + * @vm: domain object + * @asyncJob: asynchronous job identifier + * + * Add -object dbus-vmstate if necessary. + * + * Returns: 0 on success, -1 on error. + */ +int +qemuHotplugAttachDBusVMState(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + g_autoptr(virJSONValue) props =3D NULL; + int ret; + + if (priv->dbusVMState) + return 0; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) { + VIR_DEBUG("dbus-vmstate object is not supported by this QEMU binar= y"); + return 0; + } + + if (!(props =3D qemuBuildDBusVMStateInfoProps(driver, vm))) + return -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + ret =3D qemuMonitorAddObject(priv->mon, &props, NULL); + + if (ret =3D=3D 0) + priv->dbusVMState =3D true; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + return -1; + + return ret; +} + + +/** + * qemuHotplugRemoveDBusVMState: + * @driver: QEMU driver object + * @vm: domain object + * @asyncJob: asynchronous job identifier + * + * Remove -object dbus-vmstate from @vm if the configuration does not requ= ire + * it any more. + * + * Returns: 0 on success, -1 on error. + */ +int +qemuHotplugRemoveDBusVMState(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + int ret; + + if (!priv->dbusVMState) + return 0; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + ret =3D qemuMonitorDelObject(priv->mon, qemuDomainGetDBusVMStateAlias(= )); + + if (ret =3D=3D 0) + priv->dbusVMState =3D false; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + return -1; + + return ret; +} + + /** * qemuHotplugAttachManagedPR: * @driver: QEMU driver object diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 6605a6a3e0..4a49e04a15 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -152,3 +152,11 @@ int qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, bool state); =20 unsigned long long qemuDomainGetUnplugTimeout(virDomainObjPtr vm); + +int qemuHotplugAttachDBusVMState(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob); + +int qemuHotplugRemoveDBusVMState(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 29aaad58c7..773d7c9799 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1168,6 +1168,7 @@ qemuMigrationSrcIsAllowed(virQEMUDriverPtr driver, bool remote, unsigned int flags) { + qemuDomainObjPrivatePtr priv =3D vm->privateData; int nsnapshots; int pauseReason; size_t i; @@ -1272,6 +1273,13 @@ qemuMigrationSrcIsAllowed(virQEMUDriverPtr driver, return false; } } + + if (virStringListLength((const char **)priv->dbusVMStateIds) > 0 && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot migrate this domain without dbus-vmst= ate support")); + return false; + } } =20 return true; @@ -1937,8 +1945,14 @@ qemuMigrationDstRun(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; =20 + rv =3D qemuMonitorSetDBusVMStateIdList(priv->mon, + (const char **)priv->dbusVMStateI= ds); + if (rv < 0) + goto exit_monitor; + rv =3D qemuMonitorMigrateIncoming(priv->mon, uri); =20 + exit_monitor: if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0) return -1; =20 @@ -3407,6 +3421,37 @@ qemuMigrationSrcContinue(virQEMUDriverPtr driver, } =20 =20 +static int +qemuMigrationSetDBusVMState(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + if (virStringListLength((const char **)priv->dbusVMStateIds) > 0) { + int rv; + + if (qemuHotplugAttachDBusVMState(driver, vm, QEMU_ASYNC_JOB_NONE) = < 0) + return -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE= ) < 0) + return -1; + + rv =3D qemuMonitorSetDBusVMStateIdList(priv->mon, + (const char **)priv->dbusVMSt= ateIds); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + rv =3D -1; + + return rv; + } else { + if (qemuHotplugRemoveDBusVMState(driver, vm, QEMU_ASYNC_JOB_NONE) = < 0) + return -1; + } + + return 0; +} + + static int qemuMigrationSrcRun(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -3559,6 +3604,9 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, } } =20 + if (qemuMigrationSetDBusVMState(driver, vm) < 0) + goto exit_monitor; + /* Before EnterMonitor, since already qemuProcessStopCPUs does that */ if (!(flags & VIR_MIGRATE_LIVE) && virDomainObjGetState(vm, NULL) =3D=3D VIR_DOMAIN_RUNNING) { @@ -5244,6 +5292,9 @@ qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDo= mainObjPtr vm, char *errbuf =3D NULL; virErrorPtr orig_err =3D NULL; =20 + if (qemuMigrationSetDBusVMState(driver, vm) < 0) + return -1; + /* Increase migration bandwidth to unlimited since target is a file. * Failure to change migration speed is not fatal. */ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) =3D=3D 0) { diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 008d4a0e75..d91af76503 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -25,6 +25,7 @@ #include #include =20 +#include "qemu_alias.h" #include "qemu_monitor.h" #include "qemu_monitor_text.h" #include "qemu_monitor_json.h" @@ -2382,6 +2383,26 @@ qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon, } =20 =20 +int +qemuMonitorSetDBusVMStateIdList(qemuMonitorPtr mon, + const char **list) +{ + g_autofree char *path =3D NULL; + + VIR_DEBUG("list=3D%p", list); + + if (virStringListLength(list) =3D=3D 0) + return 0; + + path =3D g_strdup_printf("/objects/%s", + qemuDomainGetDBusVMStateAlias()); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONSetDBusVMStateIdList(mon, path, list); +} + + int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon, unsigned long bandwidth) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 8cf9e11899..cd9a6afe80 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -747,6 +747,9 @@ int qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon, unsigned long long length, const char *path); =20 +int qemuMonitorSetDBusVMStateIdList(qemuMonitorPtr mon, + const char **list); + int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon, unsigned long bandwidth); =20 diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 50d93c0c7e..6fc716e3a1 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2352,6 +2352,21 @@ qemuMonitorJSONSetMemoryStatsPeriod(qemuMonitorPtr m= on, } =20 =20 +int +qemuMonitorJSONSetDBusVMStateIdList(qemuMonitorPtr mon, + const char *vmstatepath, + const char **list) +{ + g_autofree char *str =3D virStringListJoin(list, ","); + qemuMonitorJSONObjectProperty prop =3D { + .type =3D QEMU_MONITOR_OBJECT_PROPERTY_STRING, + .val.str =3D str, + }; + + return qemuMonitorJSONSetObjectProperty(mon, vmstatepath, "id-list", &= prop); +} + + /* qemuMonitorJSONQueryBlock: * @mon: Monitor pointer * diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index fd2e09025e..b4c013d46c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -679,3 +679,8 @@ qemuMonitorJSONTransactionBackup(virJSONValuePtr action= s, const char *target, const char *bitmap, qemuMonitorTransactionBackupSyncMode sync= mode); + +int qemuMonitorJSONSetDBusVMStateIdList(qemuMonitorPtr mon, + const char *vmstatepath, + const char **list) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); --=20 2.25.0.rc2.1.g09a9a1a997