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

Sharad Mishra snmishra at linux.vnet.ibm.com
Wed Mar 7 17:51:22 UTC 2012


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)
> +                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;
>  }





More information about the Libvirt-cim mailing list