提交 a7c4202c 编写于 作者: O Osier Yang

qemu: Support discard for disk

QEMU introduced "discard" option for drive since commit a9384aff53,

<...>
@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and
controls whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap})
requests are ignored or passed to the filesystem.  Some machine types
may not support discard requests.
</...>

This patch exposes the support in libvirt.

QEMU supported "discard" for "-drive" since v1.5.0-rc0:

% git tag --contains a9384aff53
contains
v1.5.0-rc0
v1.5.0-rc1

So this only detects the capability bit using virQEMUCapsProbeQMPCommandLine.
上级 f60bd7c7
......@@ -1702,6 +1702,14 @@
network. By default copy-on-read is off.
<span class='since'>Since 0.9.10 (QEMU and KVM only)</span>
</li>
<li>
The optional <code>discard</code> attribute controls whether
to discard (also known as "trim" or "unmap") requests are
ignored or passed to the filesystem. The value can be either
"on" (allow the discard request to be passed) or "off" (ingore
the discard request).
<span class='since'>Since 1.0.6 (QEMU and KVM only)</span>
</li>
</ul>
</dd>
<dt><code>boot</code></dt>
......
......@@ -1311,6 +1311,9 @@
<optional>
<ref name="copy_on_read"/>
</optional>
<optional>
<ref name="discard"/>
</optional>
<empty/>
</element>
</define>
......@@ -1406,6 +1409,14 @@
<value>off</value>
</choice>
</attribute>
</define>
<define name="discard">
<attribute name='discard'>
<choice>
<value>on</value>
<value>off</value>
</choice>
</attribute>
</define>
<define name="controller">
<element name="controller">
......
......@@ -743,6 +743,10 @@ VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST,
VIR_ENUM_IMPL(virDomainTPMBackend, VIR_DOMAIN_TPM_TYPE_LAST,
"passthrough")
VIR_ENUM_IMPL(virDomainDiskDiscard, VIR_DOMAIN_DISK_DISCARD_LAST,
"default",
"on",
"off")
#define VIR_DOMAIN_XML_WRITE_FLAGS VIR_DOMAIN_XML_SECURE
#define VIR_DOMAIN_XML_READ_FLAGS VIR_DOMAIN_XML_INACTIVE
......@@ -4534,6 +4538,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
char *wwn = NULL;
char *vendor = NULL;
char *product = NULL;
char *discard = NULL;
int expected_secret_usage = -1;
int auth_secret_usage = -1;
......@@ -4761,6 +4766,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
ioeventfd = virXMLPropString(cur, "ioeventfd");
event_idx = virXMLPropString(cur, "event_idx");
copy_on_read = virXMLPropString(cur, "copy_on_read");
discard = virXMLPropString(cur, "discard");
} else if (!mirror && xmlStrEqual(cur->name, BAD_CAST "mirror") &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
char *ready;
......@@ -5207,6 +5213,14 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
def->copy_on_read = cor;
}
if (discard) {
if ((def->discard = virDomainDiskDiscardTypeFromString(discard)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk discard mode '%s'"), discard);
goto error;
}
}
if (devaddr) {
if (virDomainParseLegacyDeviceAddress(devaddr,
&def->info.addr.pci) < 0) {
......@@ -5326,6 +5340,7 @@ cleanup:
VIR_FREE(ioeventfd);
VIR_FREE(event_idx);
VIR_FREE(copy_on_read);
VIR_FREE(discard);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
......@@ -13658,6 +13673,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
const char *copy_on_read = virDomainVirtioEventIdxTypeToString(def->copy_on_read);
const char *sgio = virDomainDiskSGIOTypeToString(def->sgio);
const char *discard = virDomainDiskDiscardTypeToString(def->discard);
char uuidstr[VIR_UUID_STRING_BUFLEN];
......@@ -13734,6 +13750,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " event_idx='%s'", event_idx);
if (def->copy_on_read)
virBufferAsprintf(buf, " copy_on_read='%s'", copy_on_read);
if (def->discard)
virBufferAsprintf(buf, " discard='%s'", discard);
virBufferAddLit(buf, "/>\n");
}
......
......@@ -625,6 +625,14 @@ enum virDomainDiskSGIO {
VIR_DOMAIN_DISK_SGIO_LAST
};
enum virDomainDiskDiscard {
VIR_DOMAIN_DISK_DISCARD_DEFAULT = 0,
VIR_DOMAIN_DISK_DISCARD_ON,
VIR_DOMAIN_DISK_DISCARD_OFF,
VIR_DOMAIN_DISK_DISCARD_LAST
};
typedef struct _virDomainBlockIoTuneInfo virDomainBlockIoTuneInfo;
struct _virDomainBlockIoTuneInfo {
unsigned long long total_bytes_sec;
......@@ -707,6 +715,7 @@ struct _virDomainDiskDef {
bool rawio_specified;
int rawio; /* no = 0, yes = 1 */
int sgio; /* enum virDomainDiskSGIO */
int discard; /* enum virDomainDiskDiscard */
size_t nseclabels;
virSecurityDeviceLabelDefPtr *seclabels;
......@@ -2464,6 +2473,7 @@ VIR_ENUM_DECL(virDomainDiskIo)
VIR_ENUM_DECL(virDomainDiskSecretType)
VIR_ENUM_DECL(virDomainDiskSGIO)
VIR_ENUM_DECL(virDomainDiskTray)
VIR_ENUM_DECL(virDomainDiskDiscard)
VIR_ENUM_DECL(virDomainIoEventFd)
VIR_ENUM_DECL(virDomainVirtioEventIdx)
VIR_ENUM_DECL(virDomainDiskCopyOnRead)
......
......@@ -142,6 +142,7 @@ virDomainDiskDefFree;
virDomainDiskDefGenSecurityLabelDef;
virDomainDiskDefGetSecurityLabelDef;
virDomainDiskDeviceTypeToString;
virDomainDiskDiscardTypeToString;
virDomainDiskErrorPolicyTypeFromString;
virDomainDiskErrorPolicyTypeToString;
virDomainDiskFindByBusAndDst;
......
......@@ -229,6 +229,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"scsi-generic.bootindex", /* 145 */
"mem-merge",
"vnc-websocket",
"drive-discard",
);
struct _virQEMUCaps {
......@@ -2244,6 +2245,7 @@ struct virQEMUCapsCommandLineProps {
static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
{ "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
{ "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
};
static int
......
......@@ -186,6 +186,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX = 145, /* -device scsi-generic.bootindex */
QEMU_CAPS_MEM_MERGE = 146, /* -machine mem-merge */
QEMU_CAPS_VNC_WEBSOCKET = 147, /* -vnc x:y,websocket */
QEMU_CAPS_DRIVE_DISCARD = 148, /* -drive discard=off(ignore)|on(unmap) */
QEMU_CAPS_LAST, /* this must always be the last item */
};
......
......@@ -3274,6 +3274,17 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
}
}
if (disk->discard) {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_DISCARD)) {
virBufferAsprintf(&opt, ",discard=%s",
virDomainDiskDiscardTypeToString(disk->discard));
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("discard is not supported by this QEMU binary"));
goto error;
}
}
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
const char *wpolicy = NULL, *rpolicy = NULL;
......
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
/usr/bin/qemu -S -M pc-0.13 -m 1024 -smp 1 -nographic -nodefaults \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot dc -usb \
-drive file=/var/lib/libvirt/images/f14.img,if=none,id=drive-virtio-disk0,discard=on \
-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0 \
-drive file=/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso,if=none,media=cdrom,id=drive-ide0-1-0,discard=off \
-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
<domain type='qemu'>
<name>test</name>
<uuid>92d7a226-cfae-425b-a6d3-00bbf9ec5c9e</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-0.13'>hvm</type>
<boot dev='cdrom'/>
<boot dev='hd'/>
<bootmenu enable='yes'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' discard='on'/>
<source file='/var/lib/libvirt/images/f14.img'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw' discard='off'/>
<source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/>
<target dev='hdc' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<memballoon model='virtio'/>
</devices>
</domain>
......@@ -585,6 +585,9 @@ mymain(void)
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_COPY_ON_READ,
QEMU_CAPS_VIRTIO_TX_ALG, QEMU_CAPS_DEVICE,
QEMU_CAPS_VIRTIO_BLK_SCSI, QEMU_CAPS_VIRTIO_BLK_SG_IO);
DO_TEST("disk-drive-discard",
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_DISCARD,
QEMU_CAPS_DEVICE);
DO_TEST("disk-snapshot",
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT);
DO_TEST("event_idx",
......
......@@ -261,6 +261,8 @@ mymain(void)
DO_TEST("disk-scsi-disk-vpd");
DO_TEST("disk-source-pool");
DO_TEST("disk-drive-discard");
DO_TEST("virtio-rng-random");
DO_TEST("virtio-rng-egd");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册