[libvirt] [PATCH 12/13] Add support for an explicit IO error event

Daniel Veillard veillard at redhat.com
Mon Mar 22 16:42:39 UTC 2010


On Fri, Mar 19, 2010 at 03:39:00PM +0000, Daniel P. Berrange wrote:
> This introduces a new event type
> 
>    VIR_DOMAIN_EVENT_ID_IO_ERROR
> 
> This event includes the action that is about to be taken
> as a result of the watchdog triggering
> 
>   typedef enum {
>      VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
>      VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
>      VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
>   } virDomainEventIOErrorAction;

  okay

> In addition is has the source path of the disk that had the
> error and its unique device alias. It does not include the
> target device name (/dev/sda), since this would preclude
> triggering IO errors from other file backed devices (eg
> serial ports connected to a file)
> 
> Thus there is a new callback definition for this event type
> 
> typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
>                                                      virDomainPtr dom,
>                                                      const char *srcPath,
>                                                      const char *devAlias,
>                                                      int action,
>                                                      void *opaque);

  okay

[...]
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -1858,6 +1858,17 @@ typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
>                                                        virDomainPtr dom,
>                                                        int action,
>                                                        void *opaque);
> +typedef enum {
> +    VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
> +    VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
> +    VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
> +} virDomainEventIOErrorAction;

  again let's describe the parameters in the header as this is the only
  place (beside those list archives) where the semantic is described

> +typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
> +                                                     virDomainPtr dom,
> +                                                     const char *srcPath,
> +                                                     const char *devAlias,
> +                                                     int action,
> +                                                     void *opaque);
>  
>  /* Use this to cast the event specific callback into the generic one
>   * for use for virDomainEventRegister */
> @@ -1869,6 +1880,7 @@ typedef enum {
>      VIR_DOMAIN_EVENT_ID_REBOOT = 1,          /* virConnectDomainEventGenericCallback */
>      VIR_DOMAIN_EVENT_ID_RTC_CHANGE = 2,      /* virConnectDomainEventRTCChangeCallback */
>      VIR_DOMAIN_EVENT_ID_WATCHDOG = 3,        /* virConnectDomainEventWatchdogCallback */
> +    VIR_DOMAIN_EVENT_ID_IO_ERROR = 4,        /* virConnectDomainEventIOErrorCallback */
>  
>      /*
>       * NB: this enum value will increase over time as new events are

[...]
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index ceba5db..71cca5c 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -747,6 +747,26 @@ findDomainDiskByPath(virDomainObjPtr vm,
>      return NULL;
>  }
>  
> +static virDomainDiskDefPtr
> +findDomainDiskByAlias(virDomainObjPtr vm,
> +                      const char *alias)
> +{
> +    int i;
> +
> +    for (i = 0; i < vm->def->ndisks; i++) {
> +        virDomainDiskDefPtr disk;
> +
> +        disk = vm->def->disks[i];
> +        if (disk->info.alias != NULL && STREQ(disk->info.alias, alias))
> +            return disk;
> +    }
> +
> +    qemuReportError(VIR_ERR_INTERNAL_ERROR,
> +                    _("no disk found with alias %s"),
> +                    alias);
> +    return NULL;
> +}
> +
>  static int
>  getVolumeQcowPassphrase(virConnectPtr conn,
>                          virDomainDiskDefPtr disk,
> @@ -928,12 +948,49 @@ qemuHandleDomainWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
>  }
>  
>  
> +static int
> +qemuHandleDomainIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
> +                        virDomainObjPtr vm,
> +                        const char *diskAlias,
> +                        int action)
> +{
> +    struct qemud_driver *driver = qemu_driver;
> +    virDomainEventPtr event;
> +    const char *srcPath;
> +    const char *devAlias;
> +    virDomainDiskDefPtr disk;
> +
> +    virDomainObjLock(vm);
> +    disk = findDomainDiskByAlias(vm, diskAlias);
> +
> +    if (disk) {
> +        srcPath = disk->src;
> +        devAlias = disk->info.alias;
> +    } else {
> +        srcPath = "";
> +        devAlias = "";
> +    }
> +
> +    event = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action);
> +    virDomainObjUnlock(vm);
> +
> +    if (event) {
> +        qemuDriverLock(driver);
> +        qemuDomainEventQueue(driver, event);
> +        qemuDriverUnlock(driver);
> +    }
> +
> +    return 0;
> +}
> +
> +
>  static qemuMonitorCallbacks monitorCallbacks = {
>      .eofNotify = qemuHandleMonitorEOF,
>      .diskSecretLookup = findVolumeQcowPassphrase,
>      .domainReset = qemuHandleDomainReset,
>      .domainRTCChange = qemuHandleDomainRTCChange,
>      .domainWatchdog = qemuHandleDomainWatchdog,
> +    .domainIOError = qemuHandleDomainIOError,
>  };

  okay,

ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list