This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON
This event is the same as the previous VIR_DOMAIN_ID_IO_ERROR
event, but also includes a string describing the cause of
the event.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
const char *reason,
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
---
daemon/remote.c | 38 +++++++++++++++
daemon/remote_dispatch_table.h | 5 ++
include/libvirt/libvirt.h.in | 23 +++++++++
python/libvirt-override-virConnect.py | 14 +++++-
python/libvirt-override.c | 55 +++++++++++++++++++++
src/conf/domain_event.c | 84 ++++++++++++++++++++++++++++-----
src/conf/domain_event.h | 10 ++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_driver.c | 9 +++-
src/qemu/qemu_monitor.c | 5 +-
src/qemu/qemu_monitor.h | 6 ++-
src/qemu/qemu_monitor_json.c | 2 +-
src/remote/remote_driver.c | 35 ++++++++++++++
src/remote/remote_protocol.c | 17 +++++++
src/remote/remote_protocol.h | 12 +++++
src/remote/remote_protocol.x | 11 ++++-
16 files changed, 307 insertions(+), 21 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 6dbe7ee..c54565c 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -256,6 +256,43 @@ static int remoteRelayDomainEventIOError(virConnectPtr conn
ATTRIBUTE_UNUSED,
}
+static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque)
+{
+ struct qemud_client *client = opaque;
+ remote_domain_event_io_error_reason_msg data;
+
+ if (!client)
+ return -1;
+
+ REMOTE_DEBUG("Relaying domain io error %s %d %s %s %d %s",
+ dom->name, dom->id, srcPath, devAlias, action, reason);
+
+ virMutexLock(&client->lock);
+
+ /* build return data */
+ memset(&data, 0, sizeof data);
+ make_nonnull_domain (&data.dom, dom);
+ data.srcPath = (char*)srcPath;
+ data.devAlias = (char*)devAlias;
+ data.action = action;
+ data.reason = (char*)reason;
+
+ remoteDispatchDomainEventSend (client,
+ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON,
+
(xdrproc_t)xdr_remote_domain_event_io_error_reason_msg, &data);
+
+ virMutexUnlock(&client->lock);
+
+ return 0;
+}
+
+
static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
int phase,
@@ -327,6 +364,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] =
{
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventWatchdog),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOError),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventGraphics),
+ VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOErrorReason),
};
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index 984634f..86bd3b0 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -977,3 +977,8 @@
.args_filter = (xdrproc_t) xdr_remote_domain_get_block_info_args,
.ret_filter = (xdrproc_t) xdr_remote_domain_get_block_info_ret,
},
+{ /* Async event DomainEventIoErrorReason => 195 */
+ .fn = NULL,
+ .args_filter = (xdrproc_t) xdr_void,
+ .ret_filter = (xdrproc_t) xdr_void,
+},
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 4237b7b..f296d16 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2054,6 +2054,28 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr
conn,
void *opaque);
/**
+ * virConnectDomainEventWatchdogCallback:
+ * @conn: connection object
+ * @dom: domain on which the event occurred
+ * @srcPath: The host file on which the IO error occurred
+ * @devAlias: The guest device alias associated with the path
+ * @action: action that is to be taken due to the IO error
+ * @reason: the cause of the IO error
+ * @opaque: application specified data
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_DOMAIN_EVENT_ID_IO_ERROR with virConnectDomainEventRegisterAny()
+ *
+ */
+typedef void (*virConnectDomainEventIOErrorReasonCallback)(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque);
+
+/**
* virDomainEventGraphicsPhase:
*
* The phase of the graphics client connection
@@ -2161,6 +2183,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_WATCHDOG = 3, /* virConnectDomainEventWatchdogCallback */
VIR_DOMAIN_EVENT_ID_IO_ERROR = 4, /* virConnectDomainEventIOErrorCallback */
VIR_DOMAIN_EVENT_ID_GRAPHICS = 5, /* virConnectDomainEventGraphicsCallback */
+ VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON = 6, /*
virConnectDomainEventIOErrorReasonCallback */
/*
* NB: this enum value will increase over time as new events are
diff --git a/python/libvirt-override-virConnect.py
b/python/libvirt-override-virConnect.py
index cb38e3f..df39b79 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -94,7 +94,19 @@
cb = cbData["cb"]
opaque = cbData["opaque"]
- cb(self, virDomain(self, _obj=dom), opaque)
+ cb(self, virDomain(self, _obj=dom), srcPath, devAlias, opaque)
+ return 0
+ except AttributeError:
+ pass
+
+ def dispatchDomainEventIOErrorReasonCallback(self, dom, srcPath, devAlias, action,
reason, cbData):
+ """Dispatches events to python user domain IO error event
callbacks
+ """
+ try:
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, reason,
opaque)
return 0
except AttributeError:
pass
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 7c7682c..b97445b 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -3208,6 +3208,58 @@ libvirt_virConnectDomainEventIOErrorCallback(virConnectPtr conn
ATTRIBUTE_UNUSED
}
static int
+libvirt_virConnectDomainEventIOErrorReasonCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_dom;
+ PyObject *pyobj_ret;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+ int ret = -1;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+
+ /* Create a python instance of this virDomainPtr */
+ virDomainRef(dom);
+ pyobj_dom = libvirt_virDomainPtrWrap(dom);
+ Py_INCREF(pyobj_cbData);
+
+ dictKey = libvirt_constcharPtrWrap("conn");
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+
(char*)"dispatchDomainEventIOErrorCallback",
+ (char*)"OssisO",
+ pyobj_dom,
+ srcPath, devAlias, action, reason,
+ pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+ Py_DECREF(pyobj_dom);
+
+ if(!pyobj_ret) {
+#if DEBUG_ERROR
+ printf("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+#endif
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ ret = 0;
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+ return ret;
+}
+
+static int
libvirt_virConnectDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
int phase,
@@ -3345,6 +3397,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject *
self,
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventIOErrorCallback);
break;
+ case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
+ cb =
VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventIOErrorReasonCallback);
+ break;
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGraphicsCallback);
break;
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index e3ce5ba..e5bd458 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -74,6 +74,7 @@ struct _virDomainEvent {
char *srcPath;
char *devAlias;
int action;
+ char *reason;
} ioError;
struct {
int phase;
@@ -474,6 +475,7 @@ void virDomainEventFree(virDomainEventPtr event)
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
VIR_FREE(event->data.ioError.srcPath);
VIR_FREE(event->data.ioError.devAlias);
+ VIR_FREE(event->data.ioError.reason);
break;
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
@@ -630,19 +632,22 @@ virDomainEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr
obj,
return ev;
}
-virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action)
+static virDomainEventPtr virDomainEventIOErrorNewFromDomImpl(int event,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason)
{
virDomainEventPtr ev =
- virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_IO_ERROR,
+ virDomainEventNewInternal(event,
dom->id, dom->name, dom->uuid);
if (ev) {
ev->data.ioError.action = action;
if (!(ev->data.ioError.srcPath = strdup(srcPath)) ||
- !(ev->data.ioError.devAlias = strdup(devAlias))) {
+ !(ev->data.ioError.devAlias = strdup(devAlias)) ||
+ (reason && !(ev->data.ioError.reason = strdup(reason)))) {
virDomainEventFree(ev);
ev = NULL;
}
@@ -650,19 +655,23 @@ virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
return ev;
}
-virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
- const char *srcPath,
- const char *devAlias,
- int action)
+
+static virDomainEventPtr virDomainEventIOErrorNewFromObjImpl(int event,
+ virDomainObjPtr obj,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason)
{
virDomainEventPtr ev =
- virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_IO_ERROR,
+ virDomainEventNewInternal(event,
obj->def->id, obj->def->name,
obj->def->uuid);
if (ev) {
ev->data.ioError.action = action;
if (!(ev->data.ioError.srcPath = strdup(srcPath)) ||
- !(ev->data.ioError.devAlias = strdup(devAlias))) {
+ !(ev->data.ioError.devAlias = strdup(devAlias)) ||
+ !(ev->data.ioError.reason = strdup(reason))) {
virDomainEventFree(ev);
ev = NULL;
}
@@ -671,6 +680,48 @@ virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr
obj,
return ev;
}
+virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action)
+{
+ return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
+ dom, srcPath, devAlias,
+ action, NULL);
+}
+
+virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
+ const char *srcPath,
+ const char *devAlias,
+ int action)
+{
+ return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
+ obj, srcPath, devAlias,
+ action, NULL);
+}
+
+virDomainEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason)
+{
+ return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
+ dom, srcPath, devAlias,
+ action, reason);
+}
+
+virDomainEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason)
+{
+ return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
+ obj, srcPath, devAlias,
+ action, reason);
+}
+
virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
int phase,
@@ -853,6 +904,15 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque);
break;
+ case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
+ ((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
+ event->data.ioError.srcPath,
+
event->data.ioError.devAlias,
+ event->data.ioError.action,
+ event->data.ioError.reason,
+ cbopaque);
+ break;
+
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
event->data.graphics.phase,
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index f72ac58..e28293d 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -129,6 +129,16 @@ virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr
obj,
const char *srcPath,
const char *devAlias,
int action);
+virDomainEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason);
+virDomainEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason);
virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
int phase,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 746327d..09f3da1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -246,6 +246,8 @@ virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
virDomainEventIOErrorNewFromDom;
virDomainEventIOErrorNewFromObj;
+virDomainEventIOErrorReasonNewFromDom;
+virDomainEventIOErrorReasonNewFromObj;
virDomainEventGraphicsNewFromDom;
virDomainEventGraphicsNewFromObj;
virDomainEventFree;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c2902ac..52f2df8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1015,10 +1015,12 @@ static int
qemuHandleDomainIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *diskAlias,
- int action)
+ int action,
+ const char *reason)
{
struct qemud_driver *driver = qemu_driver;
virDomainEventPtr ioErrorEvent = NULL;
+ virDomainEventPtr ioErrorEvent2 = NULL;
virDomainEventPtr lifecycleEvent = NULL;
const char *srcPath;
const char *devAlias;
@@ -1036,6 +1038,7 @@ qemuHandleDomainIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
ioErrorEvent = virDomainEventIOErrorNewFromObj(vm, srcPath, devAlias, action);
+ ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action,
reason);
if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE &&
vm->state == VIR_DOMAIN_RUNNING) {
@@ -1051,10 +1054,12 @@ qemuHandleDomainIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
virDomainObjUnlock(vm);
- if (ioErrorEvent || lifecycleEvent) {
+ if (ioErrorEvent || ioErrorEvent2 || lifecycleEvent) {
qemuDriverLock(driver);
if (ioErrorEvent)
qemuDomainEventQueue(driver, ioErrorEvent);
+ if (ioErrorEvent2)
+ qemuDomainEventQueue(driver, ioErrorEvent2);
if (lifecycleEvent)
qemuDomainEventQueue(driver, lifecycleEvent);
qemuDriverUnlock(driver);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 5e83afc..fca8590 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -833,7 +833,8 @@ int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action)
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
const char *diskAlias,
- int action)
+ int action,
+ const char *reason)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
@@ -841,7 +842,7 @@ int qemuMonitorEmitIOError(qemuMonitorPtr mon,
qemuMonitorRef(mon);
qemuMonitorUnlock(mon);
if (mon->cb && mon->cb->domainIOError)
- ret = mon->cb->domainIOError(mon, mon->vm, diskAlias, action);
+ ret = mon->cb->domainIOError(mon, mon->vm, diskAlias, action, reason);
qemuMonitorLock(mon);
qemuMonitorUnref(mon);
return ret;
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index ec848a8..3fa83b7 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -95,7 +95,8 @@ struct _qemuMonitorCallbacks {
int (*domainIOError)(qemuMonitorPtr mon,
virDomainObjPtr vm,
const char *diskAlias,
- int action);
+ int action,
+ const char *reason);
int (*domainGraphics)(qemuMonitorPtr mon,
virDomainObjPtr vm,
int phase,
@@ -148,7 +149,8 @@ int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset);
int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action);
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
const char *diskAlias,
- int action);
+ int action,
+ const char *reason);
int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
int phase,
int localFamily,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 09a3562..8c77ab1 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -534,7 +534,7 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon,
virJSONValuePtr dat
actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
}
- qemuMonitorEmitIOError(mon, device, actionID);
+ qemuMonitorEmitIOError(mon, device, actionID, "");
}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index e589f8e..317125f 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7430,6 +7430,37 @@ remoteDomainReadEventIOError(virConnectPtr conn, XDR *xdr)
static virDomainEventPtr
+remoteDomainReadEventIOErrorReason(virConnectPtr conn, XDR *xdr)
+{
+ remote_domain_event_io_error_reason_msg msg;
+ virDomainPtr dom;
+ virDomainEventPtr event = NULL;
+ memset (&msg, 0, sizeof msg);
+
+ /* unmarshall parameters, and process it*/
+ if (! xdr_remote_domain_event_io_error_reason_msg(xdr, &msg) ) {
+ remoteError(VIR_ERR_RPC, "%s",
+ _("unable to demarshall reboot event"));
+ return NULL;
+ }
+
+ dom = get_nonnull_domain(conn,msg.dom);
+ if (!dom)
+ return NULL;
+
+ event = virDomainEventIOErrorReasonNewFromDom(dom,
+ msg.srcPath,
+ msg.devAlias,
+ msg.action,
+ msg.reason);
+ xdr_free ((xdrproc_t) &xdr_remote_domain_event_io_error_reason_msg, (char *)
&msg);
+
+ virDomainFree(dom);
+ return event;
+}
+
+
+static virDomainEventPtr
remoteDomainReadEventGraphics(virConnectPtr conn, XDR *xdr)
{
remote_domain_event_graphics_msg msg;
@@ -9327,6 +9358,10 @@ processCallDispatchMessage(virConnectPtr conn, struct private_data
*priv,
event = remoteDomainReadEventIOError(conn, xdr);
break;
+ case REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON:
+ event = remoteDomainReadEventIOErrorReason(conn, xdr);
+ break;
+
case REMOTE_PROC_DOMAIN_EVENT_GRAPHICS:
event = remoteDomainReadEventGraphics(conn, xdr);
break;
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 71eed42..187281d 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -3290,6 +3290,23 @@ xdr_remote_domain_event_io_error_msg (XDR *xdrs,
remote_domain_event_io_error_ms
}
bool_t
+xdr_remote_domain_event_io_error_reason_msg (XDR *xdrs,
remote_domain_event_io_error_reason_msg *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->srcPath))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->devAlias))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->action))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->reason))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_event_graphics_address (XDR *xdrs, remote_domain_event_graphics_address
*objp)
{
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index 8c4291f..6f01da7 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -1864,6 +1864,15 @@ struct remote_domain_event_io_error_msg {
};
typedef struct remote_domain_event_io_error_msg remote_domain_event_io_error_msg;
+struct remote_domain_event_io_error_reason_msg {
+ remote_nonnull_domain dom;
+ remote_nonnull_string srcPath;
+ remote_nonnull_string devAlias;
+ int action;
+ remote_nonnull_string reason;
+};
+typedef struct remote_domain_event_io_error_reason_msg
remote_domain_event_io_error_reason_msg;
+
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
@@ -2206,6 +2215,7 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_REVERT_TO_SNAPSHOT = 192,
REMOTE_PROC_DOMAIN_SNAPSHOT_DELETE = 193,
REMOTE_PROC_DOMAIN_GET_BLOCK_INFO = 194,
+ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON = 195,
};
typedef enum remote_procedure remote_procedure;
@@ -2541,6 +2551,7 @@ extern bool_t xdr_remote_domain_event_reboot_msg (XDR *,
remote_domain_event_re
extern bool_t xdr_remote_domain_event_rtc_change_msg (XDR *,
remote_domain_event_rtc_change_msg*);
extern bool_t xdr_remote_domain_event_watchdog_msg (XDR *,
remote_domain_event_watchdog_msg*);
extern bool_t xdr_remote_domain_event_io_error_msg (XDR *,
remote_domain_event_io_error_msg*);
+extern bool_t xdr_remote_domain_event_io_error_reason_msg (XDR *,
remote_domain_event_io_error_reason_msg*);
extern bool_t xdr_remote_domain_event_graphics_address (XDR *,
remote_domain_event_graphics_address*);
extern bool_t xdr_remote_domain_event_graphics_identity (XDR *,
remote_domain_event_graphics_identity*);
extern bool_t xdr_remote_domain_event_graphics_msg (XDR *,
remote_domain_event_graphics_msg*);
@@ -2873,6 +2884,7 @@ extern bool_t xdr_remote_domain_event_reboot_msg ();
extern bool_t xdr_remote_domain_event_rtc_change_msg ();
extern bool_t xdr_remote_domain_event_watchdog_msg ();
extern bool_t xdr_remote_domain_event_io_error_msg ();
+extern bool_t xdr_remote_domain_event_io_error_reason_msg ();
extern bool_t xdr_remote_domain_event_graphics_address ();
extern bool_t xdr_remote_domain_event_graphics_identity ();
extern bool_t xdr_remote_domain_event_graphics_msg ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index ae306d2..8000ee0 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1659,6 +1659,14 @@ struct remote_domain_event_io_error_msg {
int action;
};
+struct remote_domain_event_io_error_reason_msg {
+ remote_nonnull_domain dom;
+ remote_nonnull_string srcPath;
+ remote_nonnull_string devAlias;
+ int action;
+ remote_nonnull_string reason;
+};
+
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
@@ -1996,7 +2004,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SNAPSHOT_CURRENT = 191,
REMOTE_PROC_DOMAIN_REVERT_TO_SNAPSHOT = 192,
REMOTE_PROC_DOMAIN_SNAPSHOT_DELETE = 193,
- REMOTE_PROC_DOMAIN_GET_BLOCK_INFO = 194
+ REMOTE_PROC_DOMAIN_GET_BLOCK_INFO = 194,
+ REMOTE_PROC_DOMAIN_EVENT_IO_ERROR_REASON = 195
/*
* Notice how the entries are grouped in sets of 10 ?
--
1.6.6.1