[Libvirt-cim] [PATCH 1 of 3] Add VirtualSystemSnapshotService

Heidi Eckhart heidieck at linux.vnet.ibm.com
Wed Feb 27 10:59:25 UTC 2008


Dan Smith wrote:
> +++ b/src/Virt_VirtualSystemSnapshotService.c	Tue Feb 26 11:19:56 2008 -0800
> @@ -0,0 +1,521 @@
> +/*
> + * Copyright IBM Corp. 2007
>   
2008 ;)

> +static void do_snapshot(struct snap_context *ctx,
> +                        virConnectPtr conn,
> +                        virDomainPtr dom)
> +{
> +  ...
> +        if (ctx->restore) {
> +                CU_DEBUG("Starting restore from %s", ctx->save_path);
> +
> +                ret = virDomainRestore(conn, ctx->save_path);
> +                if (ret == -1) {
> +                        CU_DEBUG("Restore failed");
> +                        snap_job_set_status(ctx,
> +                                            CIM_JOBSTATE_COMPLETE,
> +                                            "Snapshot Failed (restore)");
> +                        return;
> +                }
> +
> +                CU_DEBUG("Restore completed");
> +                snap_job_set_status(ctx,
> +                                    CIM_JOBSTATE_RUNNING,
> +                                    "Restore finished");
>   
Please can you explain why you set the status here and overwrite it 
right afterwards ? I think the CIM_JOBSTATE is already COMPLETE here.
> +        }
> +
> +        CU_DEBUG("Snapshot (%s/%s) completed",
> +                 ctx->save ? "Save" : "None",
> +                 ctx->restore ? "Restore" : "None");
> +
> +        snap_job_set_status(ctx,
> +                            CIM_JOBSTATE_COMPLETE,
> +                            "Snapshot complete");
> +
> +        return;
> +}
> +
> +static CMPI_THREAD_RETURN snapshot_thread(struct snap_context *ctx)
> +{...
> +        conn = connect_by_classname(_BROKER, ctx->ref_cn, &s);
> +        if (conn == NULL) {
> +                CU_DEBUG("Failed to connect with classname `%s'", ctx->ref_cn);
> +                snap_job_set_status(ctx,
> +                                    CIM_JOBSTATE_COMPLETE,
> +                                    "Unable to connect to hypervisor");
> +                goto out;
> +        }
> +
> +        dom = virDomainLookupByName(conn, ctx->domain);
> +        if (dom == NULL) {
> +                CU_DEBUG("No such domain `%s'", ctx->domain);
> +                snap_job_set_status(ctx,
> +                                    CIM_JOBSTATE_COMPLETE,
> +                                    "No such domain");
> +                goto out;
> +        }
> +
> +        do_snapshot(ctx, conn, dom);
> +
> + out:
>   
FYI - I encountered some problems with another provider, where I tried 
virDomainFree() with a not initialized dom. This could also happen here 
with the goto out from conn. Maybe virDomainFree() can not handle NULL ?
> +        virDomainFree(dom);
> +        virConnectClose(conn);
> +
> +        snap_job_free(ctx);
> +
> +        return NULL;
> +}
> +
> +static CMPIStatus create_job(const CMPIContext *context,
> +                             const CMPIObjectPath *ref,
> +                             struct snap_context *ctx,
> +                             CMPIObjectPath **job)
> +{
> +        CMPIObjectPath *op;
> +        CMPIInstance *inst;
> +        CMPIStatus s;
> +
> +        op = CMNewObjectPath(_BROKER,
> +                             NAMESPACE(ref),
> +                             "CIM_ConcreteJob", /*FIXME*/
> +                             &s);
> +        if ((s.rc != CMPI_RC_OK) || (op == NULL)) {
> +                CU_DEBUG("Failed to create job path");
> +                goto out;
> +        }
> +
> +        CMSetNameSpace(op, NAMESPACE(ref));
>   
This step is not necessary as NewObjectPath already sets the namespace.
> +
> +        inst = CMNewInstance(_BROKER, op, &s);
> +        if ((s.rc != CMPI_RC_OK) || (inst == NULL)) {
> +                CU_DEBUG("Failed to create job instance");
> +                goto out;
> +        }
> +
> +        CMSetProperty(inst, "InstanceID",
> +                      (CMPIValue *)ctx->uuid, CMPI_chars);
> +
> +        CMSetProperty(inst, "Name",
> +                      (CMPIValue *)"Snapshot", CMPI_chars);
> +
> +        CMSetProperty(inst, "Status",
> +                      (CMPIValue *)"Queued", CMPI_chars);
> +
> +        op = CMGetObjectPath(inst, &s);
> +        if ((op == NULL) || (s.rc != CMPI_RC_OK)) {
> +                CU_DEBUG("Failed to get path of job instance");
> +                goto out;
> +        }
> +
> +        CMSetNameSpace(op, NAMESPACE(ref));
>   
This should also be not necessary. But as you debug the ref right 
afterwards ... did you encounter some problems here ?
> +
> +        CU_DEBUG("ref was %s", CMGetCharPtr(CMObjectPathToString(op, NULL)));
> +
> +        *job = CBCreateInstance(_BROKER, context, op, inst, &s);
> +        if ((*job == NULL) || (s.rc != CMPI_RC_OK)) {
> +                CU_DEBUG("Failed to create job");
> +                goto out;
> +        }
> +
> +        ctx->ref_ns = strdup(NAMESPACE(ref));
> +        ctx->ref_cn = strdup(CLASSNAME(ref));
> +
> +        ctx->context = CBPrepareAttachThread(_BROKER, context);
> +
> +        _BROKER->xft->newThread((void *)snapshot_thread, ctx, 0);
> +
> +        cu_statusf(_BROKER, &s,
> +                   CMPI_RC_OK,
> +                   "");
>   
Its more my personal view, but as you "goto out" each time the status is 
something else than CMPI_RC_OK, it should still be CMPI_RC_OK at this 
point, if you initialize it right at the beginning of the function with
CMPIStatus s = {CMPI_RC_OK, NULL}; .
> + out:
> +        return s;
> +}
> +
> +char *vsss_get_save_path(const char *domname)
> +{
> +        int ret;
> +        char *path = NULL;
>   
You could use a CMPIString and return its char* to the caller. This 
avoids missing frees.
> +
> +        ret = asprintf(&path,
> +                       "/var/lib/libvirt/%s.save", domname);
> +        if (ret == -1)
> +                return NULL;
> +
> +        return path;
> +}
> + ...
> +
> +
> +static CMPIStatus create_snapshot(CMPIMethodMI *self,
> +                                  const CMPIContext *context,
> +                                  const CMPIResult *results,
> +                                  const CMPIObjectPath *reference,
> +                                  const CMPIArgs *argsin,
> +                                  CMPIArgs *argsout)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIObjectPath *system;
> +        CMPIInstance *sd;
> +        uint16_t type;
> +        uint32_t retcode = 0;
> +        const char *name;
> +
> +        if (cu_get_u16_arg(argsin, "SnapshotType", &type) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER, &s,
> +                           CMPI_RC_ERR_INVALID_PARAMETER,
> +                           "Missing SnapshotType");
> +                goto out;
> +        }
> + ...
> +
> +        s = start_snapshot_job(reference, context, name, type);
> +
> +        CMReturnData(results, (CMPIValue *)&retcode, CMPI_uint32);
> + out:
> +        CU_DEBUG("Returning: %i", s.rc);
>   
You also need to do a CMReturnData for a failed request.
> +        return s;
> +}
> +
> +static CMPIStatus destroy_snapshot(CMPIMethodMI *self,
> +                                   const CMPIContext *context,
> +                                   const CMPIResult *results,
> +                                   const CMPIObjectPath *reference,
> +                                   const CMPIArgs *argsin,
> +                                   CMPIArgs *argsout)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIObjectPath *snap;
> +        char *name = NULL;
> +        char *path = NULL;
> + ...
> + out:
> +        free(path);
> +        free(name);
You need to return the uint32 status of this method. The same for 
apply_snapshot().
> +        return s;
> +}
> + ...
> +
> +STDIM_MethodMIStub(, Virt_VirtualSystemSnapshotService,
> +                   _BROKER, libvirt_cim_init(), handlers);
>   
I miss the instance provider interface. Do you plan to add this ?


-- 
Regards

Heidi Eckhart
Software Engineer
IBM Linux Technology Center - Open Hypervisor




More information about the Libvirt-cim mailing list