[PATCH 0 of 3] (#2) Add VirtualSystemSnapshotService

This includes the associated Capabilities object this time. The changes to VSSD (and other related items) will be a separate set

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053596 28800 # Node ID fce1a31a53090b42dbfbd788a6db2a1164636197 # Parent bb0530f50ea8d4a75ec34cd54f3bc2daebbda556 Add VirtualSystemSnapshotService Changes: - Added header block Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r bb0530f50ea8 -r fce1a31a5309 src/Virt_VirtualSystemSnapshotService.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Virt_VirtualSystemSnapshotService.c Tue Feb 26 11:19:56 2008 -0800 @@ -0,0 +1,521 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Dan Smith <danms@us.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdbool.h> + +#include <uuid/uuid.h> + +#include <cmpidt.h> +#include <cmpift.h> +#include <cmpimacs.h> + +#include <libcmpiutil/libcmpiutil.h> +#include <libcmpiutil/std_invokemethod.h> + +#include "misc_util.h" + +#include "Virt_VirtualSystemSnapshotService.h" + +#define CIM_JOBSTATE_STARTING 3 +#define CIM_JOBSTATE_RUNNING 4 +#define CIM_JOBSTATE_COMPLETE 7 + +static const CMPIBroker *_BROKER; + +struct snap_context { + CMPIContext *context; + char *domain; + char uuid[33]; + char *save_path; + char *ref_ns; + char *ref_cn; + + bool save; + bool restore; +}; + +static void snap_job_free(struct snap_context *ctx) +{ + free(ctx->domain); + free(ctx->save_path); + free(ctx->ref_ns); + free(ctx->ref_cn); + free(ctx); +} + +static void snap_job_set_status(struct snap_context *ctx, + uint16_t state, + const char *status) +{ + CMPIInstance *inst; + CMPIStatus s; + CMPIObjectPath *op; + + op = CMNewObjectPath(_BROKER, + ctx->ref_ns, + "CIM_ConcreteJob", + &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Failed to create job path for update"); + return; + } + + CMAddKey(op, "InstanceID", (CMPIValue *)ctx->uuid, CMPI_chars); + + inst = CBGetInstance(_BROKER, ctx->context, op, NULL, &s); + if ((inst == NULL) || (s.rc != CMPI_RC_OK)) { + CU_DEBUG("Failed to get job instance for update of %s", + ctx->uuid); + return; + } + + CMSetProperty(inst, "JobState", + (CMPIValue *)&state, CMPI_uint16); + CMSetProperty(inst, "Status", + (CMPIValue *)status, CMPI_chars); + + s = CBModifyInstance(_BROKER, ctx->context, op, inst, NULL); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Failed to update job instance %s: %s", + ctx->uuid, + CMGetCharPtr(s.msg)); + return; + } + + CU_DEBUG("Set %s status to %i:%s", ctx->uuid, state, status); +} + +static void do_snapshot(struct snap_context *ctx, + virConnectPtr conn, + virDomainPtr dom) +{ + int ret; + + if (ctx->save) { + CU_DEBUG("Starting save to %s", ctx->save_path); + + ret = virDomainSave(dom, ctx->save_path); + if (ret == -1) { + CU_DEBUG("Save failed"); + snap_job_set_status(ctx, + CIM_JOBSTATE_COMPLETE, + "Snapshot Failed (save)"); + return; + } + + CU_DEBUG("Save completed"); + snap_job_set_status(ctx, + CIM_JOBSTATE_RUNNING, + "Save finished"); + } + + 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"); + } + + 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) +{ + CMPIStatus s; + virConnectPtr conn = NULL; + virDomainPtr dom = NULL; + + CU_DEBUG("Snapshot thread alive"); + + CBAttachThread(_BROKER, ctx->context); + + snap_job_set_status(ctx, CIM_JOBSTATE_RUNNING, "Running"); + + 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: + 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)); + + 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)); + + 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, + ""); + out: + return s; +} + +char *vsss_get_save_path(const char *domname) +{ + int ret; + char *path = NULL; + + ret = asprintf(&path, + "/var/lib/libvirt/%s.save", domname); + if (ret == -1) + return NULL; + + return path; +} + +static struct snap_context *new_context(const char *name, + CMPIStatus *s) +{ + struct snap_context *ctx; + uuid_t uuid; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + CU_DEBUG("Failed to alloc snapshot context"); + goto out; + } + + ctx->domain = strdup(name); + + uuid_generate(uuid); + uuid_unparse(uuid, ctx->uuid); + + ctx->save_path = get_save_path(ctx->domain); + if (ctx->save_path == NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Unable to get save_path"); + goto out; + } + + cu_statusf(_BROKER, s, + CMPI_RC_OK, + ""); + out: + if (s->rc != CMPI_RC_OK) { + snap_job_free(ctx); + ctx = NULL; + } + + return ctx; +} + +static CMPIStatus start_snapshot_job(const CMPIObjectPath *ref, + const CMPIContext *context, + const char *name, + uint16_t type) +{ + struct snap_context *ctx; + CMPIStatus s; + CMPIObjectPath *job; + + ctx = new_context(name, &s); + if (ctx == NULL) + goto out; + + ctx->save = (type != 0); + ctx->restore = (type != VIR_VSSS_SNAPSHOT_MEM); + + s = create_job(context, ref, ctx, &job); + + out: + return s; +} + +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; + } + + if ((type != VIR_VSSS_SNAPSHOT_MEM) && + (type != VIR_VSSS_SNAPSHOT_MEMT)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_SUPPORTED, + "Only memory(%i,%i) snapshots are supported", + VIR_VSSS_SNAPSHOT_MEM, + VIR_VSSS_SNAPSHOT_MEMT); + goto out; + } + + if (cu_get_ref_arg(argsin, "AffectedSystem", &system) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing AffectedSystem"); + goto out; + } + + if (cu_get_inst_arg(argsin, "SnapshotSettings", &sd) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing SnapshotSettings"); + goto out; + } + + if (cu_get_str_path(system, "Name", &name) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing Name property of AffectedSystem"); + goto out; + } + + s = start_snapshot_job(reference, context, name, type); + + CMReturnData(results, (CMPIValue *)&retcode, CMPI_uint32); + out: + CU_DEBUG("Returning: %i", s.rc); + 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; + + if (cu_get_ref_arg(argsin, "AffectedSnapshot", &snap) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing Snapshot"); + goto out; + } + + if (!parse_instanceid(snap, NULL, &name)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Invalid InstanceID in Snapshot"); + goto out; + } + + path = get_save_path(name); + if (path == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to get save_path"); + goto out; + } + + if (unlink(path) == -1) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to remove snapshot: %s", path); + } + out: + free(path); + free(name); + + return s; +} + +static CMPIStatus apply_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; + + if (cu_get_ref_arg(argsin, "AffectedSnapshot", &snap) != CMPI_RC_OK) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing Snapshot"); + goto out; + } + + if (!parse_instanceid(snap, NULL, &name)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Invalid InstanceID in Snapshot"); + goto out; + } + + s = start_snapshot_job(reference, context, name, 0); + + out: + free(name); + + return s; +} + +static struct method_handler CreateSnapshot = { + .name = "CreateSnapshot", + .handler = create_snapshot, + .args = {{"AffectedSystem", CMPI_ref, false}, + {"SnapshotSettings", CMPI_instance, false}, + {"SnapshotType", CMPI_uint16, false}, + ARG_END} +}; + +static struct method_handler DestroySnapshot = { + .name = "DestroySnapshot", + .handler = destroy_snapshot, + .args = {{"AffectedSnapshot", CMPI_ref, false}, + ARG_END} +}; + +static struct method_handler ApplySnapshot = { + .name = "ApplySnapshot", + .handler = apply_snapshot, + .args = {{"AffectedSnapshot", CMPI_ref, false}, + ARG_END} +}; + +static struct method_handler *handlers[] = { + &CreateSnapshot, + &DestroySnapshot, + &ApplySnapshot, + NULL +}; + +STDIM_MethodMIStub(, Virt_VirtualSystemSnapshotService, + _BROKER, libvirt_cim_init(), handlers); + + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ diff -r bb0530f50ea8 -r fce1a31a5309 src/Virt_VirtualSystemSnapshotService.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Virt_VirtualSystemSnapshotService.h Tue Feb 26 11:19:56 2008 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Dan Smith <danms@us.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Returns a malloc()'d string; caller must free() */ +char *vsss_get_save_path(const char *domname); + +#define CIM_VSSS_SNAPSHOT_FULL 2 +#define CIM_VSSS_SNAPSHOT_DISK 3 + +/* VIR_VSSS_SNAPSHOT_MEM - Attempt to save/restore to create a running snap + * VIR_VSSS_SNAPSHOT_MEMT - Just save and let the domain be "off" + */ +#define VIR_VSSS_SNAPSHOT_MEM 32768 +#define VIR_VSSS_SNAPSHOT_MEMT 32769 + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053596 28800 # Node ID fce1a31a53090b42dbfbd788a6db2a1164636197 # Parent bb0530f50ea8d4a75ec34cd54f3bc2daebbda556 Add VirtualSystemSnapshotService
Changes: - Added header block
Signed-off-by: Dan Smith <danms@us.ibm.com>
diff -r bb0530f50ea8 -r fce1a31a5309 src/Virt_VirtualSystemSnapshotService.c
+static CMPI_THREAD_RETURN snapshot_thread(struct snap_context *ctx) +{ + CMPIStatus s;
We don't use this, which is fine. However, leads to a question.. why the decision to have do_snapshot() return void?
+ +char *vsss_get_save_path(const char *domname)
The function is defined as vss_get_save_path() here, but called as get_save_path() later on.
+{ + int ret; + char *path = NULL; + + ret = asprintf(&path, + "/var/lib/libvirt/%s.save", domname);
I assume this path will be valid on all systems / distros?
+ +static struct snap_context *new_context(const char *name, + CMPIStatus *s) +{ + struct snap_context *ctx; + uuid_t uuid; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + CU_DEBUG("Failed to alloc snapshot context"); + goto out; + } + + ctx->domain = strdup(name); + + uuid_generate(uuid); + uuid_unparse(uuid, ctx->uuid); + + ctx->save_path = get_save_path(ctx->domain);
Needs to be vsss_get_save_path()
+ if (ctx->save_path == NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Unable to get save_path"); + goto out; + } + + cu_statusf(_BROKER, s, + CMPI_RC_OK, + ""); + out: + if (s->rc != CMPI_RC_OK) { + snap_job_free(ctx); + ctx = NULL; + } + + return ctx; +} + +static CMPIStatus start_snapshot_job(const CMPIObjectPath *ref, + const CMPIContext *context, + const char *name, + uint16_t type) +{ + struct snap_context *ctx; + CMPIStatus s;
Need to initialize s here. Or make sure to set the status when the calloc fails in new_context().
+ CMPIObjectPath *job; + + ctx = new_context(name, &s); + if (ctx == NULL) + goto out; + + ctx->save = (type != 0); + ctx->restore = (type != VIR_VSSS_SNAPSHOT_MEM); + + s = create_job(context, ref, ctx, &job); + + out: + 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;
+ path = get_save_path(name);
Needs to be vsss_get_save_path() -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com

KR> We don't use this, which is fine. However, leads to a KR> question.. why the decision to have do_snapshot() return void? Because the status and state information is conveyed through the job. What else could the caller do with a return value? It's in a thread. KR> The function is defined as vss_get_save_path() here, but called as KR> get_save_path() later on. Wow, that was dumb. I changed this right before I sent it out, but I think it compiled the first time because I had the function defined in the installed libraries and headers. Thanks :) KR> I assume this path will be valid on all systems / distros? Probably not. We probably need to put this in our configure.ac. KR> Need to initialize s here. Or make sure to set the status when KR> the calloc fails in new_context(). Yep, thanks. -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

Dan Smith wrote:
KR> We don't use this, which is fine. However, leads to a KR> question.. why the decision to have do_snapshot() return void?
Because the status and state information is conveyed through the job. What else could the caller do with a return value? It's in a thread.
Oh yes, sorry. My mistake. For some reason, I spaced that do_snapshot() was handled in the thread. -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com

Dan Smith wrote:
+static void snap_job_set_status(struct snap_context *ctx, + uint16_t state, + const char *status) +{ + CMPIInstance *inst; + CMPIStatus s; + CMPIObjectPath *op; + + op = CMNewObjectPath(_BROKER, + ctx->ref_ns, + "CIM_ConcreteJob", + &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Failed to create job path for update"); + return; + } + + CMAddKey(op, "InstanceID", (CMPIValue *)ctx->uuid, CMPI_chars); + + inst = CBGetInstance(_BROKER, ctx->context, op, NULL, &s); + if ((inst == NULL) || (s.rc != CMPI_RC_OK)) { + CU_DEBUG("Failed to get job instance for update of %s", + ctx->uuid); + return; + } + + CMSetProperty(inst, "JobState", + (CMPIValue *)&state, CMPI_uint16); + CMSetProperty(inst, "Status", + (CMPIValue *)status, CMPI_chars);
It would be good to also add the domain and save_path information to the Job instance, e.g. as value of the property "Name".
+ + s = CBModifyInstance(_BROKER, ctx->context, op, inst, NULL); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Failed to update job instance %s: %s", + ctx->uuid, + CMGetCharPtr(s.msg)); + return; + } + + CU_DEBUG("Set %s status to %i:%s", ctx->uuid, state, status); +} + Somehow I think that success and error scenarios are merged by this function. Even if a snapshot request failed, the JobState has COMPLETE, which is in general correct. But the client can only interpret the Status property then, if the snapshot was created or not. The CIM_Job mof tells to use ErrorCode and ErrorDescription. I think this is a good way to communicate a snapshot failure.
-- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

HE> It would be good to also add the domain and save_path information HE> to the Job instance, e.g. as value of the property "Name". Okay, I'll stuff it in there somewhere. HE> Somehow I think that success and error scenarios are merged by HE> this function. Even if a snapshot request failed, the JobState has HE> COMPLETE, which is in general correct. But the client can only HE> interpret the Status property then, if the snapshot was created or HE> not. The CIM_Job mof tells to use ErrorCode and HE> ErrorDescription. I think this is a good way to communicate a HE> snapshot failure. Okay, good point. Having the job status be "complete" for a failed job bugs me, but I'll set the error information. Thanks! -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

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

HE> 2008 ;) Whoops, thanks :) HE> Please can you explain why you set the status here and overwrite HE> it right afterwards ? I think the CIM_JOBSTATE is already COMPLETE HE> here. I wanted this function to serve three roles: save, save-then-restore, and restore. In the save-then-restore scenario, we want a status update after the save is complete, of course. Because I like symmetric code, I added the same sort of status update to the end of restore. In the save-only case, this comes out to setting the save status and then changing it to "complete" right afterwards. I don't know if this is a big deal or not, but I think that the code to make it avoid the extra set would be less pretty. Suggestions are welcome, of course :) HE> FYI - I encountered some problems with another provider, where I HE> tried virDomainFree() with a not initialized dom. This could also HE> happen here with the goto out from conn. Maybe virDomainFree() can HE> not handle NULL ? No, it can handle it just fine. We do this in many, many places elsewhere in the code. I think you might get a warning out of it in some cases, but the code does check for NULL. HE> This step is not necessary as NewObjectPath already sets the HE> namespace. It doesn't for me. If I don't do this, the CBCreateInstance fails with "Target namespace does not exist". We do this in the migration job creation code as well.
+ CMSetNameSpace(op, NAMESPACE(ref));
Er, hmm, maybe it's this one. HE> This should also be not necessary. But as you debug the ref right HE> afterwards ... did you encounter some problems here ? Yes, removing at least one of these results in the behavior described above. I'll revisit and see which is the necessary one. HE> Its more my personal view, but as you "goto out" each time the HE> status is something else than CMPI_RC_OK, it should still be HE> CMPI_RC_OK at this point, if you initialize it right at the HE> beginning of the function with CMPIStatus s = {CMPI_RC_OK, NULL}; HE> . The reason I don't like doing this in all cases is because it's implied success at the bottom of the function, instead of making it explicit. Also, if we are in the habit of doing this, and then have a function where we catch s.rc != CMPI_RC_OK somewhere and take a default value, then we might fall through here and return an error when we don't intend to. However, I've changed it in this case. HE> You could use a CMPIString and return its char* to the HE> caller. This avoids missing frees. But then I have to pass a broker pointer, since this is used outside this file. I'll look to see if it makes sense to do that here or not. HE> You also need to do a CMReturnData for a failed request. Ah, yes, thanks. HE> I miss the instance provider interface. Do you plan to add this ? Yes :) -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

Dan Smith wrote:
HE> Please can you explain why you set the status here and overwrite HE> it right afterwards ? I think the CIM_JOBSTATE is already COMPLETE HE> here.
I wanted this function to serve three roles: save, save-then-restore, and restore. In the save-then-restore scenario, we want a status update after the save is complete, of course. Ok, thanks - makes sense now for me. Because I like symmetric code, I added the same sort of status update to the end of restore. In the save-only case, this comes out to setting the save status and then changing it to "complete" right afterwards.
I don't know if this is a big deal or not, but I think that the code to make it avoid the extra set would be less pretty. Suggestions are welcome, of course :)
Well, I have no suggestion to reorder the code - as it would end up in less pretty code (as you already said). But maybe a little description to do_snapshot() would help to understand it better.
... Yes, removing at least one of these results in the behavior described above. I'll revisit and see which is the necessary one.
Please check if the CMPIInstance contains the namespace information. I guess this will be the leak.
...
HE> You could use a CMPIString and return its char* to the HE> caller. This avoids missing frees.
But then I have to pass a broker pointer, since this is used outside this file. I'll look to see if it makes sense to do that here or not.
Oh yes, I forgot about that. Mhh, then it might be better to not use CMPIString, as this would also break the common look and feel with similar functions in libvirt-cim. -- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

HE> Please check if the CMPIInstance contains the namespace HE> information. I guess this will be the leak. Yes, I forgot to check this, so I'll do it before I re-send. HE> Oh yes, I forgot about that. Mhh, then it might be better to not HE> use CMPIString, as this would also break the common look and feel HE> with similar functions in libvirt-cim. I meant to mention that I checked into this and remembered why I did it. If we create a thread and pass in broker memory, then the memory gets free()'d when the current operation returns, which means the thread starts working, but later has a pointer to free()'d memory and crashes. -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053674 28800 # Node ID 0f1a316b04aca1fa962f624444ae57b960fc2a37 # Parent fce1a31a53090b42dbfbd788a6db2a1164636197 Add VirtualSystemSnapshotCapabilities Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r fce1a31a5309 -r 0f1a316b04ac src/Virt_VirtualSystemSnapshotServiceCapabilities.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Virt_VirtualSystemSnapshotServiceCapabilities.c Tue Feb 26 11:21:14 2008 -0800 @@ -0,0 +1,204 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Dan Smith <danms@us.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <stdbool.h> +#include <stdint.h> + +#include <libvirt/libvirt.h> + +#include "misc_util.h" + +#include <cmpidt.h> +#include <cmpift.h> +#include <cmpimacs.h> + +#include <libcmpiutil/libcmpiutil.h> +#include <libcmpiutil/std_instance.h> + +#include "Virt_VirtualSystemSnapshotService.h" + +const static CMPIBroker *_BROKER; + +enum { CREATE_SNAPSHOT = 2, + DESTROY_SNAPSHOT, + APPLY_SNAPSHOT, +}; + +static CMPIStatus set_inst_properties(const CMPIBroker *broker, + CMPIInstance *inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *array; + uint16_t element; + + CMSetProperty(inst, "InstanceID", + (CMPIValue *)"SnapshotCapabilities", CMPI_chars); + + array = CMNewArray(broker, 2, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (array == NULL)) + goto out; + + element = (uint16_t)CREATE_SNAPSHOT; + CMSetArrayElementAt(array, 0, &element, CMPI_uint16); + + element = (uint16_t)APPLY_SNAPSHOT; + CMSetArrayElementAt(array, 1, &element, CMPI_uint16); + + CMSetProperty(inst, "AsynchronousMethodsSupported", + (CMPIValue *)&array, CMPI_uint16A); + + array = CMNewArray(broker, 1, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (array == NULL)) + goto out; + + element = (uint16_t)DESTROY_SNAPSHOT; + CMSetArrayElementAt(array, 0, &element, CMPI_uint16); + + CMSetProperty(inst, "SynchronousMethodsSupported", + (CMPIValue *)&array, CMPI_uint16A); + + array = CMNewArray(broker, 2, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (array == NULL)) + goto out; + + element = (uint16_t)CIM_VSSS_SNAPSHOT_MEM; + CMSetArrayElementAt(array, 0, &element, CMPI_uint16); + + element = (uint16_t)CIM_VSSS_SNAPSHOT_MEMT; + CMSetArrayElementAt(array, 1, &element, CMPI_uint16); + + CMSetProperty(inst, "SnapshotTypesSupported", + (CMPIValue *)&array, CMPI_uint16A); + + out: + return s; +} + +static CMPIStatus get_vss_cap(const CMPIBroker *broker, + const CMPIObjectPath *ref, + CMPIInstance **_inst, + bool is_get_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + virConnectPtr conn = NULL; + + conn = connect_by_classname(broker, CLASSNAME(ref), &s); + if (conn == NULL) { + if (is_get_inst) + cu_statusf(broker, &s, + CMPI_RC_ERR_NOT_FOUND, + "No such instance"); + goto out; + } + + inst = get_typed_instance(broker, + pfx_from_conn(conn), + "VirtualSystemSnapshotServiceCapabilities", + NAMESPACE(ref)); + if (inst == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Can't create instance for %s", CLASSNAME(ref)); + goto out; + } + + s = set_inst_properties(broker, inst); + + if (is_get_inst) { + s = cu_validate_ref(broker, ref, inst); + if (s.rc != CMPI_RC_OK) + goto out; + } + + *_inst = inst; + out: + virConnectClose(conn); + + return s; +} + +static CMPIStatus return_vss_cap(const CMPIObjectPath *ref, + const CMPIResult *results, + bool names_only, + bool is_get_inst) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIInstance *inst = NULL; + + s = get_vss_cap(_BROKER, ref, &inst, is_get_inst); + if ((s.rc != CMPI_RC_OK) || (inst == NULL)) + goto out; + + if (names_only) + cu_return_instance_name(results, inst); + else + CMReturnInstance(results, inst); + out: + return s; +} + +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference) +{ + return return_vss_cap(reference, results, true, false); +} + +static CMPIStatus EnumInstances(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + + return return_vss_cap(reference, results, false, false); +} + +static CMPIStatus GetInstance(CMPIInstanceMI *self, + const CMPIContext *context, + const CMPIResult *results, + const CMPIObjectPath *reference, + const char **properties) +{ + return return_vss_cap(reference, results, false, true); +} + +DEFAULT_CI(); +DEFAULT_MI(); +DEFAULT_DI(); +DEFAULT_EQ(); +DEFAULT_INST_CLEANUP(); + +STD_InstanceMIStub(, + Virt_VirtualSystemSnapshotServiceCapabilities, + _BROKER, + libvirt_cim_init()); + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053674 28800 # Node ID 0f1a316b04aca1fa962f624444ae57b960fc2a37 # Parent fce1a31a53090b42dbfbd788a6db2a1164636197 Add VirtualSystemSnapshotCapabilities
Signed-off-by: Dan Smith <danms@us.ibm.com>
diff -r fce1a31a5309 -r 0f1a316b04ac src/Virt_VirtualSystemSnapshotServiceCapabilities.c
+ +static CMPIStatus set_inst_properties(const CMPIBroker *broker, + CMPIInstance *inst) +{
+ + array = CMNewArray(broker, 2, CMPI_uint16, &s); + if ((s.rc != CMPI_RC_OK) || (array == NULL)) + goto out; + + element = (uint16_t)CIM_VSSS_SNAPSHOT_MEM; + CMSetArrayElementAt(array, 0, &element, CMPI_uint16); + + element = (uint16_t)CIM_VSSS_SNAPSHOT_MEMT; + CMSetArrayElementAt(array, 1, &element, CMPI_uint16);
These should be VIR_VSSS_SNAPSHOT_MEM and VIR_VSSS_SNAPSHOT_MEMT
+ + CMSetProperty(inst, "SnapshotTypesSupported", + (CMPIValue *)&array, CMPI_uint16A); + + out: + return s; +} +
-- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com

KR> These should be VIR_VSSS_SNAPSHOT_MEM and VIR_VSSS_SNAPSHOT_MEMT I just realized that these compile errors weren't caught because my build changes were in a separate patch after the code. Thus, I would recompile to test changes, but not actually include the new stuff in the compile. /me is a super-genius Thanks :) -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com

Dan Smith wrote:
+++ b/src/Virt_VirtualSystemSnapshotServiceCapabilities.c Tue Feb 26 11:21:14 2008 -0800 @@ -0,0 +1,204 @@ +/* + * Copyright IBM Corp. 2007
2008 ;)
+static CMPIStatus get_vss_cap(const CMPIBroker *broker, + const CMPIObjectPath *ref, + CMPIInstance **_inst, + bool is_get_inst)
As this function is already prepared for external use (e.g. by ElementCapabilities), it makes sense to remove the static and also add the header file right with this patch set. Other than that ... looks very good. Thanks for using the updated interfaces :). -- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053694 28800 # Node ID ce18bd2b2708e263dd03fbcd3e94ce21182e847d # Parent 0f1a316b04aca1fa962f624444ae57b960fc2a37 Add VirtualSystemSnapshotService{,Capabilities} build support Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 0f1a316b04ac -r ce18bd2b2708 Makefile.am --- a/Makefile.am Tue Feb 26 11:21:14 2008 -0800 +++ b/Makefile.am Tue Feb 26 11:21:34 2008 -0800 @@ -37,7 +37,9 @@ MOFS = \ schema/ElementSettingData.mof \ schema/VSMigrationCapabilities.mof \ schema/VSMigrationService.mof \ - schema/VSMigrationSettingData.mof + schema/VSMigrationSettingData.mof \ + schema/VirtualSystemSnapshotService.mof \ + schema/VirtualSystemSnapshotServiceCapabilities.mof INTEROP_MOFS = \ schema/ComputerSystem.mof \ @@ -81,7 +83,9 @@ REGS = \ schema/VSMigrationCapabilities.registration \ schema/VSMigrationService.registration \ schema/ElementConformsToProfile.registration \ - schema/VSMigrationSettingData.registration + schema/VSMigrationSettingData.registration \ + schema/VirtualSystemSnapshotService.registration \ + schema/VirtualSystemSnapshotServiceCapabilities.registration INTEROP_REGS = \ schema/RegisteredProfile.registration \ diff -r 0f1a316b04ac -r ce18bd2b2708 schema/VirtualSystemSnapshotService.mof --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/schema/VirtualSystemSnapshotService.mof Tue Feb 26 11:21:34 2008 -0800 @@ -0,0 +1,7 @@ +// Copyright IBM Corp. 2008 + +[Description ( "Snapshot types are as follows: " + "32768: Memory-only snapshot (suspend, resume, keep image)" + "32769: Memory-only, terminal (domain is offline after op)")] +class Xen_VirtualSystemSnapshotService : CIM_VirtualSystemSnapshotService { }; +class KVM_VirtualSystemSnapshotService : CIM_VirtualSystemSnapshotService { }; diff -r 0f1a316b04ac -r ce18bd2b2708 schema/VirtualSystemSnapshotService.registration --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/schema/VirtualSystemSnapshotService.registration Tue Feb 26 11:21:34 2008 -0800 @@ -0,0 +1,4 @@ +# Copyright IBM Corp. 2007 +# Classname Namespace ProviderName ProviderModule ProviderTypes +Xen_VirtualSystemSnapshotService root/virt Virt_VirtualSystemSnapshotService Virt_VirtualSystemSnapshotService method +KVM_VirtualSystemSnapshotService root/virt Virt_VirtualSystemSnapshotService Virt_VirtualSystemSnapshotService method diff -r 0f1a316b04ac -r ce18bd2b2708 src/Makefile.am --- a/src/Makefile.am Tue Feb 26 11:21:14 2008 -0800 +++ b/src/Makefile.am Tue Feb 26 11:21:34 2008 -0800 @@ -17,7 +17,8 @@ noinst_HEADERS = profiles.h svpc_types.h Virt_VSSD.h \ Virt_VSMigrationCapabilities.h \ Virt_VSMigrationService.h \ - Virt_AllocationCapabilities.h + Virt_AllocationCapabilities.h \ + Virt_VirtualSystemSnapshotService.h XKUADD = $(top_builddir)/libxkutil/libxkutil.la @@ -56,7 +57,9 @@ provider_LTLIBRARIES = libVirt_ComputerS libVirt_ElementSettingData.la \ libVirt_VSMigrationCapabilities.la \ libVirt_VSMigrationService.la \ - libVirt_VSMigrationSettingData.la + libVirt_VSMigrationSettingData.la \ + libVirt_VirtualSystemSnapshotService.la \ + libVirt_VirtualSystemSnapshotServiceCapabilities.la libVirt_ComputerSystem_la_SOURCES = Virt_ComputerSystem.c libVirt_Device_la_SOURCES = Virt_Device.c @@ -161,3 +164,10 @@ libVirt_VSMigrationService_la_LIBADD = - libVirt_VSMigrationSettingData_la_SOURCES = Virt_VSMigrationSettingData.c +libVirt_VirtualSystemSnapshotService_la_DEPENDENCIES = +libVirt_VirtualSystemSnapshotService_la_SOURCES = Virt_VirtualSystemSnapshotService.c +libVirt_VirtualSystemSnapshotService_la_LIBADD = + +libVirt_VirtualSystemSnapshotServiceCapabilities_la_DEPENDENCIES = +libVirt_VirtualSystemSnapshotServiceCapabilities_la_SOURCES = Virt_VirtualSystemSnapshotServiceCapabilities.c +libVirt_VirtualSystemSnapshotServiceCapabilities_la_LIBADD =

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1204053694 28800 # Node ID ce18bd2b2708e263dd03fbcd3e94ce21182e847d # Parent 0f1a316b04aca1fa962f624444ae57b960fc2a37 Add VirtualSystemSnapshotService{,Capabilities} build support
Signed-off-by: Dan Smith <danms@us.ibm.com>
diff -r 0f1a316b04ac -r ce18bd2b2708 Makefile.am --- a/Makefile.am Tue Feb 26 11:21:14 2008 -0800 +++ b/Makefile.am Tue Feb 26 11:21:34 2008 -0800 @@ -37,7 +37,9 @@ MOFS = \ schema/ElementSettingData.mof \ schema/VSMigrationCapabilities.mof \ schema/VSMigrationService.mof \ - schema/VSMigrationSettingData.mof + schema/VSMigrationSettingData.mof \ + schema/VirtualSystemSnapshotService.mof \ + schema/VirtualSystemSnapshotServiceCapabilities.mof
VirtualSystemSnapshotServiceCapabilities.mof is added here, but this patch doesn't add the corresponding mof file.
INTEROP_MOFS = \ schema/ComputerSystem.mof \ @@ -81,7 +83,9 @@ REGS = \ schema/VSMigrationCapabilities.registration \ schema/VSMigrationService.registration \ schema/ElementConformsToProfile.registration \ - schema/VSMigrationSettingData.registration + schema/VSMigrationSettingData.registration \ + schema/VirtualSystemSnapshotService.registration \ + schema/VirtualSystemSnapshotServiceCapabilities.registration
Same for registration. -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com

KR> VirtualSystemSnapshotServiceCapabilities.mof is added here, but KR> this patch doesn't add the corresponding mof file. Same for KR> registration. Aiee, this has been the set from hell. I'll fix it in the (obviously necessary) resend. -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com
participants (3)
-
Dan Smith
-
Heidi Eckhart
-
Kaitlin Rupert