mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Add support for an explicit IO error event
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;
In addition it 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);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
This commit is contained in:
@@ -204,6 +204,19 @@ static int myDomainEventWatchdogCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int myDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
const char *srcPath,
|
||||
const char *devAlias,
|
||||
int action,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
printf("%s EVENT: Domain %s(%d) io error path=%s alias=%s action=%d\n", __func__, virDomainGetName(dom),
|
||||
virDomainGetID(dom), srcPath, devAlias, action);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myFreeFunc(void *opaque)
|
||||
{
|
||||
char *str = opaque;
|
||||
@@ -324,6 +337,7 @@ int main(int argc, char **argv)
|
||||
int callback3ret = -1;
|
||||
int callback4ret = -1;
|
||||
int callback5ret = -1;
|
||||
int callback6ret = -1;
|
||||
|
||||
struct sigaction action_stop = {
|
||||
.sa_handler = stop
|
||||
@@ -376,12 +390,18 @@ int main(int argc, char **argv)
|
||||
VIR_DOMAIN_EVENT_ID_WATCHDOG,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventWatchdogCallback),
|
||||
strdup("callback watchdog"), myFreeFunc);
|
||||
callback6ret = virConnectDomainEventRegisterAny(dconn,
|
||||
NULL,
|
||||
VIR_DOMAIN_EVENT_ID_IO_ERROR,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventIOErrorCallback),
|
||||
strdup("callback io error"), myFreeFunc);
|
||||
|
||||
if ((callback1ret != -1) &&
|
||||
(callback2ret != -1) &&
|
||||
(callback3ret != -1) &&
|
||||
(callback4ret != -1) &&
|
||||
(callback5ret != -1)) {
|
||||
(callback5ret != -1) &&
|
||||
(callback6ret != -1)) {
|
||||
while(run) {
|
||||
struct pollfd pfd = { .fd = h_fd,
|
||||
.events = h_event,
|
||||
@@ -422,6 +442,7 @@ int main(int argc, char **argv)
|
||||
virConnectDomainEventDeregisterAny(dconn, callback3ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback4ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback5ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback6ret);
|
||||
}
|
||||
|
||||
DEBUG0("Closing connection");
|
||||
|
||||
Reference in New Issue
Block a user