[libvirt] [PATCH] qemu: Emit domain events for all virtio-serial channels
Matt Broadstone
mbroadst at gmail.com
Fri Nov 11 12:51:25 UTC 2016
On Fri, Nov 11, 2016 at 5:13 AM, Peter Krempa <pkrempa at redhat.com> wrote:
> On Mon, Nov 07, 2016 at 15:48:35 -0500, Matt Broadstone wrote:
>> Presently domain events are emitted for the "agent lifecycle" which
>> is a specialization on virtio-serial events specific to the channel
>> named "org.qemu.guest_agent.0". This patch adds a generic event for
>> "channel lifecycles", which emit state change events for all
>> attached channels.
>> ---
>> daemon/remote.c | 42 +++++++++++++++++
>> examples/object-events/event-test.c | 57 ++++++++++++++++++++++++
>> include/libvirt/libvirt-domain.h | 41 +++++++++++++++++
>> src/conf/domain_event.c | 89 +++++++++++++++++++++++++++++++++++++
>> src/conf/domain_event.h | 12 +++++
>> src/libvirt_private.syms | 2 +
>> src/qemu/qemu_driver.c | 5 +++
>> src/qemu/qemu_process.c | 6 +++
>> src/remote/remote_driver.c | 32 +++++++++++++
>> src/remote/remote_protocol.x | 17 ++++++-
>> src/remote_protocol-structs | 7 +++
>> tools/virsh-domain.c | 35 +++++++++++++++
>> 12 files changed, 344 insertions(+), 1 deletion(-)
>>
>
> [...]
>
>> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
>> index 5f50660..d720132 100644
>> --- a/include/libvirt/libvirt-domain.h
>> +++ b/include/libvirt/libvirt-domain.h
>> @@ -3965,6 +3965,46 @@ typedef void (*virConnectDomainEventAgentLifecycleCallback)(virConnectPtr conn,
>> int reason,
>> void *opaque);
>>
>> +typedef enum {
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_CONNECTED = 1, /* channel connected */
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_DISCONNECTED = 2, /* channel disconnected */
>> +
>> +# ifdef VIR_ENUM_SENTINELS
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_STATE_LAST
>> +# endif
>> +} virConnectDomainEventChannelLifecycleState;
>> +
>> +typedef enum {
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_UNKNOWN = 0, /* unknown state change reason */
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_DOMAIN_STARTED = 1, /* state changed due to domain start */
>
> This reason is not used at all and I don't think it even makes sense to
> be reported for channel events. With guest agent it might make sense and
> also other possible reasons as guest agent error.
>
This reason is, in fact, being used in qemu_process.c:1925
(qemuProcessRefreshChannelVirtioState). The state is actually aligned
with the virConnectDomainEventChannelLifecycleReason enum in order to
reuse the existing `agentReason` for emitting this event. I can
explicitly add a `channelReason` if that makes the code clearer/more
readable.
> With channels you mostly care about the connect and disconnect events.
> It might make sense to report client connect or disconnect in the future
> for certain backend types, but I don't think that qemu supports such
> report currently.
I agree that with chanels you generally care about `connected` and
`disconnected`, but the real problem here is that there is no framing
over the virtio-serial channel. As a result, it's important for
developers of guest agents to know when a channel connection is being
cycled or started for the first time. Remember that the reason for
this patch in the first place is that I am creating an agent myself.
>
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHANNEL = 2, /* channel state changed */
>> +
>> +# ifdef VIR_ENUM_SENTINELS
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_LAST
>> +# endif
>> +} virConnectDomainEventChannelLifecycleReason;
>> +
>> +/**
>> + * virConnectDomainEventChannelLifecycleCallback:
>> + * @conn: connection object
>> + * @dom: domain on which the event occurred
>> + * @channelName: the name of the channel on which the event occurred
>> + * @state: new state of the guest channel, one of virConnectDomainEventChannelLifecycleState
>> + * @reason: reason for state change; one of virConnectDomainEventChannelLifecycleReason
>> + * @opaque: application specified data
>> + *
>> + * This callback occurs when libvirt detects a change in the state of a guest
>> + * serial channel.
>
> You should note that the hypervisor needs to support channel state
> notifications, otherwise it won't work. (Qemu supporting this has been
> around for ages now, but we still support versions older than that. Also
> other hypervisors don't support this currently)
>
Agreed.
>> + *
>> + * The callback signature to use when registering for an event of type
>> + * VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE with virConnectDomainEventRegisterAny()
>> + */
>> +typedef void (*virConnectDomainEventChannelLifecycleCallback)(virConnectPtr conn,
>> + virDomainPtr dom,
>> + const char *channelName,
>> + int state,
>> + int reason,
>> + void *opaque);
>>
>> /**
>> * VIR_DOMAIN_EVENT_CALLBACK:
>> @@ -4006,6 +4046,7 @@ typedef enum {
>> VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION = 20, /* virConnectDomainEventMigrationIterationCallback */
>> VIR_DOMAIN_EVENT_ID_JOB_COMPLETED = 21, /* virConnectDomainEventJobCompletedCallback */
>> VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED = 22, /* virConnectDomainEventDeviceRemovalFailedCallback */
>> + VIR_DOMAIN_EVENT_ID_CHANNEL_LIFECYCLE = 23, /* virConnectDomainEventChannelLifecycleCallback */
>>
>> # ifdef VIR_ENUM_SENTINELS
>> VIR_DOMAIN_EVENT_ID_LAST
>
> [...]
>
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index 38c8414..b464412 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -4407,6 +4407,7 @@ processSerialChangedEvent(virQEMUDriverPtr driver,
>> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>> virDomainChrDeviceState newstate;
>> virObjectEventPtr event = NULL;
>> + virObjectEventPtr channelEvent = NULL;
>> virDomainDeviceDef dev;
>> qemuDomainObjPrivatePtr priv = vm->privateData;
>> int rc;
>> @@ -4482,6 +4483,10 @@ processSerialChangedEvent(virQEMUDriverPtr driver,
>> qemuDomainEventQueue(driver, event);
>> }
>>
>> + channelEvent = virDomainEventChannelLifecycleNewFromObj(vm, dev.data.chr->target.name, newstate,
>> + VIR_CONNECT_DOMAIN_EVENT_CHANNEL_LIFECYCLE_REASON_CHANNEL);
>
> I don't think we should emit this event for the guest agent channel. It
> has a separate one and the channel is reserved for libvirt anyways, so
> client applications should use the guest agent event for this.
>
This has been answered in subsequent emails.
>> + qemuDomainEventQueue(driver, channelEvent);
>> +
>> endjob:
>> qemuDomainObjEndJob(driver, vm);
>>
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index 1b67aee..31b5028 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>
> [...]
>
>> @@ -1958,6 +1959,11 @@ qemuProcessRefreshChannelVirtioState(virQEMUDriverPtr driver,
>> agentReason)))
>> qemuDomainEventQueue(driver, event);
>>
>> +
>> + channelEvent =
>> + virDomainEventChannelLifecycleNewFromObj(vm, chr->target.name, entry->state, agentReason);
>> + qemuDomainEventQueue(driver, channelEvent);
>
> Same comment as above.
>
>> +
>> chr->state = entry->state;
>> }
>> }
>> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
>> index a3cd7cd..c778c42 100644
>> --- a/src/remote/remote_driver.c
>> +++ b/src/remote/remote_driver.c
>
> [...]
>
>> @@ -538,6 +543,10 @@ static virNetClientProgramEvent remoteEvents[] = {
>> remoteDomainBuildEventCallbackAgentLifecycle,
>> sizeof(remote_domain_event_callback_agent_lifecycle_msg),
>> (xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg },
>> + { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_CHANNEL_LIFECYCLE,
>> + remoteDomainBuildEventCallbackChannelLifecycle,
>> + sizeof(remote_domain_event_callback_channel_lifecycle_msg),
>> + (xdrproc_t)xdr_remote_domain_event_callback_channel_lifecycle_msg },
>> { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED,
>> remoteDomainBuildEventCallbackDeviceAdded,
>> sizeof(remote_domain_event_callback_device_added_msg),
>
>
> These are ordered in the way the events were added, and you are not
> putting yours at the end.
>
Oops, thanks for catching that. I thought I had caught all the ordering issues!
> Other than the few details looks good.
>
> Peter
More information about the libvir-list
mailing list