[Libvirt-cim] [PATCH 3/3] ComputerSystem: Reboot state change also a job

Sharad Mishra snmishra at linux.vnet.ibm.com
Tue Mar 20 19:30:57 UTC 2012


On Wed, 2012-03-07 at 09:51 -0800, Sharad Mishra wrote:
> 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)" <eblima at br.ibm.com>
> > 
> > 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) <eblima at br.ibm.com>
> > ---
> >  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)

I don't see "VIR_DOMAIN_EVENT_SHUTDOWN" defined in libvirt.h.

-Sharad

> > +                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
> Libvirt-cim at redhat.com
> https://www.redhat.com/mailman/listinfo/libvirt-cim
> 





More information about the Libvirt-cim mailing list