mirror of https://gitee.com/openkylin/libvirt.git
Add support for an explicit guest reboot event
The reboot event is not a normal lifecycle event, since the virtual machine on the host does not change state. Rather the guest OS is resetting the virtual CPUs. ie, the QEMU process does not restart. Thus, this does not belong in the current lifecycle events callback. This introduces a new event type VIR_DOMAIN_EVENT_ID_REBOOT It takes no parameters, besides the virDomainPtr, so it can use the generic callback signature. * daemon/remote.c: Dispatch reboot events to client * examples/domain-events/events-c/event-test.c: Watch for reboot events * include/libvirt/libvirt.h.in: Define new reboot event ID * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Extend API to handle reboot events * src/qemu/qemu_driver.c: Connect to the QEMU monitor event for reboots and emit a libvirt reboot event * src/remote/remote_driver.c: Receive and dispatch reboot events to application * src/remote/remote_protocol.x: Wire protocol definition for reboot events
This commit is contained in:
parent
d51638d0ad
commit
8613273458
|
@ -129,9 +129,37 @@ static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
void *opaque)
|
||||
{
|
||||
struct qemud_client *client = opaque;
|
||||
remote_domain_event_reboot_msg data;
|
||||
|
||||
static virConnectDomainEventGenericCallback domainEventCallbacks[VIR_DOMAIN_EVENT_ID_LAST] = {
|
||||
if (!client)
|
||||
return -1;
|
||||
|
||||
REMOTE_DEBUG("Relaying domain reboot event %s %d", dom->name, dom->id);
|
||||
|
||||
virMutexLock(&client->lock);
|
||||
|
||||
/* build return data */
|
||||
memset(&data, 0, sizeof data);
|
||||
make_nonnull_domain (&data.dom, dom);
|
||||
|
||||
remoteDispatchDomainEventSend (client,
|
||||
REMOTE_PROC_DOMAIN_EVENT_REBOOT,
|
||||
(xdrproc_t)xdr_remote_domain_event_reboot_msg, &data);
|
||||
|
||||
virMutexUnlock(&client->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle),
|
||||
VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot),
|
||||
};
|
||||
|
||||
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
|
||||
|
|
|
@ -847,3 +847,8 @@
|
|||
.args_filter = (xdrproc_t) xdr_remote_domain_events_deregister_any_args,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
{ /* Async event DomainEventReboot => 169 */
|
||||
.fn = NULL,
|
||||
.args_filter = (xdrproc_t) xdr_void,
|
||||
.ret_filter = (xdrproc_t) xdr_void,
|
||||
},
|
||||
|
|
|
@ -172,6 +172,16 @@ static int myDomainEventCallback2(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int myDomainEventRebootCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
printf("%s EVENT: Domain %s(%d) rebooted\n", __func__, virDomainGetName(dom),
|
||||
virDomainGetID(dom));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void myFreeFunc(void *opaque)
|
||||
{
|
||||
char *str = opaque;
|
||||
|
@ -289,6 +299,7 @@ int main(int argc, char **argv)
|
|||
int sts;
|
||||
int callback1ret = -1;
|
||||
int callback2ret = -1;
|
||||
int callback3ret = -1;
|
||||
|
||||
struct sigaction action_stop = {
|
||||
.sa_handler = stop
|
||||
|
@ -326,9 +337,15 @@ int main(int argc, char **argv)
|
|||
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventCallback2),
|
||||
strdup("callback 2"), myFreeFunc);
|
||||
callback3ret = virConnectDomainEventRegisterAny(dconn,
|
||||
NULL,
|
||||
VIR_DOMAIN_EVENT_ID_REBOOT,
|
||||
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventRebootCallback),
|
||||
strdup("callback reboot"), myFreeFunc);
|
||||
|
||||
if ((callback1ret != -1) &&
|
||||
(callback2ret != -1)) {
|
||||
(callback2ret != -1) &&
|
||||
(callback3ret != -1)) {
|
||||
while(run) {
|
||||
struct pollfd pfd = { .fd = h_fd,
|
||||
.events = h_event,
|
||||
|
@ -366,6 +383,7 @@ int main(int argc, char **argv)
|
|||
DEBUG0("Deregistering event handlers");
|
||||
virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback2ret);
|
||||
virConnectDomainEventDeregisterAny(dconn, callback3ret);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1874,6 +1874,7 @@ typedef void (*virConnectDomainEventGenericCallback)(virConnectPtr conn,
|
|||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */
|
||||
VIR_DOMAIN_EVENT_ID_REBOOT = 1, /* virConnectDomainEventGenericCallback */
|
||||
|
||||
/*
|
||||
* NB: this enum value will increase over time as new events are
|
||||
|
|
|
@ -523,6 +523,17 @@ virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int de
|
|||
return virDomainEventNew(def->id, def->name, def->uuid, type, detail);
|
||||
}
|
||||
|
||||
virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom)
|
||||
{
|
||||
return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
|
||||
dom->id, dom->name, dom->uuid);
|
||||
}
|
||||
virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj)
|
||||
{
|
||||
return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
|
||||
obj->def->id, obj->def->name, obj->def->uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* virDomainEventQueueFree:
|
||||
* @queue: pointer to the queue
|
||||
|
@ -628,6 +639,11 @@ void virDomainEventDispatchDefaultFunc(virConnectPtr conn,
|
|||
cbopaque);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_EVENT_ID_REBOOT:
|
||||
(cb)(conn, dom,
|
||||
cbopaque);
|
||||
break;
|
||||
|
||||
default:
|
||||
VIR_WARN("Unexpected event ID %d", event->eventID);
|
||||
break;
|
||||
|
|
|
@ -112,6 +112,9 @@ virDomainEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detai
|
|||
virDomainEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail);
|
||||
virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail);
|
||||
|
||||
virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom);
|
||||
virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj);
|
||||
|
||||
int virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
|
||||
virDomainEventPtr event);
|
||||
|
||||
|
|
|
@ -214,6 +214,8 @@ virDomainEventNew;
|
|||
virDomainEventNewFromDom;
|
||||
virDomainEventNewFromObj;
|
||||
virDomainEventNewFromDef;
|
||||
virDomainEventRebootNewFromDom;
|
||||
virDomainEventRebootNewFromObj;
|
||||
virDomainEventFree;
|
||||
virDomainEventDispatchDefaultFunc;
|
||||
virDomainEventDispatch;
|
||||
|
|
|
@ -864,9 +864,32 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuHandleDomainReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm)
|
||||
{
|
||||
struct qemud_driver *driver = qemu_driver;
|
||||
virDomainEventPtr event;
|
||||
|
||||
virDomainObjLock(vm);
|
||||
event = virDomainEventRebootNewFromObj(vm);
|
||||
virDomainObjUnlock(vm);
|
||||
|
||||
if (event) {
|
||||
qemuDriverLock(driver);
|
||||
qemuDomainEventQueue(driver, event);
|
||||
qemuDriverUnlock(driver);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static qemuMonitorCallbacks monitorCallbacks = {
|
||||
.eofNotify = qemuHandleMonitorEOF,
|
||||
.diskSecretLookup = findVolumeQcowPassphrase,
|
||||
.domainReset = qemuHandleDomainReset,
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
@ -6913,6 +6913,33 @@ remoteDomainReadEventLifecycle(virConnectPtr conn, XDR *xdr)
|
|||
}
|
||||
|
||||
|
||||
static virDomainEventPtr
|
||||
remoteDomainReadEventReboot(virConnectPtr conn, XDR *xdr)
|
||||
{
|
||||
remote_domain_event_reboot_msg msg;
|
||||
virDomainPtr dom;
|
||||
virDomainEventPtr event = NULL;
|
||||
memset (&msg, 0, sizeof msg);
|
||||
|
||||
/* unmarshall parameters, and process it*/
|
||||
if (! xdr_remote_domain_event_reboot_msg(xdr, &msg) ) {
|
||||
error (conn, VIR_ERR_RPC,
|
||||
_("unable to demarshall reboot event"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dom = get_nonnull_domain(conn,msg.dom);
|
||||
if (!dom)
|
||||
return NULL;
|
||||
|
||||
event = virDomainEventRebootNewFromDom(dom);
|
||||
xdr_free ((xdrproc_t) &xdr_remote_domain_event_reboot_msg, (char *) &msg);
|
||||
|
||||
virDomainFree(dom);
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
|
||||
remoteSecretOpen (virConnectPtr conn,
|
||||
virConnectAuthPtr auth,
|
||||
|
@ -8456,6 +8483,10 @@ processCallDispatchMessage(virConnectPtr conn, struct private_data *priv,
|
|||
event = remoteDomainReadEventLifecycle(conn, xdr);
|
||||
break;
|
||||
|
||||
case REMOTE_PROC_DOMAIN_EVENT_REBOOT:
|
||||
event = remoteDomainReadEventReboot(conn, xdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("Unexpected event proc %d", hdr->proc);
|
||||
break;
|
||||
|
|
|
@ -3050,6 +3050,15 @@ xdr_remote_domain_events_deregister_any_args (XDR *xdrs, remote_domain_events_de
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_domain_event_reboot_msg (XDR *xdrs, remote_domain_event_reboot_msg *objp)
|
||||
{
|
||||
|
||||
if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
|
||||
{
|
||||
|
|
|
@ -1727,6 +1727,11 @@ struct remote_domain_events_deregister_any_args {
|
|||
int eventID;
|
||||
};
|
||||
typedef struct remote_domain_events_deregister_any_args remote_domain_events_deregister_any_args;
|
||||
|
||||
struct remote_domain_event_reboot_msg {
|
||||
remote_nonnull_domain dom;
|
||||
};
|
||||
typedef struct remote_domain_event_reboot_msg remote_domain_event_reboot_msg;
|
||||
#define REMOTE_PROGRAM 0x20008086
|
||||
#define REMOTE_PROTOCOL_VERSION 1
|
||||
|
||||
|
@ -1899,6 +1904,7 @@ enum remote_procedure {
|
|||
REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME = 166,
|
||||
REMOTE_PROC_DOMAIN_EVENTS_REGISTER_ANY = 167,
|
||||
REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER_ANY = 168,
|
||||
REMOTE_PROC_DOMAIN_EVENT_REBOOT = 169,
|
||||
};
|
||||
typedef enum remote_procedure remote_procedure;
|
||||
|
||||
|
@ -2212,6 +2218,7 @@ extern bool_t xdr_remote_domain_abort_job_args (XDR *, remote_domain_abort_job_
|
|||
extern bool_t xdr_remote_domain_migrate_set_max_downtime_args (XDR *, remote_domain_migrate_set_max_downtime_args*);
|
||||
extern bool_t xdr_remote_domain_events_register_any_args (XDR *, remote_domain_events_register_any_args*);
|
||||
extern bool_t xdr_remote_domain_events_deregister_any_args (XDR *, remote_domain_events_deregister_any_args*);
|
||||
extern bool_t xdr_remote_domain_event_reboot_msg (XDR *, remote_domain_event_reboot_msg*);
|
||||
extern bool_t xdr_remote_procedure (XDR *, remote_procedure*);
|
||||
extern bool_t xdr_remote_message_type (XDR *, remote_message_type*);
|
||||
extern bool_t xdr_remote_message_status (XDR *, remote_message_status*);
|
||||
|
@ -2499,6 +2506,7 @@ extern bool_t xdr_remote_domain_abort_job_args ();
|
|||
extern bool_t xdr_remote_domain_migrate_set_max_downtime_args ();
|
||||
extern bool_t xdr_remote_domain_events_register_any_args ();
|
||||
extern bool_t xdr_remote_domain_events_deregister_any_args ();
|
||||
extern bool_t xdr_remote_domain_event_reboot_msg ();
|
||||
extern bool_t xdr_remote_procedure ();
|
||||
extern bool_t xdr_remote_message_type ();
|
||||
extern bool_t xdr_remote_message_status ();
|
||||
|
|
|
@ -1536,6 +1536,9 @@ struct remote_domain_events_deregister_any_args {
|
|||
int eventID;
|
||||
};
|
||||
|
||||
struct remote_domain_event_reboot_msg {
|
||||
remote_nonnull_domain dom;
|
||||
};
|
||||
|
||||
/*----- Protocol. -----*/
|
||||
|
||||
|
@ -1727,7 +1730,8 @@ enum remote_procedure {
|
|||
REMOTE_PROC_STORAGE_VOL_WIPE = 165,
|
||||
REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_DOWNTIME = 166,
|
||||
REMOTE_PROC_DOMAIN_EVENTS_REGISTER_ANY = 167,
|
||||
REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER_ANY = 168
|
||||
REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER_ANY = 168,
|
||||
REMOTE_PROC_DOMAIN_EVENT_REBOOT = 169
|
||||
|
||||
/*
|
||||
* Notice how the entries are grouped in sets of 10 ?
|
||||
|
|
Loading…
Reference in New Issue