提交 d489b046 编写于 作者: A Adam Litke 提交者: Daniel Veillard

Asynchronous event for BlockJob completion

When an operation started by virDomainBlockPull completes (either with
success or with failure), raise an event to indicate the final status.
This API allow users to avoid polling on virDomainGetBlockJobInfo if
they would prefer to use an event mechanism.

* daemon/remote.c: Dispatch events to client
* include/libvirt/libvirt.h.in: Define event ID and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
  src/libvirt_private.syms: Extend API to handle the new event
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
  for block_stream completion and emit a libvirt block pull event
* src/remote/remote_driver.c: Receive and dispatch events to application
* src/remote/remote_protocol.x: Wire protocol definition for the event
* src/remote_protocol-structs: structure definitions for protocol verification
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
  src/qemu/qemu_monitor_json.c: Watch for BLOCK_STREAM_COMPLETED event
  from QEMU monitor
上级 f50750b2
...@@ -339,6 +339,36 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -339,6 +339,36 @@ static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0; return 0;
} }
static int remoteRelayDomainEventBlockJob(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
const char *path,
int type,
int status,
void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_block_job_msg data;
if (!client)
return -1;
VIR_DEBUG("Relaying domain block job event %s %d %s %i, %i",
dom->name, dom->id, path, type, status);
/* build return data */
memset(&data, 0, sizeof data);
make_nonnull_domain(&data.dom, dom);
data.path = (char*)path;
data.type = type;
data.status = status;
remoteDispatchDomainEventSend(client, remoteProgram,
REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
(xdrproc_t)xdr_remote_domain_event_block_job_msg, &data);
return 0;
}
static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED, static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom, virDomainPtr dom,
...@@ -373,6 +403,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { ...@@ -373,6 +403,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventGraphics), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventGraphics),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOErrorReason), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventIOErrorReason),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventControlError),
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob),
}; };
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST); verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
......
...@@ -2785,6 +2785,34 @@ typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn, ...@@ -2785,6 +2785,34 @@ typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainEventGraphicsSubjectPtr subject, virDomainEventGraphicsSubjectPtr subject,
void *opaque); void *opaque);
/**
* virConnectDomainEventBlockJobStatus:
*
* The final status of a virDomainBlockPullAll() operation
*/
typedef enum {
VIR_DOMAIN_BLOCK_JOB_COMPLETED = 0,
VIR_DOMAIN_BLOCK_JOB_FAILED = 1,
} virConnectDomainEventBlockJobStatus;
/**
* virConnectDomainEventBlockJobCallback:
* @conn: connection object
* @dom: domain on which the event occurred
* @path: fully-qualified filename of the affected disk
* @type: type of block job (virDomainBlockJobType)
* @status: final status of the operation (virConnectDomainEventBlockJobStatus)
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_BLOCK_JOB with virConnectDomainEventRegisterAny()
*/
typedef void (*virConnectDomainEventBlockJobCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *path,
int type,
int status,
void *opaque);
/** /**
* VIR_DOMAIN_EVENT_CALLBACK: * VIR_DOMAIN_EVENT_CALLBACK:
* *
...@@ -2803,6 +2831,7 @@ typedef enum { ...@@ -2803,6 +2831,7 @@ typedef enum {
VIR_DOMAIN_EVENT_ID_GRAPHICS = 5, /* virConnectDomainEventGraphicsCallback */ VIR_DOMAIN_EVENT_ID_GRAPHICS = 5, /* virConnectDomainEventGraphicsCallback */
VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON = 6, /* virConnectDomainEventIOErrorReasonCallback */ VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON = 6, /* virConnectDomainEventIOErrorReasonCallback */
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */ VIR_DOMAIN_EVENT_ID_CONTROL_ERROR = 7, /* virConnectDomainEventGenericCallback */
VIR_DOMAIN_EVENT_ID_BLOCK_JOB = 8, /* virConnectDomainEventBlockJobCallback */
/* /*
* NB: this enum value will increase over time as new events are * NB: this enum value will increase over time as new events are
......
...@@ -113,6 +113,18 @@ ...@@ -113,6 +113,18 @@
authScheme, subject, opaque) authScheme, subject, opaque)
return 0 return 0
def dispatchDomainEventBlockPullCallback(self, dom, path, type, status, cbData):
"""Dispatches events to python user domain blockJob event callbacks
"""
try:
cb = cbData["cb"]
opaque = cbData["opaque"]
cb(self, virDomain(self, _obj=dom), path, type, status, opaque)
return 0
except AttributeError:
pass
def domainEventDeregisterAny(self, callbackID): def domainEventDeregisterAny(self, callbackID):
"""Removes a Domain Event Callback. De-registering for a """Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """ domain callback will disable delivery of this event type """
......
...@@ -3582,6 +3582,55 @@ libvirt_virConnectDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSE ...@@ -3582,6 +3582,55 @@ libvirt_virConnectDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSE
return ret; return ret;
} }
static int
libvirt_virConnectDomainEventBlockJobCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
virDomainPtr dom,
const char *path,
int type,
int status,
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*)"dispatchDomainEventBlockPullCallback",
(char*)"OsiiO",
pyobj_dom, path, type, status, 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 PyObject * static PyObject *
libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args) PyObject * args)
...@@ -3636,6 +3685,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, ...@@ -3636,6 +3685,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR: case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGenericCallback); cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventGenericCallback);
break; break;
case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBlockJobCallback);
break;
} }
if (!cb) { if (!cb) {
......
...@@ -83,6 +83,11 @@ struct _virDomainEvent { ...@@ -83,6 +83,11 @@ struct _virDomainEvent {
char *authScheme; char *authScheme;
virDomainEventGraphicsSubjectPtr subject; virDomainEventGraphicsSubjectPtr subject;
} graphics; } graphics;
struct {
char *path;
int type;
int status;
} blockJob;
} data; } data;
}; };
...@@ -499,6 +504,11 @@ void virDomainEventFree(virDomainEventPtr event) ...@@ -499,6 +504,11 @@ void virDomainEventFree(virDomainEventPtr event)
} }
VIR_FREE(event->data.graphics.subject); VIR_FREE(event->data.graphics.subject);
} }
break;
case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
VIR_FREE(event->data.blockJob.path);
break;
} }
VIR_FREE(event->dom.name); VIR_FREE(event->dom.name);
...@@ -874,6 +884,44 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj, ...@@ -874,6 +884,44 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
return ev; return ev;
} }
static virDomainEventPtr
virDomainEventBlockJobNew(int id, const char *name, unsigned char *uuid,
const char *path, int type, int status)
{
virDomainEventPtr ev =
virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
id, name, uuid);
if (ev) {
if (!(ev->data.blockJob.path = strdup(path))) {
virReportOOMError();
virDomainEventFree(ev);
return NULL;
}
ev->data.blockJob.type = type;
ev->data.blockJob.status = status;
}
return ev;
}
virDomainEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
const char *path,
int type,
int status)
{
return virDomainEventBlockJobNew(obj->def->id, obj->def->name,
obj->def->uuid, path, type, status);
}
virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
const char *path,
int type,
int status)
{
return virDomainEventBlockJobNew(dom->id, dom->name, dom->uuid,
path, type, status);
}
virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom) virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
{ {
...@@ -1027,6 +1075,14 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn, ...@@ -1027,6 +1075,14 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
cbopaque); cbopaque);
break; break;
case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
event->data.blockJob.path,
event->data.blockJob.type,
event->data.blockJob.status,
cbopaque);
break;
default: default:
VIR_WARN("Unexpected event ID %d", event->eventID); VIR_WARN("Unexpected event ID %d", event->eventID);
break; break;
......
...@@ -169,7 +169,14 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj, ...@@ -169,7 +169,14 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom); virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj); virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj);
virDomainEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
const char *path,
int type,
int status);
virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
const char *path,
int type,
int status);
int virDomainEventQueuePush(virDomainEventQueuePtr evtQueue, int virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
virDomainEventPtr event); virDomainEventPtr event);
......
...@@ -414,6 +414,8 @@ virDomainWatchdogModelTypeToString; ...@@ -414,6 +414,8 @@ virDomainWatchdogModelTypeToString;
# domain_event.h # domain_event.h
virDomainEventBlockJobNewFromObj;
virDomainEventBlockJobNewFromDom;
virDomainEventCallbackListAdd; virDomainEventCallbackListAdd;
virDomainEventCallbackListAddID; virDomainEventCallbackListAddID;
virDomainEventCallbackListCount; virDomainEventCallbackListCount;
......
...@@ -957,6 +957,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, ...@@ -957,6 +957,19 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
return ret; return ret;
} }
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
int status)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, ret, domainBlockJob, mon->vm,
diskAlias, type, status);
return ret;
}
int qemuMonitorSetCapabilities(qemuMonitorPtr mon) int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
......
...@@ -117,6 +117,11 @@ struct _qemuMonitorCallbacks { ...@@ -117,6 +117,11 @@ struct _qemuMonitorCallbacks {
const char *authScheme, const char *authScheme,
const char *x509dname, const char *x509dname,
const char *saslUsername); const char *saslUsername);
int (*domainBlockJob)(qemuMonitorPtr mon,
virDomainObjPtr vm,
const char *diskAlias,
int type,
int status);
}; };
...@@ -179,6 +184,11 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, ...@@ -179,6 +184,11 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
const char *authScheme, const char *authScheme,
const char *x509dname, const char *x509dname,
const char *saslUsername); const char *saslUsername);
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
int status);
int qemuMonitorStartCPUs(qemuMonitorPtr mon, int qemuMonitorStartCPUs(qemuMonitorPtr mon,
......
...@@ -56,6 +56,7 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat ...@@ -56,6 +56,7 @@ static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr dat
static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data);
struct { struct {
const char *type; const char *type;
...@@ -71,6 +72,7 @@ struct { ...@@ -71,6 +72,7 @@ struct {
{ "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, }, { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
{ "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, }, { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
{ "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, }, { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
{ "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJob, },
}; };
...@@ -678,6 +680,44 @@ static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValueP ...@@ -678,6 +680,44 @@ static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValueP
qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT); qemuMonitorJSONHandleVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
} }
static void qemuMonitorJSONHandleBlockJob(qemuMonitorPtr mon, virJSONValuePtr data)
{
const char *device;
const char *type_str;
int type = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
unsigned long long offset, len;
int status = VIR_DOMAIN_BLOCK_JOB_FAILED;
if ((device = virJSONValueObjectGetString(data, "device")) == NULL) {
VIR_WARN("missing device in block job event");
goto out;
}
if (virJSONValueObjectGetNumberUlong(data, "offset", &offset) < 0) {
VIR_WARN("missing offset in block job event");
goto out;
}
if (virJSONValueObjectGetNumberUlong(data, "len", &len) < 0) {
VIR_WARN("missing len in block job event");
goto out;
}
if ((type_str = virJSONValueObjectGetString(data, "type")) == NULL) {
VIR_WARN("missing type in block job event");
goto out;
}
if (STREQ(type_str, "stream"))
type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
if (offset != 0 && offset == len)
status = VIR_DOMAIN_BLOCK_JOB_COMPLETED;
out:
qemuMonitorEmitBlockJob(mon, device, type, status);
}
int int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon, qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
......
...@@ -662,6 +662,36 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, ...@@ -662,6 +662,36 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
return 0; return 0;
} }
static int
qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *diskAlias,
int type,
int status)
{
struct qemud_driver *driver = qemu_driver;
virDomainEventPtr event = NULL;
const char *path;
virDomainDiskDefPtr disk;
virDomainObjLock(vm);
disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
if (disk) {
path = disk->src;
event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
}
virDomainObjUnlock(vm);
if (event) {
qemuDriverLock(driver);
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
return 0;
}
static int static int
qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED, qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
...@@ -779,6 +809,7 @@ static qemuMonitorCallbacks monitorCallbacks = { ...@@ -779,6 +809,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainWatchdog = qemuProcessHandleWatchdog, .domainWatchdog = qemuProcessHandleWatchdog,
.domainIOError = qemuProcessHandleIOError, .domainIOError = qemuProcessHandleIOError,
.domainGraphics = qemuProcessHandleGraphics, .domainGraphics = qemuProcessHandleGraphics,
.domainBlockJob = qemuProcessHandleBlockJob,
}; };
static int static int
......
...@@ -223,6 +223,11 @@ remoteDomainBuildEventControlError(virNetClientProgramPtr prog, ...@@ -223,6 +223,11 @@ remoteDomainBuildEventControlError(virNetClientProgramPtr prog,
virNetClientPtr client, virNetClientPtr client,
void *evdata, void *opaque); void *evdata, void *opaque);
static void
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog,
virNetClientPtr client,
void *evdata, void *opaque);
static virNetClientProgramEvent remoteDomainEvents[] = { static virNetClientProgramEvent remoteDomainEvents[] = {
{ REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE, { REMOTE_PROC_DOMAIN_EVENT_RTC_CHANGE,
remoteDomainBuildEventRTCChange, remoteDomainBuildEventRTCChange,
...@@ -256,6 +261,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = { ...@@ -256,6 +261,10 @@ static virNetClientProgramEvent remoteDomainEvents[] = {
remoteDomainBuildEventControlError, remoteDomainBuildEventControlError,
sizeof(remote_domain_event_control_error_msg), sizeof(remote_domain_event_control_error_msg),
(xdrproc_t)xdr_remote_domain_event_control_error_msg }, (xdrproc_t)xdr_remote_domain_event_control_error_msg },
{ REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB,
remoteDomainBuildEventBlockJob,
sizeof(remote_domain_event_block_job_msg),
(xdrproc_t)xdr_remote_domain_event_block_job_msg },
}; };
enum virDrvOpenRemoteFlags { enum virDrvOpenRemoteFlags {
...@@ -3095,6 +3104,28 @@ remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED ...@@ -3095,6 +3104,28 @@ remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
remoteDomainEventQueue(priv, event); remoteDomainEventQueue(priv, event);
} }
static void
remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
struct private_data *priv = conn->privateData;
remote_domain_event_block_job_msg *msg = evdata;
virDomainPtr dom;
virDomainEventPtr event = NULL;
dom = get_nonnull_domain(conn, msg->dom);
if (!dom)
return;
event = virDomainEventBlockJobNewFromDom(dom, msg->path, msg->type,
msg->status);
virDomainFree(dom);
remoteDomainEventQueue(priv, event);
}
static void static void
remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
......
...@@ -1972,6 +1972,13 @@ struct remote_domain_event_graphics_msg { ...@@ -1972,6 +1972,13 @@ struct remote_domain_event_graphics_msg {
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>; remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
}; };
struct remote_domain_event_block_job_msg {
remote_nonnull_domain dom;
remote_nonnull_string path;
int type;
int status;
};
struct remote_domain_managed_save_args { struct remote_domain_managed_save_args {
remote_nonnull_domain dom; remote_nonnull_domain dom;
unsigned int flags; unsigned int flags;
...@@ -2466,7 +2473,9 @@ enum remote_procedure { ...@@ -2466,7 +2473,9 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_BLOCK_JOB_ABORT = 237, /* autogen autogen */ REMOTE_PROC_DOMAIN_BLOCK_JOB_ABORT = 237, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO = 238, /* skipgen skipgen */ REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO = 238, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, /* autogen autogen */ REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, /* autogen autogen */
REMOTE_PROC_DOMAIN_BLOCK_PULL = 240 /* autogen autogen */ REMOTE_PROC_DOMAIN_BLOCK_PULL = 240, /* autogen autogen */
REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241 /* skipgen skipgen */
/* /*
* Notice how the entries are grouped in sets of 10 ? * Notice how the entries are grouped in sets of 10 ?
......
...@@ -1479,6 +1479,12 @@ struct remote_domain_event_graphics_msg { ...@@ -1479,6 +1479,12 @@ struct remote_domain_event_graphics_msg {
remote_domain_event_graphics_identity * subject_val; remote_domain_event_graphics_identity * subject_val;
} subject; } subject;
}; };
struct remote_domain_event_block_job_msg {
remote_nonnull_domain dom;
remote_nonnull_string path;
int type;
int status;
};
struct remote_domain_managed_save_args { struct remote_domain_managed_save_args {
remote_nonnull_domain dom; remote_nonnull_domain dom;
u_int flags; u_int flags;
...@@ -1929,4 +1935,5 @@ enum remote_procedure { ...@@ -1929,4 +1935,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO = 238, REMOTE_PROC_DOMAIN_GET_BLOCK_JOB_INFO = 238,
REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239, REMOTE_PROC_DOMAIN_BLOCK_JOB_SET_SPEED = 239,
REMOTE_PROC_DOMAIN_BLOCK_PULL = 240, REMOTE_PROC_DOMAIN_BLOCK_PULL = 240,
REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB = 241,
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册