virDomainDiskSourceFormat(virBufferPtr buf,
                          virStorageSourcePtr src,
                          const char *element,
                          int policy,
                          bool attrIndex,
                          unsigned int flags,
                          bool formatsecrets,
                          virDomainXMLOptionPtr xmlopt)
{
    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);

    switch ((virStorageType)src->type) {
    case VIR_STORAGE_TYPE_FILE:
        virBufferEscapeString(&attrBuf, " file='%s'", src->path);
        break;

    case VIR_STORAGE_TYPE_BLOCK:
        virBufferEscapeString(&attrBuf, " dev='%s'", src->path);
        break;

    case VIR_STORAGE_TYPE_DIR:
        virBufferEscapeString(&attrBuf, " dir='%s'", src->path);
        break;

    case VIR_STORAGE_TYPE_NETWORK:
        if (virDomainDiskSourceFormatNetwork(&attrBuf, &childBuf,
                                             src, flags) < 0)
            return -1;
        break;

    case VIR_STORAGE_TYPE_VOLUME:
        if (src->srcpool) {
            virBufferEscapeString(&attrBuf, " pool='%s'", src->srcpool->pool);
            virBufferEscapeString(&attrBuf, " volume='%s'",
                                  src->srcpool->volume);
            if (src->srcpool->mode)
                virBufferAsprintf(&attrBuf, " mode='%s'",
                                  virStorageSourcePoolModeTypeToString(src->srcpool->mode));
        }

        break;

    case VIR_STORAGE_TYPE_NVME:
        virDomainDiskSourceNVMeFormat(&attrBuf, &childBuf, src->nvme);
        break;

    case VIR_STORAGE_TYPE_NONE:
    case VIR_STORAGE_TYPE_LAST:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected disk type %d"), src->type);
        return -1;
    }

    virDomainDiskSourceFormatSlices(&childBuf, src);

    if (src->type != VIR_STORAGE_TYPE_NETWORK)
        virDomainSourceDefFormatSeclabel(&childBuf, src->nseclabels,
                                         src->seclabels, flags);

    /* Storage Source formatting will not carry through the blunder
     * that disk source formatting had at one time to format the
     * <auth> for a volume source type. The <auth> information is
     * kept in the storage pool and would be overwritten anyway.
     * So avoid formatting it for volumes. */
    if (src->auth && (src->authInherited || formatsecrets) &&
        src->type != VIR_STORAGE_TYPE_VOLUME)
        virStorageAuthDefFormat(&childBuf, src->auth);

    /* If we found encryption as a child of <source>, then format it
     * as we found it. */
    if (src->encryption && (src->encryptionInherited || formatsecrets) &&
        virStorageEncryptionFormat(&childBuf, src->encryption) < 0)
        return -1;

    if (src->pr)
        virStoragePRDefFormat(&childBuf, src->pr,
                              flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE);
    if (policy && src->type != VIR_STORAGE_TYPE_NETWORK)
        virBufferEscapeString(&attrBuf, " startupPolicy='%s'",
                              virDomainStartupPolicyTypeToString(policy));

    if (attrIndex && src->id != 0)
        virBufferAsprintf(&attrBuf, " index='%u'", src->id);

    if (virDomainDiskSourceFormatPrivateData(&childBuf, src, flags, xmlopt) < 0)
        return -1;

    virXMLFormatElement(buf, element, &attrBuf, &childBuf);

    return 0;
}