1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-25 01:34:11 +03:00

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, int *nparams,
unsigned int flags); 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 * NUMA support

View File

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

View File

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

View File

@ -18282,3 +18282,68 @@ error:
virDispatchError(domain->conn); virDispatchError(domain->conn);
return -1; 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 { LIBVIRT_0.9.10 {
global: global:
virDomainGetCPUStats; virDomainGetCPUStats;
virDomainGetDiskErrors;
virDomainPMSuspendForDuration; virDomainPMSuspendForDuration;
virDomainShutdownFlags; virDomainShutdownFlags;
virStorageVolResize; virStorageVolResize;