mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
Add support for another explicit IO error event
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
This commit is contained in:
parent
c90a1ad7d0
commit
34dcbbb470
@ -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);
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -2053,6 +2053,28 @@ typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
|
||||
int action,
|
||||
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:
|
||||
*
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -3207,6 +3207,58 @@ libvirt_virConnectDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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;
|
||||
|
@ -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,
|
||||
static virDomainEventPtr virDomainEventIOErrorNewFromDomImpl(int event,
|
||||
virDomainPtr dom,
|
||||
const char *srcPath,
|
||||
const char *devAlias,
|
||||
int action)
|
||||
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,
|
||||
|
||||
static virDomainEventPtr virDomainEventIOErrorNewFromObjImpl(int event,
|
||||
virDomainObjPtr obj,
|
||||
const char *srcPath,
|
||||
const char *devAlias,
|
||||
int action)
|
||||
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,
|
||||
|
@ -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,
|
||||
|
@ -246,6 +246,8 @@ virDomainEventWatchdogNewFromDom;
|
||||
virDomainEventWatchdogNewFromObj;
|
||||
virDomainEventIOErrorNewFromDom;
|
||||
virDomainEventIOErrorNewFromObj;
|
||||
virDomainEventIOErrorReasonNewFromDom;
|
||||
virDomainEventIOErrorReasonNewFromObj;
|
||||
virDomainEventGraphicsNewFromDom;
|
||||
virDomainEventGraphicsNewFromObj;
|
||||
virDomainEventFree;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -514,6 +514,7 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat
|
||||
{
|
||||
const char *device;
|
||||
const char *action;
|
||||
const char *reason;
|
||||
int actionID;
|
||||
|
||||
/* Throughout here we try our best to carry on upon errors,
|
||||
@ -529,12 +530,17 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat
|
||||
VIR_WARN0("missing device in disk io error event");
|
||||
}
|
||||
|
||||
if ((reason = virJSONValueObjectGetString(data, "reason")) == NULL) {
|
||||
VIR_WARN0("missing reason in disk io error event");
|
||||
reason = "";
|
||||
}
|
||||
|
||||
if ((actionID = qemuMonitorIOErrorActionTypeFromString(action)) < 0) {
|
||||
VIR_WARN("unknown disk io error action '%s'", action);
|
||||
actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
|
||||
}
|
||||
|
||||
qemuMonitorEmitIOError(mon, device, actionID);
|
||||
qemuMonitorEmitIOError(mon, device, actionID, reason);
|
||||
}
|
||||
|
||||
|
||||
|
@ -7429,6 +7429,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)
|
||||
{
|
||||
@ -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;
|
||||
|
@ -3289,6 +3289,23 @@ xdr_remote_domain_event_io_error_msg (XDR *xdrs, remote_domain_event_io_error_ms
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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 ();
|
||||
|
@ -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 ?
|
||||
|
Loading…
Reference in New Issue
Block a user