Compare commits
491 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4820e2d885 | |||
| b5ff942369 | |||
| dafc4559bd | |||
| bfcb9ad2f0 | |||
| acce46f726 | |||
| f80d27e126 | |||
| 63cd2ced20 | |||
| cad1b6966f | |||
| a27f478451 | |||
| b94faf01a5 | |||
| 60a70c925a | |||
| e184d967ac | |||
| 985ee7390d | |||
| 156ce5b5c7 | |||
| 77b02695ab | |||
| 50057212b3 | |||
| c61c2c83ef | |||
| e3e721c529 | |||
| 7bf08eb7cb | |||
| 0862e2b778 | |||
| 9ae002fc72 | |||
| 7749fc4a26 | |||
| 5b0f05f970 | |||
| 36079ddefa | |||
| 9abc69f078 | |||
| f4d251ad6e | |||
| b0d2e09842 | |||
| b0dd011728 | |||
| 2513c9ff81 | |||
| 9ef5501a94 | |||
| 659f2f0b36 | |||
| f3cac3532b | |||
| 6eb56c2e71 | |||
| 93a549eb1a | |||
| f2a998ce76 | |||
| 8556d44e84 | |||
| f8539fae13 | |||
| 80a3188a20 | |||
| 56d89b1d61 | |||
| 2a7828bae8 | |||
| c879325741 | |||
| edf6aa6cd7 | |||
| 163b87484b | |||
| 5828ec5da6 | |||
| adaeee1c2c | |||
| 200f2942a9 | |||
| cbf07f0551 | |||
| eb9ceebe38 | |||
| 507eb37491 | |||
| 3e211fa0f6 | |||
| d4bb64489a | |||
| 6d908194bf | |||
| 2333a80c1a | |||
| f4fd6d7df6 | |||
| c1a3411c3b | |||
| 619904f37a | |||
| 044c5b0665 | |||
| 50aba9b5a0 | |||
| c98b586e70 | |||
| 987430ba8b | |||
| 58043b20fb | |||
| f1888958a6 | |||
| 6c3d79e65d | |||
| dc9be9b9a7 | |||
| 5e0d67787a | |||
| 662f0e2ba4 | |||
| 66060fa395 | |||
| 83def04a25 | |||
| 535bbcdd91 | |||
| 417e4c9cf7 | |||
| 24d349fa37 | |||
| 9f3b22fec4 | |||
| 7285a57f5c | |||
| 9944fa190c | |||
| 1a44dca7d4 | |||
| 0c2262d602 | |||
| da598118cf | |||
| da34e517db | |||
| 7b17ccd035 | |||
| 908a2f2a46 | |||
| acf19787de | |||
| c269619b9a | |||
| 3f6336f446 | |||
| a552a10ec8 | |||
| bfb8157052 | |||
| edb5200d83 | |||
| fe3f90dedd | |||
| 437df85540 | |||
| 2d6cbe6672 | |||
| 97a323d7c2 | |||
| cb839d3dfc | |||
| dc6b512f3c | |||
| ac122f4525 | |||
| 7744acbb6b | |||
| 3807f07c15 | |||
| e484fdc92b | |||
| 6752fe8c9e | |||
| 15f52369ae | |||
| 65a0e26138 | |||
| 497e096592 | |||
| 03a98aaf59 | |||
| 5845f1efec | |||
| a8d01eb9d7 | |||
| 6d76ba5956 | |||
| a11202d9e2 | |||
| bbfa59c8da | |||
| b97ad8956c | |||
| f9639a0012 | |||
| c71e60c76c | |||
| 9764121247 | |||
| a18ed3c492 | |||
| 9e2eeb32e3 | |||
| 8bf91f5d22 | |||
| 91d8eff569 | |||
| a761ea338f | |||
| 7eef88add4 | |||
| 0c88a64234 | |||
| c2f3be1f4d | |||
| 18b1c9d77e | |||
| 4528832026 | |||
| 037cd36ba2 | |||
| b94fb6a393 | |||
| b0c05ac2ae | |||
| 15c305caf3 | |||
| bc1b3e59a7 | |||
| 3c4492c415 | |||
| fecc0295a2 | |||
| 325dc837c6 | |||
| 5a45cb7f0d | |||
| 21269530e8 | |||
| fc18e983e7 | |||
| 4a7cc743a9 | |||
| 4398397311 | |||
| 401f9087bc | |||
| dd3698988e | |||
| 3df49002c2 | |||
| 1bf0aedb9f | |||
| 79accd5a6e | |||
| 422d548fce | |||
| 20ec6e955c | |||
| 406a235cbc | |||
| 4d15e56a38 | |||
| 8693111790 | |||
| 8461a521f2 | |||
| 511e2c5124 | |||
| 749dc3d3cb | |||
| 73c9e38f2c | |||
| afe8184d3f | |||
| 7d77bf76aa | |||
| 7f0f1b831e | |||
| d964be0097 | |||
| a2479f539e | |||
| c2c89ec6a3 | |||
| d61e2404ba | |||
| a2be167dfe | |||
| 15ca09e1da | |||
| 2cc07e6366 | |||
| 4dd4fe78a4 | |||
| 0bc22fb6f7 | |||
| 76097a6961 | |||
| 98cbf39fd3 | |||
| d670e246d0 | |||
| 50e7b9a91d | |||
| 5cbc0451ce | |||
| b420054636 | |||
| 143fedee46 | |||
| 88887cac0f | |||
| 579afc99f2 | |||
| 7f5808b9d0 | |||
| 4df5f77071 | |||
| 1bdd527daf | |||
| e5fa1c00d2 | |||
| 18f7b8c79c | |||
| 782468f8e9 | |||
| 202e7d9569 | |||
| 0676a07265 | |||
| f57ce74947 | |||
| 851cfde15b | |||
| 06123137eb | |||
| 6ccf3cb58c | |||
| 030ddaa4ef | |||
| a8886736c4 | |||
| 4fd635e537 | |||
| 6210c457fc | |||
| 82926cfdf0 | |||
| e7a3ca6f6b | |||
| 1ae6f647b7 | |||
| 48941c011f | |||
| a3c4cc6f3d | |||
| 90fbcbd48f | |||
| 6efd96d995 | |||
| 21316e7a45 | |||
| 8adbb7a402 | |||
| 3f19d41908 | |||
| 34da93e0c9 | |||
| 208f506190 | |||
| 0ca715cad9 | |||
| 0f5d8c1c22 | |||
| a56bcbd063 | |||
| 89c3fa751c | |||
| 051644ffcb | |||
| 2a9c282548 | |||
| 2ae80af461 | |||
| 7335ede0e1 | |||
| 6c92ba3805 | |||
| 446f680673 | |||
| 3f56aa2870 | |||
| 3cec91694f | |||
| cb0cfa566f | |||
| a27acebf66 | |||
| 99d3a0ca1a | |||
| 9c962ebc4f | |||
| 99cbbf6606 | |||
| b73e509648 | |||
| b23ff9c0f7 | |||
| 20f9ed9c4c | |||
| 04cb28c315 | |||
| a74ea318d1 | |||
| 98ed6b4e36 | |||
| 2c49d1fd11 | |||
| 6e7bca6631 | |||
| 2fe145bb02 | |||
| 10b7d235e3 | |||
| 232e2e7de2 | |||
| fb1e4b061e | |||
| 0b1a013081 | |||
| a972457f43 | |||
| 67cfa34a05 | |||
| fc2ebb7646 | |||
| e92b461b4f | |||
| b1ac7b5791 | |||
| 88424efe85 | |||
| 4e2aab98a2 | |||
| f4bc1a2fe2 | |||
| a4bf2768b8 | |||
| 47cd44e9da | |||
| 731c6b90ff | |||
| 47ca46905d | |||
| 860ffc5b13 | |||
| 611b2ee520 | |||
| edcb926f9d | |||
| caebff8304 | |||
| 8fa41135ca | |||
| 0debbff964 | |||
| d6cc78be66 | |||
| 8d9645735e | |||
| 4c65f08330 | |||
| 2427f8f078 | |||
| d168e4f934 | |||
| 4dd365589f | |||
| 50e253df29 | |||
| cb71801a2b | |||
| 4a9c74e91d | |||
| 281508ec99 | |||
| feb92626e1 | |||
| 93cadb0880 | |||
| dd6b57aa60 | |||
| b8cb754e9d | |||
| dbe61507bd | |||
| ce7b23d9d0 | |||
| 8ded6ff93e | |||
| 1ef96f3488 | |||
| ee3bf37900 | |||
| 7452a06938 | |||
| fe8f9ed9c4 | |||
| 1b64f74c82 | |||
| c81949046d | |||
| 19dcb913e6 | |||
| e4b5ba1a9d | |||
| 5f1a422d83 | |||
| c5b0b3ef9d | |||
| c0a04cb876 | |||
| 3cc7cdf12f | |||
| 6b531d9967 | |||
| 4d05ac021c | |||
| d29aa84b17 | |||
| a075adc818 | |||
| 4d0e63f99c | |||
| 9e11936ec5 | |||
| a4075ec632 | |||
| dadb59c95f | |||
| e73cc6a9d8 | |||
| 10cd84e37f | |||
| e63e2040cd | |||
| 91063332d7 | |||
| 503330ba5d | |||
| 0a64085f47 | |||
| 1073e2447a | |||
| 5b1a906ace | |||
| aff97e0146 | |||
| a4b41a378b | |||
| 3ec523d168 | |||
| 622cf0d642 | |||
| a540751e83 | |||
| 11b596669a | |||
| fefbae879b | |||
| 695b281409 | |||
| 9f9eae34c1 | |||
| ae37ed3500 | |||
| f7f509999b | |||
| 419bcc4b2f | |||
| 7b59d4f7eb | |||
| 03326e9c04 | |||
| f40b464d1e | |||
| 810ca6c207 | |||
| 8df3aef6aa | |||
| 0223d5a656 | |||
| aad810a204 | |||
| 1b8b7567b1 | |||
| 442040caac | |||
| 65efaafca2 | |||
| e87c8ab0c7 | |||
| be6bda45b4 | |||
| 8c9e40d383 | |||
| 0f6f9b973a | |||
| 3db6039b2b | |||
| 4051217c8b | |||
| c5c28baba1 | |||
| 43618df1d4 | |||
| a2951dccb5 | |||
| b884323c03 | |||
| adeaf839fd | |||
| 40d99010e1 | |||
| 11755d8663 | |||
| 2daa92daf9 | |||
| db2858c661 | |||
| 53adb9aaba | |||
| 168df8b606 | |||
| f9085f2538 | |||
| b159bbdc98 | |||
| a5af3cf105 | |||
| 27ca069db7 | |||
| 000a3274d2 | |||
| 19c7799c31 | |||
| 198ff818c6 | |||
| e80c83ad06 | |||
| 660e0112c6 | |||
| 45c1cabef6 | |||
| 56be2c5e38 | |||
| 4aa9c4f1a3 | |||
| 7be420ad22 | |||
| 40b00623a4 | |||
| ce09ec66c7 | |||
| 97d7c80e2e | |||
| b856ae03bf | |||
| 803b3b891a | |||
| 350081d1a9 | |||
| 1b71b68bb9 | |||
| 4084288dd5 | |||
| d1cd1b7ceb | |||
| 5ed69704b9 | |||
| be6e136cb1 | |||
| d3109abfa4 | |||
| f5ff4a2393 | |||
| 8cc50838dc | |||
| 2c2e71c0ce | |||
| 96b1b18b42 | |||
| f7763bfd17 | |||
| 404e58cb18 | |||
| cd3767e3b9 | |||
| f1867a5ecc | |||
| b5548f62cb | |||
| 52f3bedee7 | |||
| f87237919c | |||
| e8969fb913 | |||
| 74d46bc7dd | |||
| 4b6ea94306 | |||
| 963754bc8c | |||
| 7b5483236c | |||
| 438006407c | |||
| 76c8282ee2 | |||
| f463598b24 | |||
| f4e752a385 | |||
| c37cb21dea | |||
| e0bfc1f8aa | |||
| 544ad4a787 | |||
| 8f163760ed | |||
| 565427cf89 | |||
| e10da2f6d4 | |||
| aa386576d5 | |||
| c73c129b48 | |||
| afe729ac3c | |||
| b6038bae4f | |||
| e6d9787587 | |||
| 44699dc495 | |||
| 991d719dde | |||
| 96a520b555 | |||
| e31df5e9de | |||
| 6763b267b9 | |||
| 24e91208a4 | |||
| 15dec999e7 | |||
| d6b0635d3d | |||
| 336a93264e | |||
| 6398d1cff5 | |||
| 6926ed26ea | |||
| 6253f97a2d | |||
| 37ddbd0eac | |||
| 95fe7c8df2 | |||
| 79ae809020 | |||
| f19e302ba9 | |||
| e9c1d3f4b0 | |||
| 0f577d932b | |||
| 21a02c2e90 | |||
| 4e460d5f09 | |||
| f9de2f6bc6 | |||
| 2daa1b7814 | |||
| f99eeb8567 | |||
| 7069f75cb8 | |||
| 2cac7dac46 | |||
| 913c3c6554 | |||
| a5a4c0c89b | |||
| 8c8aca2fab | |||
| daf8e124ca | |||
| 38c4b724fe | |||
| 4d00487275 | |||
| a6831c26c1 | |||
| c363c7ebdb | |||
| 18ee6daf8a | |||
| 459eb426c3 | |||
| a0d670d2bf | |||
| d7b41212c1 | |||
| 2e1539eba4 | |||
| ee9521d87c | |||
| 8d8fc08bac | |||
| e79d304c79 | |||
| db03f03fd9 | |||
| 957403ebec | |||
| 6c32e1aaeb | |||
| 362e335c0b | |||
| ed6c49f874 | |||
| 47fcec5405 | |||
| d7239a45b6 | |||
| f13fb18c58 | |||
| d29644418d | |||
| ed9e426b26 | |||
| 659febf9ff | |||
| fca1fccfad | |||
| f713d63bab | |||
| 5a45e466cf | |||
| 742b24eb23 | |||
| 03369d2383 | |||
| 2605d662e0 | |||
| e8394ab5b5 | |||
| 8ad156a5c2 | |||
| f2d6fb6239 | |||
| e3a592c38d | |||
| 7e99819dda | |||
| a160d7f98d | |||
| 36cab842e8 | |||
| 7b7b86e327 | |||
| f4bfe638b6 | |||
| 0e9d242f05 | |||
| e24467a8c2 | |||
| b39c370a76 | |||
| 62e4e7cde2 | |||
| f822179f97 | |||
| 47e7e1e548 | |||
| e73b75314b | |||
| 8193a55b4a | |||
| 6036708fa2 | |||
| 4717aa0b6d | |||
| 97ae25ea7d | |||
| 6470ed033b | |||
| b550f9c1d5 | |||
| ee0273ffc3 | |||
| 50fce74b00 | |||
| e29f71d1c9 | |||
| 427ed20801 | |||
| d23e6c285b | |||
| 2c139b45d8 | |||
| 762435e3b7 | |||
| 6383d6b056 | |||
| 3712441ea6 | |||
| 9d0bc882fa | |||
| 90dddf3d3d | |||
| 86abd54d02 | |||
| 4ab5ad5425 | |||
| f9c1b758c3 | |||
| 38cf1bd5ba | |||
| aeda455930 | |||
| 288291b795 | |||
| 7c2073faca | |||
| 5b528ba717 | |||
| 4f731a7250 | |||
| f1ac0031f5 | |||
| e45b9c9030 | |||
| 3cf75c269d | |||
| 585033f372 | |||
| 897506e66a | |||
| e4bf8ffa42 | |||
| 20367a58a6 |
@@ -0,0 +1,31 @@
|
||||
[suppress_function]
|
||||
symbol_version_regexp = LIBVIRT_PRIVATE.*
|
||||
soname_regexp = libvirt\\.so.*
|
||||
|
||||
[suppress_function]
|
||||
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
|
||||
soname_regexp = libvirt-admin\\.so.*
|
||||
|
||||
[suppress_variable]
|
||||
symbol_version_regexp = LIBVIRT_PRIVATE.*
|
||||
soname_regexp = libvirt\\.so.*
|
||||
|
||||
[suppress_variable]
|
||||
symbol_version_regexp = LIBVIRT_ADMIN_PRIVATE.*
|
||||
soname_regexp = libvirt-admin\\.so.*
|
||||
|
||||
[suppress_function]
|
||||
symbol_version_regexp = .*
|
||||
soname_regexp = libvirt_storage_.*\\.so.*
|
||||
|
||||
[suppress_variable]
|
||||
symbol_version_regexp = .*
|
||||
soname_regexp = libvirt_storage_.*\\.so.*
|
||||
|
||||
[suppress_function]
|
||||
symbol_version_regexp = .*
|
||||
soname_regexp = libvirt_driver_.*\\.so.*
|
||||
|
||||
[suppress_variable]
|
||||
symbol_version_regexp = .*
|
||||
soname_regexp = libvirt_driver_.*\\.so.*
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
.build*.log
|
||||
*.rpm
|
||||
i686
|
||||
x86_64
|
||||
libvirt-*.tar.gz
|
||||
libvirt-0.6.0.tar.gz
|
||||
libvirt-0.6.1.tar.gz
|
||||
libvirt-0.6.2.tar.gz
|
||||
libvirt-0.6.3.tar.gz
|
||||
libvirt-0.6.4.tar.gz
|
||||
libvirt-0.6.5.tar.gz
|
||||
libvirt-0.7.0-0.1.gitf055724.tar.gz
|
||||
libvirt-0.7.0-0.6.gite195b43.tar.gz
|
||||
libvirt-0.7.0.tar.gz
|
||||
@@ -0,0 +1,5 @@
|
||||
.build*.log
|
||||
*.rpm
|
||||
i686
|
||||
x86_64
|
||||
libvirt-*.tar.xz
|
||||
@@ -0,0 +1,31 @@
|
||||
From 5629ebcb4234fde10fd9468d5fc5dd4947ed8677 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Tue, 29 Apr 2025 15:49:10 +0100
|
||||
Subject: [PATCH] Fix mocking of virQEMUCapsProbeHVF function
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
src/qemu/qemu_capabilities.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
||||
index ea7c14daa9..488a1a058e 100644
|
||||
--- a/src/qemu/qemu_capabilities.h
|
||||
+++ b/src/qemu/qemu_capabilities.h
|
||||
@@ -943,7 +943,7 @@ bool
|
||||
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
|
||||
|
||||
bool
|
||||
-virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE;
|
||||
+virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE __attribute__((noipa));
|
||||
|
||||
virArch virQEMUCapsArchFromString(const char *arch);
|
||||
const char *virQEMUCapsArchToString(virArch arch);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From 63a3d70697dc44ef2f8b40f7c8e9aa869227a7da Mon Sep 17 00:00:00 2001
|
||||
From: Jiang XueQian <jiangxueqian@gmail.com>
|
||||
Date: Sat, 18 Jan 2025 16:32:10 +0800
|
||||
Subject: [PATCH] nss: Skip empty files and avoid use of uninitialized value
|
||||
Content-type: text/plain
|
||||
|
||||
JSON parser isn't called when reading empty files so `jerr` will be used
|
||||
uninitialized in the original code. Empty files appear when a network
|
||||
has no dhcp clients.
|
||||
|
||||
This patch checks for such files and skip them.
|
||||
|
||||
Fixes: a8d828c88bbdaf83ae78dc06cdd84d5667fcc424
|
||||
Signed-off-by: Jiang XueQian <jiangxueqian@gmail.com>
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
---
|
||||
tools/nss/libvirt_nss_leases.c | 9 +++++++--
|
||||
tools/nss/libvirt_nss_macs.c | 9 +++++++--
|
||||
2 files changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/nss/libvirt_nss_leases.c b/tools/nss/libvirt_nss_leases.c
|
||||
index aea81bb56e..25ea6b0ce2 100644
|
||||
--- a/tools/nss/libvirt_nss_leases.c
|
||||
+++ b/tools/nss/libvirt_nss_leases.c
|
||||
@@ -263,7 +263,7 @@ findLeases(const char *file,
|
||||
enum json_tokener_error jerr;
|
||||
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8;
|
||||
char line[1024];
|
||||
- ssize_t nreadTotal = 0;
|
||||
+ size_t nreadTotal = 0;
|
||||
int rv;
|
||||
|
||||
if ((fd = open(file, O_RDONLY)) < 0) {
|
||||
@@ -290,12 +290,17 @@ findLeases(const char *file,
|
||||
jerr = json_tokener_get_error(tok);
|
||||
} while (jerr == json_tokener_continue);
|
||||
|
||||
+ if (nreadTotal == 0) {
|
||||
+ ret = 0;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
if (jerr == json_tokener_continue) {
|
||||
ERROR("Cannot parse %s: incomplete json found", file);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (nreadTotal > 0 && jerr != json_tokener_success) {
|
||||
+ if (jerr != json_tokener_success) {
|
||||
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr));
|
||||
goto cleanup;
|
||||
}
|
||||
diff --git a/tools/nss/libvirt_nss_macs.c b/tools/nss/libvirt_nss_macs.c
|
||||
index 23229a18f3..bac8c0e1bb 100644
|
||||
--- a/tools/nss/libvirt_nss_macs.c
|
||||
+++ b/tools/nss/libvirt_nss_macs.c
|
||||
@@ -124,7 +124,7 @@ findMACs(const char *file,
|
||||
json_tokener *tok = NULL;
|
||||
enum json_tokener_error jerr;
|
||||
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8;
|
||||
- ssize_t nreadTotal = 0;
|
||||
+ size_t nreadTotal = 0;
|
||||
int rv;
|
||||
size_t i;
|
||||
|
||||
@@ -152,12 +152,17 @@ findMACs(const char *file,
|
||||
jerr = json_tokener_get_error(tok);
|
||||
} while (jerr == json_tokener_continue);
|
||||
|
||||
+ if (nreadTotal == 0) {
|
||||
+ ret = 0;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
if (jerr == json_tokener_continue) {
|
||||
ERROR("Cannot parse %s: incomplete json found", file);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (nreadTotal > 0 && jerr != json_tokener_success) {
|
||||
+ if (jerr != json_tokener_success) {
|
||||
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr));
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
From cd0de70e05475d5f4aa46e578fbb98033d38c06b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Mon, 16 Jun 2025 10:28:37 +0200
|
||||
Subject: [PATCH] qemu: Be more forgiving when acquiring QUERY job when
|
||||
formatting domain XML
|
||||
Content-type: text/plain
|
||||
|
||||
In my previous commit of v11.0.0-rc1~115 I've made QEMU driver
|
||||
implementation for virDomainGetXMLDesc() (qemuDomainGetXMLDesc())
|
||||
acquire QERY job. See its commit message for more info. But this
|
||||
unfortunately broke apps witch fetch domain XML for incoming
|
||||
migration (like virt-manager). The reason is that for incoming
|
||||
migration the VIR_ASYNC_JOB_MIGRATION_IN async job is set, but
|
||||
the mask of allowed synchronous jobs is empty (because QEMU can't
|
||||
talk on monitor really). This makes virDomainObjBeginJob() fail
|
||||
which in turn makes qemuDomainGetXMLDesc() fail too.
|
||||
|
||||
It makes sense for qemuDomainGetXMLDesc() to acquire the job
|
||||
(e.g. so that it's coherent with another thread that might be in
|
||||
the middle of a MODIFY job). But failure to dump XML may be
|
||||
treated as broken daemon (e.g. virt-manager does so).
|
||||
|
||||
Therefore, still try to acquire the QUERY job (if job mask
|
||||
permits it) but, do not treat failure as an error.
|
||||
|
||||
Fixes: 6cc93bf28842526be2fd596a607ebca796b7fb2e
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2369243
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
|
||||
---
|
||||
src/qemu/qemu_driver.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index d2eddbd9ae..6bdeede2e8 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -6158,6 +6158,7 @@ static char
|
||||
{
|
||||
virQEMUDriver *driver = dom->conn->privateData;
|
||||
virDomainObj *vm;
|
||||
+ bool hasJob = false;
|
||||
char *ret = NULL;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_UPDATE_CPU,
|
||||
@@ -6169,8 +6170,10 @@ static char
|
||||
if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0)
|
||||
goto cleanup;
|
||||
|
||||
- if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
|
||||
- goto cleanup;
|
||||
+ if (virDomainNestedJobAllowed(vm->job, VIR_JOB_QUERY) &&
|
||||
+ virDomainObjBeginJob(vm, VIR_JOB_QUERY) >= 0) {
|
||||
+ hasJob = true;
|
||||
+ }
|
||||
|
||||
qemuDomainUpdateCurrentMemorySize(vm);
|
||||
|
||||
@@ -6186,7 +6189,8 @@ static char
|
||||
|
||||
ret = qemuDomainFormatXML(driver, vm, flags);
|
||||
|
||||
- virDomainObjEndJob(vm);
|
||||
+ if (hasJob)
|
||||
+ virDomainObjEndJob(vm);
|
||||
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
@@ -0,0 +1,94 @@
|
||||
From 63e4cbd109374f44e8bd4f8d1af5e2a2c67611bc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 28 Apr 2025 11:42:13 +0100
|
||||
Subject: [PATCH] storage: stop hardcoding paths for mkfs, mount, umount
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
This was always undesirable but now causes problems on Fedora 42
|
||||
where at build time we detect a /sbin path but at runtime this
|
||||
will only exist on upgraded machines, not fresh installs.
|
||||
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
meson.build | 13 -------------
|
||||
src/storage/storage_backend_fs.c | 17 +++--------------
|
||||
2 files changed, 3 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 37b1caa566..14c98b49a1 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1827,23 +1827,10 @@ if conf.has('WITH_LIBVIRTD')
|
||||
endif
|
||||
endif
|
||||
|
||||
- if fs_enable
|
||||
- mount_prog = find_program('mount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
||||
- umount_prog = find_program('umount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
||||
- mkfs_prog = find_program('mkfs', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
|
||||
-
|
||||
- if not mount_prog.found() or not umount_prog.found() or not mkfs_prog.found()
|
||||
- fs_enable = false
|
||||
- endif
|
||||
- endif
|
||||
-
|
||||
if fs_enable
|
||||
use_storage = true
|
||||
|
||||
conf.set('WITH_STORAGE_FS', 1)
|
||||
- conf.set_quoted('MOUNT', mount_prog.full_path())
|
||||
- conf.set_quoted('UMOUNT', umount_prog.full_path())
|
||||
- conf.set_quoted('MKFS', mkfs_prog.full_path())
|
||||
endif
|
||||
endif
|
||||
|
||||
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
|
||||
index fce395d60f..6ec359625a 100644
|
||||
--- a/src/storage/storage_backend_fs.c
|
||||
+++ b/src/storage/storage_backend_fs.c
|
||||
@@ -304,7 +304,7 @@ virStorageBackendFileSystemMount(virStoragePoolObj *pool)
|
||||
if (!(src = virStorageBackendFileSystemGetPoolSource(pool)))
|
||||
return -1;
|
||||
|
||||
- cmd = virStorageBackendFileSystemMountCmd(MOUNT, def, src);
|
||||
+ cmd = virStorageBackendFileSystemMountCmd("mount", def, src);
|
||||
|
||||
/* Mounting a shared FS might take a long time. Don't hold
|
||||
* the pool locked meanwhile. */
|
||||
@@ -362,7 +362,7 @@ virStorageBackendFileSystemStop(virStoragePoolObj *pool)
|
||||
if ((rc = virStorageBackendFileSystemIsMounted(pool)) != 1)
|
||||
return rc;
|
||||
|
||||
- cmd = virCommandNewArgList(UMOUNT, def->target.path, NULL);
|
||||
+ cmd = virCommandNewArgList("umount", def->target.path, NULL);
|
||||
return virCommandRun(cmd, NULL);
|
||||
}
|
||||
#endif /* WITH_STORAGE_FS */
|
||||
@@ -402,18 +402,7 @@ virStorageBackendExecuteMKFS(const char *device,
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
g_autofree char *mkfs = NULL;
|
||||
|
||||
-#if WITH_STORAGE_FS
|
||||
- mkfs = virFindFileInPath(MKFS);
|
||||
-#endif /* WITH_STORAGE_FS */
|
||||
-
|
||||
- if (!mkfs) {
|
||||
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
- _("mkfs is not available on this platform: Failed to make filesystem of type '%1$s' on device '%2$s'"),
|
||||
- format, device);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cmd = virCommandNewArgList(mkfs, "-t", format, NULL);
|
||||
+ cmd = virCommandNewArgList("mkfs", "-t", format, NULL);
|
||||
|
||||
/* use the force, otherwise mkfs.xfs won't overwrite existing fs.
|
||||
* Similarly mkfs.ext2, mkfs.ext3, and mkfs.ext4 require supplying -F
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
To: devel@lists.libvirt.org
|
||||
Subject: [PATCH] util: avoid overflow in hextable buffer
|
||||
Date: Mon, 20 Jan 2025 10:09:24 +0000
|
||||
Message-ID: <20250120100924.3864818-1-berrange@redhat.com>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The assigned string is 17 chars long once the trailing nul is taken
|
||||
into account. This triggers a warning with GCC 15
|
||||
|
||||
src/util/virsystemd.c: In function ‘virSystemdEscapeName’:
|
||||
src/util/virsystemd.c:59:38: error: initializer-string for array of ‘char’ is too long [-Werror=unterminated-string-initialization]
|
||||
59 | static const char hextable[16] = "0123456789abcdef";
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
|
||||
Switch to a dynamically sized array as used in all the other places
|
||||
we have a hextable array.
|
||||
|
||||
See also: https://gcc.gnu.org/PR115185
|
||||
Reported-by: Yaakov Selkowitz <yselkowi@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
src/util/virsystemd.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
|
||||
index 5b772e29dd..d46e5f74fc 100644
|
||||
--- a/src/util/virsystemd.c
|
||||
+++ b/src/util/virsystemd.c
|
||||
@@ -56,7 +56,7 @@ struct _virSystemdActivationEntry {
|
||||
static void virSystemdEscapeName(virBuffer *buf,
|
||||
const char *name)
|
||||
{
|
||||
- static const char hextable[16] = "0123456789abcdef";
|
||||
+ static const char hextable[] = "0123456789abcdef";
|
||||
|
||||
#define ESCAPE(c) \
|
||||
do { \
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From 7ab0f1c2a3fddf46d381f055e49111e3063b4829 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 28 Apr 2025 11:47:34 +0100
|
||||
Subject: [PATCH] util: stop hardcoding numad path
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
From: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
Change the meson rules to always enable numad if on a Linux host, unless
|
||||
the meson options say not to.
|
||||
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
meson.build | 10 +++-------
|
||||
src/util/virnuma.c | 2 +-
|
||||
2 files changed, 4 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 14c98b49a1..767205f44b 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -2028,14 +2028,10 @@ if not get_option('nss').disabled()
|
||||
endif
|
||||
endif
|
||||
|
||||
-if not get_option('numad').disabled() and numactl_dep.found()
|
||||
- numad_prog = find_program('numad', required: get_option('numad'), dirs: libvirt_sbin_path)
|
||||
- if numad_prog.found()
|
||||
- conf.set('WITH_NUMAD', 1)
|
||||
- conf.set_quoted('NUMAD', numad_prog.full_path())
|
||||
- endif
|
||||
+if not get_option('numad').disabled() and numactl_dep.found() and host_machine.system() == 'linux'
|
||||
+ conf.set('WITH_NUMAD', 1)
|
||||
elif get_option('numad').enabled()
|
||||
- error('You must have numactl enabled for numad support.')
|
||||
+ error('You must have a Linux host with numactl enabled for numad support.')
|
||||
endif
|
||||
|
||||
# nwfilter should only be compiled for linux, and only if the
|
||||
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
|
||||
index 9393c20875..67c51630c7 100644
|
||||
--- a/src/util/virnuma.c
|
||||
+++ b/src/util/virnuma.c
|
||||
@@ -61,7 +61,7 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus,
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
char *output = NULL;
|
||||
|
||||
- cmd = virCommandNewArgList(NUMAD, "-w", NULL);
|
||||
+ cmd = virCommandNewArgList("numad", "-w", NULL);
|
||||
virCommandAddArgFormat(cmd, "%d:%llu", vcpus,
|
||||
VIR_DIV_UP(balloon, 1024));
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From b825bb556bd3967bf5422c243b77bd4038e317e2 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Mon, 13 Oct 2025 10:34:51 +0200
|
||||
Subject: [PATCH 1/8] wireshark: Drop needless declaration of
|
||||
proto_register_libvirt() and proto_reg_handoff_libvirt()
|
||||
Content-type: text/plain
|
||||
|
||||
Both proto_register_libvirt() and proto_reg_handoff_libvirt() are
|
||||
declared in packet-libvirt.h which is included from plugin.c.
|
||||
There's no need to provide another declaration in plugin.c.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/plugin.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
|
||||
index 9a83f2ca07..19b25e7b1a 100644
|
||||
--- a/tools/wireshark/src/plugin.c
|
||||
+++ b/tools/wireshark/src/plugin.c
|
||||
@@ -72,9 +72,6 @@ void plugin_register(void)
|
||||
|
||||
#else /* WIRESHARK_VERSION >= 2009000 */
|
||||
|
||||
-void proto_register_libvirt(void);
|
||||
-void proto_reg_handoff_libvirt(void);
|
||||
-
|
||||
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = PLUGIN_VERSION;
|
||||
WS_DLL_PUBLIC_DEF const int plugin_want_major = WIRESHARK_VERSION_MAJOR;
|
||||
WS_DLL_PUBLIC_DEF const int plugin_want_minor = WIRESHARK_VERSION_MINOR;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 41d3b457972bde85991fa7ed6f282370aca4b2af Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <41d3b457972bde85991fa7ed6f282370aca4b2af.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 10 Oct 2025 15:20:05 +0200
|
||||
Subject: [PATCH 2/8] wireshark: Switch header files to #pragma once
|
||||
Content-type: text/plain
|
||||
|
||||
The genxdrstub.pl script generates some header files. But they
|
||||
use the old pattern to guard against multiple inclusion:
|
||||
|
||||
#ifndef SOMETHING_H
|
||||
#define SOMETHING_H
|
||||
...
|
||||
#endif
|
||||
|
||||
Change the script to generate just '#pragma once' used everywhere
|
||||
else in our code.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/util/genxdrstub.pl | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
|
||||
index 8cfda25a27..01b663a88c 100755
|
||||
--- a/tools/wireshark/util/genxdrstub.pl
|
||||
+++ b/tools/wireshark/util/genxdrstub.pl
|
||||
@@ -563,11 +563,8 @@ sub add_header_file {
|
||||
local $self->{header_contents} = [];
|
||||
$self->print("/* *DO NOT MODIFY* this file directly.\n");
|
||||
$self->print(" * This file was generated by $0 from libvirt version $libvirt_version */\n");
|
||||
- my $ucname = uc $name;
|
||||
- $self->print("#ifndef _$ucname\_H_\n");
|
||||
- $self->print("#define _$ucname\_H_\n");
|
||||
+ $self->print("#pragma once\n");
|
||||
$block->();
|
||||
- $self->print("#endif /* _$ucname\_H_ */");
|
||||
push @{ $self->{headers} }, [ $name, delete $self->{header_contents} ];
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
From 02a0e78bf54c903da8922c56bade9b3298ade351 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <02a0e78bf54c903da8922c56bade9b3298ade351.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Mon, 13 Oct 2025 09:04:17 +0200
|
||||
Subject: [PATCH 3/8] wireshark: Move WIRESHARK_VERSION macro definition
|
||||
Content-type: text/plain
|
||||
|
||||
Soon, other parts of the wireshark code will need to
|
||||
differentiate wrt wireshark version. Therefore, move the
|
||||
WIRESHARK_VERSION macro definition among with its deps into
|
||||
packet-libvirt.h.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/packet-libvirt.h | 14 ++++++++++++++
|
||||
tools/wireshark/src/plugin.c | 14 --------------
|
||||
2 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.h b/tools/wireshark/src/packet-libvirt.h
|
||||
index 14e6e13696..15cfcb0534 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.h
|
||||
+++ b/tools/wireshark/src/packet-libvirt.h
|
||||
@@ -19,5 +19,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
+#ifdef WITH_WS_VERSION
|
||||
+# include <wireshark/ws_version.h>
|
||||
+#else
|
||||
+# include <wireshark/config.h>
|
||||
+# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
|
||||
+# define WIRESHARK_VERSION_MINOR VERSION_MINOR
|
||||
+# define WIRESHARK_VERSION_MICRO VERSION_MICRO
|
||||
+#endif
|
||||
+
|
||||
+#define WIRESHARK_VERSION \
|
||||
+ ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
|
||||
+ (WIRESHARK_VERSION_MINOR * 1000) + \
|
||||
+ (WIRESHARK_VERSION_MICRO))
|
||||
+
|
||||
void proto_register_libvirt(void);
|
||||
void proto_reg_handoff_libvirt(void);
|
||||
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
|
||||
index 19b25e7b1a..64317b5280 100644
|
||||
--- a/tools/wireshark/src/plugin.c
|
||||
+++ b/tools/wireshark/src/plugin.c
|
||||
@@ -12,15 +12,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
-#ifdef WITH_WS_VERSION
|
||||
-# include <wireshark/ws_version.h>
|
||||
-#else
|
||||
-# include <wireshark/config.h>
|
||||
-# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
|
||||
-# define WIRESHARK_VERSION_MINOR VERSION_MINOR
|
||||
-# define WIRESHARK_VERSION_MICRO VERSION_MICRO
|
||||
-#endif
|
||||
-
|
||||
#define HAVE_PLUGINS 1
|
||||
#include <wireshark/epan/proto.h>
|
||||
/* plugins are DLLs */
|
||||
@@ -32,11 +23,6 @@
|
||||
/* Let the plugin version be the version of libvirt */
|
||||
#define PLUGIN_VERSION VERSION
|
||||
|
||||
-#define WIRESHARK_VERSION \
|
||||
- ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
|
||||
- (WIRESHARK_VERSION_MINOR * 1000) + \
|
||||
- (WIRESHARK_VERSION_MICRO))
|
||||
-
|
||||
#if WIRESHARK_VERSION < 2005000
|
||||
|
||||
WS_DLL_PUBLIC_DEF const gchar version[] = VERSION;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
From 7374c4ecbd591b02f7be4b2918addc6d5852aafb Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <7374c4ecbd591b02f7be4b2918addc6d5852aafb.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Mon, 13 Oct 2025 09:21:30 +0200
|
||||
Subject: [PATCH 4/8] wireshark: Fix int type of some virNetMessageHeader
|
||||
members
|
||||
Content-type: text/plain
|
||||
|
||||
Our virNetMessageHeader is a struct that's declared as follows:
|
||||
|
||||
struct virNetMessageHeader {
|
||||
unsigned prog;
|
||||
unsigned vers;
|
||||
int proc;
|
||||
virNetMessageType type;
|
||||
unsigned serial;
|
||||
virNetMessageStatus status;
|
||||
};
|
||||
|
||||
Now, per RFC 4506 enums are also encoded as signed integers. This
|
||||
means, that only 'prog', 'vers' and 'serial' are really unsigned
|
||||
integers. The others ('proc', 'type' and 'status') are encoded as
|
||||
signed integers. Fix their type when dissecting.
|
||||
|
||||
While at it, also follow latest trend in wireshark and switch
|
||||
from guint32 to uint32_t.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/packet-libvirt.c | 34 +++++++++++++++++++---------
|
||||
1 file changed, 23 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
||||
index da2aabd98a..af14c6bed7 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.c
|
||||
+++ b/tools/wireshark/src/packet-libvirt.c
|
||||
@@ -92,7 +92,7 @@ typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xd
|
||||
|
||||
typedef struct vir_dissector_index vir_dissector_index_t;
|
||||
struct vir_dissector_index {
|
||||
- guint32 proc;
|
||||
+ int32_t proc;
|
||||
vir_xdr_dissector_t args;
|
||||
vir_xdr_dissector_t ret;
|
||||
vir_xdr_dissector_t msg;
|
||||
@@ -275,8 +275,10 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
||||
}
|
||||
|
||||
static vir_xdr_dissector_t
|
||||
-find_payload_dissector(guint32 proc, guint32 type,
|
||||
- const vir_dissector_index_t *pds, gsize length)
|
||||
+find_payload_dissector(int32_t proc,
|
||||
+ enum vir_net_message_type type,
|
||||
+ const vir_dissector_index_t *pds,
|
||||
+ gsize length)
|
||||
{
|
||||
const vir_dissector_index_t *pd;
|
||||
guint32 first, last, direction;
|
||||
@@ -309,6 +311,10 @@ find_payload_dissector(guint32 proc, guint32 type,
|
||||
return pd->ret;
|
||||
case VIR_NET_MESSAGE:
|
||||
return pd->msg;
|
||||
+ case VIR_NET_STREAM:
|
||||
+ case VIR_NET_STREAM_HOLE:
|
||||
+ /* Handled elsewhere */
|
||||
+ return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -397,8 +403,12 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
#include "libvirt/protocol.h"
|
||||
|
||||
static void
|
||||
-dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
|
||||
- guint32 prog, guint32 proc, guint32 type, guint32 status)
|
||||
+dissect_libvirt_payload(tvbuff_t *tvb,
|
||||
+ proto_tree *tree,
|
||||
+ uint32_t prog,
|
||||
+ int32_t proc,
|
||||
+ int32_t type,
|
||||
+ int32_t status)
|
||||
{
|
||||
gssize payload_length;
|
||||
|
||||
@@ -430,7 +440,8 @@ dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
|
||||
return;
|
||||
|
||||
unknown:
|
||||
- dbg("Cannot determine payload: Prog=%u, Proc=%u, Type=%u, Status=%u", prog, proc, type, status);
|
||||
+ dbg("Cannot determine payload: Prog=%u, Proc=%d, Type=%d, Status=%d",
|
||||
+ prog, proc, type, status);
|
||||
proto_tree_add_item(tree, hf_libvirt_unknown, tvb, VIR_HEADER_LEN, -1, ENC_NA);
|
||||
}
|
||||
|
||||
@@ -439,7 +450,8 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
void *opaque G_GNUC_UNUSED)
|
||||
{
|
||||
goffset offset;
|
||||
- guint32 prog, proc, type, serial, status;
|
||||
+ uint32_t prog, serial;
|
||||
+ int32_t proc, type, status;
|
||||
const value_string *vs;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
|
||||
@@ -448,17 +460,17 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
offset = 4; /* End of length field */
|
||||
prog = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
offset += 4; /* Ignore version header field */
|
||||
- proc = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
- type = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
+ proc = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
+ type = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
serial = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
- status = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
+ status = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
|
||||
val_to_str(prog, program_strings, "%x"));
|
||||
|
||||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
|
||||
if (vs == NULL) {
|
||||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%u", proc);
|
||||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
|
||||
} else {
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 1086888f95a322101f8cf53b63c96600ccbeb882 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <1086888f95a322101f8cf53b63c96600ccbeb882.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 10 Oct 2025 19:16:54 +0200
|
||||
Subject: [PATCH 5/8] wireshark: Don't special case retval of
|
||||
get_program_data() in dissect_libvirt_message()
|
||||
Content-type: text/plain
|
||||
|
||||
The get_program_data() function returns a pointer (in this
|
||||
specific case to an array of procedure strings) which, if
|
||||
non-NULL is then passed val_to_str(). Well, if val_to_str() sees
|
||||
NULL it is treated gracefully, i.e. like if the numeric value
|
||||
'proc' wasn't found in the array.
|
||||
|
||||
Therefore, there's no need to special case call to
|
||||
col_append_fstr(). Both result into the same behaviour.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/packet-libvirt.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
||||
index af14c6bed7..6c729801d4 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.c
|
||||
+++ b/tools/wireshark/src/packet-libvirt.c
|
||||
@@ -469,11 +469,7 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
val_to_str(prog, program_strings, "%x"));
|
||||
|
||||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
|
||||
- if (vs == NULL) {
|
||||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
|
||||
- } else {
|
||||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
||||
- }
|
||||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
||||
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
|
||||
val_to_str(type, type_strings, "%d"), serial,
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 10 Oct 2025 18:23:18 +0200
|
||||
Subject: [PATCH 6/8] wireshark: Introduce and use vir_val_to_str()
|
||||
Content-type: text/plain
|
||||
|
||||
Wireshark offers val_to_str() function which converts numeric
|
||||
value to string by looking up value ('val') in an array ('vs') of
|
||||
<val, string> pairs. If no corresponding string is found, then
|
||||
the value is formatted using given 'fmt' string.
|
||||
|
||||
Starting from wireshark-4.6.0 not only this function gained
|
||||
another argument but also returns a strdup()-ed string. To keep
|
||||
our code simple, let's introduce a wrapper so which can be then
|
||||
adjusted as needed.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/packet-libvirt.c | 17 +++++++++++++----
|
||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
||||
index 6c729801d4..f6ad2c4578 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.c
|
||||
+++ b/tools/wireshark/src/packet-libvirt.c
|
||||
@@ -140,6 +140,15 @@ static const value_string status_strings[] = {
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
+static const char *
|
||||
+G_GNUC_PRINTF(3, 0)
|
||||
+vir_val_to_str(const uint32_t val,
|
||||
+ const value_string *vs,
|
||||
+ const char *fmt)
|
||||
+{
|
||||
+ return val_to_str(val, vs, fmt);
|
||||
+}
|
||||
+
|
||||
static gboolean
|
||||
dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
guint32 maxlen)
|
||||
@@ -466,14 +475,14 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
status = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
|
||||
- val_to_str(prog, program_strings, "%x"));
|
||||
+ vir_val_to_str(prog, program_strings, "%x"));
|
||||
|
||||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
|
||||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
|
||||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
|
||||
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
|
||||
- val_to_str(type, type_strings, "%d"), serial,
|
||||
- val_to_str(status, status_strings, "%d"));
|
||||
+ vir_val_to_str(type, type_strings, "%d"), serial,
|
||||
+ vir_val_to_str(status, status_strings, "%d"));
|
||||
|
||||
if (tree) {
|
||||
gint *hf_proc;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
From 002b9f559d69b92e77ab2d234df6966fecdaf0ec Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <002b9f559d69b92e77ab2d234df6966fecdaf0ec.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 10 Oct 2025 19:13:48 +0200
|
||||
Subject: [PATCH 7/8] wireshark: Don't leak column strings
|
||||
Content-type: text/plain
|
||||
|
||||
One of the problems of using val_to_str() is that it may return a
|
||||
const string from given table ('vs'), OR return an allocated one.
|
||||
Since the caller has no idea which case it is, it resides to safe
|
||||
option and don't free returned string. But that might lead to a
|
||||
memleak. This behaviour is fixed with wireshark-4.6.0 and support
|
||||
for it will be introduced soon. But first, make vir_val_to_str()
|
||||
behave like fixed val_to_str() from newer wireshark: just always
|
||||
allocate the string.
|
||||
|
||||
Now, if val_to_str() needs to allocate new memory it obtains
|
||||
allocator by calling wmem_packet_scope() which is what we may do
|
||||
too.
|
||||
|
||||
Hand in hand with that, we need to free the memory using the
|
||||
correct allocator, hence wmem_free(). But let's put it into a
|
||||
wrapper vir_wmem_free() because just like val_to_str(), it'll
|
||||
need additional argument when adapting to new wireshark.
|
||||
|
||||
Oh, and freeing the memory right after col_add_fstr() is safe as
|
||||
it uses vsnprintf() under the hood to format passed args.
|
||||
|
||||
One last thing, the wmem.h file used to live under epan/wmem/ but
|
||||
then in v3.5.0~240 [1] was moved to wsutil/wmem/.
|
||||
|
||||
1: https://gitlab.com/wireshark/wireshark/-/commit/7f9c1f5f92c131354fc8b2b88d473706786064c0
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
meson.build | 20 ++++++++++++++++
|
||||
tools/wireshark/src/meson.build | 1 +
|
||||
tools/wireshark/src/packet-libvirt.c | 35 ++++++++++++++++++++++------
|
||||
3 files changed, 49 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index bcc18b20e5..a1e0e5ecd5 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1365,6 +1365,26 @@ if wireshark_dep.found()
|
||||
if cc.check_header('wireshark/ws_version.h')
|
||||
conf.set('WITH_WS_VERSION', 1)
|
||||
endif
|
||||
+
|
||||
+ # Find wmem.h
|
||||
+ # But it's not as easy as you'd think. Ubuntu 20.04 has split parts of
|
||||
+ # libwireshark.so into libwsutil.so but:
|
||||
+ # a) wireshark.pc never mentions it,
|
||||
+ # b) libwsutil-dev package doesn't install pkg-config file.
|
||||
+ # Fortunately, it's fixed in 24.04.
|
||||
+ if cc.check_header('wireshark/epan/wmem/wmem.h', dependencies: wireshark_dep)
|
||||
+ conf.set('WITH_WS_EPAN_WMEM', 1)
|
||||
+ elif cc.check_header('wireshark/wsutil/wmem/wmem.h', dependencies: wireshark_dep)
|
||||
+ conf.set('WITH_WS_WSUTIL_WMEM', 1)
|
||||
+ else
|
||||
+ error('Unable to locate wmem.h file')
|
||||
+ endif
|
||||
+
|
||||
+ # TODO: drop wsutil dep once support for Ubuntu 20.04 is dropped
|
||||
+ wsutil_dep = dependency('', required: false)
|
||||
+ if not cc.has_function('wmem_free', dependencies: wireshark_dep)
|
||||
+ wsutil_dep = cc.find_library('wsutil', required: true)
|
||||
+ endif
|
||||
endif
|
||||
|
||||
# generic build dependencies checks
|
||||
diff --git a/tools/wireshark/src/meson.build b/tools/wireshark/src/meson.build
|
||||
index 9b452dc5ca..ba0df913e0 100644
|
||||
--- a/tools/wireshark/src/meson.build
|
||||
+++ b/tools/wireshark/src/meson.build
|
||||
@@ -9,6 +9,7 @@ shared_library(
|
||||
],
|
||||
dependencies: [
|
||||
wireshark_dep,
|
||||
+ wsutil_dep,
|
||||
xdr_dep,
|
||||
tools_dep,
|
||||
],
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
||||
index f6ad2c4578..3178ac6f27 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.c
|
||||
+++ b/tools/wireshark/src/packet-libvirt.c
|
||||
@@ -21,6 +21,11 @@
|
||||
#include <wireshark/epan/proto.h>
|
||||
#include <wireshark/epan/packet.h>
|
||||
#include <wireshark/epan/dissectors/packet-tcp.h>
|
||||
+#ifdef WITH_WS_EPAN_WMEM
|
||||
+# include <wireshark/epan/wmem/wmem.h>
|
||||
+#elif WITH_WS_WSUTIL_WMEM
|
||||
+# include <wireshark/wsutil/wmem/wmem.h>
|
||||
+#endif
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include "packet-libvirt.h"
|
||||
@@ -140,13 +145,19 @@ static const value_string status_strings[] = {
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
-static const char *
|
||||
+static char *
|
||||
G_GNUC_PRINTF(3, 0)
|
||||
vir_val_to_str(const uint32_t val,
|
||||
const value_string *vs,
|
||||
const char *fmt)
|
||||
{
|
||||
- return val_to_str(val, vs, fmt);
|
||||
+ return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+vir_wmem_free(void *ptr)
|
||||
+{
|
||||
+ wmem_free(wmem_packet_scope(), ptr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -462,6 +473,10 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
uint32_t prog, serial;
|
||||
int32_t proc, type, status;
|
||||
const value_string *vs;
|
||||
+ char *prog_str = NULL;
|
||||
+ char *proc_str = NULL;
|
||||
+ char *type_str = NULL;
|
||||
+ char *status_str = NULL;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
|
||||
col_clear(pinfo->cinfo, COL_INFO);
|
||||
@@ -474,15 +489,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
serial = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
status = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
|
||||
- col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
|
||||
- vir_val_to_str(prog, program_strings, "%x"));
|
||||
+ prog_str = vir_val_to_str(prog, program_strings, "%x");
|
||||
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str);
|
||||
+ vir_wmem_free(prog_str);
|
||||
|
||||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
|
||||
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
|
||||
+ proc_str = vir_val_to_str(proc, vs, "%d");
|
||||
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str);
|
||||
+ vir_wmem_free(proc_str);
|
||||
|
||||
+ type_str = vir_val_to_str(type, type_strings, "%d");
|
||||
+ status_str = vir_val_to_str(status, status_strings, "%d");
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
|
||||
- vir_val_to_str(type, type_strings, "%d"), serial,
|
||||
- vir_val_to_str(status, status_strings, "%d"));
|
||||
+ type_str, serial, status_str);
|
||||
+ vir_wmem_free(status_str);
|
||||
+ vir_wmem_free(type_str);
|
||||
|
||||
if (tree) {
|
||||
gint *hf_proc;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -0,0 +1,493 @@
|
||||
From b42a12174c787b99cd6fcb29b44e4b13bd64ee58 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <b42a12174c787b99cd6fcb29b44e4b13bd64ee58.1760476767.git.crobinso@redhat.com>
|
||||
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 10 Oct 2025 15:22:34 +0200
|
||||
Subject: [PATCH 8/8] wireshark: Adapt to wireshark-4.6.0
|
||||
Content-type: text/plain
|
||||
|
||||
The main difference is that wmem_packet_scope() is gone [1] but
|
||||
the packet_info struct has 'pool` member which points to the
|
||||
allocator used for given packet.
|
||||
|
||||
Unfortunately, while we were given pointer to packet_info at the
|
||||
entry level to our dissector (dissect_libvirt() ->
|
||||
tcp_dissect_pdus() -> dissect_libvirt_message()) it was never
|
||||
propagated to generated/primitive dissectors.
|
||||
|
||||
But not all dissectors need to allocate memory, so mark the new
|
||||
argument as unused. And while our generator could be rewritten so
|
||||
that the argument is annotated as unused iff it's really unused,
|
||||
I couldn't bother rewriting it. It's generated code after all.
|
||||
Too much work for little gain.
|
||||
|
||||
Another significant change is that val_to_str() now requires new
|
||||
argument: pointer to allocator to use because it always allocates
|
||||
new memory [2][3].
|
||||
|
||||
1: https://gitlab.com/wireshark/wireshark/-/commit/5ca5c9ca372e06881b23ba9f4fdcb6b479886444
|
||||
2: https://gitlab.com/wireshark/wireshark/-/commit/b63599762468e4cf1783419a5556377604d344bb
|
||||
3: https://gitlab.com/wireshark/wireshark/-/commit/84799be215313e61b83a3eaf074f89d6ee349b8c
|
||||
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/823
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
||||
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||||
---
|
||||
tools/wireshark/src/packet-libvirt.c | 157 +++++++++++++++++++--------
|
||||
tools/wireshark/util/genxdrstub.pl | 18 +--
|
||||
2 files changed, 119 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
|
||||
index 3178ac6f27..c5c8fb4756 100644
|
||||
--- a/tools/wireshark/src/packet-libvirt.c
|
||||
+++ b/tools/wireshark/src/packet-libvirt.c
|
||||
@@ -63,7 +63,7 @@ static gint ett_libvirt_stream_hole = -1;
|
||||
|
||||
#define XDR_PRIMITIVE_DISSECTOR(xtype, ctype, ftype) \
|
||||
static gboolean \
|
||||
- dissect_xdr_##xtype(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf) \
|
||||
+ dissect_xdr_##xtype(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf) \
|
||||
{ \
|
||||
goffset start; \
|
||||
ctype val; \
|
||||
@@ -93,7 +93,7 @@ XDR_PRIMITIVE_DISSECTOR(bool, bool_t, boolean)
|
||||
|
||||
VIR_WARNINGS_RESET
|
||||
|
||||
-typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf);
|
||||
+typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, XDR *xdrs, int hf);
|
||||
|
||||
typedef struct vir_dissector_index vir_dissector_index_t;
|
||||
struct vir_dissector_index {
|
||||
@@ -146,22 +146,32 @@ static const value_string status_strings[] = {
|
||||
};
|
||||
|
||||
static char *
|
||||
-G_GNUC_PRINTF(3, 0)
|
||||
-vir_val_to_str(const uint32_t val,
|
||||
+G_GNUC_PRINTF(4, 0)
|
||||
+vir_val_to_str(packet_info *pinfo,
|
||||
+ const uint32_t val,
|
||||
const value_string *vs,
|
||||
const char *fmt)
|
||||
{
|
||||
- return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
|
||||
+#if WIRESHARK_VERSION < 4006000
|
||||
+ return val_to_str_wmem(pinfo->pool, val, vs, fmt);
|
||||
+#else
|
||||
+ return val_to_str(pinfo->pool, val, vs, fmt);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static void
|
||||
-vir_wmem_free(void *ptr)
|
||||
+vir_wmem_free(packet_info *pinfo,
|
||||
+ void *ptr)
|
||||
{
|
||||
- wmem_free(wmem_packet_scope(), ptr);
|
||||
+ wmem_free(pinfo->pool, ptr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
+dissect_xdr_string(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo G_GNUC_UNUSED,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
guint32 maxlen)
|
||||
{
|
||||
goffset start;
|
||||
@@ -179,7 +189,11 @@ dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
+dissect_xdr_opaque(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
guint32 size)
|
||||
{
|
||||
goffset start;
|
||||
@@ -190,7 +204,7 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
start = xdr_getpos(xdrs);
|
||||
if ((rc = xdr_opaque(xdrs, (caddr_t)val, size))) {
|
||||
gint len = xdr_getpos(xdrs) - start;
|
||||
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
|
||||
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
|
||||
|
||||
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s);
|
||||
} else {
|
||||
@@ -202,7 +216,11 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
+dissect_xdr_bytes(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
guint32 maxlen)
|
||||
{
|
||||
goffset start;
|
||||
@@ -212,7 +230,7 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
start = xdr_getpos(xdrs);
|
||||
if (xdr_bytes(xdrs, (char **)&val, &length, maxlen)) {
|
||||
gint len = xdr_getpos(xdrs) - start;
|
||||
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
|
||||
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
|
||||
|
||||
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s);
|
||||
free(val);
|
||||
@@ -224,7 +242,11 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
+dissect_xdr_pointer(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
vir_xdr_dissector_t dissect)
|
||||
{
|
||||
goffset start;
|
||||
@@ -236,7 +258,7 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
return FALSE;
|
||||
}
|
||||
if (not_null) {
|
||||
- return dissect(tvb, tree, xdrs, hf);
|
||||
+ return dissect(tvb, pinfo, tree, xdrs, hf);
|
||||
} else {
|
||||
proto_item *ti;
|
||||
ti = proto_tree_add_item(tree, hf, tvb, start, xdr_getpos(xdrs) - start, ENC_NA);
|
||||
@@ -246,15 +268,22 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf,
|
||||
- guint32 length, vir_xdr_dissector_t dissect, goffset start)
|
||||
+dissect_xdr_iterable(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_item *ti,
|
||||
+ XDR *xdrs,
|
||||
+ gint ett,
|
||||
+ int rhf,
|
||||
+ guint32 length,
|
||||
+ vir_xdr_dissector_t dissect,
|
||||
+ goffset start)
|
||||
{
|
||||
proto_tree *tree;
|
||||
guint32 i;
|
||||
|
||||
tree = proto_item_add_subtree(ti, ett);
|
||||
for (i = 0; i < length; i++) {
|
||||
- if (!dissect(tvb, tree, xdrs, rhf))
|
||||
+ if (!dissect(tvb, pinfo, tree, xdrs, rhf))
|
||||
return FALSE;
|
||||
}
|
||||
proto_item_set_len(ti, xdr_getpos(xdrs) - start);
|
||||
@@ -262,8 +291,16 @@ dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
||||
- int rhf, const gchar *rtype, guint32 size, vir_xdr_dissector_t dissect)
|
||||
+dissect_xdr_vector(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
+ gint ett,
|
||||
+ int rhf,
|
||||
+ const gchar *rtype,
|
||||
+ guint32 size,
|
||||
+ vir_xdr_dissector_t dissect)
|
||||
{
|
||||
goffset start;
|
||||
proto_item *ti;
|
||||
@@ -271,12 +308,20 @@ dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
||||
start = xdr_getpos(xdrs);
|
||||
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA);
|
||||
proto_item_append_text(ti, " :: %s[%u]", rtype, size);
|
||||
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, size, dissect, start);
|
||||
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, size, dissect, start);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
||||
- int rhf, const gchar *rtype, guint32 maxlen, vir_xdr_dissector_t dissect)
|
||||
+dissect_xdr_array(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf,
|
||||
+ gint ett,
|
||||
+ int rhf,
|
||||
+ const gchar *rtype,
|
||||
+ guint32 maxlen,
|
||||
+ vir_xdr_dissector_t dissect)
|
||||
{
|
||||
goffset start;
|
||||
proto_item *ti;
|
||||
@@ -291,7 +336,7 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
|
||||
|
||||
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA);
|
||||
proto_item_append_text(ti, " :: %s<%u>", rtype, length);
|
||||
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, length, dissect, start);
|
||||
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, length, dissect, start);
|
||||
}
|
||||
|
||||
static vir_xdr_dissector_t
|
||||
@@ -340,7 +385,10 @@ find_payload_dissector(int32_t proc,
|
||||
}
|
||||
|
||||
static void
|
||||
-dissect_libvirt_stream(tvbuff_t *tvb, proto_tree *tree, gint payload_length)
|
||||
+dissect_libvirt_stream(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo G_GNUC_UNUSED,
|
||||
+ proto_tree *tree,
|
||||
+ gint payload_length)
|
||||
{
|
||||
proto_tree_add_item(tree, hf_libvirt_stream, tvb, VIR_HEADER_LEN,
|
||||
payload_length - VIR_HEADER_LEN, ENC_NA);
|
||||
@@ -357,6 +405,7 @@ dissect_libvirt_num_of_fds(tvbuff_t *tvb, proto_tree *tree)
|
||||
|
||||
static void
|
||||
dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED,
|
||||
+ packet_info *pinfo G_GNUC_UNUSED,
|
||||
gint start G_GNUC_UNUSED,
|
||||
gint32 nfds G_GNUC_UNUSED)
|
||||
{
|
||||
@@ -364,8 +413,12 @@ dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED,
|
||||
}
|
||||
|
||||
static void
|
||||
-dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_length,
|
||||
- gint32 status, vir_xdr_dissector_t dissect)
|
||||
+dissect_libvirt_payload_xdr_data(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ gint payload_length,
|
||||
+ gint32 status,
|
||||
+ vir_xdr_dissector_t dissect)
|
||||
{
|
||||
gint32 nfds = 0;
|
||||
gint start = VIR_HEADER_LEN;
|
||||
@@ -384,17 +437,21 @@ dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_l
|
||||
payload_data = (caddr_t)tvb_memdup(NULL, payload_tvb, 0, payload_length);
|
||||
xdrmem_create(&xdrs, payload_data, payload_length, XDR_DECODE);
|
||||
|
||||
- dissect(payload_tvb, tree, &xdrs, -1);
|
||||
+ dissect(payload_tvb, pinfo, tree, &xdrs, -1);
|
||||
|
||||
xdr_destroy(&xdrs);
|
||||
g_free(payload_data);
|
||||
|
||||
if (nfds != 0)
|
||||
- dissect_libvirt_fds(tvb, start + payload_length, nfds);
|
||||
+ dissect_libvirt_fds(tvb, pinfo, start + payload_length, nfds);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
-dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
+dissect_xdr_stream_hole(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ XDR *xdrs,
|
||||
+ int hf)
|
||||
{
|
||||
goffset start;
|
||||
proto_item *ti;
|
||||
@@ -411,10 +468,10 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
tree = proto_item_add_subtree(ti, ett_libvirt_stream_hole);
|
||||
|
||||
hf = hf_libvirt_stream_hole_length;
|
||||
- if (!dissect_xdr_hyper(tvb, tree, xdrs, hf)) return FALSE;
|
||||
+ if (!dissect_xdr_hyper(tvb, pinfo, tree, xdrs, hf)) return FALSE;
|
||||
|
||||
hf = hf_libvirt_stream_hole_flags;
|
||||
- if (!dissect_xdr_u_int(tvb, tree, xdrs, hf)) return FALSE;
|
||||
+ if (!dissect_xdr_u_int(tvb, pinfo, tree, xdrs, hf)) return FALSE;
|
||||
|
||||
proto_item_set_len(ti, xdr_getpos(xdrs) - start);
|
||||
return TRUE;
|
||||
@@ -424,6 +481,7 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
|
||||
static void
|
||||
dissect_libvirt_payload(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
uint32_t prog,
|
||||
int32_t proc,
|
||||
@@ -447,13 +505,13 @@ dissect_libvirt_payload(tvbuff_t *tvb,
|
||||
xd = find_payload_dissector(proc, type, pds, *len);
|
||||
if (xd == NULL)
|
||||
goto unknown;
|
||||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, xd);
|
||||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, xd);
|
||||
} else if (status == VIR_NET_ERROR) {
|
||||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_remote_error);
|
||||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_remote_error);
|
||||
} else if (type == VIR_NET_STREAM) { /* implicitly, status == VIR_NET_CONTINUE */
|
||||
- dissect_libvirt_stream(tvb, tree, payload_length);
|
||||
+ dissect_libvirt_stream(tvb, pinfo, tree, payload_length);
|
||||
} else if (type == VIR_NET_STREAM_HOLE) {
|
||||
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_stream_hole);
|
||||
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_stream_hole);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
@@ -489,21 +547,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
serial = tvb_get_ntohl(tvb, offset); offset += 4;
|
||||
status = tvb_get_ntohil(tvb, offset); offset += 4;
|
||||
|
||||
- prog_str = vir_val_to_str(prog, program_strings, "%x");
|
||||
+ prog_str = vir_val_to_str(pinfo, prog, program_strings, "%x");
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str);
|
||||
- vir_wmem_free(prog_str);
|
||||
+ vir_wmem_free(pinfo, prog_str);
|
||||
|
||||
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
|
||||
- proc_str = vir_val_to_str(proc, vs, "%d");
|
||||
+ proc_str = vir_val_to_str(pinfo, proc, vs, "%d");
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str);
|
||||
- vir_wmem_free(proc_str);
|
||||
+ vir_wmem_free(pinfo, proc_str);
|
||||
|
||||
- type_str = vir_val_to_str(type, type_strings, "%d");
|
||||
- status_str = vir_val_to_str(status, status_strings, "%d");
|
||||
+ type_str = vir_val_to_str(pinfo, type, type_strings, "%d");
|
||||
+ status_str = vir_val_to_str(pinfo, status, status_strings, "%d");
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
|
||||
type_str, serial, status_str);
|
||||
- vir_wmem_free(status_str);
|
||||
- vir_wmem_free(type_str);
|
||||
+ vir_wmem_free(pinfo, status_str);
|
||||
+ vir_wmem_free(pinfo, type_str);
|
||||
|
||||
if (tree) {
|
||||
gint *hf_proc;
|
||||
@@ -532,21 +590,26 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
proto_tree_add_item(libvirt_tree, hf_libvirt_status, tvb, offset, 4, ENC_NA); offset += 4;
|
||||
|
||||
/* Dissect payload remaining */
|
||||
- dissect_libvirt_payload(tvb, libvirt_tree, prog, proc, type, status);
|
||||
+ dissect_libvirt_payload(tvb, pinfo, libvirt_tree, prog, proc, type, status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint
|
||||
-get_message_len(packet_info *pinfo G_GNUC_UNUSED, tvbuff_t *tvb, int offset, void *data G_GNUC_UNUSED)
|
||||
+get_message_len(packet_info *pinfo G_GNUC_UNUSED,
|
||||
+ tvbuff_t *tvb,
|
||||
+ int offset,
|
||||
+ void *data G_GNUC_UNUSED)
|
||||
{
|
||||
return tvb_get_ntohl(tvb, offset);
|
||||
}
|
||||
|
||||
static int
|
||||
-dissect_libvirt(tvbuff_t *tvb, packet_info *pinfo,
|
||||
- proto_tree *tree, void *data G_GNUC_UNUSED)
|
||||
+dissect_libvirt(tvbuff_t *tvb,
|
||||
+ packet_info *pinfo,
|
||||
+ proto_tree *tree,
|
||||
+ void *data G_GNUC_UNUSED)
|
||||
{
|
||||
/* Another magic const - 4; simply, how much bytes
|
||||
* is needed to tell the length of libvirt packet. */
|
||||
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
|
||||
index 01b663a88c..f69695c091 100755
|
||||
--- a/tools/wireshark/util/genxdrstub.pl
|
||||
+++ b/tools/wireshark/util/genxdrstub.pl
|
||||
@@ -250,7 +250,7 @@ sub xdr_type {
|
||||
sub render_caller {
|
||||
my ($self, $hfid) = @_;
|
||||
my $name = $c->rinc( 'dissect_xdr_'.($self->idstrip || lc($self->xdr_type)) );
|
||||
- "$name(tvb, tree, xdrs, hf)";
|
||||
+ "$name(tvb, pinfo, tree, xdrs, hf)";
|
||||
}
|
||||
|
||||
sub ft_type {
|
||||
@@ -345,7 +345,7 @@ BEGIN{::register_profile(
|
||||
sub render_caller {
|
||||
my ($self) = @_;
|
||||
my ($klass) = ref($self) =~ /([^:]+)$/;
|
||||
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
|
||||
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
|
||||
$c->rinc('dissect_xdr_'.lc($klass)),
|
||||
$c->rinc('dissect_xdr_'.$self->reftype->idstrip);
|
||||
}
|
||||
@@ -359,7 +359,7 @@ BEGIN{::register_profile(
|
||||
sub render_caller {
|
||||
my ($self, $hfid) = @_;
|
||||
my ($klass) = ref($self) =~ /([^:]+)$/;
|
||||
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
|
||||
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
|
||||
$c->rinc('dissect_xdr_'.lc($klass)), $self->length || '~0';
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ BEGIN{::register_profile(
|
||||
sub render_caller {
|
||||
my ($self, $hfid) = @_;
|
||||
my ($pname) = reverse split /__/, $hfid;
|
||||
- sprintf 'dissect_xdr_array(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
||||
+ sprintf 'dissect_xdr_array(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
||||
$c->rinc('ett_'.$self->idstrip),
|
||||
$c->rinc("hf_$hfid\__$pname"),
|
||||
$self->reftype->idstrip,
|
||||
@@ -476,7 +476,7 @@ BEGIN{::register_profile(
|
||||
sub render_caller {
|
||||
my ($self, $hfid) = @_;
|
||||
my ($pname) = reverse split /__/, $hfid;
|
||||
- sprintf 'dissect_xdr_vector(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
||||
+ sprintf 'dissect_xdr_vector(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
|
||||
$c->rinc('ett_'.$self->idstrip),
|
||||
$c->rinc("hf_$hfid\__$pname"),
|
||||
$self->reftype->idstrip,
|
||||
@@ -857,7 +857,7 @@ __END__<<DUMMY # Dummy heredoc to disable perl syntax highlighting
|
||||
my ($self, $ident) = @_;
|
||||
return if $self->is_primitive;
|
||||
%>
|
||||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
||||
{
|
||||
return <%= $self->dealias->render_caller($self->ident eq $ident ? undef : $ident) %>;
|
||||
}
|
||||
@@ -865,7 +865,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
||||
<% my ($self, $ident) = @_;
|
||||
my $hfvar = $c->rinc('hf_'.$self->idstrip);
|
||||
%>
|
||||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
||||
{
|
||||
goffset start;
|
||||
proto_item *ti;
|
||||
@@ -890,7 +890,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
||||
}
|
||||
@@ Sym::Type::Enum#render_dissector
|
||||
<% my ($self, $ident) = @_; %>
|
||||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
||||
{
|
||||
goffset start;
|
||||
enum { DUMMY } es;
|
||||
@@ -914,7 +914,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
|
||||
my ($self, $ident) = @_;
|
||||
my $decl_type = $self->decl->type->idstrip;
|
||||
%>
|
||||
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
|
||||
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
|
||||
{
|
||||
gboolean rc = TRUE;
|
||||
goffset start;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# Makefile for source rpm: libvirt
|
||||
# $Id$
|
||||
NAME := libvirt
|
||||
SPECFILE = $(firstword $(wildcard *.spec))
|
||||
|
||||
define find-makefile-common
|
||||
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(find-makefile-common))
|
||||
|
||||
ifeq ($(MAKEFILE_COMMON),)
|
||||
# attempt a checkout
|
||||
define checkout-makefile-common
|
||||
test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
|
||||
endif
|
||||
|
||||
include $(MAKEFILE_COMMON)
|
||||
@@ -1,51 +0,0 @@
|
||||
From 5f8d720b5f1393ee333a5fa8375ffe9ac954d48b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Mon, 17 Aug 2009 08:32:08 +0100
|
||||
Subject: [PATCH] Disable sound cards when running sVirt
|
||||
|
||||
Temporary hack till PulseAudio autostart problems are sorted out when
|
||||
SELinux enforcing (bz 486112)
|
||||
|
||||
Fedora-patch: libvirt-0.6.4-svirt-sound.patch
|
||||
---
|
||||
src/qemu_conf.c | 17 ++++++++++++++++-
|
||||
1 files changed, 16 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
|
||||
index 6b0b404..53186e0 100644
|
||||
--- a/src/qemu_conf.c
|
||||
+++ b/src/qemu_conf.c
|
||||
@@ -1384,6 +1384,20 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||
char domid[50];
|
||||
const char *cpu = NULL;
|
||||
+ int skipSound = 0;
|
||||
+
|
||||
+ if (driver->securityDriver &&
|
||||
+ driver->securityDriver->name &&
|
||||
+ STREQ(driver->securityDriver->name, "selinux") &&
|
||||
+ getuid() == 0) {
|
||||
+ static int soundWarned = 0;
|
||||
+ skipSound = 1;
|
||||
+ if (def->nsounds &&
|
||||
+ !soundWarned) {
|
||||
+ soundWarned = 1;
|
||||
+ VIR_WARN0("Sound cards for VMs are disabled while SELinux security model is active");
|
||||
+ }
|
||||
+ }
|
||||
|
||||
uname_normalize(&ut);
|
||||
|
||||
@@ -2015,7 +2029,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
}
|
||||
|
||||
/* Add sound hardware */
|
||||
- if (def->nsounds) {
|
||||
+ if (def->nsounds &&
|
||||
+ !skipSound) {
|
||||
int size = 100;
|
||||
char *modstr;
|
||||
if (VIR_ALLOC_N(modstr, size+1) < 0)
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
From 541cfdf5465ac3bba2c0c0901950547bc6638e47 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Thu, 6 Aug 2009 15:14:19 +0100
|
||||
Subject: [PATCH] chown kernel/initrd before spawning qemu
|
||||
|
||||
If we're running qemu unprivileged, we need to chown any supplied kernel
|
||||
or initrd before spawning it.
|
||||
|
||||
* src/qemu_driver.c: rename qemuDomainSetDiskOwnership() to
|
||||
qemuDomainSetFileOwnership(), pass it a path string instead of a disk
|
||||
definition and use it for chowning the kernel/initrd in
|
||||
qemuDomainSetAllDeviceOwnership()
|
||||
|
||||
(cherry picked from commit c42b39784534930791d1feb3de859d85a7848168)
|
||||
|
||||
Fedora-patch: libvirt-0.7.0-chown-kernel-initrd-before-spawning-qemu.patch
|
||||
---
|
||||
src/qemu_driver.c | 20 ++++++++++++--------
|
||||
1 files changed, 12 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index 412b68d..bd58435 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -1684,18 +1684,18 @@ static int qemuDomainSetHostdevOwnership(virConnectPtr conn,
|
||||
|
||||
}
|
||||
|
||||
-static int qemuDomainSetDiskOwnership(virConnectPtr conn,
|
||||
- virDomainDiskDefPtr def,
|
||||
+static int qemuDomainSetFileOwnership(virConnectPtr conn,
|
||||
+ const char *path,
|
||||
uid_t uid, gid_t gid)
|
||||
{
|
||||
|
||||
- if (!def->src)
|
||||
+ if (!path)
|
||||
return 0;
|
||||
|
||||
- VIR_DEBUG("Setting ownership on %s to %d:%d", def->src, uid, gid);
|
||||
- if (chown(def->src, uid, gid) < 0) {
|
||||
+ VIR_DEBUG("Setting ownership on %s to %d:%d", path, uid, gid);
|
||||
+ if (chown(path, uid, gid) < 0) {
|
||||
virReportSystemError(conn, errno, _("cannot set ownership on %s"),
|
||||
- def->src);
|
||||
+ path);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1725,7 +1725,7 @@ static int qemuDomainSetDeviceOwnership(virConnectPtr conn,
|
||||
(def->data.disk->readonly || def->data.disk->shared))
|
||||
return 0;
|
||||
|
||||
- return qemuDomainSetDiskOwnership(conn, def->data.disk, uid, gid);
|
||||
+ return qemuDomainSetFileOwnership(conn, def->data.disk->src, uid, gid);
|
||||
|
||||
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||
return qemuDomainSetHostdevOwnership(conn, def->data.hostdev, uid, gid);
|
||||
@@ -1753,12 +1753,16 @@ static int qemuDomainSetAllDeviceOwnership(virConnectPtr conn,
|
||||
uid = restore ? 0 : driver->user;
|
||||
gid = restore ? 0 : driver->group;
|
||||
|
||||
+ if (qemuDomainSetFileOwnership(conn, def->os.kernel, uid, gid) < 0 ||
|
||||
+ qemuDomainSetFileOwnership(conn, def->os.initrd, uid, gid) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
for (i = 0 ; i < def->ndisks ; i++) {
|
||||
if (restore &&
|
||||
(def->disks[i]->readonly || def->disks[i]->shared))
|
||||
continue;
|
||||
|
||||
- if (qemuDomainSetDiskOwnership(conn, def->disks[i], uid, gid) < 0)
|
||||
+ if (qemuDomainSetFileOwnership(conn, def->disks[i]->src, uid, gid) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
From ddf0a7cb04debe60825d11186e68cc6de6fd1dd2 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Mon, 10 Aug 2009 11:16:37 +0100
|
||||
Subject: [PATCH] Handle kernels with no ipv6 support
|
||||
|
||||
If the ipv6 kernel module is not loaded, then we get this when starting
|
||||
a virtual network:
|
||||
|
||||
libvir: Network Config error :
|
||||
cannot enable /proc/sys/net/ipv6/conf/virbr0/disable_ipv6:
|
||||
No such file or directory
|
||||
|
||||
If disable_ipv6 is not present, we should just merrily continue on our
|
||||
way.
|
||||
|
||||
* src/network_driver.c: make networkDisableIPV6() not fail if the kernel
|
||||
has no ipv6 support
|
||||
|
||||
(cherry picked from commit f5a8f969dd92ec2744e1eec5d35288d5fbcded22)
|
||||
|
||||
Fedora-patch: libvirt-0.7.0-handle-kernels-with-no-ipv6-support.patch
|
||||
---
|
||||
src/network_driver.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/network_driver.c b/src/network_driver.c
|
||||
index eaea454..84910ab 100644
|
||||
--- a/src/network_driver.c
|
||||
+++ b/src/network_driver.c
|
||||
@@ -801,6 +801,12 @@ static int networkDisableIPV6(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ if (access(field, W_OK) < 0 && errno == ENOENT) {
|
||||
+ VIR_DEBUG("ipv6 appears to already be disabled on %s", network->def->bridge);
|
||||
+ ret = 0;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
if (virFileWriteStr(field, "1") < 0) {
|
||||
virReportSystemError(conn, errno,
|
||||
_("cannot enable %s"), field);
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
From 663bf081dc6737c7fcc68a7ca1169aca60fbf8e5 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Thu, 13 Aug 2009 11:56:31 +0100
|
||||
Subject: [PATCH] Make LXC / UML drivers robust against NUMA topology brokenness
|
||||
|
||||
Some kernel versions expose broken NUMA topology for some machines.
|
||||
This causes the LXC/UML drivers to fail to start. QEMU driver was
|
||||
already fixed for this problem
|
||||
|
||||
* src/lxc_conf.c: Log and ignore failure to populate NUMA info
|
||||
* src/uml_conf.c: Log and ignore failure to populate NUMA info
|
||||
* src/capabilities.c: Reset nnumaCell to 0 after freeing
|
||||
|
||||
(cherry picked from commit 19bac57b26c2d46ac8a7601158f210f34acdceac)
|
||||
|
||||
Fedora-patch: libvirt-0.7.0-numa-ignore-fail.patch
|
||||
---
|
||||
src/capabilities.c | 1 +
|
||||
src/lxc_conf.c | 12 ++++++++++--
|
||||
src/uml_conf.c | 11 +++++++++--
|
||||
3 files changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/capabilities.c b/src/capabilities.c
|
||||
index c6766b6..193a9fe 100644
|
||||
--- a/src/capabilities.c
|
||||
+++ b/src/capabilities.c
|
||||
@@ -139,6 +139,7 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
|
||||
for (i = 0 ; i < caps->host.nnumaCell ; i++)
|
||||
virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]);
|
||||
VIR_FREE(caps->host.numaCell);
|
||||
+ caps->host.nnumaCell = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/lxc_conf.c b/src/lxc_conf.c
|
||||
index d06a024..fef60ba 100644
|
||||
--- a/src/lxc_conf.c
|
||||
+++ b/src/lxc_conf.c
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "lxc_conf.h"
|
||||
#include "nodeinfo.h"
|
||||
#include "virterror_internal.h"
|
||||
+#include "logging.h"
|
||||
+
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||
|
||||
@@ -46,8 +48,14 @@ virCapsPtr lxcCapsInit(void)
|
||||
0, 0)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
- if (nodeCapsInitNUMA(caps) < 0)
|
||||
- goto no_memory;
|
||||
+ /* Some machines have problematic NUMA toplogy causing
|
||||
+ * unexpected failures. We don't want to break the QEMU
|
||||
+ * driver in this scenario, so log errors & carry on
|
||||
+ */
|
||||
+ if (nodeCapsInitNUMA(caps) < 0) {
|
||||
+ virCapabilitiesFreeNUMAInfo(caps);
|
||||
+ VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
|
||||
+ }
|
||||
|
||||
/* XXX shouldn't 'borrow' KVM's prefix */
|
||||
virCapabilitiesSetMacPrefix(caps, (unsigned char []){ 0x52, 0x54, 0x00 });
|
||||
diff --git a/src/uml_conf.c b/src/uml_conf.c
|
||||
index 48e05a8..4f756d4 100644
|
||||
--- a/src/uml_conf.c
|
||||
+++ b/src/uml_conf.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "nodeinfo.h"
|
||||
#include "verify.h"
|
||||
#include "bridge.h"
|
||||
+#include "logging.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_UML
|
||||
|
||||
@@ -63,8 +64,14 @@ virCapsPtr umlCapsInit(void) {
|
||||
0, 0)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
- if (nodeCapsInitNUMA(caps) < 0)
|
||||
- goto no_memory;
|
||||
+ /* Some machines have problematic NUMA toplogy causing
|
||||
+ * unexpected failures. We don't want to break the QEMU
|
||||
+ * driver in this scenario, so log errors & carry on
|
||||
+ */
|
||||
+ if (nodeCapsInitNUMA(caps) < 0) {
|
||||
+ virCapabilitiesFreeNUMAInfo(caps);
|
||||
+ VIR_WARN0("Failed to query host NUMA topology, disabling NUMA capabilities");
|
||||
+ }
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps,
|
||||
"uml",
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
From d54fc5008d465d192101a0cb78fd02c437dff736 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Mon, 17 Aug 2009 08:32:08 +0100
|
||||
Subject: [PATCH] Policykit rewrite (bug #499970)
|
||||
|
||||
Fedora-patch: libvirt-0.7.0-policy-kit-rewrite.patch
|
||||
---
|
||||
configure.in | 73 ++++++++++++++++++++++++++++--------------
|
||||
qemud/Makefile.am | 11 +++++-
|
||||
qemud/libvirtd.policy | 42 ------------------------
|
||||
qemud/libvirtd.policy-0 | 42 ++++++++++++++++++++++++
|
||||
qemud/libvirtd.policy-1 | 42 ++++++++++++++++++++++++
|
||||
qemud/qemud.c | 4 +-
|
||||
qemud/qemud.h | 4 +-
|
||||
qemud/remote.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--
|
||||
src/remote_internal.c | 7 ++++
|
||||
9 files changed, 230 insertions(+), 76 deletions(-)
|
||||
delete mode 100644 qemud/libvirtd.policy
|
||||
create mode 100644 qemud/libvirtd.policy-0
|
||||
create mode 100644 qemud/libvirtd.policy-1
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 45fa9ed..d28c44a 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -641,40 +641,61 @@ AC_SUBST([SASL_LIBS])
|
||||
dnl PolicyKit library
|
||||
POLKIT_CFLAGS=
|
||||
POLKIT_LIBS=
|
||||
+PKCHECK_PATH=
|
||||
AC_ARG_WITH([polkit],
|
||||
[ --with-polkit use PolicyKit for UNIX socket access checks],
|
||||
[],
|
||||
[with_polkit=check])
|
||||
|
||||
+with_polkit0=no
|
||||
+with_polkit1=no
|
||||
if test "x$with_polkit" = "xyes" -o "x$with_polkit" = "xcheck"; then
|
||||
- PKG_CHECK_MODULES(POLKIT, polkit-dbus >= $POLKIT_REQUIRED,
|
||||
- [with_polkit=yes], [
|
||||
- if test "x$with_polkit" = "xcheck" ; then
|
||||
- with_polkit=no
|
||||
- else
|
||||
- AC_MSG_ERROR(
|
||||
- [You must install PolicyKit >= $POLKIT_REQUIRED to compile libvirt])
|
||||
- fi
|
||||
- ])
|
||||
- if test "x$with_polkit" = "xyes" ; then
|
||||
+ dnl Check for new polkit first - just a binary
|
||||
+ AC_PATH_PROG([PKCHECK_PATH],[pkcheck], [], [/usr/sbin:$PATH])
|
||||
+ if test "x$PKCHECK_PATH" != "x" ; then
|
||||
+ AC_DEFINE_UNQUOTED([PKCHECK_PATH],["$PKCHECK_PATH"],[Location of pkcheck program])
|
||||
AC_DEFINE_UNQUOTED([HAVE_POLKIT], 1,
|
||||
- [use PolicyKit for UNIX socket access checks])
|
||||
-
|
||||
- old_CFLAGS=$CFLAGS
|
||||
- old_LDFLAGS=$LDFLAGS
|
||||
- CFLAGS="$CFLAGS $POLKIT_CFLAGS"
|
||||
- LDFLAGS="$LDFLAGS $POLKIT_LIBS"
|
||||
- AC_CHECK_FUNCS([polkit_context_is_caller_authorized])
|
||||
- CFLAGS="$old_CFLAGS"
|
||||
- LDFLAGS="$old_LDFLAGS"
|
||||
-
|
||||
- AC_PATH_PROG([POLKIT_AUTH], [polkit-auth])
|
||||
- if test "x$POLKIT_AUTH" != "x"; then
|
||||
- AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
|
||||
+ [use PolicyKit for UNIX socket access checks])
|
||||
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT1], 1,
|
||||
+ [use PolicyKit for UNIX socket access checks])
|
||||
+ with_polkit="yes"
|
||||
+ with_polkit1="yes"
|
||||
+ else
|
||||
+ dnl Check for old polkit second - library + binary
|
||||
+ PKG_CHECK_MODULES(POLKIT, polkit-dbus >= $POLKIT_REQUIRED,
|
||||
+ [with_polkit=yes], [
|
||||
+ if test "x$with_polkit" = "xcheck" ; then
|
||||
+ with_polkit=no
|
||||
+ else
|
||||
+ AC_MSG_ERROR(
|
||||
+ [You must install PolicyKit >= $POLKIT_REQUIRED to compile libvirt])
|
||||
+ fi
|
||||
+ ])
|
||||
+ if test "x$with_polkit" = "xyes" ; then
|
||||
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT], 1,
|
||||
+ [use PolicyKit for UNIX socket access checks])
|
||||
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT0], 1,
|
||||
+ [use PolicyKit for UNIX socket access checks])
|
||||
+
|
||||
+ old_CFLAGS=$CFLAGS
|
||||
+ old_LDFLAGS=$LDFLAGS
|
||||
+ CFLAGS="$CFLAGS $POLKIT_CFLAGS"
|
||||
+ LDFLAGS="$LDFLAGS $POLKIT_LIBS"
|
||||
+ AC_CHECK_FUNCS([polkit_context_is_caller_authorized])
|
||||
+ CFLAGS="$old_CFLAGS"
|
||||
+ LDFLAGS="$old_LDFLAGS"
|
||||
+
|
||||
+ AC_PATH_PROG([POLKIT_AUTH], [polkit-auth])
|
||||
+ if test "x$POLKIT_AUTH" != "x"; then
|
||||
+ AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
|
||||
+ fi
|
||||
+ with_polkit0="yes"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_POLKIT], [test "x$with_polkit" = "xyes"])
|
||||
+AM_CONDITIONAL([HAVE_POLKIT0], [test "x$with_polkit0" = "xyes"])
|
||||
+AM_CONDITIONAL([HAVE_POLKIT1], [test "x$with_polkit1" = "xyes"])
|
||||
AC_SUBST([POLKIT_CFLAGS])
|
||||
AC_SUBST([POLKIT_LIBS])
|
||||
|
||||
@@ -1695,7 +1716,11 @@ else
|
||||
AC_MSG_NOTICE([ avahi: no])
|
||||
fi
|
||||
if test "$with_polkit" = "yes" ; then
|
||||
-AC_MSG_NOTICE([ polkit: $POLKIT_CFLAGS $POLKIT_LIBS])
|
||||
+if test "$with_polkit0" = "yes" ; then
|
||||
+AC_MSG_NOTICE([ polkit: $POLKIT_CFLAGS $POLKIT_LIBS (version 0)])
|
||||
+else
|
||||
+AC_MSG_NOTICE([ polkit: $PKCHECK_PATH (version 1)])
|
||||
+fi
|
||||
else
|
||||
AC_MSG_NOTICE([ polkit: no])
|
||||
fi
|
||||
diff --git a/qemud/Makefile.am b/qemud/Makefile.am
|
||||
index 959ff88..3d143da 100644
|
||||
--- a/qemud/Makefile.am
|
||||
+++ b/qemud/Makefile.am
|
||||
@@ -21,7 +21,8 @@ EXTRA_DIST = \
|
||||
remote_protocol.x \
|
||||
libvirtd.conf \
|
||||
libvirtd.init.in \
|
||||
- libvirtd.policy \
|
||||
+ libvirtd.policy-0 \
|
||||
+ libvirtd.policy-1 \
|
||||
libvirtd.sasl \
|
||||
libvirtd.sysconf \
|
||||
libvirtd.aug \
|
||||
@@ -147,7 +148,13 @@ endif
|
||||
libvirtd_LDADD += ../src/libvirt.la
|
||||
|
||||
if HAVE_POLKIT
|
||||
+if HAVE_POLKIT0
|
||||
policydir = $(datadir)/PolicyKit/policy
|
||||
+policyfile = libvirtd.policy-0
|
||||
+else
|
||||
+policydir = $(datadir)/polkit-1/actions
|
||||
+policyfile = libvirtd.policy-1
|
||||
+endif
|
||||
endif
|
||||
|
||||
if HAVE_AVAHI
|
||||
@@ -197,7 +204,7 @@ endif
|
||||
if HAVE_POLKIT
|
||||
install-data-polkit:: install-init
|
||||
mkdir -p $(DESTDIR)$(policydir)
|
||||
- $(INSTALL_DATA) $(srcdir)/libvirtd.policy $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
+ $(INSTALL_DATA) $(srcdir)/$(policyfile) $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
uninstall-data-polkit:: install-init
|
||||
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
|
||||
else
|
||||
diff --git a/qemud/libvirtd.policy b/qemud/libvirtd.policy
|
||||
deleted file mode 100644
|
||||
index b6da946..0000000
|
||||
--- a/qemud/libvirtd.policy
|
||||
+++ /dev/null
|
||||
@@ -1,42 +0,0 @@
|
||||
-<!DOCTYPE policyconfig PUBLIC
|
||||
- "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
- "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
-
|
||||
-<!--
|
||||
-Policy definitions for libvirt daemon
|
||||
-
|
||||
-Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
-
|
||||
-libvirt is licensed to you under the GNU Lesser General Public License
|
||||
-version 2. See COPYING for details.
|
||||
-
|
||||
-NOTE: If you make changes to this file, make sure to validate the file
|
||||
-using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
-file are instantly applied.
|
||||
--->
|
||||
-
|
||||
-<policyconfig>
|
||||
- <action id="org.libvirt.unix.monitor">
|
||||
- <description>Monitor local virtualized systems</description>
|
||||
- <message>System policy prevents monitoring of local virtualized systems</message>
|
||||
- <defaults>
|
||||
- <!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
- even if not part of a session -->
|
||||
- <allow_any>yes</allow_any>
|
||||
- <allow_inactive>yes</allow_inactive>
|
||||
- <allow_active>yes</allow_active>
|
||||
- </defaults>
|
||||
- </action>
|
||||
-
|
||||
- <action id="org.libvirt.unix.manage">
|
||||
- <description>Manage local virtualized systems</description>
|
||||
- <message>System policy prevents management of local virtualized systems</message>
|
||||
- <defaults>
|
||||
- <!-- Only a program in the active host session can use libvirt in
|
||||
- read-write mode for management, and we require user password -->
|
||||
- <allow_any>no</allow_any>
|
||||
- <allow_inactive>no</allow_inactive>
|
||||
- <allow_active>auth_admin_keep_session</allow_active>
|
||||
- </defaults>
|
||||
- </action>
|
||||
-</policyconfig>
|
||||
diff --git a/qemud/libvirtd.policy-0 b/qemud/libvirtd.policy-0
|
||||
new file mode 100644
|
||||
index 0000000..b6da946
|
||||
--- /dev/null
|
||||
+++ b/qemud/libvirtd.policy-0
|
||||
@@ -0,0 +1,42 @@
|
||||
+<!DOCTYPE policyconfig PUBLIC
|
||||
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
+
|
||||
+<!--
|
||||
+Policy definitions for libvirt daemon
|
||||
+
|
||||
+Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
+
|
||||
+libvirt is licensed to you under the GNU Lesser General Public License
|
||||
+version 2. See COPYING for details.
|
||||
+
|
||||
+NOTE: If you make changes to this file, make sure to validate the file
|
||||
+using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
+file are instantly applied.
|
||||
+-->
|
||||
+
|
||||
+<policyconfig>
|
||||
+ <action id="org.libvirt.unix.monitor">
|
||||
+ <description>Monitor local virtualized systems</description>
|
||||
+ <message>System policy prevents monitoring of local virtualized systems</message>
|
||||
+ <defaults>
|
||||
+ <!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
+ even if not part of a session -->
|
||||
+ <allow_any>yes</allow_any>
|
||||
+ <allow_inactive>yes</allow_inactive>
|
||||
+ <allow_active>yes</allow_active>
|
||||
+ </defaults>
|
||||
+ </action>
|
||||
+
|
||||
+ <action id="org.libvirt.unix.manage">
|
||||
+ <description>Manage local virtualized systems</description>
|
||||
+ <message>System policy prevents management of local virtualized systems</message>
|
||||
+ <defaults>
|
||||
+ <!-- Only a program in the active host session can use libvirt in
|
||||
+ read-write mode for management, and we require user password -->
|
||||
+ <allow_any>no</allow_any>
|
||||
+ <allow_inactive>no</allow_inactive>
|
||||
+ <allow_active>auth_admin_keep_session</allow_active>
|
||||
+ </defaults>
|
||||
+ </action>
|
||||
+</policyconfig>
|
||||
diff --git a/qemud/libvirtd.policy-1 b/qemud/libvirtd.policy-1
|
||||
new file mode 100644
|
||||
index 0000000..6fa3a5e
|
||||
--- /dev/null
|
||||
+++ b/qemud/libvirtd.policy-1
|
||||
@@ -0,0 +1,42 @@
|
||||
+<!DOCTYPE policyconfig PUBLIC
|
||||
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
+
|
||||
+<!--
|
||||
+Policy definitions for libvirt daemon
|
||||
+
|
||||
+Copyright (c) 2007 Daniel P. Berrange <berrange redhat com>
|
||||
+
|
||||
+libvirt is licensed to you under the GNU Lesser General Public License
|
||||
+version 2. See COPYING for details.
|
||||
+
|
||||
+NOTE: If you make changes to this file, make sure to validate the file
|
||||
+using the polkit-policy-file-validate(1) tool. Changes made to this
|
||||
+file are instantly applied.
|
||||
+-->
|
||||
+
|
||||
+<policyconfig>
|
||||
+ <action id="org.libvirt.unix.monitor">
|
||||
+ <description>Monitor local virtualized systems</description>
|
||||
+ <message>System policy prevents monitoring of local virtualized systems</message>
|
||||
+ <defaults>
|
||||
+ <!-- Any program can use libvirt in read-only mode for monitoring,
|
||||
+ even if not part of a session -->
|
||||
+ <allow_any>yes</allow_any>
|
||||
+ <allow_inactive>yes</allow_inactive>
|
||||
+ <allow_active>yes</allow_active>
|
||||
+ </defaults>
|
||||
+ </action>
|
||||
+
|
||||
+ <action id="org.libvirt.unix.manage">
|
||||
+ <description>Manage local virtualized systems</description>
|
||||
+ <message>System policy prevents management of local virtualized systems</message>
|
||||
+ <defaults>
|
||||
+ <!-- Only a program in the active host session can use libvirt in
|
||||
+ read-write mode for management, and we require user password -->
|
||||
+ <allow_any>no</allow_any>
|
||||
+ <allow_inactive>no</allow_inactive>
|
||||
+ <allow_active>auth_admin_keep</allow_active>
|
||||
+ </defaults>
|
||||
+ </action>
|
||||
+</policyconfig>
|
||||
diff --git a/qemud/qemud.c b/qemud/qemud.c
|
||||
index 3e551ca..50b0cdd 100644
|
||||
--- a/qemud/qemud.c
|
||||
+++ b/qemud/qemud.c
|
||||
@@ -895,7 +895,7 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
|
||||
}
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_POLKIT
|
||||
+#if HAVE_POLKIT0
|
||||
if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
||||
auth_unix_ro == REMOTE_AUTH_POLKIT) {
|
||||
DBusError derr;
|
||||
@@ -982,7 +982,7 @@ static struct qemud_server *qemudNetworkInit(struct qemud_server *server) {
|
||||
sock = sock->next;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_POLKIT
|
||||
+#if HAVE_POLKIT0
|
||||
if (server->sysbus)
|
||||
dbus_connection_unref(server->sysbus);
|
||||
#endif
|
||||
diff --git a/qemud/qemud.h b/qemud/qemud.h
|
||||
index 254db44..e8ce209 100644
|
||||
--- a/qemud/qemud.h
|
||||
+++ b/qemud/qemud.h
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <sasl/sasl.h>
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_POLKIT
|
||||
+#if HAVE_POLKIT0
|
||||
#include <dbus/dbus.h>
|
||||
#endif
|
||||
|
||||
@@ -253,7 +253,7 @@ struct qemud_server {
|
||||
#if HAVE_SASL
|
||||
char **saslUsernameWhitelist;
|
||||
#endif
|
||||
-#if HAVE_POLKIT
|
||||
+#if HAVE_POLKIT0
|
||||
DBusConnection *sysbus;
|
||||
#endif
|
||||
};
|
||||
diff --git a/qemud/remote.c b/qemud/remote.c
|
||||
index d32d513..490a807 100644
|
||||
--- a/qemud/remote.c
|
||||
+++ b/qemud/remote.c
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <fnmatch.h>
|
||||
#include "virterror_internal.h"
|
||||
|
||||
-#ifdef HAVE_POLKIT
|
||||
+#if HAVE_POLKIT0
|
||||
#include <polkit/polkit.h>
|
||||
#include <polkit-dbus/polkit-dbus.h>
|
||||
#endif
|
||||
@@ -3106,7 +3106,80 @@ remoteDispatchAuthSaslStep (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
#endif /* HAVE_SASL */
|
||||
|
||||
|
||||
-#if HAVE_POLKIT
|
||||
+#if HAVE_POLKIT1
|
||||
+static int
|
||||
+remoteDispatchAuthPolkit (struct qemud_server *server,
|
||||
+ struct qemud_client *client,
|
||||
+ virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
+ remote_error *rerr,
|
||||
+ void *args ATTRIBUTE_UNUSED,
|
||||
+ remote_auth_polkit_ret *ret)
|
||||
+{
|
||||
+ pid_t callerPid;
|
||||
+ uid_t callerUid;
|
||||
+ const char *action;
|
||||
+ int status = -1;
|
||||
+ char pidbuf[50];
|
||||
+ int rv;
|
||||
+
|
||||
+ virMutexLock(&server->lock);
|
||||
+ virMutexLock(&client->lock);
|
||||
+ virMutexUnlock(&server->lock);
|
||||
+
|
||||
+ action = client->readonly ?
|
||||
+ "org.libvirt.unix.monitor" :
|
||||
+ "org.libvirt.unix.manage";
|
||||
+
|
||||
+ const char * const pkcheck [] = {
|
||||
+ PKCHECK_PATH,
|
||||
+ "--action-id", action,
|
||||
+ "--process", pidbuf,
|
||||
+ "--allow-user-interaction",
|
||||
+ NULL
|
||||
+ };
|
||||
+
|
||||
+ REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
|
||||
+ if (client->auth != REMOTE_AUTH_POLKIT) {
|
||||
+ VIR_ERROR0(_("client tried invalid PolicyKit init request"));
|
||||
+ goto authfail;
|
||||
+ }
|
||||
+
|
||||
+ if (qemudGetSocketIdentity(client->fd, &callerUid, &callerPid) < 0) {
|
||||
+ VIR_ERROR0(_("cannot get peer socket identity"));
|
||||
+ goto authfail;
|
||||
+ }
|
||||
+
|
||||
+ VIR_INFO(_("Checking PID %d running as %d"), callerPid, callerUid);
|
||||
+
|
||||
+ rv = snprintf(pidbuf, sizeof pidbuf, "%d", callerPid);
|
||||
+ if (rv < 0 || rv >= sizeof pidbuf) {
|
||||
+ VIR_ERROR(_("Caller PID was too large %d"), callerPid);
|
||||
+ goto authfail;
|
||||
+ }
|
||||
+
|
||||
+ if (virRun(NULL, pkcheck, &status) < 0) {
|
||||
+ VIR_ERROR(_("Cannot invoke %s"), PKCHECK_PATH);
|
||||
+ goto authfail;
|
||||
+ }
|
||||
+ if (status != 0) {
|
||||
+ VIR_ERROR(_("Policy kit denied action %s from pid %d, uid %d, result: %d\n"),
|
||||
+ action, callerPid, callerUid, status);
|
||||
+ goto authfail;
|
||||
+ }
|
||||
+ VIR_INFO(_("Policy allowed action %s from pid %d, uid %d"),
|
||||
+ action, callerPid, callerUid);
|
||||
+ ret->complete = 1;
|
||||
+ client->auth = REMOTE_AUTH_NONE;
|
||||
+
|
||||
+ virMutexUnlock(&client->lock);
|
||||
+ return 0;
|
||||
+
|
||||
+authfail:
|
||||
+ remoteDispatchAuthError(rerr);
|
||||
+ virMutexUnlock(&client->lock);
|
||||
+ return -1;
|
||||
+}
|
||||
+#elif HAVE_POLKIT0
|
||||
static int
|
||||
remoteDispatchAuthPolkit (struct qemud_server *server,
|
||||
struct qemud_client *client,
|
||||
@@ -3217,7 +3290,7 @@ authfail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
-#else /* HAVE_POLKIT */
|
||||
+#else /* !HAVE_POLKIT0 & !HAVE_POLKIT1*/
|
||||
|
||||
static int
|
||||
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
@@ -3231,7 +3304,7 @@ remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
remoteDispatchAuthError(rerr);
|
||||
return -1;
|
||||
}
|
||||
-#endif /* HAVE_POLKIT */
|
||||
+#endif /* HAVE_POLKIT1 */
|
||||
|
||||
|
||||
/***************************************************************
|
||||
diff --git a/src/remote_internal.c b/src/remote_internal.c
|
||||
index a58b768..e98c99b 100644
|
||||
--- a/src/remote_internal.c
|
||||
+++ b/src/remote_internal.c
|
||||
@@ -6201,6 +6201,7 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
|
||||
virConnectAuthPtr auth)
|
||||
{
|
||||
remote_auth_polkit_ret ret;
|
||||
+#if HAVE_POLKIT0
|
||||
int i, allowcb = 0;
|
||||
virConnectCredential cred = {
|
||||
VIR_CRED_EXTERNAL,
|
||||
@@ -6210,8 +6211,10 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
|
||||
NULL,
|
||||
0,
|
||||
};
|
||||
+#endif
|
||||
DEBUG0("Client initialize PolicyKit authentication");
|
||||
|
||||
+#if HAVE_POLKIT0
|
||||
if (auth && auth->cb) {
|
||||
/* Check if the necessary credential type for PolicyKit is supported */
|
||||
for (i = 0 ; i < auth->ncredtype ; i++) {
|
||||
@@ -6220,6 +6223,7 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
|
||||
}
|
||||
|
||||
if (allowcb) {
|
||||
+ DEBUG0("Client run callback for PolicyKit authentication");
|
||||
/* Run the authentication callback */
|
||||
if ((*(auth->cb))(&cred, 1, auth->cbdata) < 0) {
|
||||
virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
|
||||
@@ -6233,6 +6237,9 @@ remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int in_open,
|
||||
} else {
|
||||
DEBUG0("No auth callback provided");
|
||||
}
|
||||
+#else
|
||||
+ DEBUG0("No auth callback required for PolicyKit-1");
|
||||
+#endif
|
||||
|
||||
memset (&ret, 0, sizeof ret);
|
||||
if (call (conn, priv, in_open, REMOTE_PROC_AUTH_POLKIT,
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,465 +0,0 @@
|
||||
From 332979bb680d833529ab9cecac6828c6ce54d731 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Fri, 14 Aug 2009 08:31:10 +0100
|
||||
Subject: [PATCH] Add host PCI device hotplug support
|
||||
|
||||
Attaching a host PCI device to a qemu guest is done with a
|
||||
straightforward 'pci_add pci_addr auto host host=XX:XX.X' command.
|
||||
|
||||
Like with NIC and disk hotplug, we need to retain the guest PCI address
|
||||
assigned by qemu so that we can use it for hot-unplug.
|
||||
|
||||
Identifying a device for detach is done using the host PCI address.
|
||||
|
||||
Managed mode is handled by detaching/resetting the device before
|
||||
attaching it to the guest and re-attaching it after detaching it from
|
||||
the guest.
|
||||
|
||||
(cherry picked from commit 7636ef4630fc15c3d559eceb5b5c4fb1524b7c5a)
|
||||
(cherry picked from commit 0c5b7b93a3cdb197c55d79c2605e9e19e3af43f5)
|
||||
(cherry picked from commit 60ff07585ca8f7e639fed477e2e2cf79ce1c5c21)
|
||||
(cherry picked from commit 4e12af5623e4a962a6bb911af06fa29aa85befba)
|
||||
(cherry picked from commit 4dbecff9fbd5b5d1154bc7a41a5d4dd00533b359)
|
||||
(cherry picked from commit 12edef9a6aca5bd9a2ea18b73ca862f615684d84)
|
||||
(cherry picked from commit 457e05062863a35c7efb35470886b9b83a49d04d)
|
||||
(cherry picked from commit e8ad33931296c67de0538e78d12e21706a826d37)
|
||||
|
||||
Fedora-patch: libvirt-add-pci-hostdev-hotplug-support.patch
|
||||
---
|
||||
src/domain_conf.c | 33 +++++-
|
||||
src/domain_conf.h | 13 +++
|
||||
src/libvirt_private.syms | 2 +
|
||||
src/qemu_driver.c | 266 ++++++++++++++++++++++++++++++++++++++++++++--
|
||||
4 files changed, 300 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/domain_conf.c b/src/domain_conf.c
|
||||
index 2301a96..bad53f7 100644
|
||||
--- a/src/domain_conf.c
|
||||
+++ b/src/domain_conf.c
|
||||
@@ -1977,7 +1977,8 @@ out:
|
||||
static int
|
||||
virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn,
|
||||
const xmlNodePtr node,
|
||||
- virDomainHostdevDefPtr def) {
|
||||
+ virDomainHostdevDefPtr def,
|
||||
+ int flags) {
|
||||
|
||||
int ret = -1;
|
||||
xmlNodePtr cur;
|
||||
@@ -2049,6 +2050,20 @@ virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn,
|
||||
_("pci address needs function id"));
|
||||
goto out;
|
||||
}
|
||||
+ } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
|
||||
+ xmlStrEqual(cur->name, BAD_CAST "state")) {
|
||||
+ char *devaddr = virXMLPropString(cur, "devaddr");
|
||||
+ if (devaddr &&
|
||||
+ sscanf(devaddr, "%x:%x:%x",
|
||||
+ &def->source.subsys.u.pci.guest_addr.domain,
|
||||
+ &def->source.subsys.u.pci.guest_addr.bus,
|
||||
+ &def->source.subsys.u.pci.guest_addr.slot) < 3) {
|
||||
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("Unable to parse devaddr parameter '%s'"),
|
||||
+ devaddr);
|
||||
+ VIR_FREE(devaddr);
|
||||
+ goto out;
|
||||
+ }
|
||||
} else {
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("unknown pci source type '%s'"),
|
||||
@@ -2123,7 +2138,7 @@ virDomainHostdevDefParseXML(virConnectPtr conn,
|
||||
}
|
||||
if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
|
||||
def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
|
||||
- if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def) < 0)
|
||||
+ if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def, flags) < 0)
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
@@ -3937,7 +3952,8 @@ virDomainGraphicsDefFormat(virConnectPtr conn,
|
||||
static int
|
||||
virDomainHostdevDefFormat(virConnectPtr conn,
|
||||
virBufferPtr buf,
|
||||
- virDomainHostdevDefPtr def)
|
||||
+ virDomainHostdevDefPtr def,
|
||||
+ int flags)
|
||||
{
|
||||
const char *mode = virDomainHostdevModeTypeToString(def->mode);
|
||||
const char *type;
|
||||
@@ -3978,6 +3994,15 @@ virDomainHostdevDefFormat(virConnectPtr conn,
|
||||
def->source.subsys.u.pci.bus,
|
||||
def->source.subsys.u.pci.slot,
|
||||
def->source.subsys.u.pci.function);
|
||||
+ if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) {
|
||||
+ virBufferAddLit(buf, " <state");
|
||||
+ if (virHostdevHasValidGuestAddr(def))
|
||||
+ virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'",
|
||||
+ def->source.subsys.u.pci.guest_addr.domain,
|
||||
+ def->source.subsys.u.pci.guest_addr.bus,
|
||||
+ def->source.subsys.u.pci.guest_addr.slot);
|
||||
+ virBufferAddLit(buf, "/>\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
virBufferAddLit(buf, " </source>\n");
|
||||
@@ -4192,7 +4217,7 @@ char *virDomainDefFormat(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
|
||||
for (n = 0 ; n < def->nhostdevs ; n++)
|
||||
- if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
|
||||
+ if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0)
|
||||
goto cleanup;
|
||||
|
||||
virBufferAddLit(&buf, " </devices>\n");
|
||||
diff --git a/src/domain_conf.h b/src/domain_conf.h
|
||||
index 63fca76..44302be 100644
|
||||
--- a/src/domain_conf.h
|
||||
+++ b/src/domain_conf.h
|
||||
@@ -391,6 +391,11 @@ struct _virDomainHostdevDef {
|
||||
unsigned bus;
|
||||
unsigned slot;
|
||||
unsigned function;
|
||||
+ struct {
|
||||
+ unsigned domain;
|
||||
+ unsigned bus;
|
||||
+ unsigned slot;
|
||||
+ } guest_addr;
|
||||
} pci;
|
||||
} u;
|
||||
} subsys;
|
||||
@@ -404,6 +409,14 @@ struct _virDomainHostdevDef {
|
||||
char* target;
|
||||
};
|
||||
|
||||
+static inline int
|
||||
+virHostdevHasValidGuestAddr(virDomainHostdevDefPtr def)
|
||||
+{
|
||||
+ return def->source.subsys.u.pci.guest_addr.domain ||
|
||||
+ def->source.subsys.u.pci.guest_addr.bus ||
|
||||
+ def->source.subsys.u.pci.guest_addr.slot;
|
||||
+}
|
||||
+
|
||||
/* Flags for the 'type' field in next struct */
|
||||
enum virDomainDeviceType {
|
||||
VIR_DOMAIN_DEVICE_DISK,
|
||||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
||||
index 4f1b01f..22131c4 100644
|
||||
--- a/src/libvirt_private.syms
|
||||
+++ b/src/libvirt_private.syms
|
||||
@@ -88,6 +88,8 @@ virDomainGetRootFilesystem;
|
||||
virDomainGraphicsTypeFromString;
|
||||
virDomainGraphicsDefFree;
|
||||
virDomainHostdevDefFree;
|
||||
+virDomainHostdevModeTypeToString;
|
||||
+virDomainHostdevSubsysTypeToString;
|
||||
virDomainInputDefFree;
|
||||
virDomainLifecycleTypeFromString;
|
||||
virDomainLifecycleTypeToString;
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index cbc27c4..99dac52 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -5258,9 +5258,91 @@ cleanup:
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
||||
- virDomainObjPtr vm,
|
||||
- virDomainDeviceDefPtr dev)
|
||||
+static int qemudDomainAttachHostPciDevice(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainObjPtr vm,
|
||||
+ virDomainDeviceDefPtr dev)
|
||||
+{
|
||||
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
+ char *cmd, *reply;
|
||||
+ unsigned domain, bus, slot;
|
||||
+ pciDevice *pci;
|
||||
+
|
||||
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ pci = pciGetDevice(conn,
|
||||
+ hostdev->source.subsys.u.pci.domain,
|
||||
+ hostdev->source.subsys.u.pci.bus,
|
||||
+ hostdev->source.subsys.u.pci.slot,
|
||||
+ hostdev->source.subsys.u.pci.function);
|
||||
+ if (!dev)
|
||||
+ return -1;
|
||||
+
|
||||
+ if ((hostdev->managed && pciDettachDevice(conn, pci) < 0) ||
|
||||
+ pciResetDevice(conn, pci, driver->activePciHostdevs) < 0) {
|
||||
+ pciFreeDevice(conn, pci);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (pciDeviceListAdd(conn, driver->activePciHostdevs, pci) < 0) {
|
||||
+ pciFreeDevice(conn, pci);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ cmd = reply = NULL;
|
||||
+
|
||||
+ if (virAsprintf(&cmd, "pci_add pci_addr=auto host host=%.2x:%.2x.%.1x",
|
||||
+ hostdev->source.subsys.u.pci.bus,
|
||||
+ hostdev->source.subsys.u.pci.slot,
|
||||
+ hostdev->source.subsys.u.pci.function) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ "%s", _("cannot attach host pci device"));
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (strstr(reply, "invalid type: host")) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
|
||||
+ _("PCI device assignment is not supported by this version of qemu"));
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ _("parsing pci_add reply failed: %s"), reply);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ hostdev->source.subsys.u.pci.guest_addr.domain = domain;
|
||||
+ hostdev->source.subsys.u.pci.guest_addr.bus = bus;
|
||||
+ hostdev->source.subsys.u.pci.guest_addr.slot = slot;
|
||||
+
|
||||
+ vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
|
||||
+
|
||||
+ VIR_FREE(reply);
|
||||
+ VIR_FREE(cmd);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ pciDeviceListDel(conn, driver->activePciHostdevs, pci);
|
||||
+
|
||||
+ VIR_FREE(reply);
|
||||
+ VIR_FREE(cmd);
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int qemudDomainAttachHostUsbDevice(virConnectPtr conn,
|
||||
+ virDomainObjPtr vm,
|
||||
+ virDomainDeviceDefPtr dev)
|
||||
{
|
||||
int ret;
|
||||
char *cmd, *reply;
|
||||
@@ -5310,6 +5392,36 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int qemudDomainAttachHostDevice(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainObjPtr vm,
|
||||
+ virDomainDeviceDefPtr dev)
|
||||
+{
|
||||
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
+
|
||||
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
+ _("hostdev mode '%s' not supported"),
|
||||
+ virDomainHostdevModeTypeToString(hostdev->mode));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (qemuDomainSetDeviceOwnership(conn, driver, dev, 0) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ switch (hostdev->source.subsys.type) {
|
||||
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
+ return qemudDomainAttachHostPciDevice(conn, driver, vm, dev);
|
||||
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||
+ return qemudDomainAttachHostUsbDevice(conn, vm, dev);
|
||||
+ default:
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
+ _("hostdev subsys type '%s' not supported"),
|
||||
+ virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int qemudDomainAttachDevice(virDomainPtr dom,
|
||||
const char *xml) {
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
@@ -5411,13 +5523,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
|
||||
}
|
||||
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
||||
ret = qemudDomainAttachNetDevice(dom->conn, driver, vm, dev, qemuCmdFlags);
|
||||
- } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
|
||||
- dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
|
||||
- dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
|
||||
- if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
|
||||
- goto cleanup;
|
||||
-
|
||||
- ret = qemudDomainAttachHostDevice(dom->conn, vm, dev);
|
||||
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
||||
+ ret = qemudDomainAttachHostDevice(dom->conn, driver, vm, dev);
|
||||
} else {
|
||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
_("device type '%s' cannot be attached"),
|
||||
@@ -5630,6 +5737,143 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainObjPtr vm,
|
||||
+ virDomainDeviceDefPtr dev)
|
||||
+{
|
||||
+ virDomainHostdevDefPtr detach;
|
||||
+ char *cmd, *reply;
|
||||
+ int i, ret;
|
||||
+ pciDevice *pci;
|
||||
+
|
||||
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
|
||||
+ unsigned domain = vm->def->hostdevs[i]->source.subsys.u.pci.domain;
|
||||
+ unsigned bus = vm->def->hostdevs[i]->source.subsys.u.pci.bus;
|
||||
+ unsigned slot = vm->def->hostdevs[i]->source.subsys.u.pci.slot;
|
||||
+ unsigned function = vm->def->hostdevs[i]->source.subsys.u.pci.function;
|
||||
+
|
||||
+ if (dev->data.hostdev->source.subsys.u.pci.domain == domain &&
|
||||
+ dev->data.hostdev->source.subsys.u.pci.bus == bus &&
|
||||
+ dev->data.hostdev->source.subsys.u.pci.slot == slot &&
|
||||
+ dev->data.hostdev->source.subsys.u.pci.function == function) {
|
||||
+ detach = vm->def->hostdevs[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!detach) {
|
||||
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ _("host pci device %.4x:%.2x:%.2x.%.1x not found"),
|
||||
+ dev->data.hostdev->source.subsys.u.pci.domain,
|
||||
+ dev->data.hostdev->source.subsys.u.pci.bus,
|
||||
+ dev->data.hostdev->source.subsys.u.pci.slot,
|
||||
+ dev->data.hostdev->source.subsys.u.pci.function);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!virHostdevHasValidGuestAddr(detach)) {
|
||||
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ "%s", _("hostdev cannot be detached - device state missing"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x",
|
||||
+ detach->source.subsys.u.pci.guest_addr.domain,
|
||||
+ detach->source.subsys.u.pci.guest_addr.bus,
|
||||
+ detach->source.subsys.u.pci.guest_addr.slot) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ "%s", _("cannot detach host pci device"));
|
||||
+ VIR_FREE(cmd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG("%s: pci_del reply: %s", vm->def->name, reply);
|
||||
+
|
||||
+ /* If the command fails due to a wrong PCI address qemu prints
|
||||
+ * 'invalid pci address'; nothing is printed on success */
|
||||
+ if (strstr(reply, "Invalid pci address")) {
|
||||
+ qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
||||
+ _("failed to detach host pci device: invalid PCI address %.4x:%.2x:%.2x: %s"),
|
||||
+ detach->source.subsys.u.pci.guest_addr.domain,
|
||||
+ detach->source.subsys.u.pci.guest_addr.bus,
|
||||
+ detach->source.subsys.u.pci.guest_addr.slot,
|
||||
+ reply);
|
||||
+ VIR_FREE(reply);
|
||||
+ VIR_FREE(cmd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ VIR_FREE(reply);
|
||||
+ VIR_FREE(cmd);
|
||||
+
|
||||
+ ret = 0;
|
||||
+
|
||||
+ pci = pciGetDevice(conn,
|
||||
+ detach->source.subsys.u.pci.domain,
|
||||
+ detach->source.subsys.u.pci.bus,
|
||||
+ detach->source.subsys.u.pci.slot,
|
||||
+ detach->source.subsys.u.pci.function);
|
||||
+ if (!pci)
|
||||
+ ret = -1;
|
||||
+ else {
|
||||
+ pciDeviceListDel(conn, driver->activePciHostdevs, pci);
|
||||
+ if (pciResetDevice(conn, pci, driver->activePciHostdevs) < 0)
|
||||
+ ret = -1;
|
||||
+ if (detach->managed && pciReAttachDevice(conn, pci) < 0)
|
||||
+ ret = -1;
|
||||
+ pciFreeDevice(conn, pci);
|
||||
+ }
|
||||
+
|
||||
+ if (i != --vm->def->nhostdevs)
|
||||
+ memmove(&vm->def->hostdevs[i],
|
||||
+ &vm->def->hostdevs[i+1],
|
||||
+ sizeof(*vm->def->hostdevs) * (vm->def->nhostdevs-i));
|
||||
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int qemudDomainDetachHostDevice(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainObjPtr vm,
|
||||
+ virDomainDeviceDefPtr dev)
|
||||
+{
|
||||
+ virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
+ _("hostdev mode '%s' not supported"),
|
||||
+ virDomainHostdevModeTypeToString(hostdev->mode));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ switch (hostdev->source.subsys.type) {
|
||||
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||
+ ret = qemudDomainDetachHostPciDevice(conn, driver, vm, dev);
|
||||
+ break;
|
||||
+ default:
|
||||
+ qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
+ _("hostdev subsys type '%s' not supported"),
|
||||
+ virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (qemuDomainSetDeviceOwnership(conn, driver, dev, 1) < 0)
|
||||
+ VIR_WARN0("Fail to restore disk device ownership");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int qemudDomainDetachDevice(virDomainPtr dom,
|
||||
const char *xml) {
|
||||
struct qemud_driver *driver = dom->conn->privateData;
|
||||
@@ -5670,6 +5914,8 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
|
||||
VIR_WARN0("Fail to restore disk device ownership");
|
||||
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
||||
ret = qemudDomainDetachNetDevice(dom->conn, vm, dev);
|
||||
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
||||
+ ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev);
|
||||
} else
|
||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||
"%s", _("only SCSI or virtio disk device can be detached dynamically"));
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
From 100eb35a80932cd9a162c38ecd2ab8b01894fb61 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Mon, 17 Aug 2009 15:05:22 +0100
|
||||
Subject: [PATCH] Cosmetic change to 'virsh nodedev-list --tree' output
|
||||
|
||||
Maybe it's just me, but I try to select an item from the tree using
|
||||
double-click and get annoyed when "+-" gets included in the selection.
|
||||
|
||||
* src/virsh.c: add a space between "+-" and the node device name
|
||||
in 'virsh nodedev-list --tree'
|
||||
|
||||
(cherry picked from commit 097c818bf00b3777778ffc32fea3a6ed1e741e2b)
|
||||
|
||||
Fedora-patch: libvirt-add-space-to-nodedev-list-tree.patch
|
||||
---
|
||||
src/virsh.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/src/virsh.c b/src/virsh.c
|
||||
index 94c3c4e..2d0cf81 100644
|
||||
--- a/src/virsh.c
|
||||
+++ b/src/virsh.c
|
||||
@@ -5370,6 +5370,8 @@ cmdNodeListDevicesPrint(vshControl *ctl,
|
||||
if (depth && depth < MAX_DEPTH) {
|
||||
indentBuf[indentIdx] = '+';
|
||||
indentBuf[indentIdx+1] = '-';
|
||||
+ indentBuf[indentIdx+2] = ' ';
|
||||
+ indentBuf[indentIdx+3] = '\0';
|
||||
}
|
||||
|
||||
/* Print this device */
|
||||
@@ -5398,7 +5400,7 @@ cmdNodeListDevicesPrint(vshControl *ctl,
|
||||
/* If there is a child device, then print another blank line */
|
||||
if (nextlastdev != -1) {
|
||||
vshPrint(ctl, "%s", indentBuf);
|
||||
- vshPrint(ctl, " |\n");
|
||||
+ vshPrint(ctl, " |\n");
|
||||
}
|
||||
|
||||
/* Finally print all children */
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,812 +0,0 @@
|
||||
From 89eefbd116ae74c3a5cfcfc74a31a40b83c726c3 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Mon, 17 Aug 2009 15:05:23 +0100
|
||||
Subject: [PATCH] Maintain a list of active PCI hostdevs and use it in pciResetDevice()
|
||||
|
||||
https://bugzilla.redhat.com/499678
|
||||
|
||||
First we add a pciDeviceList type and add a qemuGetPciHostDeviceList()
|
||||
function to build a list from a domain definition. Use this in
|
||||
prepare/re-attach to simplify things and eliminate the multiple
|
||||
pciGetDevice() calls.
|
||||
|
||||
Then, as we start/shutdown guests we can add or delete devices as
|
||||
appropriate from a list of active devices.
|
||||
|
||||
Finally, in pciReset(), we can use this to determine whether its safe to
|
||||
reset a device as a side effect of resetting another device.
|
||||
|
||||
(cherry picked from commit 78675b228b76a83f83d64856bfb63b9e14c103a0)
|
||||
(cherry picked from commit e8ad33931296c67de0538e78d12e21706a826d37)
|
||||
|
||||
Fedora-patch: libvirt-allow-pci-hostdev-reset-to-reset-other-devices.patch
|
||||
---
|
||||
src/libvirt_private.syms | 7 +-
|
||||
src/pci.c | 211 +++++++++++++++++++++++++++++++++--------
|
||||
src/pci.h | 23 +++++-
|
||||
src/qemu_conf.h | 3 +
|
||||
src/qemu_driver.c | 237 +++++++++++++++++++++++++++-------------------
|
||||
src/xen_unified.c | 2 +-
|
||||
6 files changed, 339 insertions(+), 144 deletions(-)
|
||||
|
||||
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
||||
index bd63692..4f1b01f 100644
|
||||
--- a/src/libvirt_private.syms
|
||||
+++ b/src/libvirt_private.syms
|
||||
@@ -278,7 +278,12 @@ pciFreeDevice;
|
||||
pciDettachDevice;
|
||||
pciReAttachDevice;
|
||||
pciResetDevice;
|
||||
-
|
||||
+pciDeviceSetManaged;
|
||||
+pciDeviceGetManaged;
|
||||
+pciDeviceListNew;
|
||||
+pciDeviceListFree;
|
||||
+pciDeviceListAdd;
|
||||
+pciDeviceListDel;
|
||||
|
||||
# qparams.h
|
||||
qparam_get_query;
|
||||
diff --git a/src/pci.c b/src/pci.c
|
||||
index 74f7ef0..96e5d6d 100644
|
||||
--- a/src/pci.c
|
||||
+++ b/src/pci.c
|
||||
@@ -63,6 +63,7 @@ struct _pciDevice {
|
||||
unsigned pci_pm_cap_pos;
|
||||
unsigned has_flr : 1;
|
||||
unsigned has_pm_reset : 1;
|
||||
+ unsigned managed : 1;
|
||||
};
|
||||
|
||||
/* For virReportOOMError() and virReportSystemError() */
|
||||
@@ -225,7 +226,7 @@ pciWrite32(pciDevice *dev, unsigned pos, uint32_t val)
|
||||
pciWrite(dev, pos, &buf[0], sizeof(buf));
|
||||
}
|
||||
|
||||
-typedef int (*pciIterPredicate)(pciDevice *, pciDevice *);
|
||||
+typedef int (*pciIterPredicate)(pciDevice *, pciDevice *, void *);
|
||||
|
||||
/* Iterate over available PCI devices calling @predicate
|
||||
* to compare each one to @dev.
|
||||
@@ -236,7 +237,8 @@ static int
|
||||
pciIterDevices(virConnectPtr conn,
|
||||
pciIterPredicate predicate,
|
||||
pciDevice *dev,
|
||||
- pciDevice **matched)
|
||||
+ pciDevice **matched,
|
||||
+ void *data)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
@@ -254,7 +256,7 @@ pciIterDevices(virConnectPtr conn,
|
||||
|
||||
while ((entry = readdir(dir))) {
|
||||
unsigned domain, bus, slot, function;
|
||||
- pciDevice *try;
|
||||
+ pciDevice *check;
|
||||
|
||||
/* Ignore '.' and '..' */
|
||||
if (entry->d_name[0] == '.')
|
||||
@@ -266,18 +268,18 @@ pciIterDevices(virConnectPtr conn,
|
||||
continue;
|
||||
}
|
||||
|
||||
- try = pciGetDevice(conn, domain, bus, slot, function);
|
||||
- if (!try) {
|
||||
+ check = pciGetDevice(conn, domain, bus, slot, function);
|
||||
+ if (!check) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
- if (predicate(try, dev)) {
|
||||
- VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, try->name);
|
||||
- *matched = try;
|
||||
+ if (predicate(dev, check, data)) {
|
||||
+ VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, check->name);
|
||||
+ *matched = check;
|
||||
break;
|
||||
}
|
||||
- pciFreeDevice(conn, try);
|
||||
+ pciFreeDevice(conn, check);
|
||||
}
|
||||
closedir(dir);
|
||||
return ret;
|
||||
@@ -379,63 +381,70 @@ pciDetectPowerManagementReset(pciDevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/* Any devices other than the one supplied on the same domain/bus ? */
|
||||
+/* Any active devices other than the one supplied on the same domain/bus ? */
|
||||
static int
|
||||
-pciSharesBus(pciDevice *a, pciDevice *b)
|
||||
+pciSharesBusWithActive(pciDevice *dev, pciDevice *check, void *data)
|
||||
{
|
||||
- return
|
||||
- a->domain == b->domain &&
|
||||
- a->bus == b->bus &&
|
||||
- (a->slot != b->slot ||
|
||||
- a->function != b->function);
|
||||
-}
|
||||
+ pciDeviceList *activeDevs = data;
|
||||
|
||||
-static int
|
||||
-pciBusContainsOtherDevices(virConnectPtr conn, pciDevice *dev)
|
||||
-{
|
||||
- pciDevice *matched = NULL;
|
||||
- if (pciIterDevices(conn, pciSharesBus, dev, &matched) < 0)
|
||||
- return 1;
|
||||
- if (!matched)
|
||||
+ if (dev->domain != check->domain ||
|
||||
+ dev->bus != check->bus ||
|
||||
+ (check->slot == check->slot &&
|
||||
+ check->function == check->function))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (activeDevs && !pciDeviceListFind(activeDevs, check))
|
||||
return 0;
|
||||
- pciFreeDevice(conn, matched);
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
-/* Is @a the parent of @b ? */
|
||||
+static pciDevice *
|
||||
+pciBusContainsActiveDevices(virConnectPtr conn,
|
||||
+ pciDevice *dev,
|
||||
+ pciDeviceList *activeDevs)
|
||||
+{
|
||||
+ pciDevice *active = NULL;
|
||||
+ if (pciIterDevices(conn, pciSharesBusWithActive,
|
||||
+ dev, &active, activeDevs) < 0)
|
||||
+ return NULL;
|
||||
+ return active;
|
||||
+}
|
||||
+
|
||||
+/* Is @check the parent of @dev ? */
|
||||
static int
|
||||
-pciIsParent(pciDevice *a, pciDevice *b)
|
||||
+pciIsParent(pciDevice *dev, pciDevice *check, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
uint16_t device_class;
|
||||
uint8_t header_type, secondary, subordinate;
|
||||
|
||||
- if (a->domain != b->domain)
|
||||
+ if (dev->domain != check->domain)
|
||||
return 0;
|
||||
|
||||
/* Is it a bridge? */
|
||||
- device_class = pciRead16(a, PCI_CLASS_DEVICE);
|
||||
+ device_class = pciRead16(check, PCI_CLASS_DEVICE);
|
||||
if (device_class != PCI_CLASS_BRIDGE_PCI)
|
||||
return 0;
|
||||
|
||||
/* Is it a plane? */
|
||||
- header_type = pciRead8(a, PCI_HEADER_TYPE);
|
||||
+ header_type = pciRead8(check, PCI_HEADER_TYPE);
|
||||
if ((header_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
|
||||
return 0;
|
||||
|
||||
- secondary = pciRead8(a, PCI_SECONDARY_BUS);
|
||||
- subordinate = pciRead8(a, PCI_SUBORDINATE_BUS);
|
||||
+ secondary = pciRead8(check, PCI_SECONDARY_BUS);
|
||||
+ subordinate = pciRead8(check, PCI_SUBORDINATE_BUS);
|
||||
|
||||
- VIR_DEBUG("%s %s: found parent device %s\n", b->id, b->name, a->name);
|
||||
+ VIR_DEBUG("%s %s: found parent device %s\n", dev->id, dev->name, check->name);
|
||||
|
||||
/* No, it's superman! */
|
||||
- return (b->bus >= secondary && b->bus <= subordinate);
|
||||
+ return (dev->bus >= secondary && dev->bus <= subordinate);
|
||||
}
|
||||
|
||||
static pciDevice *
|
||||
pciGetParentDevice(virConnectPtr conn, pciDevice *dev)
|
||||
{
|
||||
pciDevice *parent = NULL;
|
||||
- pciIterDevices(conn, pciIsParent, dev, &parent);
|
||||
+ pciIterDevices(conn, pciIsParent, dev, &parent, NULL);
|
||||
return parent;
|
||||
}
|
||||
|
||||
@@ -443,9 +452,11 @@ pciGetParentDevice(virConnectPtr conn, pciDevice *dev)
|
||||
* devices behind a bus.
|
||||
*/
|
||||
static int
|
||||
-pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
||||
+pciTrySecondaryBusReset(virConnectPtr conn,
|
||||
+ pciDevice *dev,
|
||||
+ pciDeviceList *activeDevs)
|
||||
{
|
||||
- pciDevice *parent;
|
||||
+ pciDevice *parent, *conflict;
|
||||
uint8_t config_space[PCI_CONF_LEN];
|
||||
uint16_t ctl;
|
||||
int ret = -1;
|
||||
@@ -455,10 +466,10 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
||||
* In future, we could allow it so long as those devices
|
||||
* are not in use by the host or other guests.
|
||||
*/
|
||||
- if (pciBusContainsOtherDevices(conn, dev)) {
|
||||
+ if ((conflict = pciBusContainsActiveDevices(conn, dev, activeDevs))) {
|
||||
pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
- _("Other devices on bus with %s, not doing bus reset"),
|
||||
- dev->name);
|
||||
+ _("Active %s devices on bus with %s, not doing bus reset"),
|
||||
+ conflict->name, dev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -572,10 +583,18 @@ pciInitDevice(virConnectPtr conn, pciDevice *dev)
|
||||
}
|
||||
|
||||
int
|
||||
-pciResetDevice(virConnectPtr conn, pciDevice *dev)
|
||||
+pciResetDevice(virConnectPtr conn,
|
||||
+ pciDevice *dev,
|
||||
+ pciDeviceList *activeDevs)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
+ if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
|
||||
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("Not resetting active device %s"), dev->name);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (!dev->initted && pciInitDevice(conn, dev) < 0)
|
||||
return -1;
|
||||
|
||||
@@ -594,7 +613,7 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
|
||||
|
||||
/* Bus reset is not an option with the root bus */
|
||||
if (ret < 0 && dev->bus != 0)
|
||||
- ret = pciTrySecondaryBusReset(conn, dev);
|
||||
+ ret = pciTrySecondaryBusReset(conn, dev, activeDevs);
|
||||
|
||||
if (ret < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
@@ -890,8 +909,116 @@ pciGetDevice(virConnectPtr conn,
|
||||
void
|
||||
pciFreeDevice(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
||||
{
|
||||
+ if (!dev)
|
||||
+ return;
|
||||
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
|
||||
if (dev->fd >= 0)
|
||||
close(dev->fd);
|
||||
VIR_FREE(dev);
|
||||
}
|
||||
+
|
||||
+void pciDeviceSetManaged(pciDevice *dev, unsigned managed)
|
||||
+{
|
||||
+ dev->managed = !!managed;
|
||||
+}
|
||||
+
|
||||
+unsigned pciDeviceGetManaged(pciDevice *dev)
|
||||
+{
|
||||
+ return dev->managed;
|
||||
+}
|
||||
+
|
||||
+pciDeviceList *
|
||||
+pciDeviceListNew(virConnectPtr conn)
|
||||
+{
|
||||
+ pciDeviceList *list;
|
||||
+
|
||||
+ if (VIR_ALLOC(list) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return list;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pciDeviceListFree(virConnectPtr conn,
|
||||
+ pciDeviceList *list)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (!list)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < list->count; i++) {
|
||||
+ pciFreeDevice(conn, list->devs[i]);
|
||||
+ list->devs[i] = NULL;
|
||||
+ }
|
||||
+
|
||||
+ list->count = 0;
|
||||
+ VIR_FREE(list->devs);
|
||||
+ VIR_FREE(list);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+pciDeviceListAdd(virConnectPtr conn,
|
||||
+ pciDeviceList *list,
|
||||
+ pciDevice *dev)
|
||||
+{
|
||||
+ if (pciDeviceListFind(list, dev)) {
|
||||
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("Device %s is already in use"), dev->name);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ list->devs[list->count++] = dev;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pciDeviceListDel(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
+ pciDeviceList *list,
|
||||
+ pciDevice *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < list->count; i++) {
|
||||
+ if (list->devs[i]->domain != dev->domain ||
|
||||
+ list->devs[i]->bus != dev->bus ||
|
||||
+ list->devs[i]->slot != dev->slot ||
|
||||
+ list->devs[i]->function != dev->function)
|
||||
+ continue;
|
||||
+
|
||||
+ pciFreeDevice(conn, list->devs[i]);
|
||||
+
|
||||
+ if (i != --list->count)
|
||||
+ memmove(&list->devs[i],
|
||||
+ &list->devs[i+1],
|
||||
+ sizeof(*list->devs) * (list->count-i));
|
||||
+
|
||||
+ if (VIR_REALLOC_N(list->devs, list->count) < 0) {
|
||||
+ ; /* not fatal */
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+pciDevice *
|
||||
+pciDeviceListFind(pciDeviceList *list, pciDevice *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < list->count; i++)
|
||||
+ if (list->devs[i]->domain == dev->domain &&
|
||||
+ list->devs[i]->bus == dev->bus &&
|
||||
+ list->devs[i]->slot == dev->slot &&
|
||||
+ list->devs[i]->function == dev->function)
|
||||
+ return list->devs[i];
|
||||
+ return NULL;
|
||||
+}
|
||||
diff --git a/src/pci.h b/src/pci.h
|
||||
index 47882ef..685b0af 100644
|
||||
--- a/src/pci.h
|
||||
+++ b/src/pci.h
|
||||
@@ -27,6 +27,11 @@
|
||||
|
||||
typedef struct _pciDevice pciDevice;
|
||||
|
||||
+typedef struct {
|
||||
+ unsigned count;
|
||||
+ pciDevice **devs;
|
||||
+} pciDeviceList;
|
||||
+
|
||||
pciDevice *pciGetDevice (virConnectPtr conn,
|
||||
unsigned domain,
|
||||
unsigned bus,
|
||||
@@ -39,6 +44,22 @@ int pciDettachDevice (virConnectPtr conn,
|
||||
int pciReAttachDevice (virConnectPtr conn,
|
||||
pciDevice *dev);
|
||||
int pciResetDevice (virConnectPtr conn,
|
||||
- pciDevice *dev);
|
||||
+ pciDevice *dev,
|
||||
+ pciDeviceList *activeDevs);
|
||||
+void pciDeviceSetManaged(pciDevice *dev,
|
||||
+ unsigned managed);
|
||||
+unsigned pciDeviceGetManaged(pciDevice *dev);
|
||||
+
|
||||
+pciDeviceList *pciDeviceListNew (virConnectPtr conn);
|
||||
+void pciDeviceListFree (virConnectPtr conn,
|
||||
+ pciDeviceList *list);
|
||||
+int pciDeviceListAdd (virConnectPtr conn,
|
||||
+ pciDeviceList *list,
|
||||
+ pciDevice *dev);
|
||||
+void pciDeviceListDel (virConnectPtr conn,
|
||||
+ pciDeviceList *list,
|
||||
+ pciDevice *dev);
|
||||
+pciDevice * pciDeviceListFind (pciDeviceList *list,
|
||||
+ pciDevice *dev);
|
||||
|
||||
#endif /* __VIR_PCI_H__ */
|
||||
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
|
||||
index 517626a..ab9d5e1 100644
|
||||
--- a/src/qemu_conf.h
|
||||
+++ b/src/qemu_conf.h
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "threads.h"
|
||||
#include "security.h"
|
||||
#include "cgroup.h"
|
||||
+#include "pci.h"
|
||||
|
||||
#define qemudDebug(fmt, ...) do {} while(0)
|
||||
|
||||
@@ -107,6 +108,8 @@ struct qemud_driver {
|
||||
|
||||
char *securityDriverName;
|
||||
virSecurityDriverPtr securityDriver;
|
||||
+
|
||||
+ pciDeviceList *activePciHostdevs;
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index fd39fc2..cbc27c4 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -128,6 +128,9 @@ static int qemudDomainSetMemoryBalloon(virConnectPtr conn,
|
||||
static int qemudDetectVcpuPIDs(virConnectPtr conn,
|
||||
virDomainObjPtr vm);
|
||||
|
||||
+static int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
|
||||
+ virDomainDefPtr def);
|
||||
+
|
||||
static struct qemud_driver *qemu_driver = NULL;
|
||||
|
||||
static int qemuCgroupControllerActive(struct qemud_driver *driver,
|
||||
@@ -320,6 +323,10 @@ qemuReconnectDomain(struct qemud_driver *driver,
|
||||
goto error;
|
||||
}
|
||||
|
||||
+ if (qemuUpdateActivePciHostdevs(driver, obj->def) < 0) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
if (obj->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
|
||||
driver->securityDriver &&
|
||||
driver->securityDriver->domainReserveSecurityLabel &&
|
||||
@@ -524,6 +531,9 @@ qemudStartup(int privileged) {
|
||||
if ((qemu_driver->caps = qemudCapsInit(NULL)) == NULL)
|
||||
goto out_of_memory;
|
||||
|
||||
+ if ((qemu_driver->activePciHostdevs = pciDeviceListNew(NULL)) == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
|
||||
goto error;
|
||||
}
|
||||
@@ -648,6 +658,7 @@ qemudShutdown(void) {
|
||||
return -1;
|
||||
|
||||
qemuDriverLock(qemu_driver);
|
||||
+ pciDeviceListFree(NULL, qemu_driver->activePciHostdevs);
|
||||
virCapabilitiesFree(qemu_driver->caps);
|
||||
|
||||
virDomainObjListFree(&qemu_driver->domains);
|
||||
@@ -1329,48 +1340,16 @@ static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static int qemuPrepareHostDevices(virConnectPtr conn,
|
||||
- virDomainDefPtr def) {
|
||||
+static pciDeviceList *
|
||||
+qemuGetPciHostDeviceList(virConnectPtr conn,
|
||||
+ virDomainDefPtr def)
|
||||
+{
|
||||
+ pciDeviceList *list;
|
||||
int i;
|
||||
|
||||
- /* We have to use 2 loops here. *All* devices must
|
||||
- * be detached before we reset any of them, because
|
||||
- * in some cases you have to reset the whole PCI,
|
||||
- * which impacts all devices on it
|
||||
- */
|
||||
-
|
||||
- for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
-
|
||||
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
- continue;
|
||||
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
||||
- continue;
|
||||
-
|
||||
- if (hostdev->managed) {
|
||||
- pciDevice *dev = pciGetDevice(conn,
|
||||
- hostdev->source.subsys.u.pci.domain,
|
||||
- hostdev->source.subsys.u.pci.bus,
|
||||
- hostdev->source.subsys.u.pci.slot,
|
||||
- hostdev->source.subsys.u.pci.function);
|
||||
- if (!dev)
|
||||
- goto error;
|
||||
-
|
||||
- if (pciDettachDevice(conn, dev) < 0) {
|
||||
- pciFreeDevice(conn, dev);
|
||||
- goto error;
|
||||
- }
|
||||
-
|
||||
- pciFreeDevice(conn, dev);
|
||||
- } /* else {
|
||||
- XXX validate that non-managed device isn't in use, eg
|
||||
- by checking that device is either un-bound, or bound
|
||||
- to pci-stub.ko
|
||||
- } */
|
||||
- }
|
||||
+ if (!(list = pciDeviceListNew(conn)))
|
||||
+ return NULL;
|
||||
|
||||
- /* Now that all the PCI hostdevs have be dettached, we can safely
|
||||
- * reset them */
|
||||
for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
pciDevice *dev;
|
||||
@@ -1385,95 +1364,151 @@ static int qemuPrepareHostDevices(virConnectPtr conn,
|
||||
hostdev->source.subsys.u.pci.bus,
|
||||
hostdev->source.subsys.u.pci.slot,
|
||||
hostdev->source.subsys.u.pci.function);
|
||||
- if (!dev)
|
||||
- goto error;
|
||||
+ if (!dev) {
|
||||
+ pciDeviceListFree(conn, list);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- if (pciResetDevice(conn, dev) < 0) {
|
||||
+ if (pciDeviceListAdd(conn, list, dev) < 0) {
|
||||
pciFreeDevice(conn, dev);
|
||||
- goto error;
|
||||
+ pciDeviceListFree(conn, list);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- pciFreeDevice(conn, dev);
|
||||
+ pciDeviceSetManaged(dev, hostdev->managed);
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return list;
|
||||
+}
|
||||
|
||||
-error:
|
||||
- return -1;
|
||||
+static int
|
||||
+qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
|
||||
+ virDomainDefPtr def)
|
||||
+{
|
||||
+ pciDeviceList *pcidevs;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ if (!def->nhostdevs)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!(pcidevs = qemuGetPciHostDeviceList(NULL, def)))
|
||||
+ return -1;
|
||||
+
|
||||
+ ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < pcidevs->count; i++) {
|
||||
+ if (pciDeviceListAdd(NULL,
|
||||
+ driver->activePciHostdevs,
|
||||
+ pcidevs->devs[i]) < 0) {
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ pcidevs->devs[i] = NULL;
|
||||
+ }
|
||||
+
|
||||
+ pciDeviceListFree(NULL, pcidevs);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-static void
|
||||
-qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
|
||||
+static int
|
||||
+qemuPrepareHostDevices(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainDefPtr def)
|
||||
{
|
||||
+ pciDeviceList *pcidevs;
|
||||
int i;
|
||||
|
||||
- /* Again 2 loops; reset all the devices before re-attach */
|
||||
+ if (!def->nhostdevs)
|
||||
+ return 0;
|
||||
|
||||
- for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
- pciDevice *dev;
|
||||
+ if (!(pcidevs = qemuGetPciHostDeviceList(conn, def)))
|
||||
+ return -1;
|
||||
|
||||
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
- continue;
|
||||
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
||||
- continue;
|
||||
+ /* We have to use 3 loops here. *All* devices must
|
||||
+ * be detached before we reset any of them, because
|
||||
+ * in some cases you have to reset the whole PCI,
|
||||
+ * which impacts all devices on it. Also, all devices
|
||||
+ * must be reset before being marked as active.
|
||||
+ */
|
||||
|
||||
- dev = pciGetDevice(conn,
|
||||
- hostdev->source.subsys.u.pci.domain,
|
||||
- hostdev->source.subsys.u.pci.bus,
|
||||
- hostdev->source.subsys.u.pci.slot,
|
||||
- hostdev->source.subsys.u.pci.function);
|
||||
- if (!dev) {
|
||||
- virErrorPtr err = virGetLastError();
|
||||
- VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
|
||||
- err ? err->message : "");
|
||||
- virResetError(err);
|
||||
- continue;
|
||||
- }
|
||||
+ /* XXX validate that non-managed device isn't in use, eg
|
||||
+ * by checking that device is either un-bound, or bound
|
||||
+ * to pci-stub.ko
|
||||
+ */
|
||||
|
||||
- if (pciResetDevice(conn, dev) < 0) {
|
||||
- virErrorPtr err = virGetLastError();
|
||||
- VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
||||
- err ? err->message : "");
|
||||
- virResetError(err);
|
||||
- }
|
||||
+ for (i = 0; i < pcidevs->count; i++)
|
||||
+ if (pciDeviceGetManaged(pcidevs->devs[i]) &&
|
||||
+ pciDettachDevice(conn, pcidevs->devs[i]) < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ /* Now that all the PCI hostdevs have be dettached, we can safely
|
||||
+ * reset them */
|
||||
+ for (i = 0; i < pcidevs->count; i++)
|
||||
+ if (pciResetDevice(conn, pcidevs->devs[i],
|
||||
+ driver->activePciHostdevs) < 0)
|
||||
+ goto error;
|
||||
|
||||
- pciFreeDevice(conn, dev);
|
||||
+ /* Now mark all the devices as active */
|
||||
+ for (i = 0; i < pcidevs->count; i++) {
|
||||
+ if (pciDeviceListAdd(conn,
|
||||
+ driver->activePciHostdevs,
|
||||
+ pcidevs->devs[i]) < 0)
|
||||
+ goto error;
|
||||
+ pcidevs->devs[i] = NULL;
|
||||
}
|
||||
|
||||
- for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
- virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
- pciDevice *dev;
|
||||
+ pciDeviceListFree(conn, pcidevs);
|
||||
+ return 0;
|
||||
|
||||
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
- continue;
|
||||
- if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
||||
- continue;
|
||||
- if (!hostdev->managed)
|
||||
- continue;
|
||||
+error:
|
||||
+ pciDeviceListFree(conn, pcidevs);
|
||||
+ return -1;
|
||||
+}
|
||||
|
||||
- dev = pciGetDevice(conn,
|
||||
- hostdev->source.subsys.u.pci.domain,
|
||||
- hostdev->source.subsys.u.pci.bus,
|
||||
- hostdev->source.subsys.u.pci.slot,
|
||||
- hostdev->source.subsys.u.pci.function);
|
||||
- if (!dev) {
|
||||
+static void
|
||||
+qemuDomainReAttachHostDevices(virConnectPtr conn,
|
||||
+ struct qemud_driver *driver,
|
||||
+ virDomainDefPtr def)
|
||||
+{
|
||||
+ pciDeviceList *pcidevs;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!def->nhostdevs)
|
||||
+ return;
|
||||
+
|
||||
+ if (!(pcidevs = qemuGetPciHostDeviceList(conn, def))) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
+ VIR_ERROR(_("Failed to allocate pciDeviceList: %s\n"),
|
||||
+ err ? err->message : "");
|
||||
+ virResetError(err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Again 3 loops; mark all devices as inactive before reset
|
||||
+ * them and reset all the devices before re-attach */
|
||||
+
|
||||
+ for (i = 0; i < pcidevs->count; i++)
|
||||
+ pciDeviceListDel(conn, driver->activePciHostdevs, pcidevs->devs[i]);
|
||||
+
|
||||
+ for (i = 0; i < pcidevs->count; i++)
|
||||
+ if (pciResetDevice(conn, pcidevs->devs[i],
|
||||
+ driver->activePciHostdevs) < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
- VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
|
||||
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
||||
err ? err->message : "");
|
||||
virResetError(err);
|
||||
- continue;
|
||||
}
|
||||
|
||||
- if (pciReAttachDevice(conn, dev) < 0) {
|
||||
+ for (i = 0; i < pcidevs->count; i++)
|
||||
+ if (pciDeviceGetManaged(pcidevs->devs[i]) &&
|
||||
+ pciReAttachDevice(conn, pcidevs->devs[i]) < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
|
||||
err ? err->message : "");
|
||||
virResetError(err);
|
||||
}
|
||||
|
||||
- pciFreeDevice(conn, dev);
|
||||
- }
|
||||
+ pciDeviceListFree(conn, pcidevs);
|
||||
}
|
||||
|
||||
static const char *const defaultDeviceACL[] = {
|
||||
@@ -2001,7 +2036,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
||||
if (qemuSetupCgroup(conn, driver, vm) < 0)
|
||||
goto cleanup;
|
||||
|
||||
- if (qemuPrepareHostDevices(conn, vm->def) < 0)
|
||||
+ if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (VIR_ALLOC(vm->monitor_chr) < 0) {
|
||||
@@ -2183,7 +2218,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
|
||||
VIR_WARN("Failed to restore all device ownership for %s",
|
||||
vm->def->name);
|
||||
|
||||
- qemuDomainReAttachHostDevices(conn, vm->def);
|
||||
+ qemuDomainReAttachHostDevices(conn, driver, vm->def);
|
||||
|
||||
retry:
|
||||
if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) {
|
||||
@@ -6791,6 +6826,7 @@ out:
|
||||
static int
|
||||
qemudNodeDeviceReset (virNodeDevicePtr dev)
|
||||
{
|
||||
+ struct qemud_driver *driver = dev->conn->privateData;
|
||||
pciDevice *pci;
|
||||
unsigned domain, bus, slot, function;
|
||||
int ret = -1;
|
||||
@@ -6802,11 +6838,14 @@ qemudNodeDeviceReset (virNodeDevicePtr dev)
|
||||
if (!pci)
|
||||
return -1;
|
||||
|
||||
- if (pciResetDevice(dev->conn, pci) < 0)
|
||||
+ qemuDriverLock(driver);
|
||||
+
|
||||
+ if (pciResetDevice(dev->conn, pci, driver->activePciHostdevs) < 0)
|
||||
goto out;
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
+ qemuDriverUnlock(driver);
|
||||
pciFreeDevice(dev->conn, pci);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/src/xen_unified.c b/src/xen_unified.c
|
||||
index f2ffc25..dfa9ca5 100644
|
||||
--- a/src/xen_unified.c
|
||||
+++ b/src/xen_unified.c
|
||||
@@ -1641,7 +1641,7 @@ xenUnifiedNodeDeviceReset (virNodeDevicePtr dev)
|
||||
if (!pci)
|
||||
return -1;
|
||||
|
||||
- if (pciResetDevice(dev->conn, pci) < 0)
|
||||
+ if (pciResetDevice(dev->conn, pci, NULL) < 0)
|
||||
goto out;
|
||||
|
||||
ret = 0;
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
From 5aad00b08cadc4d9da8bffd3d255ffaac98d36dd Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Fri, 14 Aug 2009 08:31:11 +0100
|
||||
Subject: [PATCH] Allow PM reset on multi-function PCI devices
|
||||
|
||||
https://bugzilla.redhat.com/515689
|
||||
|
||||
It turns out that a PCI Power Management reset only affects individual
|
||||
functions, and not the whole device.
|
||||
|
||||
The PCI Power Management spec talks about resetting the 'device' rather
|
||||
than the 'function', but Intel's Dexuan Cui informs me that it is
|
||||
actually a per-function reset.
|
||||
|
||||
Also, Yu Zhao has added pci_pm_reset() to the kernel, and it doesn't
|
||||
reject multi-function devices, so it must be true! :-)
|
||||
|
||||
(A side issue is that we could defer the PM reset to the kernel if we
|
||||
could detect that the kernel has PM reset support, but barring version
|
||||
number checks we don't have a way to detect that support)
|
||||
|
||||
* src/pci.c: remove the pciDeviceContainsOtherFunctions() check from
|
||||
pciTryPowerManagementReset() and prefer PM reset over bus reset
|
||||
where both are available
|
||||
|
||||
Cc: Cui, Dexuan <dexuan.cui@intel.com>
|
||||
Cc: Yu Zhao <yu.zhao@intel.com>
|
||||
|
||||
(cherry picked from commit 64a6682b93a2a8aa38067a43979c9eaf993d2b41)
|
||||
|
||||
Fedora-patch: libvirt-allow-pm-reset-on-multi-function-pci-devices.patch
|
||||
---
|
||||
src/pci.c | 48 +++++++++---------------------------------------
|
||||
1 files changed, 9 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/src/pci.c b/src/pci.c
|
||||
index 2dc2e1c..11b3e8b 100644
|
||||
--- a/src/pci.c
|
||||
+++ b/src/pci.c
|
||||
@@ -402,29 +402,6 @@ pciBusContainsOtherDevices(virConnectPtr conn, pciDevice *dev)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-/* Any other functions on this device ? */
|
||||
-static int
|
||||
-pciSharesDevice(pciDevice *a, pciDevice *b)
|
||||
-{
|
||||
- return
|
||||
- a->domain == b->domain &&
|
||||
- a->bus == b->bus &&
|
||||
- a->slot == b->slot &&
|
||||
- a->function != b->function;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-pciDeviceContainsOtherFunctions(virConnectPtr conn, pciDevice *dev)
|
||||
-{
|
||||
- pciDevice *matched = NULL;
|
||||
- if (pciIterDevices(conn, pciSharesDevice, dev, &matched) < 0)
|
||||
- return 1;
|
||||
- if (!matched)
|
||||
- return 0;
|
||||
- pciFreeDevice(conn, matched);
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
/* Is @a the parent of @b ? */
|
||||
static int
|
||||
pciIsParent(pciDevice *a, pciDevice *b)
|
||||
@@ -529,7 +506,7 @@ out:
|
||||
* above we require the device supports a full internal reset.
|
||||
*/
|
||||
static int
|
||||
-pciTryPowerManagementReset(virConnectPtr conn, pciDevice *dev)
|
||||
+pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
||||
{
|
||||
uint8_t config_space[PCI_CONF_LEN];
|
||||
uint32_t ctl;
|
||||
@@ -537,16 +514,6 @@ pciTryPowerManagementReset(virConnectPtr conn, pciDevice *dev)
|
||||
if (!dev->pci_pm_cap_pos)
|
||||
return -1;
|
||||
|
||||
- /* For now, we just refuse to do a power management reset
|
||||
- * if there are other functions on this device.
|
||||
- * In future, we could allow it so long as those functions
|
||||
- * are not in use by the host or other guests.
|
||||
- */
|
||||
- if (pciDeviceContainsOtherFunctions(conn, dev)) {
|
||||
- VIR_WARN("%s contains other functions, not resetting", dev->name);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
/* Save and restore the device's config space. */
|
||||
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
|
||||
VIR_WARN("Failed to save PCI config space for %s", dev->name);
|
||||
@@ -604,14 +571,17 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
|
||||
if (dev->has_flr)
|
||||
return 0;
|
||||
|
||||
+ /* If the device supports PCI power management reset,
|
||||
+ * that's the next best thing because it only resets
|
||||
+ * the function, not the whole device.
|
||||
+ */
|
||||
+ if (dev->has_pm_reset)
|
||||
+ ret = pciTryPowerManagementReset(conn, dev);
|
||||
+
|
||||
/* Bus reset is not an option with the root bus */
|
||||
- if (dev->bus != 0)
|
||||
+ if (ret < 0 && dev->bus != 0)
|
||||
ret = pciTrySecondaryBusReset(conn, dev);
|
||||
|
||||
- /* Next best option is a PCI power management reset */
|
||||
- if (ret < 0 && dev->has_pm_reset)
|
||||
- ret = pciTryPowerManagementReset(conn, dev);
|
||||
-
|
||||
if (ret < 0)
|
||||
pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("No PCI reset capability available for %s"),
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
From 165fb333c9d954fec636dc0f1917ba50417478c0 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Sat, 15 Aug 2009 19:38:15 +0100
|
||||
Subject: [PATCH] Fix list updating after disk/network hot-unplug
|
||||
|
||||
The current code makes a poor effort at updating the device arrays after
|
||||
hot-unplug. Fix that and combine the two code paths into one.
|
||||
|
||||
* src/qemu_driver.c: fix list updating in qemudDomainDetachNetDevice() and
|
||||
qemudDomainDetachPciDiskDevice()
|
||||
|
||||
(cherry picked from commit 4e12af5623e4a962a6bb911af06fa29aa85befba)
|
||||
|
||||
Fedora-patch: libvirt-fix-device-list-update-after-detach.patch
|
||||
---
|
||||
src/qemu_driver.c | 38 ++++++++++++++++++--------------------
|
||||
1 files changed, 18 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index bd58435..2c4fd6f 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -5404,18 +5404,17 @@ try_command:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- if (vm->def->ndisks > 1) {
|
||||
- vm->def->disks[i] = vm->def->disks[--vm->def->ndisks];
|
||||
- if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
|
||||
- virReportOOMError(conn);
|
||||
- goto cleanup;
|
||||
- }
|
||||
- qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
|
||||
- virDomainDiskQSort);
|
||||
- } else {
|
||||
- VIR_FREE(vm->def->disks[0]);
|
||||
- vm->def->ndisks = 0;
|
||||
+ if (i != --vm->def->ndisks)
|
||||
+ memmove(&vm->def->disks[i],
|
||||
+ &vm->def->disks[i+1],
|
||||
+ sizeof(*vm->def->disks) * (vm->def->ndisks-i));
|
||||
+ if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ goto cleanup;
|
||||
}
|
||||
+ qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
|
||||
+ virDomainDiskQSort);
|
||||
+
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@@ -5503,16 +5502,15 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
|
||||
|
||||
DEBUG("%s: host_net_remove reply: %s", vm->def->name, reply);
|
||||
|
||||
- if (vm->def->nnets > 1) {
|
||||
- vm->def->nets[i] = vm->def->nets[--vm->def->nnets];
|
||||
- if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets) < 0) {
|
||||
- virReportOOMError(conn);
|
||||
- goto cleanup;
|
||||
- }
|
||||
- } else {
|
||||
- VIR_FREE(vm->def->nets[0]);
|
||||
- vm->def->nnets = 0;
|
||||
+ if (i != --vm->def->nnets)
|
||||
+ memmove(&vm->def->nets[i],
|
||||
+ &vm->def->nets[i+1],
|
||||
+ sizeof(*vm->def->nets) * (vm->def->nnets-i));
|
||||
+ if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets) < 0) {
|
||||
+ virReportOOMError(conn);
|
||||
+ goto cleanup;
|
||||
}
|
||||
+
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
From f2eb2ad5163d5bae2392a8bfc6040c45426c9f5f Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lalancette <clalance@redhat.com>
|
||||
Date: Wed, 5 Aug 2009 13:42:07 +0200
|
||||
Subject: [PATCH] Run 'cont' on successful migration finish.
|
||||
|
||||
https://bugzilla.redhat.com/516187
|
||||
|
||||
As of qemu 0.10.6, qemu now honors the -S flag on incoming migration.
|
||||
That means that when the migration completes, we have to issue a
|
||||
'cont' command to get the VM running again. We do it unconditionally
|
||||
since it won't hurt on older qemu.
|
||||
|
||||
(cherry picked from commit d1ec4d7a5a4f50c9492137eaab4f021caa075f95)
|
||||
|
||||
Fedora-patch: libvirt-fix-migration-completion-with-newer-qemu.patch
|
||||
---
|
||||
src/qemu_driver.c | 11 +++++++++++
|
||||
1 files changed, 11 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index 99dac52..bf9a0b2 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -6951,7 +6951,18 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
|
||||
*/
|
||||
if (retcode == 0) {
|
||||
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
|
||||
+
|
||||
+ /* run 'cont' on the destination, which allows migration on qemu
|
||||
+ * >= 0.10.6 to work properly. This isn't strictly necessary on
|
||||
+ * older qemu's, but it also doesn't hurt anything there
|
||||
+ */
|
||||
+ if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
||||
+ qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
+ "%s", _("resume operation failed"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
VIR_FREE(info);
|
||||
+
|
||||
vm->state = VIR_DOMAIN_RUNNING;
|
||||
event = virDomainEventNewFromObj(vm,
|
||||
VIR_DOMAIN_EVENT_RESUMED,
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
From c8a9dbe131713de83bdc67c563c4ab149e32c489 Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Fri, 14 Aug 2009 08:31:11 +0100
|
||||
Subject: [PATCH] Improve PCI host device reset error message
|
||||
|
||||
https://bugzilla.redhat.com/499678
|
||||
|
||||
Currently, if we are unable to reset a PCI device we return a fairly
|
||||
generic 'No PCI reset capability available' error message.
|
||||
|
||||
Fix that by returning an error from the individual reset messages and
|
||||
using that error to construct the higher level error mesage.
|
||||
|
||||
* src/pci.c: set errors in pciTryPowerManagementReset() and
|
||||
pciTrySecondaryBusReset() on failure; use those error messages
|
||||
in pciResetDevice(), or explain that no reset support is available
|
||||
|
||||
(cherry picked from commit ebea34185612c3b96d7d3bbd8b7c2ce6c9f4fe6f)
|
||||
|
||||
Fedora-patch: libvirt-improve-pci-hostdev-reset-error-message.patch
|
||||
---
|
||||
src/pci.c | 44 +++++++++++++++++++++++++++++++-------------
|
||||
src/qemu_driver.c | 4 ++--
|
||||
2 files changed, 33 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/pci.c b/src/pci.c
|
||||
index 11b3e8b..74f7ef0 100644
|
||||
--- a/src/pci.c
|
||||
+++ b/src/pci.c
|
||||
@@ -456,15 +456,18 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
||||
* are not in use by the host or other guests.
|
||||
*/
|
||||
if (pciBusContainsOtherDevices(conn, dev)) {
|
||||
- VIR_WARN("Other devices on bus with %s, not doing bus reset",
|
||||
- dev->name);
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Other devices on bus with %s, not doing bus reset"),
|
||||
+ dev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the parent bus */
|
||||
parent = pciGetParentDevice(conn, dev);
|
||||
if (!parent) {
|
||||
- VIR_WARN("Failed to find parent device for %s", dev->name);
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Failed to find parent device for %s"),
|
||||
+ dev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -475,7 +478,9 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
||||
* are multiple devices/functions
|
||||
*/
|
||||
if (pciRead(dev, 0, config_space, PCI_CONF_LEN) < 0) {
|
||||
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Failed to save PCI config space for %s"),
|
||||
+ dev->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -492,9 +497,12 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
||||
|
||||
usleep(200 * 1000); /* sleep 200ms */
|
||||
|
||||
- if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0)
|
||||
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
|
||||
-
|
||||
+ if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0) {
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Failed to restore PCI config space for %s"),
|
||||
+ dev->name);
|
||||
+ goto out;
|
||||
+ }
|
||||
ret = 0;
|
||||
out:
|
||||
pciFreeDevice(conn, parent);
|
||||
@@ -516,7 +524,9 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
||||
|
||||
/* Save and restore the device's config space. */
|
||||
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
|
||||
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Failed to save PCI config space for %s"),
|
||||
+ dev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -533,8 +543,12 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
||||
|
||||
usleep(10 * 1000); /* sleep 10ms */
|
||||
|
||||
- if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0)
|
||||
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
|
||||
+ if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
|
||||
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
+ _("Failed to restore PCI config space for %s"),
|
||||
+ dev->name);
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -582,10 +596,14 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
|
||||
if (ret < 0 && dev->bus != 0)
|
||||
ret = pciTrySecondaryBusReset(conn, dev);
|
||||
|
||||
- if (ret < 0)
|
||||
+ if (ret < 0) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
- _("No PCI reset capability available for %s"),
|
||||
- dev->name);
|
||||
+ _("Unable to reset PCI device %s: %s"),
|
||||
+ dev->name,
|
||||
+ err ? err->message : _("no FLR, PM reset or bus reset available"));
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index 4ce7a54..fd39fc2 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -1465,9 +1465,9 @@ qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (pciDettachDevice(conn, dev) < 0) {
|
||||
+ if (pciReAttachDevice(conn, dev) < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
- VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
||||
+ VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
|
||||
err ? err->message : "");
|
||||
virResetError(err);
|
||||
}
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
From 8f26acc66ca90eea67fd5e84be5a76e3b8aa7fbf Mon Sep 17 00:00:00 2001
|
||||
From: Mark McLoughlin <markmc@redhat.com>
|
||||
Date: Fri, 14 Aug 2009 08:31:11 +0100
|
||||
Subject: [PATCH] Reset and re-attach PCI host devices on guest shutdown
|
||||
|
||||
https://bugzilla.redhat.com/499561
|
||||
|
||||
When the guest shuts down, we should attempt to restore all PCI host
|
||||
devices to a sane state.
|
||||
|
||||
In the case of managed hostdevs, we should reset and re-attach the
|
||||
devices. In the case of unmanaged hostdevs, we should just reset them.
|
||||
|
||||
Note, KVM will already reset assigned devices when the guest shuts
|
||||
down using whatever means it can, so we are only doing it to cover the
|
||||
cases the kernel can't handle.
|
||||
|
||||
* src/qemu_driver.c: add qemuDomainReAttachHostDevices() and call
|
||||
it from qemudShutdownVMDaemon()
|
||||
|
||||
(cherry picked from commit 4035152a8767e72fd4e26a91cb4d5afa75b72e61)
|
||||
|
||||
Fedora-patch: libvirt-reattach-pci-hostdevs-after-guest-shutdown.patch
|
||||
---
|
||||
src/qemu_driver.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 76 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
||||
index 2c4fd6f..4ce7a54 100644
|
||||
--- a/src/qemu_driver.c
|
||||
+++ b/src/qemu_driver.c
|
||||
@@ -1402,6 +1402,80 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static void
|
||||
+qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ /* Again 2 loops; reset all the devices before re-attach */
|
||||
+
|
||||
+ for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
+ pciDevice *dev;
|
||||
+
|
||||
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
+ continue;
|
||||
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
||||
+ continue;
|
||||
+
|
||||
+ dev = pciGetDevice(conn,
|
||||
+ hostdev->source.subsys.u.pci.domain,
|
||||
+ hostdev->source.subsys.u.pci.bus,
|
||||
+ hostdev->source.subsys.u.pci.slot,
|
||||
+ hostdev->source.subsys.u.pci.function);
|
||||
+ if (!dev) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
+ VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
|
||||
+ err ? err->message : "");
|
||||
+ virResetError(err);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (pciResetDevice(conn, dev) < 0) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
||||
+ err ? err->message : "");
|
||||
+ virResetError(err);
|
||||
+ }
|
||||
+
|
||||
+ pciFreeDevice(conn, dev);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0 ; i < def->nhostdevs ; i++) {
|
||||
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
||||
+ pciDevice *dev;
|
||||
+
|
||||
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
+ continue;
|
||||
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
|
||||
+ continue;
|
||||
+ if (!hostdev->managed)
|
||||
+ continue;
|
||||
+
|
||||
+ dev = pciGetDevice(conn,
|
||||
+ hostdev->source.subsys.u.pci.domain,
|
||||
+ hostdev->source.subsys.u.pci.bus,
|
||||
+ hostdev->source.subsys.u.pci.slot,
|
||||
+ hostdev->source.subsys.u.pci.function);
|
||||
+ if (!dev) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
+ VIR_ERROR(_("Failed to allocate pciDevice: %s\n"),
|
||||
+ err ? err->message : "");
|
||||
+ virResetError(err);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (pciDettachDevice(conn, dev) < 0) {
|
||||
+ virErrorPtr err = virGetLastError();
|
||||
+ VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
||||
+ err ? err->message : "");
|
||||
+ virResetError(err);
|
||||
+ }
|
||||
+
|
||||
+ pciFreeDevice(conn, dev);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static const char *const defaultDeviceACL[] = {
|
||||
"/dev/null", "/dev/full", "/dev/zero",
|
||||
"/dev/random", "/dev/urandom",
|
||||
@@ -2109,6 +2183,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
|
||||
VIR_WARN("Failed to restore all device ownership for %s",
|
||||
vm->def->name);
|
||||
|
||||
+ qemuDomainReAttachHostDevices(conn, vm->def);
|
||||
+
|
||||
retry:
|
||||
if ((ret = qemuRemoveCgroup(conn, driver, vm)) < 0) {
|
||||
if (ret == -EBUSY && (retries++ < 5)) {
|
||||
--
|
||||
1.6.2.5
|
||||
|
||||
+2815
-1088
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user