[Libvirt-cim] [PATCH 4 of 4] Add suport for CreateChildResourcePool
Richard Maciel
rmaciel at linux.vnet.ibm.com
Wed Mar 25 16:09:43 UTC 2009
Kaitlin Rupert wrote:
> # HG changeset patch
> # User Kaitlin Rupert <karupert at 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 at 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 at us.ibm.com>
> + * Kaitlin Rupert <karupert at 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 at redhat.com
> https://www.redhat.com/mailman/listinfo/libvirt-cim
--
Richard Maciel, MSc
IBM Linux Technology Center
rmaciel at linux.vnet.ibm.com
More information about the Libvirt-cim
mailing list