[PATCH 0 of 4] #2 Add support for network pool creation

This just adds basic support for network pool creation. See individual patches for changes.

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1237338803 25200 # Node ID 177ae29d2ae5c1f9fe37e8cffb000bfeb2dc28af # Parent e810ca0c3e585a0b58b1da2e280fb69232a20be1 Add basic support for creating network pools. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r e810ca0c3e58 -r 177ae29d2ae5 libxkutil/Makefile.am --- a/libxkutil/Makefile.am Fri Mar 20 16:26:02 2009 -0700 +++ b/libxkutil/Makefile.am Tue Mar 17 18:13:23 2009 -0700 @@ -4,14 +4,15 @@ CFLAGS += $(CFLAGS_STRICT) -noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h infostore.h +noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h infostore.h \ + pool_parsing.h lib_LTLIBRARIES = libxkutil.la AM_LDFLAGS = -lvirt -luuid libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \ - xmlgen.c infostore.c + xmlgen.c infostore.c pool_parsing.c noinst_PROGRAMS = xml_parse_test diff -r e810ca0c3e58 -r 177ae29d2ae5 libxkutil/pool_parsing.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libxkutil/pool_parsing.c Tue Mar 17 18:13:23 2009 -0700 @@ -0,0 +1,70 @@ +/* + * Copyright IBM Corp. 2009 + * + * Authors: + * Kaitlin Rupert <karupert@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 <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> + +#include <libcmpiutil/libcmpiutil.h> + +#include "pool_parsing.h" +#include "../src/svpc_types.h" + +int define_pool(virConnectPtr conn, const char *xml, int res_type) +{ + int ret = 1; + + if (res_type == CIM_RES_TYPE_NET) { + virNetworkPtr ptr = virNetworkDefineXML(conn, xml); + if (ptr == NULL) { + CU_DEBUG("Unable to define virtual network"); + return 0; + } + + if (virNetworkCreate(ptr) != 0) { + CU_DEBUG("Unable to start virtual network"); + ret = 0; + + if (virNetworkUndefine(ptr) != 0) + CU_DEBUG("Unable to undefine virtual network"); + } + + virNetworkFree(ptr); + } + + return ret; +} + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ + diff -r e810ca0c3e58 -r 177ae29d2ae5 libxkutil/pool_parsing.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libxkutil/pool_parsing.h Tue Mar 17 18:13:23 2009 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright IBM Corp. 2009 + * + * Authors: + * Kaitlin Rupert <karupert@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 + */ +#ifndef __RES_POOLS_H_ +#define __RES_POOLS_H + +#include <stdint.h> +#include <stdbool.h> +#include <libvirt/libvirt.h> + +#include "../src/svpc_types.h" + +struct net_pool { + char *addr; + char *netmask; + char *ip_start; + char *ip_end; + char *forward_mode; + char *forward_dev; +}; + +struct virt_pool { + uint16_t type; + union { + struct net_pool net; + } pool_info; + char *id; +}; + +int define_pool(virConnectPtr conn, const char *xml, int res_type); + + +#endif + +/* + * Local Variables: + * mode: C + * c-set-style: "K&R" + * tab-width: 8 + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1237338803 25200 # Node ID e5f7a88bf9aa81e71232d3ef86b7572d9461997c # Parent 177ae29d2ae5c1f9fe37e8cffb000bfeb2dc28af (#2) Add logic to generate a pool XML to xmlgen.c Updates: -The pool ID should not be added as a property to the top level network tag. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 177ae29d2ae5 -r e5f7a88bf9aa libxkutil/xmlgen.c --- a/libxkutil/xmlgen.c Tue Mar 17 18:13:23 2009 -0700 +++ b/libxkutil/xmlgen.c Tue Mar 17 18:13:23 2009 -0700 @@ -38,6 +38,7 @@ #define XML_ERROR "Failed to allocate XML memory" typedef const char *(*devfn_t)(xmlNodePtr node, struct domain *dominfo); +typedef const char *(*poolfn_t)(xmlNodePtr node, struct virt_pool *pool); static char *disk_block_xml(xmlNodePtr root, struct disk_device *dev) { @@ -770,6 +771,114 @@ return xml; } +static const char *net_pool_xml(xmlNodePtr root, + struct virt_pool *_pool) +{ + xmlNodePtr net = NULL; + xmlNodePtr ip = NULL; + xmlNodePtr forward = NULL; + xmlNodePtr dhcp = NULL; + xmlNodePtr range = NULL; + const char *msg = NULL; + struct net_pool *pool = &_pool->pool_info.net; + + net = xmlNewChild(root, NULL, BAD_CAST "network", NULL); + if (net == NULL) + goto out; + + if (xmlNewChild(net, NULL, BAD_CAST "name", BAD_CAST _pool->id) == NULL) + goto out; + + if (xmlNewChild(net, NULL, BAD_CAST "bridge", NULL) == NULL) + goto out; + + if (pool->forward_mode != NULL) { + forward = xmlNewChild(net, NULL, BAD_CAST "forward", NULL); + if (forward == NULL) + goto out; + + if (xmlNewProp(forward, + BAD_CAST "mode", + BAD_CAST pool->forward_mode) == NULL) + goto out; + + if (pool->forward_dev != NULL) { + if (xmlNewProp(forward, + BAD_CAST "dev", + BAD_CAST pool->forward_dev) == NULL) + goto out; + } + } + + ip = xmlNewChild(net, NULL, BAD_CAST "ip", NULL); + if (ip == NULL) + goto out; + + if (xmlNewProp(ip, BAD_CAST "address", BAD_CAST pool->addr) == NULL) + goto out; + + if (xmlNewProp(ip, BAD_CAST "netmask", BAD_CAST pool->netmask) == NULL) + goto out; + + if ((pool->ip_start != NULL) && (pool->ip_end != NULL)) { + dhcp = xmlNewChild(ip, NULL, BAD_CAST "dhcp", NULL); + if (dhcp == NULL) + goto out; + + range = xmlNewChild(dhcp, NULL, BAD_CAST "range", NULL); + if (range == NULL) + goto out; + + if (xmlNewProp(range, + BAD_CAST "start", + BAD_CAST pool->ip_start) == NULL) + goto out; + + if (xmlNewProp(range, + BAD_CAST "end", + BAD_CAST pool->ip_end) == NULL) + goto out; + } + + out: + return msg; +} + +char *pool_to_xml(struct virt_pool *pool) { + char *xml = NULL; + xmlNodePtr root = NULL; + int type = pool->type; + const char *msg; + poolfn_t func; + + root = xmlNewNode(NULL, BAD_CAST "tmp"); + if (root == NULL) + goto out; + + switch (type) { + case CIM_RES_TYPE_NET: + func = net_pool_xml; + break; + default: + CU_DEBUG("pool_to_xml: invalid type specified: %d", type); + goto out; + } + + msg = func(root, pool); + if (msg != NULL) { + CU_DEBUG("Failed to create pool XML: %s", msg); + goto out; + } + + xml = tree_to_xml(root->children); + out: + CU_DEBUG("Created Device XML:\n%s\n", xml); + + xmlFreeNode(root); + + return xml; +} + /* * Local Variables: * mode: C diff -r 177ae29d2ae5 -r e5f7a88bf9aa libxkutil/xmlgen.h --- a/libxkutil/xmlgen.h Tue Mar 17 18:13:23 2009 -0700 +++ b/libxkutil/xmlgen.h Tue Mar 17 18:13:23 2009 -0700 @@ -22,6 +22,7 @@ #define __XMLGEN_H #include "device_parsing.h" +#include "pool_parsing.h" #include "cmpidt.h" @@ -33,4 +34,6 @@ char *system_to_xml(struct domain *dominfo); char *device_to_xml(struct virt_device *dev); +char *pool_to_xml(struct virt_pool *pool); + #endif

