virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
                               xmlNodePtr cur)
{
    g_autofree char *tmp = NULL;

    def->driverName = virXMLPropString(cur, "name");

    if ((tmp = virXMLPropString(cur, "cache")) &&
        (def->cachemode = virDomainDiskCacheTypeFromString(tmp)) < 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk cache mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "error_policy")) &&
        (def->error_policy = virDomainDiskErrorPolicyTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk error policy '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "rerror_policy")) &&
        (((def->rerror_policy = virDomainDiskErrorPolicyTypeFromString(tmp)) <= 0) ||
         (def->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE))) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk read error policy '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "io")) &&
        (def->iomode = virDomainDiskIoTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk io mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "ioeventfd")) &&
        (def->ioeventfd = virTristateSwitchTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk ioeventfd mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "event_idx")) &&
        (def->event_idx = virTristateSwitchTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk event_idx mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "copy_on_read")) &&
        (def->copy_on_read = virTristateSwitchTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk copy_on_read mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "discard")) &&
        (def->discard = virDomainDiskDiscardTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown disk discard mode '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "iothread")) &&
        (virStrToLong_uip(tmp, NULL, 10, &def->iothread) < 0 ||
         def->iothread == 0)) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("Invalid iothread attribute in disk driver element: %s"),
                       tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "type"))) {
        if (STREQ(tmp, "aio")) {
            /* Xen back-compat */
            def->src->format = VIR_STORAGE_FILE_RAW;
        } else {
            if ((def->src->format = virStorageFileFormatTypeFromString(tmp)) <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unknown driver format value '%s'"), tmp);
                return -1;
            }
        }

        VIR_FREE(tmp);
    }

    if ((tmp = virXMLPropString(cur, "detect_zeroes")) &&
        (def->detect_zeroes = virDomainDiskDetectZeroesTypeFromString(tmp)) <= 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unknown driver detect_zeroes value '%s'"), tmp);
        return -1;
    }
    VIR_FREE(tmp);

    if ((tmp = virXMLPropString(cur, "queues")) &&
        virStrToLong_uip(tmp, NULL, 10, &def->queues) < 0) {
        virReportError(VIR_ERR_XML_ERROR,
                       _("'queues' attribute must be positive number: %s"),
                       tmp);
        return -1;
    }

    return 0;
}