[PATCH] qemu_process: add tray changed event to queue in refresh disks

Kristina Hanicova posted 1 patch 1 year, 4 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/7c2fee3b9ea73ed47b512fd994f84a58cce447bd.1670935222.git.khanicov@redhat.com
src/qemu/qemu_process.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
[PATCH] qemu_process: add tray changed event to queue in refresh disks
Posted by Kristina Hanicova 1 year, 4 months ago
There are some cases when the internal state of disks can change
without qemu sending events about it (e.g. a disk can close
during reset). In case this happens, we should emit an event
about the modified disk.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1824722#c20

Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
---
 src/qemu/qemu_process.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5de55435d2..601e9694b6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8675,6 +8675,7 @@ qemuProcessRefreshDisks(virDomainObj *vm,
     qemuDomainObjPrivate *priv = vm->privateData;
     g_autoptr(GHashTable) table = NULL;
     size_t i;
+    virQEMUDriver *driver = QEMU_DOMAIN_PRIVATE(vm)->driver;
 
     if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) == 0) {
         table = qemuMonitorGetBlockInfo(priv->mon);
@@ -8697,14 +8698,26 @@ qemuProcessRefreshDisks(virDomainObj *vm,
             continue;
 
         if (info->removable) {
+            virObjectEvent *event = NULL;
+            int reason;
+
             if (info->empty)
                 virDomainDiskEmptySource(disk);
 
             if (info->tray) {
-                if (info->tray_open)
+                if (info->tray_open == disk->tray_status)
+                    continue;
+
+                if (info->tray_open) {
+                    reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN;
                     disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
-                else
+                } else {
+                    reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE;
                     disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
+                }
+
+                event = virDomainEventTrayChangeNewFromObj(vm, disk->info.alias, reason);
+                virObjectEventStateQueue(driver->domainEventState, event);
             }
         }
 
-- 
2.38.1
Re: [PATCH] qemu_process: add tray changed event to queue in refresh disks
Posted by Michal Prívozník 1 year, 4 months ago
On 12/13/22 13:40, Kristina Hanicova wrote:
> There are some cases when the internal state of disks can change
> without qemu sending events about it (e.g. a disk can close
> during reset). In case this happens, we should emit an event
> about the modified disk.
> 
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1824722#c20
> 
> Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
> ---
>  src/qemu/qemu_process.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 5de55435d2..601e9694b6 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -8675,6 +8675,7 @@ qemuProcessRefreshDisks(virDomainObj *vm,
>      qemuDomainObjPrivate *priv = vm->privateData;
>      g_autoptr(GHashTable) table = NULL;
>      size_t i;
> +    virQEMUDriver *driver = QEMU_DOMAIN_PRIVATE(vm)->driver;

Nit pick, we tend to declare driver first as it's usually the most
important variable. In this specific case, it can be declared second
(just like in qemuProcessFakeReboot(), for instance), because
QEMU_DOMAIN_PRIVATE(vm) is the same as priv variable.

>  
>      if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) == 0) {
>          table = qemuMonitorGetBlockInfo(priv->mon);
> @@ -8697,14 +8698,26 @@ qemuProcessRefreshDisks(virDomainObj *vm,
>              continue;
>  
>          if (info->removable) {
> +            virObjectEvent *event = NULL;
> +            int reason;
> +
>              if (info->empty)
>                  virDomainDiskEmptySource(disk);
>  
>              if (info->tray) {
> -                if (info->tray_open)
> +                if (info->tray_open == disk->tray_status)
> +                    continue;
> +
> +                if (info->tray_open) {
> +                    reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN;
>                      disk->tray_status = VIR_DOMAIN_DISK_TRAY_OPEN;
> -                else
> +                } else {
> +                    reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE;
>                      disk->tray_status = VIR_DOMAIN_DISK_TRAY_CLOSED;
> +                }
> +
> +                event = virDomainEventTrayChangeNewFromObj(vm, disk->info.alias, reason);
> +                virObjectEventStateQueue(driver->domainEventState, event);
>              }
>          }
>  

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

and pushed.

Michal