mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +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:
parent
a89bb7d75a
commit
02af3e13b2
@ -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
|
||||
|
@ -423,7 +423,8 @@ skip_impl = (
|
||||
'virDomainGetBlockIoTune',
|
||||
'virDomainSetInterfaceParameters',
|
||||
'virDomainGetInterfaceParameters',
|
||||
'virDomainGetCPUStats' # not implemented now.
|
||||
'virDomainGetCPUStats', # not implemented now.
|
||||
'virDomainGetDiskErrors',
|
||||
)
|
||||
|
||||
qemu_skip_impl = (
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -519,6 +519,7 @@ LIBVIRT_0.9.9 {
|
||||
LIBVIRT_0.9.10 {
|
||||
global:
|
||||
virDomainGetCPUStats;
|
||||
virDomainGetDiskErrors;
|
||||
virDomainPMSuspendForDuration;
|
||||
virDomainShutdownFlags;
|
||||
virStorageVolResize;
|
||||
|
Loading…
Reference in New Issue
Block a user