On Mon, Mar 23, 2009 at 12:50:29PM -0700, Kaitlin Rupert wrote: Sorry I sent the feedback on the previous iteration, but I think it still applies :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1237338803 25200 # Node ID 3a941b3f8c9d7f3da5bb344d81306d850dc76cdf # Parent e5f7a88bf9aa81e71232d3ef86b7572d9461997c (#2) Add RASDs to use when defining Network Pools Updates: -Don't remove the build target for Virt_ResourcePoolConfigurationCapabilities.c Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r e5f7a88bf9aa -r 3a941b3f8c9d schema/ResourceAllocationSettingData.mof --- a/schema/ResourceAllocationSettingData.mof Tue Mar 17 18:13:23 2009 -0700 +++ b/schema/ResourceAllocationSettingData.mof Tue Mar 17 18:13:23 2009 -0700 @@ -163,3 +163,35 @@ string BusType; }; +[Description ("Xen virtual pool settings"), + Provider("cmpi::Virt_RASD") +] +class Xen_NetPoolResourceAllocationSettingData : Xen_ResourceAllocationSettingData +{ + string Netmask; + string IPRangeStart; + string IPRangeEnd; + string ForwardMode; +}; + +[Description ("KVM virtual pool settings"), + Provider("cmpi::Virt_RASD") +] +class KVM_NetPoolResourceAllocationSettingData : KVM_ResourceAllocationSettingData +{ + string Netmask; + string IPRangeStart; + string IPRangeEnd; + string ForwardMode; +}; + +[Description ("LXC virtual pool settings"), + Provider("cmpi::Virt_RASD") +] +class LXC_NetPoolResourceAllocationSettingData : LXC_ResourceAllocationSettingData +{ + string Netmask; + string IPRangeStart; + string IPRangeEnd; + string ForwardMode; +}; diff -r e5f7a88bf9aa -r 3a941b3f8c9d src/Makefile.am --- a/src/Makefile.am Tue Mar 17 18:13:23 2009 -0700 +++ b/src/Makefile.am Tue Mar 17 18:13:23 2009 -0700 @@ -157,9 +157,11 @@ libVirt_RASD_la_SOURCES = Virt_RASD.c libVirt_RASD_la_LIBADD = -lVirt_Device -libVirt_ResourcePoolConfigurationService_la_DEPENDENCIES = libVirt_HostSystem.la +libVirt_ResourcePoolConfigurationService_la_DEPENDENCIES = libVirt_HostSystem.la libVirt_DevicePool.la libVirt_RASD.la libVirt_ResourcePoolConfigurationService_la_SOURCES = Virt_ResourcePoolConfigurationService.c -libVirt_ResourcePoolConfigurationService_la_LIBADD = -lVirt_HostSystem +libVirt_ResourcePoolConfigurationService_la_LIBADD = -lVirt_HostSystem \ + -lVirt_DevicePool \ + -lVirt_RASD libVirt_ResourcePoolConfigurationCapabilities_la_SOURCES = Virt_ResourcePoolConfigurationCapabilities.c diff -r e5f7a88bf9aa -r 3a941b3f8c9d src/Virt_RASD.c --- a/src/Virt_RASD.c Tue Mar 17 18:13:23 2009 -0700 +++ b/src/Virt_RASD.c Tue Mar 17 18:13:23 2009 -0700 @@ -526,7 +526,8 @@ if (STREQ(base, "DiskResourceAllocationSettingData")) *type = CIM_RES_TYPE_DISK; - else if (STREQ(base, "NetResourceAllocationSettingData")) + else if ((STREQ(base, "NetResourceAllocationSettingData")) || + (STREQ(base, "NetPoolResourceAllocationSettingData"))) *type = CIM_RES_TYPE_NET; else if (STREQ(base, "ProcResourceAllocationSettingData")) *type = CIM_RES_TYPE_PROC;

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1237338803 25200 # Node ID 60ea52c462457b4aa7289ae6baaa25a761141e07 # Parent 3a941b3f8c9d7f3da5bb344d81306d850dc76cdf 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. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 3a941b3f8c9d -r 60ea52c46245 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@us.ibm.com> + * Kaitlin Rupert <karupert@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,299 @@ #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 = strdup("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 = strdup("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 = strdup("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 = strdup("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("CreateResourcePool"); + + 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: + 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 +339,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 = {

