# HG changeset patch
# User Dan Smith <danms(a)us.ibm.com>
# Date 1196711744 28800
# Node ID 5ba311c0a725a603bb0e30349ad95d429a88f500
# Parent 2e1935bc44ac74a96a210b0d6c1126e0f14081ef
Add VirtualSystemMigrationService
Signed-off-by: Dan Smith <danms(a)us.ibm.com>
diff -r 2e1935bc44ac -r 5ba311c0a725 src/Virt_VSMigrationService.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Virt_VSMigrationService.c Mon Dec 03 11:55:44 2007 -0800
@@ -0,0 +1,369 @@
+/*
+ * Copyright IBM Corp. 2007
+ *
+ * Authors:
+ * Dan Smith <danms(a)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 <string.h>
+
+#include <libvirt.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include "libcmpiutil.h"
+#include "misc_util.h"
+#include "std_instance.h"
+#include "std_invokemethod.h"
+
+#include "Virt_VSMigrationService.h"
+
+const static CMPIBroker *_BROKER;
+
+static CMPIStatus vs_migratable_host(CMPIMethodMI *self,
+ const CMPIContext *ctx,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ RETURN_UNSUPPORTED();
+}
+
+static CMPIStatus vs_migratable_system(CMPIMethodMI *self,
+ const CMPIContext *ctx,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ RETURN_UNSUPPORTED();
+}
+
+static const char *transport_from_ref(const CMPIObjectPath *ref)
+{
+ const char *cn;
+
+ cn = CLASSNAME(ref);
+
+ if (STARTS_WITH(cn, "Xen"))
+ return "xen+ssh";
+ else if (STARTS_WITH(cn, "KVM"))
+ return "qemu+ssh";
+ else
+ return NULL;
+}
+
+static char *dest_uri(const CMPIObjectPath *ref,
+ const char *dest)
+{
+ char *uri;
+ const char *tport = NULL;
+
+ tport = transport_from_ref(ref);
+ if (tport == NULL) {
+ CU_DEBUG("Failed to get transport for %s", CLASSNAME(ref));
+ return NULL;
+ }
+
+ if (asprintf(&uri, "%s://%s/", tport, dest) == -1)
+ uri = NULL;
+
+ return uri;
+}
+
+static CMPIStatus migrate_vs(const CMPIObjectPath *ref,
+ const char *domain,
+ const char *destination)
+{
+ CMPIStatus s;
+ virConnectPtr conn = NULL;
+ virConnectPtr dconn = NULL;
+ virDomainPtr dom = NULL;
+ virDomainPtr ddom = NULL;
+ char *uri = NULL;
+
+ uri = dest_uri(ref, destination);
+ if (uri == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to construct a valid libvirt URI");
+ goto out;
+ }
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(ref), &s);
+ if (conn == NULL)
+ goto out;
+
+ dom = virDomainLookupByName(conn, domain);
+ if (dom == NULL) {
+ CU_DEBUG("Failed to lookup `%s'", domain);
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to lookup domain `%s'", domain);
+ goto out;
+ }
+
+ dconn = virConnectOpen(uri);
+ if (conn == NULL) {
+ CU_DEBUG("Failed to connect to remote host (%s)", uri);
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to connect to remote host (%s)", uri);
+ goto out;
+ }
+
+ CMSetStatus(&s, CMPI_RC_OK);
+ CU_DEBUG("Migrating %s -> %s", domain, uri);
+
+ ddom = virDomainMigrate(dom, dconn, VIR_MIGRATE_LIVE, NULL, NULL, 0);
+ if (ddom == NULL) {
+ CU_DEBUG("Migration failed");
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Migration Failed");
+ goto out;
+ }
+
+ CU_DEBUG("Migration succeeded");
+ CMSetStatus(&s, CMPI_RC_OK);
+
+ out:
+ free(uri);
+ virDomainFree(dom);
+ virDomainFree(ddom);
+ virConnectClose(conn);
+ virConnectClose(dconn);
+
+ return s;
+}
+
+static CMPIStatus migrate_vs_host(CMPIMethodMI *self,
+ const CMPIContext *ctx,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s;
+ const char *dhost = NULL;
+ CMPIObjectPath *system;
+ const char *name = NULL;
+
+ cu_get_str_arg(argsin, "DestinationHost", &dhost);
+ cu_get_ref_arg(argsin, "ComputerSystem", &system);
+
+ if (cu_get_str_path(system, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing key (Name) in ComputerSystem");
+ return s;
+ }
+
+ return migrate_vs(ref, name, dhost);
+}
+
+static CMPIStatus migrate_vs_system(CMPIMethodMI *self,
+ const CMPIContext *ctx,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s;
+ CMPIObjectPath *dsys;
+ CMPIObjectPath *sys;
+ const char *dname;
+ const char *name;
+
+ cu_get_ref_arg(argsin, "DestinationSystem", &dsys);
+ cu_get_ref_arg(argsin, "ComputerSystem", &sys);
+
+ if (cu_get_str_path(dsys, "Name", &dname) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing key (Name) in DestinationSystem");
+ return s;
+ }
+
+ if (cu_get_str_path(sys, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing key (Name) in ComputerSystem");
+ return s;
+ }
+
+ return migrate_vs(ref, name, dname);
+}
+
+static struct method_handler vsimth = {
+ .name = "VirtualSystemIsMigratableToHost",
+ .handler = vs_migratable_host,
+ .args = {{"ComputerSystem", CMPI_ref},
+ {"DestinationHost", CMPI_string},
+ ARG_END
+ }
+};
+
+static struct method_handler vsimts = {
+ .name = "VirtualSystemIsMigratableToSystem",
+ .handler = vs_migratable_system,
+ .args = {{"ComputerSystem", CMPI_ref},
+ {"DestinationSystem", CMPI_ref},
+ ARG_END
+ }
+};
+
+static struct method_handler mvsth = {
+ .name = "MigrateVirtualSystemToHost",
+ .handler = migrate_vs_host,
+ .args = {{"ComputerSystem", CMPI_ref},
+ {"DestinationHost", CMPI_string},
+ ARG_END
+ }
+};
+
+static struct method_handler mvsts = {
+ .name = "MigrateVirtualSystemToSystem",
+ .handler = migrate_vs_system,
+ .args = {{"ComputerSystem", CMPI_ref},
+ {"DestinationSystem", CMPI_ref},
+ ARG_END
+ }
+};
+
+static struct method_handler *my_handlers[] = {
+ &vsimth,
+ &vsimts,
+ &mvsth,
+ &mvsts,
+ NULL
+};
+
+STDIM_MethodMIStub(, Virt_VSMigrationService, _BROKER,
+ libvirt_cim_init(), my_handlers);
+
+CMPIStatus get_migration_service(const CMPIObjectPath *ref,
+ CMPIInstance **_inst,
+ const CMPIBroker *broker)
+{
+ CMPIInstance *inst;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ inst = get_typed_instance(broker,
+ CLASSNAME(ref),
+ "VirtualSystemMigrationService",
+ NAMESPACE(ref));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get instance for %s", CLASSNAME(ref));
+ return s;
+ }
+
+ CMSetProperty(inst, "Name",
+ (CMPIValue *)"MigrationService", CMPI_chars);
+
+ *_inst = inst;
+
+ return s;
+}
+
+static CMPIStatus return_vsms(const CMPIObjectPath *ref,
+ const CMPIResult *results,
+ bool name_only)
+{
+ CMPIInstance *inst;
+ CMPIStatus s;
+
+ s = get_migration_service(ref, &inst, _BROKER);
+ if (s.rc == CMPI_RC_OK) {
+ if (name_only)
+ cu_return_instance_name(results, inst);
+ else
+ CMReturnInstance(results, inst);
+ }
+
+ return s;
+}
+
+static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref)
+{
+ return return_vsms(ref, results, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const char **properties)
+{
+
+ return return_vsms(ref, results, false);
+}
+
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const char **properties)
+{
+ CMPIInstance *inst;
+ CMPIStatus s;
+ const char *prop;
+
+ s = get_migration_service(ref, &inst, _BROKER);
+ if (s.rc != CMPI_RC_OK)
+ return s;
+
+ prop = cu_compare_ref(ref, inst);
+ if (prop != NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "No such instance (%s)", prop);
+ } else {
+ CMReturnInstance(results, inst);
+ }
+
+ return s;
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+STD_InstanceMIStub(, Virt_VSMigrationService,
+ _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:
+ */
diff -r 2e1935bc44ac -r 5ba311c0a725 src/Virt_VSMigrationService.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Virt_VSMigrationService.h Mon Dec 03 11:55:44 2007 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright IBM Corp. 2007
+ *
+ * Authors:
+ * Dan Smith <danms(a)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
+ */
+
+CMPIStatus get_migration_service(const CMPIObjectPath *reference,
+ CMPIInstance **_inst,
+ const CMPIBroker *broker);
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
+