Example #1
0
static int
virStorageEncryptionInfoParseCipher(xmlNodePtr info_node,
                                    virStorageEncryptionInfoDefPtr info)
{
    int ret = -1;
    char *size_str = NULL;

    if (!(info->cipher_name = virXMLPropString(info_node, "name"))) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("cipher info missing 'name' attribute"));
        goto cleanup;
    }

    if ((size_str = virXMLPropString(info_node, "size")) &&
        virStrToLong_uip(size_str, NULL, 10, &info->cipher_size) < 0) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("cannot parse cipher size: '%s'"),
                       size_str);
        goto cleanup;
    }

    if (!size_str) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("cipher info missing 'size' attribute"));
        goto cleanup;
    }

    info->cipher_mode = virXMLPropString(info_node, "mode");
    info->cipher_hash = virXMLPropString(info_node, "hash");

    ret = 0;

 cleanup:
    VIR_FREE(size_str);
    return ret;
}
Example #2
0
static int
virDomainNumatuneNodeParseXML(virDomainNumaPtr numa,
                              xmlXPathContextPtr ctxt)
{
    char *tmp = NULL;
    int n = 0;
    int ret = -1;
    size_t i = 0;
    xmlNodePtr *nodes = NULL;

    if ((n = virXPathNodeSet("./numatune/memnode", ctxt, &nodes)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Cannot extract memnode nodes"));
        goto cleanup;
    }

    if (!n)
        return 0;

    if (numa->memory.specified &&
        numa->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Per-node binding is not compatible with "
                         "automatic NUMA placement."));
        goto cleanup;
    }

    if (!numa->nmem_nodes) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("Element 'memnode' is invalid without "
                         "any guest NUMA cells"));
        goto cleanup;
    }

    for (i = 0; i < n; i++) {
        int mode = 0;
        unsigned int cellid = 0;
        virDomainNumaNodePtr mem_node = NULL;
        xmlNodePtr cur_node = nodes[i];

        tmp = virXMLPropString(cur_node, "cellid");
        if (!tmp) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("Missing required cellid attribute "
                             "in memnode element"));
            goto cleanup;
        }
        if (virStrToLong_uip(tmp, NULL, 10, &cellid) < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Invalid cellid attribute in memnode element: %s"),
                           tmp);
            goto cleanup;
        }
        VIR_FREE(tmp);

        if (cellid >= numa->nmem_nodes) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("Argument 'cellid' in memnode element must "
                             "correspond to existing guest's NUMA cell"));
            goto cleanup;
        }

        mem_node = &numa->mem_nodes[cellid];

        if (mem_node->nodeset) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Multiple memnode elements with cellid %u"),
                           cellid);
            goto cleanup;
        }

        tmp = virXMLPropString(cur_node, "mode");
        if (!tmp) {
            mem_node->mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
        } else {
            if ((mode = virDomainNumatuneMemModeTypeFromString(tmp)) < 0) {
                virReportError(VIR_ERR_XML_ERROR, "%s",
                               _("Invalid mode attribute in memnode element"));
                goto cleanup;
            }
            VIR_FREE(tmp);
            mem_node->mode = mode;
        }

        tmp = virXMLPropString(cur_node, "nodeset");
        if (!tmp) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("Missing required nodeset attribute "
                             "in memnode element"));
            goto cleanup;
        }
        if (virBitmapParse(tmp, 0, &mem_node->nodeset,
                           VIR_DOMAIN_CPUMASK_LEN) < 0)
            goto cleanup;

        if (virBitmapIsAllClear(mem_node->nodeset)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Invalid value of 'nodeset': %s"), tmp);
            goto cleanup;
        }
        VIR_FREE(tmp);
    }

    ret = 0;
 cleanup:
    VIR_FREE(nodes);
    VIR_FREE(tmp);
    return ret;
}
Example #3
0
int
virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
                            xmlXPathContextPtr ctxt)
{
    xmlNodePtr *nodes = NULL;
    xmlNodePtr oldNode = ctxt->node;
    char *tmp = NULL;
    int n;
    size_t i;
    int ret = -1;

    /* check if NUMA definition is present */
    if (!virXPathNode("./cpu/numa[1]", ctxt))
        return 0;

    if ((n = virXPathNodeSet("./cpu/numa[1]/cell", ctxt, &nodes)) <= 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("NUMA topology defined without NUMA cells"));
        goto cleanup;
    }

    if (VIR_ALLOC_N(def->mem_nodes, n) < 0)
        goto cleanup;
    def->nmem_nodes = n;

    for (i = 0; i < n; i++) {
        size_t j;
        int rc;
        unsigned int cur_cell = i;

        /* cells are in order of parsing or explicitly numbered */
        if ((tmp = virXMLPropString(nodes[i], "id"))) {
            if (virStrToLong_uip(tmp, NULL, 10, &cur_cell) < 0) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("Invalid 'id' attribute in NUMA cell: '%s'"),
                               tmp);
                goto cleanup;
            }

            if (cur_cell >= n) {
                virReportError(VIR_ERR_XML_ERROR, "%s",
                               _("Exactly one 'cell' element per guest "
                                 "NUMA cell allowed, non-contiguous ranges or "
                                 "ranges not starting from 0 are not allowed"));
                goto cleanup;
            }
        }
        VIR_FREE(tmp);

        if (def->mem_nodes[cur_cell].cpumask) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Duplicate NUMA cell info for cell id '%u'"),
                           cur_cell);
            goto cleanup;
        }

        if (!(tmp = virXMLPropString(nodes[i], "cpus"))) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("Missing 'cpus' attribute in NUMA cell"));
            goto cleanup;
        }

        if (virBitmapParse(tmp, 0, &def->mem_nodes[cur_cell].cpumask,
                           VIR_DOMAIN_CPUMASK_LEN) < 0)
            goto cleanup;

        if (virBitmapIsAllClear(def->mem_nodes[cur_cell].cpumask)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                          _("NUMA cell %d has no vCPUs assigned"), cur_cell);
            goto cleanup;
        }
        VIR_FREE(tmp);

        for (j = 0; j < i; j++) {
            if (virBitmapOverlaps(def->mem_nodes[j].cpumask,
                                  def->mem_nodes[i].cpumask)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("NUMA cells %zu and %zu have overlapping vCPU ids"), i, j);
                goto cleanup;
            }
        }

        ctxt->node = nodes[i];
        if (virDomainParseMemory("./@memory", "./@unit", ctxt,
                                 &def->mem_nodes[cur_cell].mem, true, false) < 0)
            goto cleanup;

        if ((tmp = virXMLPropString(nodes[i], "memAccess"))) {
            if ((rc = virNumaMemAccessTypeFromString(tmp)) <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("Invalid 'memAccess' attribute value '%s'"),
                               tmp);
                goto cleanup;
            }

            def->mem_nodes[cur_cell].memAccess = rc;
            VIR_FREE(tmp);
        }
    }

    ret = 0;

 cleanup:
    ctxt->node = oldNode;
    VIR_FREE(nodes);
    VIR_FREE(tmp);
    return ret;
}
Example #4
0
static int
virDomainNumaDefNodeDistanceParseXML(virDomainNumaPtr def,
                                     xmlXPathContextPtr ctxt,
                                     unsigned int cur_cell)
{
    int ret = -1;
    int sibling;
    char *tmp = NULL;
    xmlNodePtr *nodes = NULL;
    size_t i, ndistances = def->nmem_nodes;

    if (ndistances == 0)
        return 0;

    /* check if NUMA distances definition is present */
    if (!virXPathNode("./distances[1]", ctxt))
        return 0;

    if ((sibling = virXPathNodeSet("./distances[1]/sibling", ctxt, &nodes)) <= 0) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("NUMA distances defined without siblings"));
        goto cleanup;
    }

    for (i = 0; i < sibling; i++) {
        virDomainNumaDistancePtr ldist, rdist;
        unsigned int sibling_id, sibling_value;

        /* siblings are in order of parsing or explicitly numbered */
        if (!(tmp = virXMLPropString(nodes[i], "id"))) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Missing 'id' attribute in NUMA "
                             "distances under 'cell id %d'"),
                           cur_cell);
            goto cleanup;
        }

        /* The "id" needs to be applicable */
        if (virStrToLong_uip(tmp, NULL, 10, &sibling_id) < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Invalid 'id' attribute in NUMA "
                             "distances for sibling: '%s'"),
                           tmp);
            goto cleanup;
        }
        VIR_FREE(tmp);

        /* The "id" needs to be within numa/cell range */
        if (sibling_id >= ndistances) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("'sibling_id %d' does not refer to a "
                             "valid cell within NUMA 'cell id %d'"),
                           sibling_id, cur_cell);
            goto cleanup;
        }

        /* We need a locality value. Check and correct
         * distance to local and distance to remote node.
         */
        if (!(tmp = virXMLPropString(nodes[i], "value"))) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("Missing 'value' attribute in NUMA distances "
                             "under 'cell id %d' for 'sibling id %d'"),
                           cur_cell, sibling_id);
            goto cleanup;
        }

        /* The "value" needs to be applicable */
        if (virStrToLong_uip(tmp, NULL, 10, &sibling_value) < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("'value %s' is invalid for "
                             "'sibling id %d' under NUMA 'cell id %d'"),
                           tmp, sibling_id, cur_cell);
            goto cleanup;
        }
        VIR_FREE(tmp);

        /* Assure LOCAL_DISTANCE <= "value" <= UNREACHABLE
         * and correct LOCAL_DISTANCE setting if such applies.
         */
        if ((sibling_value < LOCAL_DISTANCE ||
             sibling_value > UNREACHABLE) ||
            (sibling_id == cur_cell &&
             sibling_value != LOCAL_DISTANCE) ||
            (sibling_id != cur_cell &&
             sibling_value == LOCAL_DISTANCE)) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("'value %d' is invalid for "
                             "'sibling id %d' under NUMA 'cell id %d'"),
                           sibling_value, sibling_id, cur_cell);
            goto cleanup;
        }

        /* Apply the local / remote distance */
        ldist = def->mem_nodes[cur_cell].distances;
        if (!ldist) {
            if (VIR_ALLOC_N(ldist, ndistances) < 0)
                goto cleanup;

            ldist[cur_cell].value = LOCAL_DISTANCE;
            ldist[cur_cell].cellid = cur_cell;
            def->mem_nodes[cur_cell].ndistances = ndistances;
            def->mem_nodes[cur_cell].distances = ldist;
        }

        ldist[sibling_id].cellid = sibling_id;
        ldist[sibling_id].value = sibling_value;

        /* Apply symmetry if none given */
        rdist = def->mem_nodes[sibling_id].distances;
        if (!rdist) {
            if (VIR_ALLOC_N(rdist, ndistances) < 0)
                goto cleanup;

            rdist[sibling_id].value = LOCAL_DISTANCE;
            rdist[sibling_id].cellid = sibling_id;
            def->mem_nodes[sibling_id].ndistances = ndistances;
            def->mem_nodes[sibling_id].distances = rdist;
        }

        rdist[cur_cell].cellid = cur_cell;
        if (!rdist[cur_cell].value)
            rdist[cur_cell].value = sibling_value;
    }

    ret = 0;

 cleanup:
    if (ret < 0) {
        for (i = 0; i < ndistances; i++)
            VIR_FREE(def->mem_nodes[i].distances);
        def->mem_nodes[i].ndistances = 0;
    }
    VIR_FREE(nodes);
    VIR_FREE(tmp);

    return ret;
}