virDomainDiskDefFormat(virBufferPtr buf,
                       virDomainDiskDefPtr def,
                       unsigned int flags,
                       virDomainXMLOptionPtr xmlopt)
{
    const char *type = virStorageTypeToString(def->src->type);
    const char *device = virDomainDiskDeviceTypeToString(def->device);
    const char *bus = virDomainDiskBusTypeToString(def->bus);
    const char *sgio = virDomainDeviceSGIOTypeToString(def->sgio);

    if (!type || !def->src->type) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected disk type %d"), def->src->type);
        return -1;
    }
    if (!device) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected disk device %d"), def->device);
        return -1;
    }
    if (!bus) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected disk bus %d"), def->bus);
        return -1;
    }
    if (!sgio) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unexpected disk sgio mode '%d'"), def->sgio);
        return -1;
    }

    virBufferAsprintf(buf,
                      "<disk type='%s' device='%s'",
                      type, device);

    if (def->model) {
        virBufferAsprintf(buf, " model='%s'",
                          virDomainDiskModelTypeToString(def->model));
    }

    if (def->rawio) {
        virBufferAsprintf(buf, " rawio='%s'",
                          virTristateBoolTypeToString(def->rawio));
    }

    if (def->sgio)
        virBufferAsprintf(buf, " sgio='%s'", sgio);

    if (def->snapshot &&
        !(def->snapshot == VIR_DOMAIN_SNAPSHOT_LOCATION_NONE &&
          def->src->readonly))
        virBufferAsprintf(buf, " snapshot='%s'",
                          virDomainSnapshotLocationTypeToString(def->snapshot));
    virBufferAddLit(buf, ">\n");
    virBufferAdjustIndent(buf, 2);

    if (virDomainDiskDefFormatDriver(buf, def) < 0)
        return -1;

    /* Format as child of <disk> if defined there; otherwise,
     * if defined as child of <source>, then format later */
    if (def->src->auth && !def->src->authInherited)
        virStorageAuthDefFormat(buf, def->src->auth);

    if (virDomainDiskSourceFormat(buf, def->src, "source", def->startupPolicy,
                                  true, flags, false, xmlopt) < 0)
        return -1;

    /* Don't format backingStore to inactive XMLs until the code for
     * persistent storage of backing chains is ready. */
    if (virDomainDiskBackingStoreFormat(buf, def->src, xmlopt, flags) < 0)
        return -1;

    virBufferEscapeString(buf, "<backenddomain name='%s'/>\n", def->domain_name);

    virDomainDiskGeometryDefFormat(buf, def);
    virDomainDiskBlockIoDefFormat(buf, def);

    if (virDomainDiskDefFormatMirror(buf, def, flags, xmlopt) < 0)
        return -1;

    virBufferAsprintf(buf, "<target dev='%s' bus='%s'",
                      def->dst, bus);
    if ((def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
         def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
        def->tray_status != VIR_DOMAIN_DISK_TRAY_CLOSED)
        virBufferAsprintf(buf, " tray='%s'",
                          virDomainDiskTrayTypeToString(def->tray_status));
    if (def->bus == VIR_DOMAIN_DISK_BUS_USB &&
        def->removable != VIR_TRISTATE_SWITCH_ABSENT) {
        virBufferAsprintf(buf, " removable='%s'",
                          virTristateSwitchTypeToString(def->removable));
    }
    virBufferAddLit(buf, "/>\n");

    if (virDomainDiskDefFormatIotune(buf, def) < 0)
        return -1;

    if (def->src->readonly)
        virBufferAddLit(buf, "<readonly/>\n");
    if (def->src->shared)
        virBufferAddLit(buf, "<shareable/>\n");
    if (def->transient)
        virBufferAddLit(buf, "<transient/>\n");
    virBufferEscapeString(buf, "<serial>%s</serial>\n", def->serial);
    virBufferEscapeString(buf, "<wwn>%s</wwn>\n", def->wwn);
    virBufferEscapeString(buf, "<vendor>%s</vendor>\n", def->vendor);
    virBufferEscapeString(buf, "<product>%s</product>\n", def->product);

    /* If originally found as a child of <disk>, then format thusly;
     * otherwise, will be formatted as child of <source> */
    if (def->src->encryption && !def->src->encryptionInherited &&
        virStorageEncryptionFormat(buf, def->src->encryption) < 0)
        return -1;
    if (virDomainDeviceInfoFormat(buf, &def->info,
                                  flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) < 0) {
        return -1;
    }

    if (virDomainDiskDefFormatPrivateData(buf, def, flags, xmlopt) < 0)
        return -1;

    virBufferAdjustIndent(buf, -2);
    virBufferAddLit(buf, "</disk>\n");
    return 0;
}