* @src: disk source
* @legacy: use legacy formatting of attributes (for -drive / old qemus)
* @onlytarget: omit any data which does not identify the image itself
+ * @autoreadonly: use the auto-read-only feature of qemu
*
* Creates a JSON object describing the underlying storage or protocol of a
* storage source. Returns NULL on error and reports an appropriate error message.
virJSONValuePtr
qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
bool legacy,
- bool onlytarget)
+ bool onlytarget,
+ bool autoreadonly)
{
int actualType = virStorageSourceGetActualType(src);
VIR_AUTOPTR(virJSONValue) fileprops = NULL;
const char *driver = NULL;
+ virTristateBool aro = VIR_TRISTATE_BOOL_ABSENT;
+ virTristateBool ro = VIR_TRISTATE_BOOL_ABSENT;
+
+ if (autoreadonly) {
+ aro = VIR_TRISTATE_BOOL_YES;
+ } else {
+ if (src->readonly)
+ ro = VIR_TRISTATE_BOOL_YES;
+ else
+ ro = VIR_TRISTATE_BOOL_NO;
+ }
switch ((virStorageType)actualType) {
case VIR_STORAGE_TYPE_BLOCK:
return NULL;
if (virJSONValueObjectAdd(fileprops,
- "b:read-only", src->readonly,
+ "T:read-only", ro,
+ "T:auto-read-only", aro,
"s:discard", "unmap",
NULL) < 0)
return NULL;
/**
* qemuBlockStorageSourceAttachPrepareBlockdev:
* @src: storage source to prepare data from
+ * @autoreadonly: use 'auto-read-only' feature of qemu
*
* Creates a qemuBlockStorageSourceAttachData structure containing data to attach
* @src to a VM using the blockdev-add approach. Note that this function only
* error is reported
*/
qemuBlockStorageSourceAttachDataPtr
-qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src)
+qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src,
+ bool autoreadonly)
{
VIR_AUTOPTR(qemuBlockStorageSourceAttachData) data = NULL;
return NULL;
if (!(data->formatProps = qemuBlockStorageSourceGetBlockdevProps(src)) ||
- !(data->storageProps = qemuBlockStorageSourceGetBackendProps(src, false, false)))
+ !(data->storageProps = qemuBlockStorageSourceGetBackendProps(src, false,
+ false,
+ autoreadonly)))
return NULL;
data->storageNodeName = src->nodestorage;
virJSONValuePtr
qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
bool legacy,
- bool onlytarget);
+ bool onlytarget,
+ bool autoreadonly);
virURIPtr
qemuBlockStorageSourceGetURI(virStorageSourcePtr src);
qemuBlockStorageSourceAttachDataFree);
qemuBlockStorageSourceAttachDataPtr
-qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src);
+qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src,
+ bool autoreadonly);
qemuBlockStorageSourceAttachDataPtr
qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
virJSONValuePtr props;
virJSONValuePtr ret;
- if (!(props = qemuBlockStorageSourceGetBackendProps(src, true, false)))
+ if (!(props = qemuBlockStorageSourceGetBackendProps(src, true, false, false)))
return NULL;
if (virJSONValueObjectCreate(&ret, "a:file", &props, NULL) < 0) {
return NULL;
for (n = top; virStorageSourceIsBacking(n); n = n->backingStore) {
- if (!(elem = qemuBlockStorageSourceAttachPrepareBlockdev(n)))
+ if (!(elem = qemuBlockStorageSourceAttachPrepareBlockdev(n, true)))
return NULL;
if (qemuBuildStorageSourceAttachPrepareCommon(n, elem, qemuCaps) < 0)
virAsprintf(©src->nodeformat, "migration-%s-format", disk->dst) < 0)
goto cleanup;
- if (!(data = qemuBlockStorageSourceAttachPrepareBlockdev(copysrc)))
+ /* Migration via blockdev-mirror was supported sooner than the auto-read-only
+ * feature was added to qemu */
+ if (!(data = qemuBlockStorageSourceAttachPrepareBlockdev(copysrc, false)))
goto cleanup;
if (qemuDomainObjEnterMonitorAsync(driver, vm,
return -1;
}
- if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc, true, false))) {
+ if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc, true, false,
+ false))) {
fprintf(stderr, "failed to format disk source json\n");
return -1;
}
goto cleanup;
if (!(formatProps = qemuBlockStorageSourceGetBlockdevProps(n)) ||
- !(storageSrcOnlyProps = qemuBlockStorageSourceGetBackendProps(n, false, true)) ||
- !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false))) {
+ !(storageSrcOnlyProps = qemuBlockStorageSourceGetBackendProps(n, false, true, true)) ||
+ !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true))) {
if (!data->fail) {
VIR_TEST_VERBOSE("failed to generate qemu blockdev props\n");
goto cleanup;
"driver": "host_device",
"filename": "/dev/blah",
"node-name": "0123456789ABCDEF0123456789ABCDE",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"filename": "/dev/blah",
"pr-manager": "node-a-st-pr-alias",
"node-name": "node-a-st",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"floppy": true,
"rw": false,
"node-name": "node-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"floppy": false,
"rw": false,
"node-name": "node-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"filename": "/var/lib/libvirt/images/a",
"aio": "threads",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"filename": "/var/lib/libvirt/images/b",
"aio": "threads",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
}
],
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"filename": "/var/lib/libvirt/images/d",
"aio": "threads",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": true,
"no-flush": false
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": true,
"no-flush": false
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": true,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": false,
"no-flush": true
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": true
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": true
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": true
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": false,
"no-flush": false
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": false,
"no-flush": false
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": false
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
}
],
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/d",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/c",
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/d",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
}
],
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/d",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
}
],
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/d",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
}
],
"node-name": "node-c-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/d",
"node-name": "node-d-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/a",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/b",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1507297895",
"node-name": "#block004",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1484071872",
"node-name": "#block256",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483615252",
"node-name": "#block418",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483605924",
"node-name": "#block624",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483605920",
"node-name": "#block869",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483546244",
"node-name": "#block1047",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483545901",
"node-name": "#block1279",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483545313",
"node-name": "#block1444",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1483536402",
"node-name": "#block1602",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
"node-name": "#block1864",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1507297895",
"node-name": "#block004",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"driver": "file",
"filename": "/var/lib/libvirt/images/rhel7.3.1484071872",
"node-name": "#block256",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": true,
"no-flush": false
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/luks.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/var/lib/libvirt/images/i.img",
"node-name": "0123456789ABCDEF0123456789ABCDE",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"driver": "file",
"filename": "/path/to/i.img",
"node-name": "test2",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
},
"tls-creds": "node-a-s-tls0",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
"direct": false,
"no-flush": true
},
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"direct": false,
"no-flush": true
},
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
],
"key-secret": "node-a-s-secalias",
"node-name": "node-a-s",
- "read-only": false,
+ "auto-read-only": true,
"discard": "unmap"
}
{
"user": "testuser-iscsi",
"password-secret": "node-b-s-secalias",
"node-name": "node-b-s",
- "read-only": true,
+ "auto-read-only": true,
"discard": "unmap"
}
-boot strict=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1",\
-"node-name":"libvirt-1-storage","read-only":false,"discard":"unmap"}' \
+"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
"file":"libvirt-1-storage"}' \
-device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \
-boot strict=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1",\
-"node-name":"libvirt-1-storage","read-only":false,"discard":"unmap"}' \
+"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\
"file":"libvirt-1-storage"}' \
-device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \