[PATCH] Add ReferenceConfiguration support to VSMS

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1216672093 25200 # Node ID 427e74d2c45881820ee33b8b6cdeb9cff57a68c0 # Parent 542f77ab01389702ff1358f04b0d55c8f052067a Add ReferenceConfiguration support to VSMS This accomplishes that goal by doing a full get_dominfo() instead of a blank dominfo alloc in the event that the client passed in a ReferenceConfiguration object path. Also fix a few unchecked calloc() calls while touching them. Also make sure we're only ever editing the first memory or processor device in the list, during the domain building process. Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r 542f77ab0138 -r 427e74d2c458 src/Virt_VirtualSystemManagementService.c --- a/src/Virt_VirtualSystemManagementService.c Mon Jul 21 09:02:26 2008 -0700 +++ b/src/Virt_VirtualSystemManagementService.c Mon Jul 21 13:28:13 2008 -0700 @@ -68,24 +68,34 @@ static CMPIStatus define_system_parse_args(const CMPIArgs *argsin, CMPIInstance **sys, const char *ns, - CMPIArray **res) + CMPIArray **res, + CMPIObjectPath **refconf) { - CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + CMPIStatus s = {CMPI_RC_OK, NULL}; if (cu_get_inst_arg(argsin, "SystemSettings", sys) != CMPI_RC_OK) { CU_DEBUG("No SystemSettings string argument"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing argument `SystemSettings'"); goto out; } if (cu_get_array_arg(argsin, "ResourceSettings", res) != CMPI_RC_OK) { CU_DEBUG("Failed to get array arg"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing argument `ResourceSettings'"); goto out; } - cu_statusf(_BROKER, &s, - CMPI_RC_OK, - ""); + if (cu_get_ref_arg(argsin, "ReferenceConfiguration", refconf) != + CMPI_RC_OK) { + CU_DEBUG("Did not get ReferenceConfiguration arg"); + *refconf = NULL; + goto out; + } out: return s; } @@ -565,6 +575,20 @@ return msg; } +static bool make_space(struct virt_device **list, int cur, int new) +{ + struct virt_device *tmp; + + tmp = calloc(cur + new, sizeof(*tmp)); + if (tmp == NULL) + return false; + + memcpy(tmp, *list, sizeof(*tmp) * cur); + *list = tmp; + + return true; +} + static const char *classify_resources(CMPIArray *resources, const char *ns, struct domain *domain) @@ -573,17 +597,21 @@ uint16_t type; int count; - domain->dev_disk_ct = domain->dev_net_ct = 0; - domain->dev_vcpu_ct = domain->dev_mem_ct = 0; - count = CMGetArrayCount(resources, NULL); if (count < 1) return "No resources specified"; - domain->dev_disk = calloc(count, sizeof(struct virt_device)); - domain->dev_vcpu = calloc(count, sizeof(struct virt_device)); - domain->dev_mem = calloc(count, sizeof(struct virt_device)); - domain->dev_net = calloc(count, sizeof(struct virt_device)); + if (!make_space(&domain->dev_disk, domain->dev_disk_ct, count)) + return "Failed to alloc disk list"; + + if (!make_space(&domain->dev_vcpu, domain->dev_vcpu_ct, count)) + return "Failed to alloc vcpu list"; + + if (!make_space(&domain->dev_mem, domain->dev_mem_ct, count)) + return "Failed to alloc mem list"; + + if (!make_space(&domain->dev_net, domain->dev_net_ct, count)) + return "Failed to alloc net list"; for (i = 0; i < count; i++) { CMPIObjectPath *op; @@ -605,27 +633,29 @@ CMPI_RC_OK) return "Unable to determine resource type"; - if (type == CIM_RES_TYPE_PROC) + if (type == CIM_RES_TYPE_PROC) { + domain->dev_vcpu_ct = 1; msg = rasd_to_vdev(inst, domain, - &domain->dev_vcpu[domain->dev_vcpu_ct++], + &domain->dev_vcpu[0], ns); - else if (type == CIM_RES_TYPE_MEM) + } else if (type == CIM_RES_TYPE_MEM) { + domain->dev_mem_ct = 1; msg = rasd_to_vdev(inst, domain, - &domain->dev_mem[domain->dev_mem_ct++], + &domain->dev_mem[0], ns); - else if (type == CIM_RES_TYPE_DISK) + } else if (type == CIM_RES_TYPE_DISK) { msg = rasd_to_vdev(inst, domain, &domain->dev_disk[domain->dev_disk_ct++], ns); - else if (type == CIM_RES_TYPE_NET) + } else if (type == CIM_RES_TYPE_NET) { msg = rasd_to_vdev(inst, domain, &domain->dev_net[domain->dev_net_ct++], ns); - + } if (msg != NULL) return msg; @@ -722,23 +752,125 @@ return s; } +static CMPIStatus match_prefixes(const CMPIObjectPath *a, + const CMPIObjectPath *b) +{ + char *pfx1; + char *pfx2; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + pfx1 = class_prefix_name(CLASSNAME(a)); + pfx2 = class_prefix_name(CLASSNAME(b)); + + if ((pfx1 == NULL) || (pfx2 == NULL)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable compare ReferenceConfiguration prefix"); + goto out; + } + + if (!STREQ(pfx1, pfx2)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_CLASS, + "ReferenceConfiguration domain is not compatible"); + goto out; + } + out: + free(pfx1); + free(pfx2); + + return s; +} + +static CMPIStatus get_reference_domain(struct domain **domain, + const CMPIObjectPath *ref, + const CMPIObjectPath *refconf) +{ + virConnectPtr conn = NULL; + virDomainPtr dom = NULL; + const char *name; + CMPIStatus s; + int ret; + + s = match_prefixes(ref, refconf); + if (s.rc != CMPI_RC_OK) + return s; + + conn = connect_by_classname(_BROKER, CLASSNAME(refconf), &s); + if (conn == NULL) { + if (s.rc != CMPI_RC_OK) + return s; + else { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to connect to libvirt"); + return s; + } + } + + if (cu_get_str_path(refconf, "Name", &name) != CMPI_RC_OK) { + CU_DEBUG("Missing Name parameter"); + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_INVALID_PARAMETER, + "Missing `Name' from ReferenceConfiguration"); + goto out; + } + + CU_DEBUG("Referenced domain: %s", name); + + dom = virDomainLookupByName(conn, name); + if (dom == NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_NOT_FOUND, + "Referenced domain `%s' does not exist", name); + goto out; + } + + ret = get_dominfo(dom, domain); + if (ret == 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Error getting referenced configuration"); + goto out; + } + + /* Scrub the unique bits out of the reference domain config */ + free((*domain)->name); + (*domain)->name = NULL; + free((*domain)->uuid); + (*domain)->uuid = NULL; + + out: + virDomainFree(dom); + virConnectClose(conn); + + return s; +} + static CMPIInstance *create_system(CMPIInstance *vssd, CMPIArray *resources, const CMPIObjectPath *ref, + const CMPIObjectPath *refconf, CMPIStatus *s) { CMPIInstance *inst = NULL; char *xml = NULL; const char *msg = NULL; - struct domain *domain; + struct domain *domain = NULL; - domain = calloc(1, sizeof(*domain)); - if (domain == NULL) { - cu_statusf(_BROKER, s, - CMPI_RC_ERR_FAILED, - "Failed to allocate memory"); - goto out; + if (refconf != NULL) { + *s = get_reference_domain(&domain, ref, refconf); + if (s->rc != CMPI_RC_OK) + goto out; + } else { + domain = calloc(1, sizeof(*domain)); + if (domain == NULL) { + cu_statusf(_BROKER, s, + CMPI_RC_ERR_FAILED, + "Failed to allocate memory"); + goto out; + } } if (!vssd_to_domain(vssd, domain)) { @@ -795,6 +927,7 @@ const CMPIArgs *argsin, CMPIArgs *argsout) { + CMPIObjectPath *refconf; CMPIInstance *vssd; CMPIInstance *sys; CMPIArray *res; @@ -802,11 +935,15 @@ CU_DEBUG("DefineSystem"); - s = define_system_parse_args(argsin, &vssd, NAMESPACE(reference), &res); + s = define_system_parse_args(argsin, + &vssd, + NAMESPACE(reference), + &res, + &refconf); if (s.rc != CMPI_RC_OK) goto out; - sys = create_system(vssd, res, reference, &s); + sys = create_system(vssd, res, reference, refconf, &s); if (sys == NULL) goto out;

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1216672093 25200 # Node ID 427e74d2c45881820ee33b8b6cdeb9cff57a68c0 # Parent 542f77ab01389702ff1358f04b0d55c8f052067a Add ReferenceConfiguration support to VSMS
This accomplishes that goal by doing a full get_dominfo() instead of a blank dominfo alloc in the event that the client passed in a ReferenceConfiguration object path.
Also fix a few unchecked calloc() calls while touching them. Also make sure we're only ever editing the first memory or processor device in the list, during the domain building process.
Signed-off-by: Dan Smith <danms@us.ibm.com>
This looks good to me. I did some testing on my system as well. +1 -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com
participants (2)
-
Dan Smith
-
Kaitlin Rupert