virDomainGetDiskErrors public API

We already provide ways to detect when a domain has been paused as a
result of I/O error, but there was no way of getting the exact error or
even the device that experienced it.  This new API may be used for both.
This commit is contained in:
Jiri Denemark 2012-01-31 07:41:53 +01:00
parent a89bb7d75a
commit 02af3e13b2
5 changed files with 107 additions and 1 deletions

View File

@ -1967,6 +1967,38 @@ virDomainGetBlockIoTune(virDomainPtr dom,
int *nparams,
unsigned int flags);
/**
* virDomainDiskErrorCode:
*
* Disk I/O error.
*/
typedef enum {
VIR_DOMAIN_DISK_ERROR_NONE = 0, /* no error */
VIR_DOMAIN_DISK_ERROR_UNSPEC = 1, /* unspecified I/O error */
VIR_DOMAIN_DISK_ERROR_NO_SPACE = 2, /* no space left on the device */
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_DISK_ERROR_LAST
#endif
} virDomainDiskErrorCode;
/**
* virDomainDiskError:
*
*/
typedef struct _virDomainDiskError virDomainDiskError;
typedef virDomainDiskError *virDomainDiskErrorPtr;
struct _virDomainDiskError {
char *disk; /* disk target */
int error; /* virDomainDiskErrorCode */
};
int virDomainGetDiskErrors(virDomainPtr dom,
virDomainDiskErrorPtr errors,
unsigned int maxerrors,
unsigned int flags);
/*
* NUMA support

View File

@ -423,7 +423,8 @@ skip_impl = (
'virDomainGetBlockIoTune',
'virDomainSetInterfaceParameters',
'virDomainGetInterfaceParameters',
'virDomainGetCPUStats' # not implemented now.
'virDomainGetCPUStats', # not implemented now.
'virDomainGetDiskErrors',
)
qemu_skip_impl = (

View File

@ -810,6 +810,12 @@ typedef int
unsigned int ncpus,
unsigned int flags);
typedef int
(*virDrvDomainGetDiskErrors)(virDomainPtr dom,
virDomainDiskErrorPtr errors,
unsigned int maxerrors,
unsigned int flags);
/**
* _virDriver:
*
@ -981,6 +987,7 @@ struct _virDriver {
virDrvDomainSetBlockIoTune domainSetBlockIoTune;
virDrvDomainGetBlockIoTune domainGetBlockIoTune;
virDrvDomainGetCPUStats domainGetCPUStats;
virDrvDomainGetDiskErrors domainGetDiskErrors;
};
typedef int

View File

@ -18282,3 +18282,68 @@ error:
virDispatchError(domain->conn);
return -1;
}
/**
* virDomainGetDiskErrors:
* @dom: a domain object
* @errors: array to populate on output
* @maxerrors: size of @errors array
* @flags: extra flags; not used yet, so callers should always pass 0
*
* The function populates @errors array with all disks that encountered an
* I/O error. Disks with no error will not be returned in the @errors array.
* Each disk is identified by its target (the dev attribute of target
* subelement in domain XML), such as "vda", and accompanied with the error
* that was seen on it. The caller is also responsible for calling free()
* on each disk name returned.
*
* In a special case when @errors is NULL and @maxerrors is 0, the function
* returns preferred size of @errors that the caller should use to get all
* disk errors.
*
* Since calling virDomainGetDiskErrors(dom, NULL, 0, 0) to get preferred size
* of @errors array and getting the errors are two separate operations, new
* disks may be hotplugged to the domain and new errors may be encountered
* between the two calls. Thus, this function may not return all disk errors
* because the supplied array is not large enough. Such errors may, however,
* be detected by listening to domain events.
*
* Returns number of disks with errors filled in the @errors array or -1 on
* error.
*/
int
virDomainGetDiskErrors(virDomainPtr dom,
virDomainDiskErrorPtr errors,
unsigned int maxerrors,
unsigned int flags)
{
VIR_DOMAIN_DEBUG(dom, "errors=%p, maxerrors=%u, flags=%x",
errors, maxerrors, flags);
virResetLastError();
if (!VIR_IS_DOMAIN(dom)) {
virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
virDispatchError(NULL);
return -1;
}
if ((!errors && maxerrors) || (errors && !maxerrors)) {
virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
goto error;
}
if (dom->conn->driver->domainGetDiskErrors) {
int ret = dom->conn->driver->domainGetDiskErrors(dom, errors,
maxerrors, flags);
if (ret < 0)
goto error;
return ret;
}
virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
virDispatchError(dom->conn);
return -1;
}

View File

@ -519,6 +519,7 @@ LIBVIRT_0.9.9 {
LIBVIRT_0.9.10 {
global:
virDomainGetCPUStats;
virDomainGetDiskErrors;
virDomainPMSuspendForDuration;
virDomainShutdownFlags;
virStorageVolResize;