# HG changeset patch
# User Kaitlin Rupert <karupert(a)us.ibm.com>
# Date 1237338803 25200
# Node ID 8e877a88eae107b741682e708fc9e0f713129de2
# Parent ed393e68e8997a324651fa923e36307bae80e0ce
(#2) Add suport for CreateChildResourcePool.
Right now this creates a standalone pool. Modifications need to be made so
there is a parent primordial pool, and all created network pools should be
concrete pools that are child pools of the primordial pool.
Updates from 1 to 2:
-No need to to use strdup() when assigning a value to a const char*
-Be sure to call cleanup_virt_pool() to free the items in the structure
Signed-off-by: Kaitlin Rupert <karupert(a)us.ibm.com>
diff -r ed393e68e899 -r 8e877a88eae1 src/Virt_ResourcePoolConfigurationService.c
--- a/src/Virt_ResourcePoolConfigurationService.c Tue Mar 17 18:13:23 2009 -0700
+++ b/src/Virt_ResourcePoolConfigurationService.c Tue Mar 17 18:13:23 2009 -0700
@@ -3,6 +3,7 @@
*
* Authors:
* Dan Smith <danms(a)us.ibm.com>
+ * Kaitlin Rupert <karupert(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
@@ -27,12 +28,301 @@
#include <libcmpiutil/std_instance.h>
#include "misc_util.h"
+#include "xmlgen.h"
+#include "svpc_types.h"
#include "Virt_HostSystem.h"
#include "Virt_ResourcePoolConfigurationService.h"
+#include "Virt_DevicePool.h"
+#include "Virt_RASD.h"
const static CMPIBroker *_BROKER;
+const char *DEF_POOL_NAME = "libvirt-cim-pool";
+
+static CMPIStatus create_child_pool_parse_args(const CMPIArgs *argsin,
+ const char **name,
+ CMPIArray **set,
+ CMPIArray **parent_arr)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ if (cu_get_str_arg(argsin, "ElementName", name) != CMPI_RC_OK) {
+ CU_DEBUG("No ElementName string argument");
+ *name = strdup(DEF_POOL_NAME);
+ }
+
+ if (cu_get_array_arg(argsin, "Settings", set) != CMPI_RC_OK) {
+ CU_DEBUG("Failed to get Settings array arg");
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Missing argument `Settings'");
+ goto out;
+ }
+
+ if (cu_get_array_arg(argsin, "ParentPool", parent_arr) != CMPI_RC_OK)
+ CU_DEBUG("No parent pool specified during pool creation");
+
+ out:
+ return s;
+}
+
+static const char *net_rasd_to_pool(CMPIInstance *inst,
+ struct virt_pool *pool,
+ const char *ns)
+{
+ const char *val = NULL;
+ const char *msg = NULL;
+
+ /*FIXME: Need to add validation of addresses if user specified */
+
+ if (cu_get_str_prop(inst, "Address", &val) != CMPI_RC_OK)
+ val = "192.168.122.1";
+
+ free(pool->pool_info.net.addr);
+ pool->pool_info.net.addr = strdup(val);
+
+ if (cu_get_str_prop(inst, "Netmask", &val) != CMPI_RC_OK)
+ val = "255.255.255.0";
+
+ free(pool->pool_info.net.netmask);
+ pool->pool_info.net.netmask = strdup(val);
+
+ if (cu_get_str_prop(inst, "IPRangeStart", &val) != CMPI_RC_OK)
+ val = "192.168.122.2";
+
+ free(pool->pool_info.net.ip_start);
+ pool->pool_info.net.ip_start = strdup(val);
+
+ if (cu_get_str_prop(inst, "IPRangeStart", &val) != CMPI_RC_OK)
+ val = "192.168.122.254";
+
+ free(pool->pool_info.net.ip_end);
+ pool->pool_info.net.ip_end = strdup(val);
+
+ return msg;
+
+}
+
+static const char *rasd_to_vpool(CMPIInstance *inst,
+ struct virt_pool *pool,
+ uint16_t type,
+ const char *ns)
+{
+ pool->type = type;
+
+ if (type == CIM_RES_TYPE_NET) {
+ return net_rasd_to_pool(inst, pool, ns);
+ }
+
+ pool->type = CIM_RES_TYPE_UNKNOWN;
+
+ return "Resource type not supported on this platform";
+}
+
+static const char *get_pool_properties(CMPIArray *settings,
+ struct virt_pool *pool)
+{
+ CMPIObjectPath *op;
+ CMPIData item;
+ CMPIInstance *inst;
+ const char *msg = NULL;
+ uint16_t type;
+ int count;
+
+ count = CMGetArrayCount(settings, NULL);
+ if (count < 1)
+ return "No resources specified";
+
+ if (count > 1)
+ CU_DEBUG("More than one RASD specified during pool creation");
+
+ item = CMGetArrayElementAt(settings, 0, NULL);
+ if (CMIsNullObject(item.value.inst))
+ return "Internal array error";
+
+ inst = item.value.inst;
+
+ op = CMGetObjectPath(inst, NULL);
+ if (op == NULL)
+ return "Unknown resource instance type";
+
+ if (res_type_from_rasd_classname(CLASSNAME(op), &type) != CMPI_RC_OK)
+ return "Unable to determine resource type";
+
+ if (type != CIM_RES_TYPE_NET)
+ return "Only network pools currently supported";
+
+ msg = rasd_to_vpool(inst, pool, type, NAMESPACE(op));
+
+ return msg;
+}
+
+static char *get_pool_id(int res_type,
+ const char *name)
+{
+ char *id = NULL;
+ const char *pool = NULL;
+
+ if (res_type == CIM_RES_TYPE_NET)
+ pool = "NetworkPool";
+ else if (res_type == CIM_RES_TYPE_DISK)
+ pool = "DiskPool";
+ else if (res_type == CIM_RES_TYPE_MEM)
+ pool = "MemoryPool";
+ else if (res_type == CIM_RES_TYPE_PROC)
+ pool = "ProcessorPool";
+ else if (res_type == CIM_RES_TYPE_GRAPHICS)
+ pool = "GraphicsPool";
+ else if (res_type == CIM_RES_TYPE_INPUT)
+ pool = "InputPool";
+ else
+ pool = "Unknown";
+
+ if (asprintf(&id, "%s/%s", pool, name) == -1) {
+ return NULL;
+ }
+
+ return id;
+}
+
+static CMPIInstance *connect_and_create(char *xml,
+ const CMPIObjectPath *ref,
+ const char *id,
+ int res_type,
+ CMPIStatus *s)
+{
+ virConnectPtr conn;
+ CMPIInstance *inst = NULL;
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(ref), s);
+ if (conn == NULL) {
+ CU_DEBUG("libvirt connection failed");
+ return NULL;
+ }
+
+ if (define_pool(conn, xml, res_type) == 0) {
+ virt_set_status(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ conn,
+ "Unable to create resource pool");
+ goto out;
+ }
+
+ *s = get_pool_by_name(_BROKER, ref, id, &inst);
+ if (s->rc != CMPI_RC_OK) {
+ CU_DEBUG("Failed to get new pool instance: %s", id);
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to lookup resulting pool");
+ }
+
+ out:
+ virConnectClose(conn);
+
+ return inst;
+}
+
+static CMPIStatus create_child_pool(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ uint32_t rc = CIM_SVPC_RETURN_FAILED;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ CMPIArray *set;
+ CMPIArray *parent_pools;
+ CMPIObjectPath *result;
+ struct virt_pool *pool = NULL;
+ const char *name = NULL;
+ const char *msg = NULL;
+ char *full_id = NULL;
+ char *xml = NULL;
+
+ CU_DEBUG("CreateChildResourcePool");
+
+ s = create_child_pool_parse_args(argsin, &name, &set,
&parent_pools);
+ if (s.rc != CMPI_RC_OK)
+ goto out;
+
+ pool = calloc(1, sizeof(*pool));
+ if (pool == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to allocate pool struct");
+ goto out;
+ }
+
+ msg = get_pool_properties(set, pool);
+ if (msg != NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Settings Error: %s", msg);
+
+ goto out;
+ }
+
+ full_id = get_pool_id(pool->type, name);
+ if (full_id == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to format resulting pool ID");
+ goto out;
+ }
+
+ s = get_pool_by_name(_BROKER, reference, full_id, &inst);
+ if (s.rc == CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Pool with that name already exists");
+ goto out;
+ }
+
+ pool->id = strdup(name);
+
+ xml = pool_to_xml(pool);
+ if (xml == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to generate XML for resource pool");
+ goto out;
+ }
+
+ CU_DEBUG("Pool XML:\n%s", xml);
+
+ inst = connect_and_create(xml, reference, full_id, pool->type, &s);
+ if (inst == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to create resource pool");
+ goto out;
+ }
+
+ result = CMGetObjectPath(inst, &s);
+ if ((result != NULL) && (s.rc == CMPI_RC_OK)) {
+ CMSetNameSpace(result, NAMESPACE(reference));
+ CMAddArg(argsout, "Pool", &result, CMPI_ref);
+ }
+
+ /* FIXME: Trigger indication here */
+
+ cu_statusf(_BROKER, &s, CMPI_RC_OK, "");
+ out:
+ cleanup_virt_pool(&pool);
+
+ free(xml);
+ free(full_id);
+
+ if (s.rc == CMPI_RC_OK)
+ rc = CIM_SVPC_RETURN_COMPLETED;
+ CMReturnData(results, &rc, CMPI_uint32);
+
+ return s;
+}
+
static CMPIStatus dummy_handler(CMPIMethodMI *self,
const CMPIContext *context,
const CMPIResult *results,
@@ -51,8 +341,12 @@
static struct method_handler CreateChildResourcePool = {
.name = "CreateChildResourcePool",
- .handler = dummy_handler,
- .args = { ARG_END },
+ .handler = create_child_pool,
+ .args = {{"ElementName", CMPI_string, true},
+ {"Settings", CMPI_instanceA, false},
+ {"ParentPool", CMPI_refA, true},
+ ARG_END
+ }
};
static struct method_handler AddResourcesToResourcePool = {