Skip to content

Qemu guest agent support - #533

Open
hrosenfeld wants to merge 2 commits into
omniosorg:masterfrom
hrosenfeld:qemu-guest-agent
Open

Qemu guest agent support#533
hrosenfeld wants to merge 2 commits into
omniosorg:masterfrom
hrosenfeld:qemu-guest-agent

Conversation

@hrosenfeld

Copy link
Copy Markdown
Contributor

This code was written by Patrick van der Linden of EFit Partners. My part in this is helping with review and integration.

The first commit extends socat to support I/O multiplexing to/from stdout/stdin in addition to a TCP socket, while then 2nd adds a ksh script to talk to the qemu guest agent.

At this time, this pull request should be regarded as a request for comments, not as code that's completely ready for integration.

@noengo

noengo commented Aug 27, 2026

Copy link
Copy Markdown

Here is a fix that allows the script to work with virtio-console or com2
The script also supports silent commands
I look forward to your constructive feedback ;)

qemu-monitor-command.patch

@citrus-it citrus-it left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, and apologies for the delay in looking at it. Since it's
marked RFC I've stuck to some directional comments. Please let me know
when it's ready for a review (and @noengo 's patch is folded in).

The name will confuse people. This speaks the qemu guest agent protocol (QGA), not the qemu monitor protocol (QMP). Something like qga or guest-agent-cmd would be clearer.

Hardcoding com2 as the transport doesn't seem right given #536. The QGA
convention is a virtio-serial channel named org.qemu.guest_agent.0, which
is what virtio-consoleN provides. If #536 goes first we can discover the
channel.

Where should the user-facing entry point live? /usr/lib/brand/bhyve is a
private directory with nothing on PATH and no manpage. If this is for
administrators, it should be documented in bhyve.7, and it may be worth considering whether zadm is the natural home for this functionality. The socat helper should
probably be removed too, in favour of the real socat. I'm not sure if anything still
uses it and I see you've fixed a couple of bugs in there.

@noengo

noengo commented Aug 27, 2026

Copy link
Copy Markdown

I agree on the name: “qga” or “guest-agent-cmd” is clearer.

As for the entry point /usr/lib/brand/bhyve, this is because the commands “pkill -z ‘$ZONENAME’ bhyve” or “pkill -TERM -z ‘$ZONENAME’ bhyve” provided by /usr/lib/brand/support send an ACPI shutdown request to the virtual machine.
This ACPI signal is generally not handled well by Windows, particularly by Windows Server. This is especially true for the latest versions, Windows 2025/11.
The idea is to integrate guest-agent-cmd into the shutdown sequence

For example
...
log “Shutting down zone %s with QGA” “$ZONENAME ”
/usr/lib/brand/bhyve/guest-agent-cmd -z “$ZONENAME” -c shutdown
typeset -i retval=$?

[[ ${retval} -ne 0 ]] && log “Shutdown with QGA failed (error code: ${retval}) ” || log “QGA sent for shutdown”
log “Shutting down the bhyve process - %d” $delay
pkill -TERM -z “$ZONENAME” bhyve
...

This should therefore be self-contained, so that bhyve has no dependency on socat

As for zadm, I imagine that’s what you use to manage OmniOS, but that’s not the case for us ;), though I agree that /usr/lib/brand/bhyve/guest-agent-cmd isn’t the right location.

Perhaps /usr/lib/brand/bhyve/guest-agent-cmd could be stripped down to just its shutdown function, and the full guest-agent-cmd file could be moved to a separate package or path

On a running system, we have occasionally encountered issues with the virtual console after a shutdown. The bhyve zone fails to start because the virtual console socket is locked. We have to delete /tmp/qga.sock to allow the zone to start. With com2, this never happens (which is why we kept it), but it’s still under investigation

This allows the built-in socat of the bhyve brand to allow I/O
multiplexing between stdin/stdout and a UNIX domain socket belonging
to the VM, such as a virtual COM port.

Unfortunately, the original socat implementation wasn't easily
adaptable for this, so the result looks a bit like two different
socat implementations merged in one.
This adds a new ksh script to /usr/lib/brand/bhyve, which can be used
to talk to a qemu-guest-agent inside the guest listening on the 2nd
serial port (COM2 in Windows parlance).

This change depends on the socat changes in the previous commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants