[pushed][libvirt PATCH] Fix cpu-host-model test data
This was broken by the recent addition of vmx-* features. Signed-off-by: Tim Wiederhake --- .../cpu-host-model-fallback-kvm.x86_64-4.2.0.args | 2 +- .../cpu-host-model-fallback-kvm.x86_64-5.0.0.args | 2 +- .../cpu-host-model-fallback-kvm.x86_64-latest.args | 2 +- .../cpu-host-model-nofallback-kvm.x86_64-4.2.0.args | 2 +- .../cpu-host-model-nofallback-kvm.x86_64-5.0.0.args | 2 +- .../cpu-host-model-nofallback-kvm.x86_64-latest.args| 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-4.2.0.args b/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-4.2.0.args index e388d9..f5f0e818af 100644 --- a/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-4.2.0.args +++ b/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-4.2.0.args @@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes \ -machine pc-i440fx-4.2,usb=off,dump-guest-core=off \ -accel kvm \ --cpu Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,skip-l1dfl-vmentry=on,pschange-mc-no=on \ +-cpu Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,vmx-ins-outs=on,vmx-true-ctls=on,vmx-store-lma=on,vmx-activity-hlt=on,vmx-vmwrite-vmexit-fields=on,vmx-apicv-xapic=on,vmx-ept=on,vmx-desc-exit=on,vmx-rdtscp-exit=on,vmx-apicv-x2apic=on,vmx-vpid=on,vmx-wbinvd-exit=on,vmx-unrestricted-guest=on,vmx-rdrand-exit=on,vmx-invpcid-exit=on,vmx-vmfunc=on,vmx-shadow-vmcs=on,vmx-rdseed-exit=on,vmx-pml=on,vmx-xsaves=on,vmx-invvpid=on,vmx-invvpid-single-addr=on,vmx-invvpid-all-context=on,vmx-ept-execonly=on,vmx-page-walk-4=on,vmx-ept-2mb=on,vmx-ept-1gb=on,vmx-invept=on,vmx-eptad=on,vmx-invept-single-context=on,vmx-invept-all-context=on,vmx-intr-exit=on,vmx-nmi-exit=on,vmx-vnmi=on,vmx-preemption-timer=on,vmx-vintr-pending=on,vmx-tsc-offset=on,vmx-hlt-exit=on,vmx-invlpg-exit=on,vmx-mwait-exit=on,vmx-rdpmc-exit=on,vmx-rdtsc-exit=on,vmx-cr3-load-noexit=on,vmx-cr3-store-noexit=on,vmx-cr8-load-exit=on,vmx-cr8-store-exit=on,vmx-flexpriority=on,vmx-vnmi-pending=on,vmx-movdr-exit=on,vmx-io-exit=on,vmx-io-bitmap=on,vmx-mtf=on,vmx-msr-bitmap=on,vmx-monitor-exit=on,vmx-pause-exit=on,vmx-secondary-ctls=on,vmx-exit-nosave-debugctl=on,vmx-exit-ack-intr=on,vmx-exit-save-pat=on,vmx-exit-load-pat=on,vmx-exit-save-efer=on,vmx-exit-load-efer=on,vmx-exit-save-preemption-timer=on,vmx-entry-noload-debugctl=on,vmx-entry-ia32e-mode=on,vmx-entry-load-pat=on,vmx-entry-load-efer=on,vmx-eptp-switching=on \ -m size=219136k \ -overcommit mem-lock=off \ -smp 6,sockets=6,cores=1,threads=1 \ diff --git a/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-5.0.0.args b/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-5.0.0.args index f51c51bcb3..699f48fbaa 100644 --- a/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-5.0.0.args +++ b/tests/qemuxml2argvdata/cpu-host-model-fallback-kvm.x86_64-5.0.0.args @@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes \ -machine pc-i440fx-5.0,usb=off,dump-guest-core=off \ -accel kvm \ --cpu Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,skip-l1dfl-vmentry=on,pschange-mc-no=on \ +-cpu Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,vmx-ins-outs=on,vmx-true-ctls=on,vmx-store-lma=on,vmx-activity-hlt=on,vmx-vmwrite-vmexit-fields=on,vmx-apicv-xapic=on,vmx-ept=on,vmx-desc-exit=on,vmx-rdtscp-exit=on,vmx-apicv-x2apic=on,vmx-vpid=on,vmx-wbinvd-exit=on,vmx-unrestricted-guest=on,vmx-rdrand-exit=on,vmx-invpcid-exit=on,vmx-vmfunc=on,vmx-shadow-vmcs=on,vmx-rdseed-exit=on,vmx-pml=on,vmx-xsaves=on,vmx-invvpid=on,vmx-invvpid-single-addr=on,vmx-invvpid-all-context=on,vmx-ept-execonly=on,vmx-page-walk-4=on,vmx-ept-2mb=on,vmx-ept-1gb=on,vmx-invept=on,vmx-eptad=on,vmx-invept-single-context=on,vmx-invept-all-context=on,vmx-intr-exit=on,vmx-nmi-exit=on,vmx-vnmi=on,vmx-preemption-timer=on,vmx-vintr-pending=on,vmx-tsc-offset=on,vmx-hlt-exit=on,vmx-invlpg-exit=on,vmx-mwait-exit=on,vmx-rdpmc-exit=on,vmx-rdtsc-exit=on,vmx-cr3-load-noexit=on,vmx-cr3-store-noexit=on,vmx-cr8-load-exit=on,vmx-cr8-store-exit=on,vmx-flexpriority=on,vmx-vnmi-pending=on,vmx-movdr-exit=on,vmx-io-exit=on,vmx-io-bitmap=on,vmx-mtf=on,vmx-msr-bitmap=
[PATCH 0/7] storage_file_probe: Handle qcow2 images with 'protocol' driver name in 'backing file format' field (part 1 - the fix)
See 6/7 and 7/7 for the rationale. Further patches will be posted to refactor the rest of the parsers which are bitrotten. Peter Krempa (7): storage_file_probe: Remove unused state 'BACKING_STORE_ERROR' virStorageFileProbeGetMetadata: Do not partially skip probing of the image storage_file_probe: Remove BACKING_STORE_OK,BACKING_STORE_INVALID states virstoragetest: Use strings for storage type and format in output data virstoragetest: Format detected/unprocessed backing store format into output files virstoragetest: Add test cases for QCOW2 files with a protocol name as backing file format storage_file_probe: Treat qcow2 images with protocol drivers in backing store field as raw src/storage_file/storage_file_probe.c | 71 -- tests/virstoragetest.c| 19 - .../images/qcow2-protocol-backing-file.qcow2 | Bin 0 -> 196616 bytes .../images/qcow2-protocol-backing-nbd.qcow2 | Bin 0 -> 196616 bytes tests/virstoragetestdata/out/directory-dir| 5 +- tests/virstoragetestdata/out/directory-none | 5 +- tests/virstoragetestdata/out/directory-raw| 5 +- .../out/qcow2-auto_qcow2-qcow2_raw-raw| 5 +- .../out/qcow2-auto_raw-raw-relative | 5 +- .../out/qcow2-protocol-backing-file | 21 ++ .../out/qcow2-protocol-backing-nbd| 21 ++ .../out/qcow2-qcow2_nbd-raw | 10 ++- .../out/qcow2-qcow2_qcow2-auto| 10 ++- .../out/qcow2-qcow2_qcow2-qcow2_qcow2-auto| 15 ++-- .../out/qcow2-qcow2_qcow2-qcow2_raw-auto | 15 ++-- .../out/qcow2-qcow2_qcow2-qcow2_raw-raw | 15 ++-- .../out/qcow2-qcow2_raw-raw-relative | 10 ++- tests/virstoragetestdata/out/qcow2-symlinks | 15 ++-- tests/virstoragetestdata/out/qed-auto_raw | 5 +- tests/virstoragetestdata/out/qed-qed_raw | 10 ++- tests/virstoragetestdata/out/raw-auto | 5 +- tests/virstoragetestdata/out/raw-raw | 5 +- 22 files changed, 173 insertions(+), 99 deletions(-) create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-file create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-nbd -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 1/7] storage_file_probe: Remove unused state 'BACKING_STORE_ERROR'
None of the backing store parser functions actually use it. Remove it to avoid confusion. Signed-off-by: Peter Krempa --- src/storage_file/storage_file_probe.c | 4 1 file changed, 4 deletions(-) diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c index 19f77086da..c73f533d2d 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -46,7 +46,6 @@ enum lv_endian { enum { BACKING_STORE_OK, BACKING_STORE_INVALID, -BACKING_STORE_ERROR, }; #define FILE_TYPE_VERSIONS_LAST 3 @@ -963,9 +962,6 @@ virStorageFileProbeGetMetadata(virStorageSource *meta, if (store == BACKING_STORE_INVALID) return 0; - -if (store == BACKING_STORE_ERROR) -return -1; } g_clear_pointer(&meta->features, virBitmapFree); -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 2/7] virStorageFileProbeGetMetadata: Do not partially skip probing of the image
Since we consider the failure of parsing the backing store to be actually success based on the value we return to the caller, we should continue parsing also features and the 'compat' field so that we don't have a partial definition if e.g. the backing store format is not known. Signed-off-by: Peter Krempa --- src/storage_file/storage_file_probe.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c index c73f533d2d..4cf052c03d 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -955,13 +955,9 @@ virStorageFileProbeGetMetadata(virStorageSource *meta, VIR_FREE(meta->backingStoreRaw); if (fileTypeInfo[meta->format].getBackingStore != NULL) { -int store = fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw, - &format, - buf, len); +fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw, + &format, buf, len); meta->backingStoreRawFormat = format; - -if (store == BACKING_STORE_INVALID) -return 0; } g_clear_pointer(&meta->features, virBitmapFree); -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 3/7] storage_file_probe: Remove BACKING_STORE_OK,BACKING_STORE_INVALID states
Replace the return values by 0 because none of the callers care and some of the backing store parser functions return this state also in cases the rest of the code would consider as success. Subsequently the parsers will be refactored and proper error reporting returned. Signed-off-by: Peter Krempa --- src/storage_file/storage_file_probe.c | 51 --- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c index 4cf052c03d..16298f76c7 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -43,11 +43,6 @@ enum lv_endian { LV_BIG_ENDIAN /* 4321 */ }; -enum { -BACKING_STORE_OK, -BACKING_STORE_INVALID, -}; - #define FILE_TYPE_VERSIONS_LAST 3 struct FileEncryptionInfo { @@ -382,14 +377,14 @@ cowGetBackingStore(char **res, *format = VIR_STORAGE_FILE_AUTO; if (buf_size < 4+4+ COW_FILENAME_MAXLEN) -return BACKING_STORE_INVALID; +return 0; if (buf[4+4] == '\0') { /* cow_header_v2.backing_file[0] */ *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } *res = g_strndup((const char *)buf + 4 + 4, COW_FILENAME_MAXLEN); -return BACKING_STORE_OK; +return 0; } @@ -527,34 +522,34 @@ qcowXGetBackingStore(char **res, *format = VIR_STORAGE_FILE_AUTO; if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4) -return BACKING_STORE_INVALID; +return 0; offset = virReadBufInt64BE(buf + QCOWX_HDR_BACKING_FILE_OFFSET); if (offset > buf_size) -return BACKING_STORE_INVALID; +return 0; if (offset == 0) { *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } size = virReadBufInt32BE(buf + QCOWX_HDR_BACKING_FILE_SIZE); if (size == 0) { *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } if (size > 1023) -return BACKING_STORE_INVALID; +return 0; if (offset + size > buf_size || offset + size < offset) -return BACKING_STORE_INVALID; +return 0; *res = g_new0(char, size + 1); memcpy(*res, buf + offset, size); (*res)[size] = '\0'; if (qcow2GetExtensions(buf, buf_size, format) < 0) -return BACKING_STORE_INVALID; +return 0; -return BACKING_STORE_OK; +return 0; } @@ -582,7 +577,7 @@ vmdk4GetBackingStore(char **res, *format = VIR_STORAGE_FILE_AUTO; if (buf_size <= 0x200) -return BACKING_STORE_INVALID; +return 0; len = buf_size - 0x200; if (len >= VIR_STORAGE_MAX_HEADER) @@ -592,21 +587,21 @@ vmdk4GetBackingStore(char **res, start = strstr(desc, prefix); if (start == NULL) { *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } start += strlen(prefix); end = strchr(start, '"'); if (end == NULL) -return BACKING_STORE_INVALID; +return 0; if (end == start) { *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } *end = '\0'; *res = g_strdup(start); -return BACKING_STORE_OK; +return 0; } static int @@ -621,24 +616,24 @@ qedGetBackingStore(char **res, *res = NULL; /* Check if this image has a backing file */ if (buf_size < QED_HDR_FEATURES_OFFSET+8) -return BACKING_STORE_INVALID; +return 0; flags = virReadBufInt64LE(buf + QED_HDR_FEATURES_OFFSET); if (!(flags & QED_F_BACKING_FILE)) { *format = VIR_STORAGE_FILE_NONE; -return BACKING_STORE_OK; +return 0; } /* Parse the backing file */ if (buf_size < QED_HDR_BACKING_FILE_OFFSET+8) -return BACKING_STORE_INVALID; +return 0; offset = virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_OFFSET); if (offset > buf_size) -return BACKING_STORE_INVALID; +return 0; size = virReadBufInt32LE(buf + QED_HDR_BACKING_FILE_SIZE); if (size == 0) -return BACKING_STORE_OK; +return 0; if (offset + size > buf_size || offset + size < offset) -return BACKING_STORE_INVALID; +return 0; *res = g_new0(char, size + 1); memcpy(*res, buf + offset, size); (*res)[size] = '\0'; @@ -648,7 +643,7 @@ qedGetBackingStore(char **res, else *format = VIR_STORAGE_FILE_AUTO_SAFE; -return BACKING_STORE_OK; +return 0; } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 4/7] virstoragetest: Use strings for storage type and format in output data
Make it easier for the humans to read/compare the outputs. Signed-off-by: Peter Krempa --- tests/virstoragetest.c | 8 tests/virstoragetestdata/out/directory-dir | 4 ++-- tests/virstoragetestdata/out/directory-none | 4 ++-- tests/virstoragetestdata/out/directory-raw | 4 ++-- .../out/qcow2-auto_qcow2-qcow2_raw-raw | 4 ++-- .../out/qcow2-auto_raw-raw-relative | 4 ++-- tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw | 8 tests/virstoragetestdata/out/qcow2-qcow2_qcow2-auto | 8 .../out/qcow2-qcow2_qcow2-qcow2_qcow2-auto | 12 ++-- .../out/qcow2-qcow2_qcow2-qcow2_raw-auto | 12 ++-- .../out/qcow2-qcow2_qcow2-qcow2_raw-raw | 12 ++-- .../out/qcow2-qcow2_raw-raw-relative | 8 tests/virstoragetestdata/out/qcow2-symlinks | 12 ++-- tests/virstoragetestdata/out/qed-auto_raw| 4 ++-- tests/virstoragetestdata/out/qed-qed_raw | 8 tests/virstoragetestdata/out/raw-auto| 4 ++-- tests/virstoragetestdata/out/raw-raw | 4 ++-- 17 files changed, 60 insertions(+), 60 deletions(-) diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 11f7abbda6..c7421c55de 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -187,8 +187,8 @@ testStorageChain(const void *args) "capacity: %lld\n" "encryption: %d\n" "relPath:%s\n" - "type:%d\n" - "format:%d\n" + "type:%s\n" + "format:%s\n" "protocol:%s\n" "hostname:%s\n\n", strippedPath, @@ -196,8 +196,8 @@ testStorageChain(const void *args) elt->capacity, !!elt->encryption, strippedRelPath, - elt->type, - elt->format, + NULLSTR(virStorageTypeToString(elt->type)), + NULLSTR(virStorageFileFormatTypeToString(elt->format)), virStorageNetProtocolTypeToString(elt->protocol), NULLSTR(elt->nhosts ? elt->hosts[0].name : NULL)); } diff --git a/tests/virstoragetestdata/out/directory-dir b/tests/virstoragetestdata/out/directory-dir index 65b7b91912..298c6cfb4a 100644 --- a/tests/virstoragetestdata/out/directory-dir +++ b/tests/virstoragetestdata/out/directory-dir @@ -3,7 +3,7 @@ backingStoreRaw: capacity: 0 encryption: 0 relPath: -type:3 -format:2 +type:dir +format:dir protocol:none hostname: diff --git a/tests/virstoragetestdata/out/directory-none b/tests/virstoragetestdata/out/directory-none index 65b7b91912..298c6cfb4a 100644 --- a/tests/virstoragetestdata/out/directory-none +++ b/tests/virstoragetestdata/out/directory-none @@ -3,7 +3,7 @@ backingStoreRaw: capacity: 0 encryption: 0 relPath: -type:3 -format:2 +type:dir +format:dir protocol:none hostname: diff --git a/tests/virstoragetestdata/out/directory-raw b/tests/virstoragetestdata/out/directory-raw index 5def2c4b8b..42589746b8 100644 --- a/tests/virstoragetestdata/out/directory-raw +++ b/tests/virstoragetestdata/out/directory-raw @@ -3,7 +3,7 @@ backingStoreRaw: capacity: 0 encryption: 0 relPath: -type:3 -format:1 +type:dir +format:raw protocol:none hostname: diff --git a/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw b/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw index 2ea087592e..7c299542a4 100644 --- a/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw +++ b/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw @@ -3,7 +3,7 @@ backingStoreRaw: capacity: 0 encryption: 0 relPath: -type:1 -format:1 +type:file +format:raw protocol:none hostname: diff --git a/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative b/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative index f9afc138f0..9f8246900d 100644 --- a/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative +++ b/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative @@ -3,7 +3,7 @@ backingStoreRaw: capacity: 0 encryption: 0 relPath: -type:1 -format:1 +type:file +format:raw protocol:none hostname: diff --git a/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw b/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw index 08a93b9f32..761e65b234 100644 --- a/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw +++ b/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw @@ -3,8 +3,8 @@ backingStoreRaw: nbd+tcp://example.org:6000/blah capacity: 1024 encryption: 0 relPath: -type:1 -format:14 +type:file +format:qcow2 protocol:none hostname: @@ -13,7 +13,7 @@ backingStoreRaw: capacity: 0 encryptio
[PATCH 5/7] virstoragetest: Format detected/unprocessed backing store format into output files
Compare also the detected format of the backing file ('backingStoreRawFormat' field) into the outptu data for comparison with others. Since the ToString function can't convert VIR_STORAGE_FILE_AUTO use also the numeric value. Signed-off-by: Peter Krempa --- tests/virstoragetest.c | 3 +++ tests/virstoragetestdata/out/directory-dir | 1 + tests/virstoragetestdata/out/directory-none| 1 + tests/virstoragetestdata/out/directory-raw | 1 + tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw| 1 + tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative | 1 + tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw | 2 ++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-auto| 2 ++ .../virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_qcow2-auto | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_raw-auto | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_raw-raw | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_raw-raw-relative | 2 ++ tests/virstoragetestdata/out/qcow2-symlinks| 3 +++ tests/virstoragetestdata/out/qed-auto_raw | 1 + tests/virstoragetestdata/out/qed-qed_raw | 2 ++ tests/virstoragetestdata/out/raw-auto | 1 + tests/virstoragetestdata/out/raw-raw | 1 + 17 files changed, 31 insertions(+) diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index c7421c55de..c28a23e332 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -184,6 +184,7 @@ testStorageChain(const void *args) virBufferAsprintf(&buf, "path:%s\n" "backingStoreRaw: %s\n" + "backingStoreRawFormat: %s(%d)\n" "capacity: %lld\n" "encryption: %d\n" "relPath:%s\n" @@ -193,6 +194,8 @@ testStorageChain(const void *args) "hostname:%s\n\n", strippedPath, strippedBackingStoreRaw, + NULLSTR(virStorageFileFormatTypeToString(elt->backingStoreRawFormat)), + elt->backingStoreRawFormat, elt->capacity, !!elt->encryption, strippedRelPath, diff --git a/tests/virstoragetestdata/out/directory-dir b/tests/virstoragetestdata/out/directory-dir index 298c6cfb4a..c6a2fa3673 100644 --- a/tests/virstoragetestdata/out/directory-dir +++ b/tests/virstoragetestdata/out/directory-dir @@ -1,5 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/ backingStoreRaw: +backingStoreRawFormat: none(0) capacity: 0 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/directory-none b/tests/virstoragetestdata/out/directory-none index 298c6cfb4a..c6a2fa3673 100644 --- a/tests/virstoragetestdata/out/directory-none +++ b/tests/virstoragetestdata/out/directory-none @@ -1,5 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/ backingStoreRaw: +backingStoreRawFormat: none(0) capacity: 0 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/directory-raw b/tests/virstoragetestdata/out/directory-raw index 42589746b8..6e190c97f4 100644 --- a/tests/virstoragetestdata/out/directory-raw +++ b/tests/virstoragetestdata/out/directory-raw @@ -1,5 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/ backingStoreRaw: +backingStoreRawFormat: none(0) capacity: 0 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw b/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw index 7c299542a4..0540be0c09 100644 --- a/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw +++ b/tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw @@ -1,5 +1,6 @@ path:ABS_BUILDDIR/virstoragedata/wrap backingStoreRaw: +backingStoreRawFormat: none(0) capacity: 0 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative b/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative index 9f8246900d..e145cca417 100644 --- a/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative +++ b/tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative @@ -1,5 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/qcow2_raw-raw-relative.qcow2 backingStoreRaw: +backingStoreRawFormat: none(0) capacity: 0 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw b/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw index 761e65b234..0c2bb0ddc4 100644 --- a/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw +++ b/tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw @@ -1,5 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/qcow2_nbd-raw.qcow2 backingStoreRaw: nbd+tcp://example.org:6000/blah +backingStoreRawFormat: r
[PATCH 6/7] virstoragetest: Add test cases for QCOW2 files with a protocol name as backing file format
QEMU allows and in cases where you omit the not-strictly-needed 'raw' driver on top of raw images automatically uses the protocol name inside of the 'backing file format' field of the qcow2 image. Libvirt expects only format names in that field. Add example images showing this scenario, which will be fixed later. The qcow2 image files in this commit were formatted as: qemu-img create -f qcow2 -F nbd -b nbd+tcp://example.org:6000/blah -u qcow2-protocol-backing-nbd.qcow2 10M and qemu-img create -f qcow2 -F file -b raw qcow2-protocol-backing-file.qcow2 thus using 'nbd' and 'file' as backing format respectively. (note that '-b raw' refers to the file in the example image folder) To satisfy the test, note that the NBD image is also rejected as we can't probe it, thus such configuration would not work. Signed-off-by: Peter Krempa --- tests/virstoragetest.c| 8 +++ .../images/qcow2-protocol-backing-file.qcow2 | Bin 0 -> 196616 bytes .../images/qcow2-protocol-backing-nbd.qcow2 | Bin 0 -> 196616 bytes .../out/qcow2-protocol-backing-file | 21 ++ 4 files changed, 29 insertions(+) create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-file diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index c28a23e332..53533d5885 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -478,6 +478,14 @@ mymain(void) abs_srcdir "/virstoragetestdata/images/qcow2_qcow2-auto.qcow2", VIR_STORAGE_FILE_QCOW2, EXP_PASS); +/* QCOW2 with protocol recorded inside the 'backing file format field */ +TEST_CHAIN("qcow2-protocol-backing-file", + abs_srcdir "/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2", + VIR_STORAGE_FILE_QCOW2, EXP_PASS); +TEST_CHAIN("qcow2-protocol-backing-nbd", + abs_srcdir "/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2", + VIR_STORAGE_FILE_QCOW2, EXP_FAIL); + /* Qcow2 file with missing backing file but specified type */ TEST_CHAIN("qcow2-qcow2_missing", abs_srcdir "/virstoragetestdata/images/qcow2_qcow2-missing.qcow2", diff --git a/tests/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 b/tests/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 new file mode 100644 index ..b3fe320f0f521820f2c4a614fed4cea18fdca55c GIT binary patch literal 196616 zcmeIuJx;?g6aZi+?EyGKW=0Nygv7$c9GX-_YLh4pf-rGDj=?FASaABIib`$S`#DN% zKR?@f-^1O$iVnK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ;4%e% E0pRvEvj6}9 literal 0 HcmV?d1 diff --git a/tests/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 b/tests/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 new file mode 100644 index ..0ae422d8f550cc6bacf3d4d757110177ce457865 GIT binary patch literal 196616 zcmeIv!EVzq00v+u-2?CjH+{fAMWuudtJpor#9|pHYh?@f8JLqUT=omKF>vu ztCV4q+1BGfgQq>qBGsR&Kh8Y!HIGBne|ecV(-1) +capacity: 1024 +encryption: 0 +relPath: +type:file +format:qcow2 +protocol:none +hostname: + +path:ABS_SRCDIR/virstoragetestdata/images/raw +backingStoreRaw: +backingStoreRawFormat: none(0) +capacity: 0 +encryption: 0 +relPath:raw +type:file +format:raw +protocol:none +hostname: -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 7/7] storage_file_probe: Treat qcow2 images with protocol drivers in backing store field as raw
qemu allows and in some cases uses protocol driver names ('file', 'host_device', 'nbd', ...) in the 'backing file format' field of a qcow to denote a image where the dummy 'raw' driver was not used on top. Adapt our backing store parser for such cases. The examples added in previous patch show the difference in behaviour. Signed-off-by: Peter Krempa --- src/storage_file/storage_file_probe.c | 8 ++- tests/virstoragetest.c| 2 +- .../out/qcow2-protocol-backing-file | 2 +- .../out/qcow2-protocol-backing-nbd| 21 +++ 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-nbd diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c index 16298f76c7..243927d50a 100644 --- a/src/storage_file/storage_file_probe.c +++ b/src/storage_file/storage_file_probe.c @@ -474,9 +474,15 @@ qcow2GetExtensions(const char *buf, memcpy(tmp, buf + offset, len); tmp[len] = '\0'; +/* qemu and qemu-img allow using the protocol driver name inside + * of the format field in cases when the dummy 'raw' driver should + * not be created. Thus libvirt needs to consider anything that + * doesn't look like a format driver name to be a protocol driver + * directly and thus the image is in fact still considered raw + */ *backingFormat = virStorageFileFormatTypeFromString(tmp); if (*backingFormat <= VIR_STORAGE_FILE_NONE) -return -1; +*backingFormat = VIR_STORAGE_FILE_RAW; break; } diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 53533d5885..d07a05d04b 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -484,7 +484,7 @@ mymain(void) VIR_STORAGE_FILE_QCOW2, EXP_PASS); TEST_CHAIN("qcow2-protocol-backing-nbd", abs_srcdir "/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2", - VIR_STORAGE_FILE_QCOW2, EXP_FAIL); + VIR_STORAGE_FILE_QCOW2, EXP_PASS); /* Qcow2 file with missing backing file but specified type */ TEST_CHAIN("qcow2-qcow2_missing", diff --git a/tests/virstoragetestdata/out/qcow2-protocol-backing-file b/tests/virstoragetestdata/out/qcow2-protocol-backing-file index b565bdba77..d9d4c1316c 100644 --- a/tests/virstoragetestdata/out/qcow2-protocol-backing-file +++ b/tests/virstoragetestdata/out/qcow2-protocol-backing-file @@ -1,6 +1,6 @@ path:ABS_SRCDIR/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 backingStoreRaw: raw -backingStoreRawFormat: (-1) +backingStoreRawFormat: raw(1) capacity: 1024 encryption: 0 relPath: diff --git a/tests/virstoragetestdata/out/qcow2-protocol-backing-nbd b/tests/virstoragetestdata/out/qcow2-protocol-backing-nbd new file mode 100644 index 00..360a496ab0 --- /dev/null +++ b/tests/virstoragetestdata/out/qcow2-protocol-backing-nbd @@ -0,0 +1,21 @@ +path:ABS_SRCDIR/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 +backingStoreRaw: nbd+tcp://example.org:6000/blah +backingStoreRawFormat: raw(1) +capacity: 10485760 +encryption: 0 +relPath: +type:file +format:qcow2 +protocol:none +hostname: + +path:blah +backingStoreRaw: +backingStoreRawFormat: none(0) +capacity: 0 +encryption: 0 +relPath: +type:network +format:raw +protocol:nbd +hostname:example.org -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 01/17] qemu: block: Introduce qemuBlockStorageSourceGetSliceNodename
The helper retrieves the nodename of the slice layer if it's present. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 23 --- src/qemu/qemu_block.h | 3 +++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index fab122942a..ea1af61561 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -101,6 +101,22 @@ qemuBlockStorageSourceGetEffectiveNodename(virStorageSource *src) } +/** + * qemuBlockStorageSourceGetSliceNodename: + * + * Gets the nodename corresponding to the storage slice layer. Returns NULL + * when there is no explicit storage slice layer. + */ +const char * +qemuBlockStorageSourceGetSliceNodename(virStorageSource *src) +{ +if (!src->sliceStorage) +return NULL; + +return src->sliceStorage->nodename; +} + + /** * qemuBlockStorageSourceGetEffectiveStorageNodename: * @src: virStorageSource to get the effective nodename of @@ -111,9 +127,10 @@ qemuBlockStorageSourceGetEffectiveNodename(virStorageSource *src) const char * qemuBlockStorageSourceGetEffectiveStorageNodename(virStorageSource *src) { -if (src->sliceStorage && -src->sliceStorage->nodename) -return src->sliceStorage->nodename; +const char *slice = qemuBlockStorageSourceGetSliceNodename(src); + +if (slice) +return slice; return src->nodenamestorage; } diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 5c784a4386..85616a140d 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -40,6 +40,9 @@ qemuBlockStorageSourceGetEffectiveStorageNodename(virStorageSource *src); const char * qemuBlockStorageSourceGetStorageNodename(virStorageSource *src); +const char * +qemuBlockStorageSourceGetSliceNodename(virStorageSource *src); + const char * qemuBlockStorageSourceGetFormatNodename(virStorageSource *src); -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 00/17] qemu: Prepare block device setup for removing the 'raw' driver ('raw' driver removal part 3)
This series prepares the setup of the block device backend for removal of the raw driver from the block graph, and actually removes it from the migration NBD connection. Unfortunately for normal usage it's not yet possible as qemu then records the protocol driver name in the backing file format field which would break with older versions of libvirt (see my other series). Peter Krempa (17): qemu: block: Introduce qemuBlockStorageSourceGetSliceNodename qemu: block: Use qemuBlockStorageSourceNeedsStorageSliceLayer only for setup qemu: block: Introduce helper for deciding when a 'format' layer is needed qemuBlockStorageSourceGetBlockdevStorageSliceProps: Allow turning the slice layer into effective blockdev layer qemuBlockStorageSourceAttachPrepareBlockdev: Prepare for optionally missing format layer qemuBlockStorageSourceDetachPrepare: Prepare for possibly missing 'format' layer qemuDomainPrepareStorageSourceBlockdevNodename: Restructure code to allow missing 'format' layer qemuBlockStorageSourceGetEffectiveNodename: Prepare for missing 'format' driver qemu: block: Extract logic from qemuBlockReopenReadWrite/ReadOnly qemu: block: Absorb logic from qemuBlockReopenFormat to qemuBlockReopenAccess qemu: monitor: Sanitize arguments of qemuMonitorBlockdevReopen testQemuMonitorJSONBlockdevReopen: Don't use qemuBlockReopenFormatMon qemu: block: Absorb qemuBlockReopenFormatMon into qemuBlockReopenAccess qemuBlockReopenAccess: prepare for removal of 'raw' format layer qemuMigrationSrcNBDCopyCancel: Use qemuBlockStorageSourceAttachRollback to detach migration NBD blockdevs qemu: block: Remove unused qemuBlockStorageSourceDetachOneBlockdev qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource: Don't setup 'raw' layer for migration NBD connection src/qemu/qemu_block.c| 257 ++- src/qemu/qemu_block.h| 16 +-- src/qemu/qemu_domain.c | 17 ++- src/qemu/qemu_migration.c| 19 ++- src/qemu/qemu_monitor.c | 7 +- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 6 +- src/qemu/qemu_monitor_json.h | 2 +- tests/qemumonitorjsontest.c | 10 +- 9 files changed, 185 insertions(+), 151 deletions(-) -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 02/17] qemu: block: Use qemuBlockStorageSourceNeedsStorageSliceLayer only for setup
Add a note stating that qemuBlockStorageSourceNeedsStorageSliceLayer must be used only when setting up a new blockdev, any other case when the device might been already set up must use the existance of the nodename to do so. Adjust qemuBlockStorageSourceAttachPrepareBlockdev to do so and refactor qemuBlockStorageSourceDetachPrepare to use the same logic. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index ea1af61561..1a718ae82b 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1535,11 +1535,9 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSource *src, data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src); -if (qemuBlockStorageSourceNeedsStorageSliceLayer(src)) { +if ((data->storageSliceNodeName = qemuBlockStorageSourceGetSliceNodename(src))) { if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src))) return NULL; - -data->storageSliceNodeName = src->sliceStorage->nodename; } return g_steal_pointer(&data); @@ -1756,13 +1754,8 @@ qemuBlockStorageSourceDetachPrepare(virStorageSource *src) data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); data->storageAttached = true; -/* 'raw' format doesn't need the extra 'raw' layer when slicing, thus - * the nodename is NULL */ -if (src->sliceStorage && -src->sliceStorage->nodename) { -data->storageSliceNodeName = src->sliceStorage->nodename; +if ((data->storageSliceNodeName = qemuBlockStorageSourceGetSliceNodename(src))) data->storageSliceAttached = true; -} if (src->pr && !virStoragePRDefIsManaged(src->pr)) @@ -3264,6 +3257,12 @@ qemuBlockReopenReadOnly(virDomainObj *vm, * * Returns true if @src requires an extra 'raw' layer for handling of the storage * slice. + * + * Important: This helper must be used only for decisions when setting up a + * '-blockdev' backend in which case the storage slice layer node name will be + * populated. + * Any cases when the backend can be already in use must decide based on the + * existence of the storage slice layer nodename. */ bool qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src) -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 03/17] qemu: block: Introduce helper for deciding when a 'format' layer is needed
The 'format' layer is not required in certain cases. As the logic for this will be a bit more involved create a helper function to do the decision. For now we'll keep to always format the 'format' -blockdev layer. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 19 +++ src/qemu/qemu_block.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 1a718ae82b..123e764e63 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3281,6 +3281,25 @@ qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src) } +/** + * qemuBlockStorageSourceNeedsFormatLayer: + * @src: storage source + * + * Returns true if configuration of @src requires a 'format' layer -blockdev. + * + * Important: This helper must be used only for decisions when setting up a + * '-blockdev' backend in which case the format layer node name will be populated. + * Any cases when the backend can be already in use must decide based on the + * existence of the format layer nodename. + */ +bool +qemuBlockStorageSourceNeedsFormatLayer(const virStorageSource *src G_GNUC_UNUSED) +{ +/* Currently we always create a 'format' layer */ +return true; +} + + /** * qemuBlockStorageSourceGetCookieString: * @src: storage source diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 85616a140d..dcd8a6ed6c 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -280,6 +280,9 @@ qemuBlockReopenReadOnly(virDomainObj *vm, bool qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src); +bool +qemuBlockStorageSourceNeedsFormatLayer(const virStorageSource *src); + char * qemuBlockStorageSourceGetCookieString(virStorageSource *src); -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 04/17] qemuBlockStorageSourceGetBlockdevStorageSliceProps: Allow turning the slice layer into effective blockdev layer
Allow using the slice layer as effective layer once we stop formatting the unnecessary 'raw' driver. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 123e764e63..f7e912ece0 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1448,8 +1448,18 @@ qemuBlockStorageSourceGetFormatProps(virStorageSource *src, } +/** + * qemuBlockStorageSourceGetBlockdevStorageSliceProps: + * @src: storage source object + * @effective: Whether this blockdev will be the 'effective' layer of @src + * + * Formats the JSON object representing -blockdev configuration required to + * configure a 'slice' of @src. If @effective is true, the slice layer is the + * topmost/effective blockdev layer of @src. + */ static virJSONValue * -qemuBlockStorageSourceGetBlockdevStorageSliceProps(virStorageSource *src) +qemuBlockStorageSourceGetBlockdevStorageSliceProps(virStorageSource *src, + bool effective) { g_autoptr(virJSONValue) props = NULL; @@ -1464,7 +1474,7 @@ qemuBlockStorageSourceGetBlockdevStorageSliceProps(virStorageSource *src) if (qemuBlockStorageSourceAddBlockdevCommonProps(&props, src, src->sliceStorage->nodename, - false) < 0) + effective) < 0) return NULL; return g_steal_pointer(&props); @@ -1536,7 +1546,7 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSource *src, data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src); if ((data->storageSliceNodeName = qemuBlockStorageSourceGetSliceNodename(src))) { -if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src))) +if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src, false))) return NULL; } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 05/17] qemuBlockStorageSourceAttachPrepareBlockdev: Prepare for optionally missing format layer
Restructure the code logic so that the function is prepared for the possibility that the 'format' blockdev layer may be missing if not needed. To achieve this we need to introduce logic that selects which node (format/slice/storage) becomes the effective node and thus formats the correct set of arguments. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 26 +++--- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index f7e912ece0..749cd9fdac 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1533,23 +1533,35 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSource *src, virStorageSource *backingStore) { g_autoptr(qemuBlockStorageSourceAttachData) data = NULL; +bool effective = true; unsigned int backendpropsflags = 0; data = g_new0(qemuBlockStorageSourceAttachData, 1); -if (!(data->formatProps = qemuBlockStorageSourceGetFormatProps(src, backingStore)) || -!(data->storageProps = qemuBlockStorageSourceGetBackendProps(src, - backendpropsflags))) -return NULL; +if (qemuBlockStorageSourceGetFormatNodename(src)) { +if (!(data->formatProps = qemuBlockStorageSourceGetFormatProps(src, backingStore))) +return NULL; -data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); -data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src); +data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src); + +effective = false; +} if ((data->storageSliceNodeName = qemuBlockStorageSourceGetSliceNodename(src))) { -if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src, false))) +if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src, effective))) return NULL; + +effective = false; } +if (effective) +backendpropsflags = QEMU_BLOCK_STORAGE_SOURCE_BACKEND_PROPS_EFFECTIVE_NODE; + +if (!(data->storageProps = qemuBlockStorageSourceGetBackendProps(src, backendpropsflags))) +return NULL; + +data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); + return g_steal_pointer(&data); } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 06/17] qemuBlockStorageSourceDetachPrepare: Prepare for possibly missing 'format' layer
Setup the data for detaching of the 'format' layer only when it's present. Restructure the logic to follow the same order as qemuBlockStorageSourceAttachPrepareBlockdev in terms of format/slice/storage -blockdev objects, and drop the now-misleading comment for 'slice' of raw disks. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 749cd9fdac..7137604e36 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1771,14 +1771,15 @@ qemuBlockStorageSourceDetachPrepare(virStorageSource *src) data = g_new0(qemuBlockStorageSourceAttachData, 1); -data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src); -data->formatAttached = true; -data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); -data->storageAttached = true; +if ((data->formatNodeName = qemuBlockStorageSourceGetFormatNodename(src))) +data->formatAttached = true; if ((data->storageSliceNodeName = qemuBlockStorageSourceGetSliceNodename(src))) data->storageSliceAttached = true; +data->storageNodeName = qemuBlockStorageSourceGetStorageNodename(src); +data->storageAttached = true; + if (src->pr && !virStoragePRDefIsManaged(src->pr)) data->prmgrAlias = g_strdup(src->pr->mgralias); -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 07/17] qemuDomainPrepareStorageSourceBlockdevNodename: Restructure code to allow missing 'format' layer
Similarly to other bits of code, we don't need to setup the format layer if it will not be formatted. Add logic which uses qemuBlockStorageSourceNeedsFormatLayer to see whether the setup of the format node is needed. Signed-off-by: Peter Krempa --- src/qemu/qemu_domain.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ae19ce884b..6d3161c5d7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11145,11 +11145,21 @@ qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk, virQEMUDriverConfig *cfg) { char *nodestorage = g_strdup_printf("%s-storage", nodenameprefix); -char *nodeformat = g_strdup_printf("%s-format", nodenameprefix); +const char *encryptionAlias = nodestorage; /* qemuBlockStorageSourceSetStorageNodename steals 'nodestorage' */ qemuBlockStorageSourceSetStorageNodename(src, nodestorage); -qemuBlockStorageSourceSetFormatNodename(src, nodeformat); + +if (qemuBlockStorageSourceNeedsFormatLayer(src)) { +char *nodeformat = g_strdup_printf("%s-format", nodenameprefix); + +qemuBlockStorageSourceSetFormatNodename(src, nodeformat); + +encryptionAlias = nodeformat; +} + +if (qemuDomainSecretStorageSourcePrepareEncryption(priv, src, encryptionAlias) < 0) +return -1; if (qemuBlockStorageSourceNeedsStorageSliceLayer(src)) src->sliceStorage->nodename = g_strdup_printf("libvirt-%u-slice-sto", src->id); @@ -11163,9 +11173,6 @@ qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk, qemuDomainPrepareStorageSourceConfig(src, cfg); qemuDomainPrepareDiskSourceData(disk, src); -if (qemuDomainSecretStorageSourcePrepareEncryption(priv, src, nodeformat) < 0) -return -1; - if (!qemuDomainPrepareStorageSourceNbdkit(src, cfg, nodestorage, priv)) { /* If we're using nbdkit to serve the storage source, we don't pass * authentication secrets to qemu, but will pass them to nbdkit instead */ -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 08/17] qemuBlockStorageSourceGetEffectiveNodename: Prepare for missing 'format' driver
Return the effective storage nodename if the format layer is not present. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 7137604e36..b7f16b43ae 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -97,7 +97,10 @@ qemuBlockStorageSourceSetFormatNodename(virStorageSource *src, const char * qemuBlockStorageSourceGetEffectiveNodename(virStorageSource *src) { -return src->nodenameformat; +if (src->nodenameformat) +return src->nodenameformat; + +return qemuBlockStorageSourceGetEffectiveStorageNodename(src); } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 09/17] qemu: block: Extract logic from qemuBlockReopenReadWrite/ReadOnly
We want to preserve the wrappers for clarity but the inner logic can be extracted to a common function qemuBlockReopenAccess. In further patches the code from qemuBlockReopenFormat will be merged into the new wrapper as well as logic for handling scenarios with missing 'format' layers will be added. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 62 +-- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index b7f16b43ae..1ef6bf98bc 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3221,27 +3221,30 @@ qemuBlockReopenFormat(virDomainObj *vm, /** - * qemuBlockReopenReadWrite: + * qemuBlockReopenAccess: * @vm: domain object * @src: storage source to reopen + * @readonly: requested readonly mode * @asyncJob: qemu async job type * - * Wrapper that reopens @src read-write. We currently depend on qemu - * reopening the storage with 'auto-read-only' enabled for us. - * After successful reopen @src's 'readonly' flag is modified. Does nothing - * if @src is already read-write. + * Reopen @src image to ensure that it is in @readonly. Does nothing if it is + * already in the requested state. + * + * Callers must use qemuBlockReopenReadWrite/qemuBlockReopenReadOnly functions. */ -int -qemuBlockReopenReadWrite(virDomainObj *vm, - virStorageSource *src, - virDomainAsyncJob asyncJob) + +static int +qemuBlockReopenAccess(virDomainObj *vm, + virStorageSource *src, + bool readonly, + virDomainAsyncJob asyncJob) { -if (!src->readonly) +if (src->readonly == readonly) return 0; -src->readonly = false; +src->readonly = readonly; if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) { -src->readonly = true; +src->readonly = !readonly; return -1; } @@ -3250,31 +3253,38 @@ qemuBlockReopenReadWrite(virDomainObj *vm, /** - * qemuBlockReopenReadOnly: + * qemuBlockReopenReadWrite: * @vm: domain object * @src: storage source to reopen * @asyncJob: qemu async job type * - * Wrapper that reopens @src read-only. We currently depend on qemu - * reopening the storage with 'auto-read-only' enabled for us. - * After successful reopen @src's 'readonly' flag is modified. Does nothing - * if @src is already read-only. + * Semantic wrapper that reopens @src read-write. After successful reopen @src's + * 'readonly' flag is modified. Does nothing if @src is already read-write. */ int -qemuBlockReopenReadOnly(virDomainObj *vm, +qemuBlockReopenReadWrite(virDomainObj *vm, virStorageSource *src, virDomainAsyncJob asyncJob) { -if (src->readonly) -return 0; +return qemuBlockReopenAccess(vm, src, false, asyncJob); +} -src->readonly = true; -if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) { -src->readonly = false; -return -1; -} -return 0; +/** + * qemuBlockReopenReadOnly: + * @vm: domain object + * @src: storage source to reopen + * @asyncJob: qemu async job type + * + * Semantic wrapper that reopens @src read-only. After successful reopen @src's + * 'readonly' flag is modified. Does nothing if @src is already read-only. + */ +int +qemuBlockReopenReadOnly(virDomainObj *vm, + virStorageSource *src, + virDomainAsyncJob asyncJob) +{ +return qemuBlockReopenAccess(vm, src, true, asyncJob); } /** -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 10/17] qemu: block: Absorb logic from qemuBlockReopenFormat to qemuBlockReopenAccess
Move all the logic into the new function and remove the old one. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 60 +++ 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 1ef6bf98bc..2872d74fa2 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3182,22 +3182,29 @@ qemuBlockReopenFormatMon(qemuMonitor *mon, /** - * qemuBlockReopenFormat: + * qemuBlockReopenAccess: * @vm: domain object * @src: storage source to reopen + * @readonly: requested readonly mode * @asyncJob: qemu async job type * - * Invokes the 'blockdev-reopen' command on the format layer of @src. This means - * that @src must be already properly configured for the desired outcome. The - * nodenames of @src are used to identify the specific image in qemu. + * Reopen @src image to ensure that it is in @readonly. Does nothing if it is + * already in the requested state. + * + * Callers must use qemuBlockReopenReadWrite/qemuBlockReopenReadOnly functions. */ static int -qemuBlockReopenFormat(virDomainObj *vm, +qemuBlockReopenAccess(virDomainObj *vm, virStorageSource *src, + bool readonly, virDomainAsyncJob asyncJob) { qemuDomainObjPrivate *priv = vm->privateData; int rc; +int ret = -1; + +if (src->readonly == readonly) +return 0; /* If we are lacking the object here, qemu might have opened an image with * a node name unknown to us */ @@ -3207,48 +3214,23 @@ qemuBlockReopenFormat(virDomainObj *vm, return -1; } +src->readonly = readonly; +/* from now on all error paths must use 'goto cleanup' */ + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) -return -1; +goto cleanup; rc = qemuBlockReopenFormatMon(priv->mon, src); qemuDomainObjExitMonitor(vm); if (rc < 0) -return -1; - -return 0; -} - - -/** - * qemuBlockReopenAccess: - * @vm: domain object - * @src: storage source to reopen - * @readonly: requested readonly mode - * @asyncJob: qemu async job type - * - * Reopen @src image to ensure that it is in @readonly. Does nothing if it is - * already in the requested state. - * - * Callers must use qemuBlockReopenReadWrite/qemuBlockReopenReadOnly functions. - */ - -static int -qemuBlockReopenAccess(virDomainObj *vm, - virStorageSource *src, - bool readonly, - virDomainAsyncJob asyncJob) -{ -if (src->readonly == readonly) -return 0; +goto cleanup; -src->readonly = readonly; -if (qemuBlockReopenFormat(vm, src, asyncJob) < 0) { -src->readonly = !readonly; -return -1; -} +ret = 0; -return 0; + cleanup: +src->readonly = !readonly; +return ret; } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 11/17] qemu: monitor: Sanitize arguments of qemuMonitorBlockdevReopen
Take the virJSONValue array object which is passed to the 'blockdev-reopen' command as the 'options' argument rather than making the caller wrap all the properties. The code was a leftover from the time when the blockdev-reopen command had a different syntax, and thus can be cleaned up. Also note that the logging of the node name never worked as the top level object didn't ever contain a 'node-name' property. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c| 8 +--- src/qemu/qemu_monitor.c | 7 ++- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 6 -- src/qemu/qemu_monitor_json.h | 2 +- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 2872d74fa2..84d9ddd9ef 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3159,7 +3159,6 @@ int qemuBlockReopenFormatMon(qemuMonitor *mon, virStorageSource *src) { -g_autoptr(virJSONValue) reopenprops = NULL; g_autoptr(virJSONValue) srcprops = NULL; g_autoptr(virJSONValue) reopenoptions = virJSONValueNewArray(); @@ -3169,12 +3168,7 @@ qemuBlockReopenFormatMon(qemuMonitor *mon, if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0) return -1; -if (virJSONValueObjectAdd(&reopenprops, - "a:options", &reopenoptions, - NULL) < 0) -return -1; - -if (qemuMonitorBlockdevReopen(mon, &reopenprops) < 0) +if (qemuMonitorBlockdevReopen(mon, &reopenoptions) < 0) return -1; return 0; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 320729f067..ec586b9036 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3971,14 +3971,11 @@ qemuMonitorBlockdevAdd(qemuMonitor *mon, int qemuMonitorBlockdevReopen(qemuMonitor *mon, - virJSONValue **props) + virJSONValue **options) { -VIR_DEBUG("props=%p (node-name=%s)", *props, - NULLSTR(virJSONValueObjectGetString(*props, "node-name"))); - QEMU_CHECK_MONITOR(mon); -return qemuMonitorJSONBlockdevReopen(mon, props); +return qemuMonitorJSONBlockdevReopen(mon, options); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6c590933aa..c4af9b407d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1309,7 +1309,7 @@ int qemuMonitorBlockdevAdd(qemuMonitor *mon, virJSONValue **props); int qemuMonitorBlockdevReopen(qemuMonitor *mon, - virJSONValue **props); + virJSONValue **options); int qemuMonitorBlockdevDel(qemuMonitor *mon, const char *nodename); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 105d729d7c..9663da4722 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7783,12 +7783,14 @@ qemuMonitorJSONBlockdevAdd(qemuMonitor *mon, int qemuMonitorJSONBlockdevReopen(qemuMonitor *mon, - virJSONValue **props) + virJSONValue **options) { g_autoptr(virJSONValue) cmd = NULL; g_autoptr(virJSONValue) reply = NULL; -if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", props))) +if (!(cmd = qemuMonitorJSONMakeCommand("blockdev-reopen", + "a:options", options, + NULL))) return -1; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 06023b98ea..ed0027c118 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -691,7 +691,7 @@ qemuMonitorJSONBlockdevAdd(qemuMonitor *mon, int qemuMonitorJSONBlockdevReopen(qemuMonitor *mon, - virJSONValue **props) + virJSONValue **options) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); int -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 12/17] testQemuMonitorJSONBlockdevReopen: Don't use qemuBlockReopenFormatMon
Use the low level monitor API directly to test the QMP wrapper itself. Signed-off-by: Peter Krempa --- tests/qemumonitorjsontest.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 6293b416bd..d9ebb429e7 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -2594,6 +2594,8 @@ testQemuMonitorJSONBlockdevReopen(const void *opaque) const testGenericData *data = opaque; g_autoptr(qemuMonitorTest) test = NULL; g_autoptr(virStorageSource) src = virStorageSourceNew(); +g_autoptr(virJSONValue) reopenoptions = virJSONValueNewArray(); +g_autoptr(virJSONValue) srcprops = NULL; if (!(test = qemuMonitorTestNewSchema(data->xmlopt, data->schema))) return -1; @@ -2604,10 +2606,16 @@ testQemuMonitorJSONBlockdevReopen(const void *opaque) qemuBlockStorageSourceSetStorageNodename(src, g_strdup("backing nodename")); src->backingStore = virStorageSourceNew(); +if (!(srcprops = qemuBlockStorageSourceGetFormatProps(src, src->backingStore))) +return -1; + +if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0) +return -1; + if (qemuMonitorTestAddItem(test, "blockdev-reopen", "{\"return\":{}}") < 0) return -1; -if (qemuBlockReopenFormatMon(qemuMonitorTestGetMonitor(test), src) < 0) +if (qemuMonitorBlockdevReopen(qemuMonitorTestGetMonitor(test), &reopenoptions) < 0) return -1; return 0; -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 13/17] qemu: block: Absorb qemuBlockReopenFormatMon into qemuBlockReopenAccess
Move all the code into the now only caller. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 31 +-- src/qemu/qemu_block.h | 5 - 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 84d9ddd9ef..c62f8fe5f3 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3155,26 +3155,6 @@ qemuBlockBitmapsHandleCommitFinish(virStorageSource *topsrc, } -int -qemuBlockReopenFormatMon(qemuMonitor *mon, - virStorageSource *src) -{ -g_autoptr(virJSONValue) srcprops = NULL; -g_autoptr(virJSONValue) reopenoptions = virJSONValueNewArray(); - -if (!(srcprops = qemuBlockStorageSourceGetFormatProps(src, src->backingStore))) -return -1; - -if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0) -return -1; - -if (qemuMonitorBlockdevReopen(mon, &reopenoptions) < 0) -return -1; - -return 0; -} - - /** * qemuBlockReopenAccess: * @vm: domain object @@ -3193,7 +3173,8 @@ qemuBlockReopenAccess(virDomainObj *vm, bool readonly, virDomainAsyncJob asyncJob) { -qemuDomainObjPrivate *priv = vm->privateData; +g_autoptr(virJSONValue) reopenoptions = virJSONValueNewArray(); +g_autoptr(virJSONValue) srcprops = NULL; int rc; int ret = -1; @@ -3211,10 +3192,16 @@ qemuBlockReopenAccess(virDomainObj *vm, src->readonly = readonly; /* from now on all error paths must use 'goto cleanup' */ +if (!(srcprops = qemuBlockStorageSourceGetFormatProps(src, src->backingStore))) +return -1; + +if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0) +return -1; + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) goto cleanup; -rc = qemuBlockReopenFormatMon(priv->mon, src); +rc = qemuMonitorBlockdevReopen(qemuDomainGetMonitor(vm), &reopenoptions); qemuDomainObjExitMonitor(vm); if (rc < 0) diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index dcd8a6ed6c..f37e10216c 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -263,11 +263,6 @@ qemuBlockBitmapsHandleCommitFinish(virStorageSource *topsrc, GHashTable *blockNamedNodeData, virJSONValue **actions); -/* only for use in qemumonitorjsontest */ -int -qemuBlockReopenFormatMon(qemuMonitor *mon, - virStorageSource *src); - int qemuBlockReopenReadWrite(virDomainObj *vm, virStorageSource *src, -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 15/17] qemuMigrationSrcNBDCopyCancel: Use qemuBlockStorageSourceAttachRollback to detach migration NBD blockdevs
Rewrite the code to use the common tooling for removing blockdevs instead of the ad-hoc qemuBlockStorageSourceDetachOneBlockdev helper. Use of the common infrastructure will properly handle cases when the raw driver is ommited from the block graph. Since the TLS data object is shared for all migration QMP commands and objects we need to strip it's alias from the definition of the storage source before attempting to detach it. Signed-off-by: Peter Krempa --- src/qemu/qemu_migration.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index ac58aa1a8c..0f4c6dbe98 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -938,12 +938,26 @@ qemuMigrationSrcNBDCopyCancel(virDomainObj *vm, for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDef *disk = vm->def->disks[i]; qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); +g_autoptr(qemuBlockStorageSourceAttachData) data = NULL; if (!diskPriv->migrSource) continue; -qemuBlockStorageSourceDetachOneBlockdev(vm, asyncJob, -diskPriv->migrSource); +/* remove the alias of the TLS object when we're about to detach the + * migration NBD blockdev as the TLS object is shared for the migration + * and we don't want to detach it. The alias is not needed after + * the JSON object of the blockdev props is formatted */ +g_clear_pointer(&diskPriv->migrSource->tlsAlias, g_free); + +data = qemuBlockStorageSourceDetachPrepare(diskPriv->migrSource); + +if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) +goto cleanup; + +qemuBlockStorageSourceAttachRollback(qemuDomainGetMonitor(vm), data); + +qemuDomainObjExitMonitor(vm); + g_clear_pointer(&diskPriv->migrSource, virObjectUnref); } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 16/17] qemu: block: Remove unused qemuBlockStorageSourceDetachOneBlockdev
The only caller was converted to use the common blockdev infrastructure thus this function is no longer needed. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 34 -- src/qemu/qemu_block.h | 5 - 2 files changed, 39 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 0d676f71b0..5abbfab67e 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1942,40 +1942,6 @@ qemuBlockStorageSourceChainDetach(qemuMonitor *mon, } -/** - * qemuBlockStorageSourceDetachOneBlockdev: - * @driver: qemu driver object - * @vm: domain object - * @asyncJob: currently running async job - * @src: storage source to detach - * - * Detaches one virStorageSource using blockdev-del. Note that this does not - * detach any authentication/encryption objects. This function enters the - * monitor internally. - */ -int -qemuBlockStorageSourceDetachOneBlockdev(virDomainObj *vm, -virDomainAsyncJob asyncJob, -virStorageSource *src) -{ -int ret; - -if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) -return -1; - -ret = qemuMonitorBlockdevDel(qemuDomainGetMonitor(vm), - qemuBlockStorageSourceGetFormatNodename(src)); - -if (ret == 0) -ret = qemuMonitorBlockdevDel(qemuDomainGetMonitor(vm), - qemuBlockStorageSourceGetStorageNodename(src)); - -qemuDomainObjExitMonitor(vm); - -return ret; -} - - int qemuBlockSnapshotAddBlockdev(virJSONValue *actions, virDomainDiskDef *disk, diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index f37e10216c..0eab0d822c 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -149,11 +149,6 @@ void qemuBlockStorageSourceAttachRollback(qemuMonitor *mon, qemuBlockStorageSourceAttachData *data); -int -qemuBlockStorageSourceDetachOneBlockdev(virDomainObj *vm, -virDomainAsyncJob asyncJob, -virStorageSource *src); - struct _qemuBlockStorageSourceChainData { qemuBlockStorageSourceAttachData **srcdata; size_t nsrcdata; -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 17/17] qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource: Don't setup 'raw' layer for migration NBD connection
The raw driver layer is not needed in this case and can be dropped. Removing the nodename will cause other pieces of the code to pick up and stop addign the layer. Signed-off-by: Peter Krempa --- src/qemu/qemu_migration.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 0f4c6dbe98..f9c34b72e8 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1026,7 +1026,6 @@ qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource(virDomainDiskDef *disk, copysrc->tlsHostname = g_strdup(tlsHostname); qemuBlockStorageSourceSetStorageNodename(copysrc, g_strdup_printf("migration-%s-storage", disk->dst)); -qemuBlockStorageSourceSetFormatNodename(copysrc, g_strdup_printf("migration-%s-format", disk->dst)); return g_steal_pointer(©src); } -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH 14/17] qemuBlockReopenAccess: prepare for removal of 'raw' format layer
Make the helper reopening a blockdev for access pick the correct layer to reopen based on what is currently in use. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c62f8fe5f3..0d676f71b0 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3192,8 +3192,19 @@ qemuBlockReopenAccess(virDomainObj *vm, src->readonly = readonly; /* from now on all error paths must use 'goto cleanup' */ -if (!(srcprops = qemuBlockStorageSourceGetFormatProps(src, src->backingStore))) -return -1; +/* based on which is the current 'effecitve' layer we must reopen the + * appropriate blockdev */ +if (qemuBlockStorageSourceGetFormatNodename(src)) { +if (!(srcprops = qemuBlockStorageSourceGetFormatProps(src, src->backingStore))) +return -1; +} else if (qemuBlockStorageSourceGetSliceNodename(src)) { +if (!(srcprops = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src, true))) +return -1; +} else { +if (!(srcprops = qemuBlockStorageSourceGetBackendProps(src, + QEMU_BLOCK_STORAGE_SOURCE_BACKEND_PROPS_EFFECTIVE_NODE))) +return -1; +} if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0) return -1; -- 2.42.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH] virnuma: Avoid integer overflow in virNumaGetPages()
On systems with humongous pages (16GiB) and 32bit int it's easy to hit integer overflow in virNumaGetPages(). What happens is, inside of virNumaGetPages() as we process hugepages for given NUMA node (e.g. in order to produce capabilities XML), we keep a sum of sizes of pools in an ULL variable (huge_page_sum). In each iteration, the variable is incremented by 1024 * page_size * page_avail. Now, page_size is just an uint, so we have: ULL += U * U * ULL; and because of associativity, U * U is computed first and since we have two operands of the same type, no type expansion happens. But this means, for humongous pages (like 16GiB) the multiplication overflows. Therefore, move the multiplication out of the loop. This helps in two ways: 1) now we have ULL += U * ULL; which expands the uint in multiplication, 2) it saves couple of CPU cycles. Resolves: https://issues.redhat.com/browse/RHEL-16749 Signed-off-by: Michal Privoznik --- src/util/virnuma.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util/virnuma.c b/src/util/virnuma.c index 5053a70c61..9393c20875 100644 --- a/src/util/virnuma.c +++ b/src/util/virnuma.c @@ -787,9 +787,7 @@ virNumaGetPages(int node, tmp_free[ntmp] = page_free; ntmp++; -/* page_size is in kibibytes while we want huge_page_sum - * in just bytes. */ -huge_page_sum += 1024 * page_size * page_avail; +huge_page_sum += page_size * page_avail; } if (direrr < 0) @@ -800,6 +798,9 @@ virNumaGetPages(int node, VIR_REALLOC_N(tmp_avail, ntmp + 1); VIR_REALLOC_N(tmp_free, ntmp + 1); +/* page_size is in kibibytes while we want huge_page_sum in just bytes. */ +huge_page_sum *= 1024; + if (virNumaGetPageInfo(node, system_page_size, huge_page_sum, &tmp_avail[ntmp], &tmp_free[ntmp]) < 0) return -1; -- 2.41.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH] virnuma: Avoid integer overflow in virNumaGetPages()
On a Friday in 2023, Michal Privoznik wrote: On systems with humongous pages (16GiB) and 32bit int it's easy to hit integer overflow in virNumaGetPages(). What happens is, inside of virNumaGetPages() as we process hugepages for given NUMA node (e.g. in order to produce capabilities XML), we keep a sum of sizes of pools in an ULL variable (huge_page_sum). In each iteration, the variable is incremented by 1024 * page_size * page_avail. Now, page_size is just an uint, so we have: ULL += U * U * ULL; and because of associativity, U * U is computed first and since we have two operands of the same type, no type expansion happens. But this means, for humongous pages (like 16GiB) the multiplication overflows. Therefore, move the multiplication out of the loop. This helps in two ways: 1) now we have ULL += U * ULL; which expands the uint in multiplication, 2) it saves couple of CPU cycles. Resolves: https://issues.redhat.com/browse/RHEL-16749 Signed-off-by: Michal Privoznik --- src/util/virnuma.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) Reviewed-by: Ján Tomko Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 2/2] qemu: block: Don't try to merge bitmaps into 'raw' images
On a Thursday in 2023, Peter Krempa wrote: If any of the images in a chain above a raw image have bitmaps, libvirt would attempt to merge them when doing a block commit or block copy operation, which would result into a error in the logs as creating persistent bitmaps in a raw image is not supported. Since libvirt cares only about persisten bitmaps we can simply skip the *persistent operation if the target of a block copy or block commit is a raw image. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 10 ++ 1 file changed, 10 insertions(+) Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 0/2] qemu: block fixes
On a Thursday in 2023, Peter Krempa wrote: Few issues I've found while testing the block layer for an upcoming patchset. Peter Krempa (2): qemu: hotplug: Detect disk backing images before setting up security access qemu: block: Don't try to merge bitmaps into 'raw' images src/qemu/qemu_block.c | 10 ++ src/qemu/qemu_hotplug.c | 10 +- 2 files changed, 15 insertions(+), 5 deletions(-) Reviewed-by: Ján Tomko Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 5/7] virstoragetest: Format detected/unprocessed backing store format into output files
On a Friday in 2023, Peter Krempa wrote: Compare also the detected format of the backing file ('backingStoreRawFormat' field) into the outptu data for comparison with *output Jano others. Since the ToString function can't convert VIR_STORAGE_FILE_AUTO use also the numeric value. Signed-off-by: Peter Krempa --- tests/virstoragetest.c | 3 +++ tests/virstoragetestdata/out/directory-dir | 1 + tests/virstoragetestdata/out/directory-none| 1 + tests/virstoragetestdata/out/directory-raw | 1 + tests/virstoragetestdata/out/qcow2-auto_qcow2-qcow2_raw-raw| 1 + tests/virstoragetestdata/out/qcow2-auto_raw-raw-relative | 1 + tests/virstoragetestdata/out/qcow2-qcow2_nbd-raw | 2 ++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-auto| 2 ++ .../virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_qcow2-auto | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_raw-auto | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_qcow2-qcow2_raw-raw | 3 +++ tests/virstoragetestdata/out/qcow2-qcow2_raw-raw-relative | 2 ++ tests/virstoragetestdata/out/qcow2-symlinks| 3 +++ tests/virstoragetestdata/out/qed-auto_raw | 1 + tests/virstoragetestdata/out/qed-qed_raw | 2 ++ tests/virstoragetestdata/out/raw-auto | 1 + tests/virstoragetestdata/out/raw-raw | 1 + 17 files changed, 31 insertions(+) signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 0/7] storage_file_probe: Handle qcow2 images with 'protocol' driver name in 'backing file format' field (part 1 - the fix)
On a Friday in 2023, Peter Krempa wrote: See 6/7 and 7/7 for the rationale. Further patches will be posted to refactor the rest of the parsers which are bitrotten. Peter Krempa (7): storage_file_probe: Remove unused state 'BACKING_STORE_ERROR' virStorageFileProbeGetMetadata: Do not partially skip probing of the image storage_file_probe: Remove BACKING_STORE_OK,BACKING_STORE_INVALID states virstoragetest: Use strings for storage type and format in output data virstoragetest: Format detected/unprocessed backing store format into output files virstoragetest: Add test cases for QCOW2 files with a protocol name as backing file format storage_file_probe: Treat qcow2 images with protocol drivers in backing store field as raw src/storage_file/storage_file_probe.c | 71 -- tests/virstoragetest.c| 19 - .../images/qcow2-protocol-backing-file.qcow2 | Bin 0 -> 196616 bytes [...] tests/virstoragetestdata/out/raw-raw | 5 +- 22 files changed, 173 insertions(+), 99 deletions(-) create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-file.qcow2 create mode 100644 tests/virstoragetestdata/images/qcow2-protocol-backing-nbd.qcow2 create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-file create mode 100644 tests/virstoragetestdata/out/qcow2-protocol-backing-nbd Reviewed-by: Ján Tomko Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH v2 1/3] conf: Introduce pipewire audio backend
QEMU gained support for PipeWire audio backend (see QEMU commit of v8.0.0-403-gc2d3d1c294). Its configuration knobs are basically the same as pulseaudio's, except for PA's server name. Therefore, a lot of code is copied over from pulseadio and fixed by s/Pulse/Pipewire/ or s/pulseaudio/pipewire/. There's one ley difference to PA though: pipewire daemon is usually on per user basis (just like our qemu:///session). Therefore, introduce this 'runtimeDir' attribute, which allows specifying path to pipewire daemon socket (useful for qemu:///system for instance). Signed-off-by: Michal Privoznik --- docs/formatdomain.rst | 46 +++- src/conf/domain_conf.c| 73 +++ src/conf/domain_conf.h| 13 src/conf/schemas/domaincommon.rng | 42 +++ src/qemu/qemu_command.c | 2 + src/qemu/qemu_validate.c | 1 + .../qemuxml2argvdata/audio-pipewire-best.xml | 43 +++ .../qemuxml2argvdata/audio-pipewire-full.xml | 43 +++ .../audio-pipewire-minimal.xml| 36 + .../audio-pipewire-best.x86_64-latest.xml | 46 .../audio-pipewire-full.x86_64-latest.xml | 46 .../audio-pipewire-minimal.x86_64-latest.xml | 39 ++ tests/qemuxml2xmltest.c | 3 + 13 files changed, 431 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-best.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-full.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-minimal.x86_64-latest.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 459815d2b5..310d2bc427 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7368,7 +7368,8 @@ to the guest sound device. ``type`` The required ``type`` attribute specifies audio backend type. Currently, the supported values are ``none``, ``alsa``, ``coreaudio``, - ``dbus``, ``jack``, ``oss``, ``pulseaudio``, ``sdl``, ``spice``, ``file``. + ``dbus``, ``jack``, ``oss``, ``pipewire``, ``pulseaudio``, ``sdl``, + ``spice``, ``file``. ``id`` Integer id of the audio device. Must be greater than 0. @@ -7452,7 +7453,7 @@ following environment variables: * ``QEMU_AUDIO_DRV`` Valid values are ``pa``, ``none``, ``alsa``, ``coreaudio``, ``jack``, ``oss``, - ``sdl``, ``spice`` or ``wav``. + ``pipewire``, ``sdl``, ``spice`` or ``wav``. None audio backend ^^ @@ -7601,6 +7602,47 @@ and elements :since:`Since 6.7.0, bhyve; Since 7.2.0, qemu` +PipeWire audio backend +^^ + +The ``pipewire`` audio backend delegates to a PipeWire daemon audio input and +output. + +The following additional attributes are permitted on the and + elements: + +* ``name`` + + The sink/source name to use + +* ``streamName`` + + The name to identify the stream associated with the VM + +* ``latency`` + + Desired latency for the server to target in microseconds + +:: + + + + + + +Optionally, path to pipewire daemon socket (aka ``PIPEWIRE_RUNTIME_DIR``) can +be specified via ``runtimeDir`` attribute. This is useful when a domain under +``qemu:///system`` wants to use session pipewire daemon, or vice versa. + +:: + + + + + + +:since:`Since 9.10.0, qemu` + PulseAudio audio backend diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f7d7244738..22ad43e1d7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -791,6 +791,7 @@ VIR_ENUM_IMPL(virDomainAudioType, "spice", "file", "dbus", + "pipewire", ); VIR_ENUM_IMPL(virDomainAudioSDLDriver, @@ -3230,6 +3231,13 @@ virDomainAudioIOPulseAudioFree(virDomainAudioIOPulseAudio *def) g_free(def->streamName); } +static void +virDomainAudioIOPipewireAudioFree(virDomainAudioIOPipewireAudio *def) +{ +g_free(def->name); +g_free(def->streamName); +} + void virDomainAudioDefFree(virDomainAudioDef *def) { @@ -3274,6 +3282,12 @@ virDomainAudioDefFree(virDomainAudioDef *def) g_free(def->backend.file.path); break; +case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: +virDomainAudioIOPipewireAudioFree(&def->backend.pipewire.input); +virDomainAudioIOPipewireAudioFree(&def->backend.pipewire.output); +g_free(def->backend.pipewire.runtimeDir); +break; + case VIR_DOMAIN_AUDIO_TYPE_DBUS: case VIR_DOMAIN_AUDIO_TYPE_LAST: break; @@ -11920,6 +11934,21 @@ virDomainAudioSDLParse(virDomainAudioIOSDL *def, } +static int +virDomainAudioPipewireAudioParse(virDoma
[PATCH v2 3/3] NEWS: Document pipewire audio backend
Signed-off-by: Michal Privoznik --- NEWS.rst | 5 + 1 file changed, 5 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 08e5a3d04a..f12734c2a1 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -17,6 +17,11 @@ v9.10.0 (unreleased) * **New features** + * Introduce pipewire audio backend + +The QEMU hypervisor driver now allows setting ``pipewire`` backend for + device. + * **Improvements** * **Bug fixes** -- 2.41.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH v2 0/3] Introduce pipewire audio backend
v2 of: https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/4M7OBHJEYCXPJ7DJK2ZEQFNDCT25CK77/ diff to v1: - Introduced 'runtimeDir' attribute to so that users do not have use hack to set PIPEWIRE_RUNTIME_DIR. - Worked in the rest of Peter's review suggestions. Michal Prívozník (3): conf: Introduce pipewire audio backend qemu: Generate cmd line for pipewire audio backend NEWS: Document pipewire audio backend NEWS.rst | 5 ++ docs/formatdomain.rst | 46 +++- src/conf/domain_conf.c| 73 +++ src/conf/domain_conf.h| 13 src/conf/schemas/domaincommon.rng | 42 +++ src/qemu/qemu_command.c | 71 ++ src/qemu/qemu_validate.c | 1 + .../audio-many-backends.x86_64-latest.args| 2 + .../qemuxml2argvdata/audio-many-backends.xml | 1 + .../audio-pipewire-best.x86_64-latest.args| 36 + .../qemuxml2argvdata/audio-pipewire-best.xml | 43 +++ .../audio-pipewire-full.x86_64-latest.args| 36 + .../qemuxml2argvdata/audio-pipewire-full.xml | 43 +++ .../audio-pipewire-minimal.x86_64-latest.args | 36 + .../audio-pipewire-minimal.xml| 36 + tests/qemuxml2argvtest.c | 10 +++ .../audio-many-backends.x86_64-latest.xml | 1 + .../audio-pipewire-best.x86_64-latest.xml | 46 .../audio-pipewire-full.x86_64-latest.xml | 46 .../audio-pipewire-minimal.x86_64-latest.xml | 39 ++ tests/qemuxml2xmltest.c | 3 + 21 files changed, 627 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-best.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-full.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-minimal.x86_64-latest.xml -- 2.41.0 ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
[PATCH v2 2/3] qemu: Generate cmd line for pipewire audio backend
This is mostly straightforward, except for a teensy-weensy detail: usually, there's no system wide daemon running, no system wide available socket that anybody could connect to. PipeWire uses a per user daemon approach instead. But this in turn means, that the socket location floats between various locations and is derived from various environment variables (just like the actual socket name) and thus we must pass the variables to QEMU. Resolves: https://gitlab.com/libvirt/libvirt/-/issues/560 Signed-off-by: Michal Privoznik --- src/qemu/qemu_command.c | 69 +++ .../audio-many-backends.x86_64-latest.args| 2 + .../qemuxml2argvdata/audio-many-backends.xml | 1 + .../audio-pipewire-best.x86_64-latest.args| 36 ++ .../audio-pipewire-full.x86_64-latest.args| 36 ++ .../audio-pipewire-minimal.x86_64-latest.args | 36 ++ tests/qemuxml2argvtest.c | 10 +++ .../audio-many-backends.x86_64-latest.xml | 1 + 8 files changed, 191 insertions(+) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.x86_64-latest.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 173639277c..d54149ed2d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7833,6 +7833,68 @@ qemuBuildAudioSDLProps(virDomainAudioIOSDL *def, } +static int +qemuBuildAudioPipewireAudioProps(virDomainAudioIOPipewireAudio *def, + virJSONValue **props) +{ +return virJSONValueObjectAdd(props, + "S:name", def->name, + "S:stream-name", def->streamName, + "p:latency", def->latency, + NULL); +} + + +static void +qemuBuildAudioPipewireAudioEnv(virCommand *cmd, + const char *runtimeDir) +{ +const char *envVars[] = { "PIPEWIRE_RUNTIME_DIR", "XDG_RUNTIME_DIR", + "USERPROFILE" }; +size_t i; + +/* PipeWire needs access to its daemon socket. The socket name is + * configurable (core.name in pipewire.conf, or PIPEWIRE_CORE and + * PIPEWIRE_REMOTE env vars). If the socket name is not an absolute + * path, then the socket is looked for in the following directories + * (in order): + * + * - PIPEWIRE_RUNTIME_DIR + * - XDG_RUNTIME_DIR + * - USERPROFILE + * + * This order is defined in get_runtime_dir() from + * src/modules/module-protocol-native/local-socket.c from PipeWire's + * codebase. + * + * Now, PIPEWIRE_CORE and/or PIPEWIRE_REMOTE should be passed + * whenever present in the environment. But for the other three + * (socket location dirs): + * + * 1) set it to user defined value (@runtimeDir != NULL), or + * 2) we can add just the first existing one (basically mimic + *get_runtime_dir() logic; @runtimeDir == NULL). + */ + +virCommandAddEnvPass(cmd, "PIPEWIRE_CORE"); +virCommandAddEnvPass(cmd, "PIPEWIRE_REMOTE"); + +if (runtimeDir) { +virCommandAddEnvPair(cmd, "PIPEWIRE_RUNTIME_DIR", runtimeDir); +} else { +for (i = 0; i < G_N_ELEMENTS(envVars); i++) { +const char *value = getenv(envVars[i]); + +if (!value) +continue; + +virCommandAddEnvPair(cmd, envVars[i], value); +break; +} +} +} + + static int qemuBuildAudioCommandLineArg(virCommand *cmd, virDomainAudioDef *def) @@ -7939,6 +8001,13 @@ qemuBuildAudioCommandLineArg(virCommand *cmd, break; case VIR_DOMAIN_AUDIO_TYPE_PIPEWIRE: +if (qemuBuildAudioPipewireAudioProps(&def->backend.pipewire.input, &in) < 0 || +qemuBuildAudioPipewireAudioProps(&def->backend.pipewire.output, &out) < 0) +return -1; + +qemuBuildAudioPipewireAudioEnv(cmd, def->backend.pipewire.runtimeDir); +break; + case VIR_DOMAIN_AUDIO_TYPE_LAST: default: virReportEnumRangeError(virDomainAudioType, def->type); diff --git a/tests/qemuxml2argvdata/audio-many-backends.x86_64-latest.args b/tests/qemuxml2argvdata/audio-many-backends.x86_64-latest.args index 4c6c925ccd..0bdc75689f 100644 --- a/tests/qemuxml2argvdata/audio-many-backends.x86_64-latest.args +++ b/tests/qemuxml2argvdata/audio-many-backends.x86_64-latest.args @@ -6,6 +6,7 @@ LOGNAME=test \ XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +PIPEWIRE_RUNTIME_DIR=/run/user/1000 \ /usr/bin/qemu-system-x86_64 \ -name guest=QEMUGuest1,debug-threads=on \ -S \ @@ -32,6 +33,7 @@ XDG_CONFIG_HOM
Re: [PATCH 02/17] qemu: block: Use qemuBlockStorageSourceNeedsStorageSliceLayer only for setup
On a Friday in 2023, Peter Krempa wrote: Add a note stating that qemuBlockStorageSourceNeedsStorageSliceLayer must be used only when setting up a new blockdev, any other case when the device might been already set up must use the existance of the existence nodename to do so. Adjust qemuBlockStorageSourceAttachPrepareBlockdev to do so and refactor qemuBlockStorageSourceDetachPrepare to use the same logic. Signed-off-by: Peter Krempa --- src/qemu/qemu_block.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 15/17] qemuMigrationSrcNBDCopyCancel: Use qemuBlockStorageSourceAttachRollback to detach migration NBD blockdevs
On a Friday in 2023, Peter Krempa wrote: Rewrite the code to use the common tooling for removing blockdevs instead of the ad-hoc qemuBlockStorageSourceDetachOneBlockdev helper. Use of the common infrastructure will properly handle cases when the raw driver is ommited from the block graph. Since the TLS data object is shared for all migration QMP commands and objects we need to strip it's alias from the definition of the storage *its source before attempting to detach it. Signed-off-by: Peter Krempa --- src/qemu/qemu_migration.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 17/17] qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource: Don't setup 'raw' layer for migration NBD connection
On a Friday in 2023, Peter Krempa wrote: The raw driver layer is not needed in this case and can be dropped. Removing the nodename will cause other pieces of the code to pick up and stop addign the layer. *adding Signed-off-by: Peter Krempa --- src/qemu/qemu_migration.c | 1 - 1 file changed, 1 deletion(-) Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH 00/17] qemu: Prepare block device setup for removing the 'raw' driver ('raw' driver removal part 3)
On a Friday in 2023, Peter Krempa wrote: This series prepares the setup of the block device backend for removal of the raw driver from the block graph, and actually removes it from the migration NBD connection. Unfortunately for normal usage it's not yet possible as qemu then records the protocol driver name in the backing file format field which would break with older versions of libvirt (see my other series). Peter Krempa (17): qemu: block: Introduce qemuBlockStorageSourceGetSliceNodename qemu: block: Use qemuBlockStorageSourceNeedsStorageSliceLayer only for setup qemu: block: Introduce helper for deciding when a 'format' layer is needed qemuBlockStorageSourceGetBlockdevStorageSliceProps: Allow turning the slice layer into effective blockdev layer qemuBlockStorageSourceAttachPrepareBlockdev: Prepare for optionally missing format layer qemuBlockStorageSourceDetachPrepare: Prepare for possibly missing 'format' layer qemuDomainPrepareStorageSourceBlockdevNodename: Restructure code to allow missing 'format' layer qemuBlockStorageSourceGetEffectiveNodename: Prepare for missing 'format' driver qemu: block: Extract logic from qemuBlockReopenReadWrite/ReadOnly qemu: block: Absorb logic from qemuBlockReopenFormat to qemuBlockReopenAccess qemu: monitor: Sanitize arguments of qemuMonitorBlockdevReopen testQemuMonitorJSONBlockdevReopen: Don't use qemuBlockReopenFormatMon qemu: block: Absorb qemuBlockReopenFormatMon into qemuBlockReopenAccess qemuBlockReopenAccess: prepare for removal of 'raw' format layer qemuMigrationSrcNBDCopyCancel: Use qemuBlockStorageSourceAttachRollback to detach migration NBD blockdevs qemu: block: Remove unused qemuBlockStorageSourceDetachOneBlockdev qemuMigrationSrcNBDStorageCopyBlockdevPrepareSource: Don't setup 'raw' layer for migration NBD connection src/qemu/qemu_block.c| 257 ++- src/qemu/qemu_block.h| 16 +-- src/qemu/qemu_domain.c | 17 ++- src/qemu/qemu_migration.c| 19 ++- src/qemu/qemu_monitor.c | 7 +- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 6 +- src/qemu/qemu_monitor_json.h | 2 +- tests/qemumonitorjsontest.c | 10 +- 9 files changed, 185 insertions(+), 151 deletions(-) Reviewed-by: Ján Tomko Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH v2 1/3] conf: Introduce pipewire audio backend
On a Friday in 2023, Michal Privoznik wrote: QEMU gained support for PipeWire audio backend (see QEMU commit of v8.0.0-403-gc2d3d1c294). Its configuration knobs are basically the same as pulseaudio's, except for PA's server name. Therefore, a lot of code is copied over from pulseadio and fixed by s/Pulse/Pipewire/ or s/pulseaudio/pipewire/. There's one ley difference to PA though: pipewire daemon is s/ley/key/ Jano usually on per user basis (just like our qemu:///session). Therefore, introduce this 'runtimeDir' attribute, which allows specifying path to pipewire daemon socket (useful for qemu:///system for instance). Signed-off-by: Michal Privoznik --- docs/formatdomain.rst | 46 +++- src/conf/domain_conf.c| 73 +++ src/conf/domain_conf.h| 13 src/conf/schemas/domaincommon.rng | 42 +++ src/qemu/qemu_command.c | 2 + src/qemu/qemu_validate.c | 1 + .../qemuxml2argvdata/audio-pipewire-best.xml | 43 +++ .../qemuxml2argvdata/audio-pipewire-full.xml | 43 +++ .../audio-pipewire-minimal.xml| 36 + .../audio-pipewire-best.x86_64-latest.xml | 46 .../audio-pipewire-full.x86_64-latest.xml | 46 .../audio-pipewire-minimal.x86_64-latest.xml | 39 ++ tests/qemuxml2xmltest.c | 3 + 13 files changed, 431 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-best.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-full.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-minimal.x86_64-latest.xml signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org
Re: [PATCH v2 0/3] Introduce pipewire audio backend
On a Friday in 2023, Michal Privoznik wrote: v2 of: https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/4M7OBHJEYCXPJ7DJK2ZEQFNDCT25CK77/ diff to v1: - Introduced 'runtimeDir' attribute to so that users do not have use hack to set PIPEWIRE_RUNTIME_DIR. - Worked in the rest of Peter's review suggestions. Michal Prívozník (3): conf: Introduce pipewire audio backend qemu: Generate cmd line for pipewire audio backend NEWS: Document pipewire audio backend NEWS.rst | 5 ++ docs/formatdomain.rst | 46 +++- src/conf/domain_conf.c| 73 +++ src/conf/domain_conf.h| 13 src/conf/schemas/domaincommon.rng | 42 +++ src/qemu/qemu_command.c | 71 ++ src/qemu/qemu_validate.c | 1 + .../audio-many-backends.x86_64-latest.args| 2 + .../qemuxml2argvdata/audio-many-backends.xml | 1 + .../audio-pipewire-best.x86_64-latest.args| 36 + .../qemuxml2argvdata/audio-pipewire-best.xml | 43 +++ .../audio-pipewire-full.x86_64-latest.args| 36 + .../qemuxml2argvdata/audio-pipewire-full.xml | 43 +++ .../audio-pipewire-minimal.x86_64-latest.args | 36 + .../audio-pipewire-minimal.xml| 36 + tests/qemuxml2argvtest.c | 10 +++ .../audio-many-backends.x86_64-latest.xml | 1 + .../audio-pipewire-best.x86_64-latest.xml | 46 .../audio-pipewire-full.x86_64-latest.xml | 46 .../audio-pipewire-minimal.x86_64-latest.xml | 39 ++ tests/qemuxml2xmltest.c | 3 + 21 files changed, 627 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-best.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-full.xml create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/audio-pipewire-minimal.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-best.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-full.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/audio-pipewire-minimal.x86_64-latest.xml Reviewed-by: Ján Tomko Jano signature.asc Description: PGP signature ___ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-le...@lists.libvirt.org