Kaitlin Rupert wrote:
# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1237338803 25200 # Node ID 60ea52c462457b4aa7289ae6baaa25a761141e07 # Parent 3a941b3f8c9d7f3da5bb344d81306d850dc76cdf 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.
Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com>
diff -r 3a941b3f8c9d -r 60ea52c46245 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@us.ibm.com> + * Kaitlin Rupert <karupert@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,299 @@ #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 = strdup("192.168.122.1");
No need to do strdup here, since you strdup two lines after, no matter the result of cu_get_str_prop. Just do val = <string>
+ + 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 = strdup("255.255.255.0");
Same here
+ + 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 = strdup("192.168.122.2");
Same here
+ + 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 = strdup("192.168.122.254");
Same here
+ + free(pool->pool_info.net.ip_end); + pool->pool_info.net.ip_end = strdup(val);
If you plan to keep the duplicated strdups, you should free the alloc'ed memory here.
+ + return msg;
This will always return a NULL value. But you probably add this to be set when address validation fails, right?
+ +} + +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("CreateResourcePool"); + + 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);
You can use name directly, since the create_child_pool_parse_args already allocs memory for the name var. Or, if you decide to keep that way, free memory from the name var after this.
+ + 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: + free(xml); + free(full_id);
Missing free(msg), free(pool) How about free(inst)?
+ + 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 +339,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 = {
_______________________________________________ Libvirt-cim mailing list Libvirt-cim@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim
-- Richard Maciel, MSc IBM Linux Technology Center rmaciel@linux.vnet.ibm.com

+ + free(pool->pool_info.net.ip_end); + pool->pool_info.net.ip_end = strdup(val);
If you plan to keep the duplicated strdups, you should free the alloc'ed memory here.
Yuck.. this was a pretty sloppy patch set. Thanks for catching the strdup() bit!
+ + return msg;
This will always return a NULL value. But you probably add this to be set when address validation fails, right?
Right - it's possible that in the future one of these attributes (or a new attribute) will be mandatory.
+ + 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);
You can use name directly, since the create_child_pool_parse_args already allocs memory for the name var. Or, if you decide to keep that way, free memory from the name var after this.
There should a function to cleanup the virt_pool struct. I'll add that.
+ + 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: + free(xml); + free(full_id);
Missing free(msg), free(pool) How about free(inst)?
msg is a const - no need to free it. Good call on freeing the pool though - there should be a function that handles cleaning up the pool struct elements. -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com
participants (3)
-
Daniel Veillard
-
Kaitlin Rupert
-
Richard Maciel