Visual inspection looks good. Need to apply and test -Sharad
On Tue, 2012-03-06 at 14:55 -0300, Eduardo Lima (Etrunko) wrote: > From: "Eduardo Lima (Etrunko)" <[email protected]> > > As it happens for Shutdown, the RequestStateChange method returns immediately > with return code 0 (successful) even though the state change is still not > completed. > > Change the current job implementation to support reboot as well. For this we > need the libvirt domain events APIs and event loop implementation, which are > only available in libvirt version 0.9.0 or newer. > > Signed-off-by: Eduardo Lima (Etrunko) <[email protected]> > --- > src/Virt_ComputerSystem.c | 90 > ++++++++++++++++++++++++++++++++++++++------- > 1 files changed, 76 insertions(+), 14 deletions(-) > > diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c > index 778809d..04584f3 100644 > --- a/src/Virt_ComputerSystem.c > +++ b/src/Virt_ComputerSystem.c > @@ -32,6 +32,7 @@ > > #include <uuid.h> > #include <libvirt/libvirt.h> > +#include <libvirt/virterror.h> > > #include <libcmpiutil/libcmpiutil.h> > #include <libcmpiutil/std_invokemethod.h> > @@ -61,6 +62,8 @@ struct _state_change_job { > uint16_t status; /* job status */ > }; > > +static bool events_registered = false; > + > /* Set the "Name" property of an instance from a domain */ > static int set_name_from_dom(virDomainPtr dom, CMPIInstance *instance) > { > @@ -1203,14 +1206,12 @@ static CMPIStatus __state_change(const char *name, > s = state_change_enable(dom, &info); > else if (state == CIM_STATE_DISABLED) > s = state_change_disable(dom, &info); > - else if (state == CIM_STATE_SHUTDOWN) > - s.rc = CIM_SVPC_RETURN_JOB_STARTED; > else if (state == CIM_STATE_PAUSED) > s = state_change_pause(dom, &info); > - else if (state == CIM_STATE_REBOOT) > - s = state_change_reboot(dom, &info); > else if (state == CIM_STATE_RESET) > s = state_change_reset(dom, &info); > + else if (state == CIM_STATE_SHUTDOWN || state == CIM_STATE_REBOOT) > + s.rc = CIM_SVPC_RETURN_JOB_STARTED; > else > cu_statusf(_BROKER, &s, > CMPI_RC_ERR_NOT_SUPPORTED, > @@ -1333,6 +1334,25 @@ static CMPIStatus create_state_change_job(const > CMPIObjectPath *ref, > return s; > } > > +static void state_change_reboot_cb(virConnectPtr conn, > + virDomainPtr dom, > + void *data) > +{ > + state_change_job_t *job = (state_change_job_t *) data; > + job->status = CIM_JOB_STATE_COMPLETED; > +} > + > +static void state_change_shutdown_cb(virConnectPtr conn, > + virDomainPtr dom, > + int event, > + int detail, > + void *data) > +{ > + state_change_job_t *job = (state_change_job_t *) data; > + if (event == VIR_DOMAIN_EVENT_SHUTDOWN) > + job->status = CIM_JOB_STATE_COMPLETED; > +} > + > static CMPI_THREAD_RETURN state_change_thread(void *data) > { > CMPIStatus s; > @@ -1341,8 +1361,10 @@ static CMPI_THREAD_RETURN state_change_thread(void > *data) > virConnectPtr conn = NULL; > virDomainPtr dom = NULL; > virDomainInfo info; > + int job_cb = -1; > > - if (job->dom_state != CIM_STATE_SHUTDOWN) { > + if (job->dom_state != CIM_STATE_SHUTDOWN && > + job->dom_state != CIM_STATE_REBOOT) { > CU_DEBUG("Unrecognized state '%d'", job->dom_state); > goto end; > } > @@ -1382,17 +1404,56 @@ static CMPI_THREAD_RETURN state_change_thread(void > *data) > goto out; > } > > - s = state_change_shutdown(dom, &info); > - if (s.rc != CMPI_RC_OK) { > - CU_DEBUG("Unable to trigger domain shutdown: '%s'", > - CMGetCharPtr(s.msg)); > - goto out; > + if (events_registered == false) { > + events_registered = true; > + virEventRegisterDefaultImpl(); > + } > + > + if (job->dom_state == CIM_STATE_REBOOT) { > + job_cb = virConnectDomainEventRegisterAny(conn, NULL, > + VIR_DOMAIN_EVENT_ID_REBOOT, > + > VIR_DOMAIN_EVENT_CALLBACK(state_change_reboot_cb), > + job, NULL); > + > + if (job_cb == -1) { > + CU_DEBUG("Unable to connect domain reboot callback"); > + goto out; > + } > + > + s = state_change_reboot(dom, &info); > + > + if (s.rc != CMPI_RC_OK) { > + CU_DEBUG("Unable to trigger domain reboot: '%s'", > + CMGetCharPtr(s.msg)); > + goto out; > + } > + } else if (job->dom_state == CIM_STATE_SHUTDOWN) { > + job_cb = virConnectDomainEventRegisterAny(conn, NULL, > + VIR_DOMAIN_EVENT_ID_LIFECYCLE, > + > VIR_DOMAIN_EVENT_CALLBACK(state_change_shutdown_cb), > + job, NULL); > + > + if (job_cb == -1) { > + CU_DEBUG("Unable to connect domain shutdown > callback"); > + goto out; > + } > + > + s = state_change_shutdown(dom, &info); > + > + if (s.rc != CMPI_RC_OK) { > + CU_DEBUG("Unable to trigger domain shutdown: '%s'", > + CMGetCharPtr(s.msg)); > + goto out; > + } > } > > /* Wait for operation (shutdown/reboot) to complete */ > - while (info.state != VIR_DOMAIN_SHUTOFF) { > - usleep(100 * 1000); > - virDomainGetInfo(dom, &info); > + while (job->status == CIM_JOB_STATE_RUNNING) { > + if (virEventRunDefaultImpl() < 0) { > + virErrorPtr err = virGetLastError(); > + CU_DEBUG("Failed to run event loop: %s\n", > + err && err->message ? err->message : "Unknown > error"); > + } > } > > CU_DEBUG("Job completed"); > @@ -1405,6 +1466,8 @@ static CMPI_THREAD_RETURN state_change_thread(void > *data) > (CMPIValue *) "Completed", CMPI_chars); > } > > + virConnectDomainEventDeregisterAny(conn, job_cb); > + > out: > virDomainFree(dom); > virConnectClose(conn); > @@ -1412,7 +1475,6 @@ static CMPI_THREAD_RETURN state_change_thread(void > *data) > CBDetachThread(_BROKER, job->context); > free(job->dom_name); > free(job); > - > end: > return NULL; > } _______________________________________________ Libvirt-cim mailing list [email protected] https://www.redhat.com/mailman/listinfo/libvirt-cim
