static virStorageEncryptionPtr
virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
{
    xmlNodePtr *nodes = NULL;
    virStorageEncryptionPtr ret;
    char *format_str;
    int format, i, n;

    if (VIR_ALLOC(ret) < 0) {
        virReportOOMError();
        return NULL;
    }

    format_str = virXPathString("string(./@format)", ctxt);
    if (format_str == NULL) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("unknown volume encryption format"));
        goto cleanup;
    }
    format = virStorageEncryptionFormatTypeFromString(format_str);
    if (format < 0) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("unknown volume encryption format type %s"),
                       format_str);
        VIR_FREE(format_str);
        goto cleanup;
    }
    VIR_FREE(format_str);
    ret->format = format;

    n = virXPathNodeSet("./secret", ctxt, &nodes);
    if (n < 0){
        goto cleanup;
    }
    if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0) {
        virReportOOMError();
        goto cleanup;
    }
    ret->nsecrets = n;
    for (i = 0; i < n; i++) {
        ret->secrets[i] = virStorageEncryptionSecretParse(ctxt, nodes[i]);
        if (ret->secrets[i] == NULL)
            goto cleanup;
    }
    VIR_FREE(nodes);

    return ret;

  cleanup:
    VIR_FREE(nodes);
    virStorageEncryptionFree(ret);
    return NULL;
}
static virStorageEncryptionPtr
virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
{
    xmlNodePtr *nodes = NULL;
    virStorageEncryptionPtr ret;
    char *format_str = NULL;
    int n;
    size_t i;

    if (VIR_ALLOC(ret) < 0)
        return NULL;

    if (!(format_str = virXPathString("string(./@format)", ctxt))) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("unknown volume encryption format"));
        goto cleanup;
    }

    if ((ret->format =
         virStorageEncryptionFormatTypeFromString(format_str)) < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown volume encryption format type %s"),
                       format_str);
        goto cleanup;
    }
    VIR_FREE(format_str);

    if ((n = virXPathNodeSet("./secret", ctxt, &nodes)) < 0)
        goto cleanup;

    if (n > 0) {
        if (VIR_ALLOC_N(ret->secrets, n) < 0)
            goto cleanup;
        ret->nsecrets = n;

        for (i = 0; i < n; i++) {
            if (!(ret->secrets[i] =
                  virStorageEncryptionSecretParse(ctxt, nodes[i])))
                goto cleanup;
        }
        VIR_FREE(nodes);
    }

    return ret;

 cleanup:
    VIR_FREE(format_str);
    VIR_FREE(nodes);
    virStorageEncryptionFree(ret);
    return NULL;
}
static virStorageEncryptionPtr
virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
{
    xmlNodePtr *nodes = NULL;
    virStorageEncryptionPtr ret;
    char *format_str = NULL;
    int n;
    size_t i;

    if (VIR_ALLOC(ret) < 0)
        return NULL;

    if (!(format_str = virXPathString("string(./@format)", ctxt))) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("unknown volume encryption format"));
        goto cleanup;
    }

    if ((ret->format =
         virStorageEncryptionFormatTypeFromString(format_str)) < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown volume encryption format type %s"),
                       format_str);
        goto cleanup;
    }
    VIR_FREE(format_str);

    if ((n = virXPathNodeSet("./secret", ctxt, &nodes)) < 0)
        goto cleanup;

    if (n > 0) {
        if (VIR_ALLOC_N(ret->secrets, n) < 0)
            goto cleanup;
        ret->nsecrets = n;

        for (i = 0; i < n; i++) {
            if (!(ret->secrets[i] =
                  virStorageEncryptionSecretParse(ctxt, nodes[i])))
                goto cleanup;
        }
        VIR_FREE(nodes);
    }

    if (ret->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
        xmlNodePtr tmpnode;

        if ((tmpnode = virXPathNode("./cipher[1]", ctxt))) {
            if (virStorageEncryptionInfoParseCipher(tmpnode, &ret->encinfo) < 0)
                goto cleanup;
        }

        if ((tmpnode = virXPathNode("./ivgen[1]", ctxt))) {
            /* If no cipher node, then fail */
            if (!ret->encinfo.cipher_name) {
                virReportError(VIR_ERR_XML_ERROR, "%s",
                                _("ivgen element found, but cipher is missing"));
                goto cleanup;
            }

            if (virStorageEncryptionInfoParseIvgen(tmpnode, &ret->encinfo) < 0)
                goto cleanup;
        }
    }


    return ret;

 cleanup:
    VIR_FREE(format_str);
    VIR_FREE(nodes);
    virStorageEncryptionFree(ret);
    return NULL;
}