[PATCH v2 0/4] bhyve: extend agent support
Changes from v2 are mechanical: - squash 4/5 and 5/5 together (virDomainFSInfoFormat() move and rename), and it becomes 3/4. - add bhyve implementation of domainGetFSInfo() after the code move, so 3/5 becomes 4/4 Roman Bogorodskiy (4): bhyve: reorder qemu agent code bhyve: support getting interface addresses from agent hypervisor: qemu_agent: add virDomainFSInfoFormat() bhyve: implement the domainGetFSInfo() API src/bhyve/bhyve_driver.c | 273 +++++++++++++++++++++++------------- src/hypervisor/qemu_agent.c | 70 +++++++++ src/hypervisor/qemu_agent.h | 5 + src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 72 +--------- 5 files changed, 254 insertions(+), 167 deletions(-) -- 2.52.0
Move all the helpers to the beginning for the file to be able to use them in every API implementation. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 181 ++++++++++++++++++++------------------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 331d9eb439..075b8ea64f 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -93,6 +93,97 @@ bhyveAutostartDomain(virDomainObj *vm, void *opaque) } } + +static qemuAgent * +bhyveDomainObjEnterAgent(virDomainObj *obj) +{ + bhyveDomainObjPrivate *priv = obj->privateData; + qemuAgent *agent = priv->agent; + + VIR_DEBUG("Entering agent (agent=%p vm=%p name=%s)", + priv->agent, obj, obj->def->name); + + virObjectLock(agent); + virObjectRef(agent); + virObjectUnlock(obj); + + return agent; +} + + +static void +bhyveDomainObjExitAgent(virDomainObj *obj, qemuAgent *agent) +{ + virObjectUnlock(agent); + virObjectUnref(agent); + virObjectLock(obj); + + VIR_DEBUG("Exited agent (agent=%p vm=%p name=%s)", + agent, obj, obj->def->name); +} + + +static bool +bhyveDomainAgentAvailable(virDomainObj *vm, + bool reportError) +{ + bhyveDomainObjPrivate *priv = vm->privateData; + + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { + if (reportError) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + } + return false; + } + + if (!priv->agent) { + if (bhyveFindAgentConfig(vm->def)) { + if (reportError) { + virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s", + _("QEMU guest agent is not connected")); + } + return false; + } else { + if (reportError) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("QEMU guest agent is not configured")); + } + return false; + } + } + return true; +} + + +static int +bhyveDomainEnsureAgent(virDomainObj *vm, + bool reportError) +{ + bhyveDomainObjPrivate *priv = vm->privateData; + + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { + if (reportError) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + } + return -1; + } + + if (priv->agent) + return 0; + + if (!priv->eventThread && + virBhyveDomainObjStartWorker(vm) < 0) + return -1; + + if (bhyveConnectAgent(NULL, vm) < 0) + return -1; + + return 0; +} + + /** * bhyveDriverGetCapabilities: * @@ -1907,96 +1998,6 @@ bhyveDomainInterfaceAddresses(virDomainPtr domain, } -static qemuAgent * -bhyveDomainObjEnterAgent(virDomainObj *obj) -{ - bhyveDomainObjPrivate *priv = obj->privateData; - qemuAgent *agent = priv->agent; - - VIR_DEBUG("Entering agent (agent=%p vm=%p name=%s)", - priv->agent, obj, obj->def->name); - - virObjectLock(agent); - virObjectRef(agent); - virObjectUnlock(obj); - - return agent; -} - - -static void -bhyveDomainObjExitAgent(virDomainObj *obj, qemuAgent *agent) -{ - virObjectUnlock(agent); - virObjectUnref(agent); - virObjectLock(obj); - - VIR_DEBUG("Exited agent (agent=%p vm=%p name=%s)", - agent, obj, obj->def->name); -} - - -static bool -bhyveDomainAgentAvailable(virDomainObj *vm, - bool reportError) -{ - bhyveDomainObjPrivate *priv = vm->privateData; - - if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { - if (reportError) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("domain is not running")); - } - return false; - } - - if (!priv->agent) { - if (bhyveFindAgentConfig(vm->def)) { - if (reportError) { - virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s", - _("QEMU guest agent is not connected")); - } - return false; - } else { - if (reportError) { - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", - _("QEMU guest agent is not configured")); - } - return false; - } - } - return true; -} - - -static int -bhyveDomainEnsureAgent(virDomainObj *vm, - bool reportError) -{ - bhyveDomainObjPrivate *priv = vm->privateData; - - if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { - if (reportError) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("domain is not running")); - } - return -1; - } - - if (priv->agent) - return 0; - - if (!priv->eventThread && - virBhyveDomainObjStartWorker(vm) < 0) - return -1; - - if (bhyveConnectAgent(NULL, vm) < 0) - return -1; - - return 0; -} - - static int bhyveDomainGetHostnameAgent(virDomainObj *vm, char **hostname) -- 2.52.0
Extend bhyveDomainInterfaceAddresses() to support the VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT source. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 075b8ea64f..2556384002 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1957,6 +1957,7 @@ bhyveDomainInterfaceAddresses(virDomainPtr domain, unsigned int flags) { virDomainObj *vm = NULL; + qemuAgent *agent; int ret = -1; virCheckFlags(0, -1); @@ -1971,6 +1972,22 @@ bhyveDomainInterfaceAddresses(virDomainPtr domain, goto cleanup; switch (source) { + case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT: + if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0) + goto cleanup; + + if (bhyveDomainEnsureAgent(vm, true) < 0) + goto endjob; + + agent = bhyveDomainObjEnterAgent(vm); + ret = qemuAgentGetInterfaces(agent, ifaces, true); + bhyveDomainObjExitAgent(vm, agent); + + endjob: + virDomainObjEndAgentJob(vm); + + break; + case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP: ret = virDomainNetARPInterfaces(vm->def, ifaces); break; @@ -1979,12 +1996,6 @@ bhyveDomainInterfaceAddresses(virDomainPtr domain, ret = virDomainNetDHCPInterfaces(vm->def, ifaces); break; - case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT: - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, - _("Unsupported IP address data source %1$d"), - source); - break; - default: virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("Unknown IP address data source %1$d"), -- 2.52.0
The virDomainFSInfoFormat() and qemuAgentFSInfoToPublic() function implementations are not driver dependent and can be shared across drivers, so move them to a common place to avoid code duplication. Also, rename virDomainFSInfoFormat() to qemuAgentFSInfoFormat() to follow the naming scheme in qemu_agent.c. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/hypervisor/qemu_agent.c | 70 ++++++++++++++++++++++++++++++++++++ src/hypervisor/qemu_agent.h | 5 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 72 +------------------------------------ 4 files changed, 77 insertions(+), 71 deletions(-) diff --git a/src/hypervisor/qemu_agent.c b/src/hypervisor/qemu_agent.c index 70f0cde5dd..e549947fbf 100644 --- a/src/hypervisor/qemu_agent.c +++ b/src/hypervisor/qemu_agent.c @@ -2611,3 +2611,73 @@ qemuAgentGetLoadAvg(qemuAgent *agent, return 0; } + +static virDomainFSInfoPtr +qemuAgentFSInfoToPublic(qemuAgentFSInfo *agent, + virDomainDef *vmdef) +{ + virDomainFSInfoPtr ret = NULL; + size_t i; + + ret = g_new0(virDomainFSInfo, 1); + + ret->mountpoint = g_strdup(agent->mountpoint); + ret->name = g_strdup(agent->name); + ret->fstype = g_strdup(agent->fstype); + + if (agent->disks) + ret->devAlias = g_new0(char *, agent->ndisks); + + for (i = 0; i < agent->ndisks; i++) { + qemuAgentDiskAddress *agentdisk = agent->disks[i]; + virDomainDiskDef *diskDef; + + diskDef = virDomainDiskByAddress(vmdef, + &agentdisk->pci_controller, + agentdisk->ccw_addr, + agentdisk->bus, + agentdisk->target, + agentdisk->unit); + if (diskDef != NULL) + ret->devAlias[ret->ndevAlias++] = g_strdup(diskDef->dst); + else + VIR_DEBUG("Missing target name for '%s'.", ret->mountpoint); + } + + return ret; +} + +/* Returns: 0 on success + * -1 otherwise + */ +int +qemuAgentFSInfoFormat(qemuAgentFSInfo **agentinfo, + int nagentinfo, + virDomainDef *vmdef, + virDomainFSInfoPtr **info) +{ + int ret = -1; + virDomainFSInfoPtr *info_ret = NULL; + size_t i; + + info_ret = g_new0(virDomainFSInfoPtr, nagentinfo); + + for (i = 0; i < nagentinfo; i++) { + if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef))) + goto cleanup; + } + + *info = g_steal_pointer(&info_ret); + ret = nagentinfo; + + cleanup: + if (info_ret) { + for (i = 0; i < nagentinfo; i++) { + /* if there was an error, free any memory we've allocated for the + * return value */ + virDomainFSInfoFree(info_ret[i]); + } + g_free(info_ret); + } + return ret; +} diff --git a/src/hypervisor/qemu_agent.h b/src/hypervisor/qemu_agent.h index 9117d3743c..3dbc3baec1 100644 --- a/src/hypervisor/qemu_agent.h +++ b/src/hypervisor/qemu_agent.h @@ -196,3 +196,8 @@ int qemuAgentGetLoadAvg(qemuAgent *agent, double *load5m, double *load15m, bool report_unsupported); + +int qemuAgentFSInfoFormat(qemuAgentFSInfo **agentinfo, + int nagentinfo, + virDomainDef *vmdef, + virDomainFSInfoPtr **info); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a76da45fb9..0aad60fed7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1714,6 +1714,7 @@ qemuAgentArbitraryCommand; qemuAgentClose; qemuAgentDiskInfoFree; qemuAgentFSFreeze; +qemuAgentFSInfoFormat; qemuAgentFSInfoFree; qemuAgentFSThaw; qemuAgentFSTrim; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index bcafacfb60..58b68a6e2b 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18767,76 +18767,6 @@ qemuDomainGetFSInfoAgent(virDomainObj *vm, return ret; } -static virDomainFSInfoPtr -qemuAgentFSInfoToPublic(qemuAgentFSInfo *agent, - virDomainDef *vmdef) -{ - virDomainFSInfoPtr ret = NULL; - size_t i; - - ret = g_new0(virDomainFSInfo, 1); - - ret->mountpoint = g_strdup(agent->mountpoint); - ret->name = g_strdup(agent->name); - ret->fstype = g_strdup(agent->fstype); - - if (agent->disks) - ret->devAlias = g_new0(char *, agent->ndisks); - - for (i = 0; i < agent->ndisks; i++) { - qemuAgentDiskAddress *agentdisk = agent->disks[i]; - virDomainDiskDef *diskDef; - - diskDef = virDomainDiskByAddress(vmdef, - &agentdisk->pci_controller, - agentdisk->ccw_addr, - agentdisk->bus, - agentdisk->target, - agentdisk->unit); - if (diskDef != NULL) - ret->devAlias[ret->ndevAlias++] = g_strdup(diskDef->dst); - else - VIR_DEBUG("Missing target name for '%s'.", ret->mountpoint); - } - - return ret; -} - -/* Returns: 0 on success - * -1 otherwise - */ -static int -virDomainFSInfoFormat(qemuAgentFSInfo **agentinfo, - int nagentinfo, - virDomainDef *vmdef, - virDomainFSInfoPtr **info) -{ - int ret = -1; - virDomainFSInfoPtr *info_ret = NULL; - size_t i; - - info_ret = g_new0(virDomainFSInfoPtr, nagentinfo); - - for (i = 0; i < nagentinfo; i++) { - if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef))) - goto cleanup; - } - - *info = g_steal_pointer(&info_ret); - ret = nagentinfo; - - cleanup: - if (info_ret) { - for (i = 0; i < nagentinfo; i++) { - /* if there was an error, free any memory we've allocated for the - * return value */ - virDomainFSInfoFree(info_ret[i]); - } - g_free(info_ret); - } - return ret; -} - static int qemuDomainGetFSInfo(virDomainPtr dom, virDomainFSInfoPtr **info, @@ -18864,7 +18794,7 @@ qemuDomainGetFSInfo(virDomainPtr dom, if (virDomainObjCheckActive(vm) < 0) goto endjob; - ret = virDomainFSInfoFormat(agentinfo, nfs, vm->def, info); + ret = qemuAgentFSInfoFormat(agentinfo, nfs, vm->def, info); endjob: virDomainObjEndJob(vm); -- 2.52.0
This implementation is identical to the one found in the qemu driver. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 2556384002..2e7a534396 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -2307,6 +2307,74 @@ bhyveDomainSetMemoryParameters(virDomainPtr domain, return ret; } +static int +bhyveDomainGetFSInfoAgent(virDomainObj *vm, + qemuAgentFSInfo ***info) +{ + int ret = -1; + qemuAgent *agent; + + if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0) + return ret; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (bhyveDomainEnsureAgent(vm, true) < 0) + goto endjob; + + agent = bhyveDomainObjEnterAgent(vm); + ret = qemuAgentGetFSInfo(agent, info, true); + bhyveDomainObjExitAgent(vm, agent); + + endjob: + virDomainObjEndAgentJob(vm); + return ret; +} + +static int +bhyveDomainGetFSInfo(virDomainPtr dom, + virDomainFSInfoPtr **info, + unsigned int flags) +{ + virDomainObj *vm; + qemuAgentFSInfo **agentinfo = NULL; + int ret = -1; + int nfs = 0; + + virCheckFlags(0, ret); + + if (!(vm = bhyveDomObjFromDomain(dom))) + return ret; + + if (virDomainGetFSInfoEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if ((nfs = bhyveDomainGetFSInfoAgent(vm, &agentinfo)) < 0) + goto cleanup; + + if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + ret = qemuAgentFSInfoFormat(agentinfo, nfs, vm->def, info); + + endjob: + virDomainObjEndJob(vm); + + cleanup: + if (agentinfo) { + size_t i; + for (i = 0; i < nfs; i++) + qemuAgentFSInfoFree(agentinfo[i]); + g_free(agentinfo); + } + virDomainObjEndAPI(&vm); + return ret; +} + static virHypervisorDriver bhyveHypervisorDriver = { .name = "bhyve", .connectURIProbe = bhyveConnectURIProbe, @@ -2378,6 +2446,7 @@ static virHypervisorDriver bhyveHypervisorDriver = { .domainQemuAgentCommand = bhyveDomainQemuAgentCommand, /* 12.4.0 */ .domainGetMemoryParameters = bhyveDomainGetMemoryParameters, /* 12.4.0 */ .domainSetMemoryParameters = bhyveDomainSetMemoryParameters, /* 12.4.0 */ + .domainGetFSInfo = bhyveDomainGetFSInfo, /* 12.5.0 */ }; -- 2.52.0
On 5/25/26 13:14, Roman Bogorodskiy wrote:
Changes from v2 are mechanical:
- squash 4/5 and 5/5 together (virDomainFSInfoFormat() move and rename), and it becomes 3/4. - add bhyve implementation of domainGetFSInfo() after the code move, so 3/5 becomes 4/4
Roman Bogorodskiy (4): bhyve: reorder qemu agent code bhyve: support getting interface addresses from agent hypervisor: qemu_agent: add virDomainFSInfoFormat() bhyve: implement the domainGetFSInfo() API
src/bhyve/bhyve_driver.c | 273 +++++++++++++++++++++++------------- src/hypervisor/qemu_agent.c | 70 +++++++++ src/hypervisor/qemu_agent.h | 5 + src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 72 +--------- 5 files changed, 254 insertions(+), 167 deletions(-)
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Michal Prívozník -
Roman Bogorodskiy