Compare commits

...

236 Commits

Author SHA1 Message Date
Cole Robinson 54d3da1da5 CVE-2017-1000256: libvirt: TLS certificate verification disabled for clients (bz #1503687) 2017-12-04 12:16:49 -05:00
Cole Robinson faf5df2081 Fix TPM2 passthrough (bz #1486240)
Fix spice GL qemu:///system rendernode permissions (bz #1460804)
Fix on_reboot=destroy setting (bz #1476866)
Fix disk images in /dev/shm (bz #1482146)
2017-09-15 19:04:20 -04:00
Cole Robinson e5075407b1 Enable ZFS storage driver (bz #1471912)
Don't use cgroup mount points from /proc/mounts that are hidden (bz #1470593)
disk driver name=... should be optional (bz #1473091)
2017-08-04 16:11:19 -04:00
Cole Robinson 8c3f1e830e Fix resuming qemu VMs suspended before libvirt 3.2.0
Fix issues with AMD CPU models, and some others
2017-07-12 16:26:46 -04:00
Cole Robinson 58083f4418 Remove wireshark workaround 2017-06-14 10:47:37 -04:00
Cole Robinson 55a13fd521 Tweak condition for not starting in live environment (bz #1146232) 2017-05-31 17:28:27 -04:00
Cole Robinson 262bbf08f2 Fix aarch64 gic default for non-kvm VMs (bz #1449837)
Don't run libvirtd in live environment, to avoid network collision (bz #1146232)
2017-05-30 18:57:48 -04:00
Cole Robinson 0fe69a9b44 Rebased to version 3.2.1 2017-05-10 20:26:58 -04:00
Daniel P. Berrange 04cb28c315 Update to 3.2.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-04-03 14:30:13 +01:00
Daniel P. Berrange a74ea318d1 Update to 3.1.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-03-03 16:48:12 +00:00
Fedora Release Engineering 98ed6b4e36 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild 2017-02-10 19:39:29 +00:00
Daniel P. Berrange 2c49d1fd11 Update to 3.0.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-01-19 10:16:16 +00:00
Igor Gnatenko 6e7bca6631 Rebuild for readline 7.x
Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>
2017-01-12 17:30:33 +01:00
Daniel P. Berrange 2fe145bb02 Rebuild to pick up new libxen* soname
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-12-08 18:31:20 +00:00
Daniel P. Berrange 10b7d235e3 Temp hack for gnutls 3.5.6 regression
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-12-05 12:06:04 +00:00
Daniel P. Berrange 232e2e7de2 Add workaround for wireshark-devel brokeness yet again
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-12-05 11:21:03 +00:00
Daniel P. Berrange fb1e4b061e Kill changeog entries prior to 2015
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-12-05 10:07:41 +00:00
Daniel P. Berrange 0b1a013081 Update to 2.5.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-12-05 10:06:54 +00:00
Daniel P. Berrange a972457f43 Update to 2.4.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-11-02 09:20:09 +00:00
Daniel P. Berrange 67cfa34a05 Update to 2.3.0 release 2016-10-06 11:42:08 +01:00
Daniel P. Berrange fc2ebb7646 Update to 2.2.0 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-09-05 12:42:42 +01:00
Daniel P. Berrange e92b461b4f Upload 2.1.0 tar
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-08-02 15:12:35 +01:00
Daniel P. Berrange b1ac7b5791 Rebase to 2.1.0
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-08-02 15:11:55 +01:00
Richard W.M. Jones 88424efe85 Rebuild to attempt to fix 'nothing provides libxenctrl.so.4.6()(64bit) needed
by libvirt-daemon-2.0.0-1.fc25.x86_64'
2016-07-23 16:35:53 +01:00
Daniel P. Berrange 4e2aab98a2 Add deps on systemd-container 2016-07-13 17:50:00 +01:00
Daniel P. Berrange f4bc1a2fe2 Disable wireshark 2016-07-01 11:21:55 +01:00
Daniel P. Berrange a4bf2768b8 Update to 2.0.0 release 2016-07-01 10:43:53 +01:00
Richard W.M. Jones 47cd44e9da Rebuild against new glibc
(see https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/VUOTESHSWFRCYPXIVG6BSMAUITS7QCK2/).
2016-06-13 14:29:22 +01:00
Daniel P. Berrange 731c6b90ff Add patch to avoid building against libsystemd-daemon.so
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-06-07 09:48:24 +01:00
Daniel P. Berrange 47ca46905d Rebase to 1.3.5
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-06-06 11:46:44 +01:00
Cole Robinson 860ffc5b13 Fix libxl video config via virt-install (bz #1334557)
Advertise fedora edk2 firmware builds to apps (bz #1335395)
2016-05-20 16:37:26 -04:00
Cole Robinson 611b2ee520 Rebased to version 1.3.4 2016-05-02 20:22:05 -04:00
Richard W.M. Jones edcb926f9d Fix 200ms performance problem when waiting for monitor socket of new domains. 2016-04-19 11:53:54 +01:00
Cole Robinson caebff8304 Re-run autotools, since patches touch configure 2016-04-15 06:23:13 -04:00
Cole Robinson 8fa41135ca libvirt assigns same address to two PCI devices (bz #1325085)
Fix build with -Werror
2016-04-14 19:46:33 -04:00
Cole Robinson 0debbff964 Rebased to version 1.3.3 2016-04-07 09:55:06 -04:00
Cole Robinson d6cc78be66 Fix qemu:///session disconnect after 30 seconds
Fix 'permission denied' errors trying to unlink disk images (bz #1289327)
Fix qemu:///session connect race failures (bz #1271183)
driver: log missing modules as INFO, not WARN (bz #1274849)
2016-03-17 17:38:30 -04:00
Richard W.M. Jones 8d9645735e Add fix for RHBZ#1315606. 2016-03-09 14:51:59 +00:00
Daniel P. Berrange 4c65f08330 Update to 1.3.2 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2016-03-01 14:26:53 +00:00
Daniel P. Berrange 2427f8f078 Re-enable wireshark 2016-02-24 22:23:39 +00:00
Dennis Gilmore d168e4f934 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild 2016-02-04 04:06:44 +00:00
Daniel P. Berrange 4dd365589f Disable wireshark due to https://bugzilla.redhat.com/show_bug.cgi?id=1300002 2016-01-19 17:44:37 +00:00
Daniel P. Berrange 50e253df29 Update to 1.3.1 release 2016-01-19 14:44:36 +00:00
Daniel P. Berrange cb71801a2b Add patch to fix 32-bit test suite check
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-12-11 12:15:31 +00:00
Daniel P. Berrange 4a9c74e91d Update to 1.3.0 release 2015-12-09 20:53:57 +00:00
Daniel P. Berrange 281508ec99 Update to 1.2.21 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-11-11 10:01:32 +00:00
Cole Robinson feb92626e1 Rebuild for xen 4.6 2015-10-11 16:08:21 -04:00
Daniel P. Berrange 93cadb0880 Update to 1.2.20 release 2015-10-02 15:58:35 +01:00
Daniel P. Berrange dd6b57aa60 Update to 1.2.19 release 2015-09-02 12:52:54 +01:00
Daniel P. Berrange b8cb754e9d Add workaround for //bugzilla.redhat.com/show_bug.cgi?id=1250020 2015-08-04 12:29:04 +01:00
Daniel P. Berrange dbe61507bd Update to 1.2.18 release 2015-08-04 09:50:35 +01:00
Richard W.M. Jones ce7b23d9d0 Fix 'Cannot write data: Broken pipe [code=38 domain=7]' (RHBZ#1247746). 2015-07-29 11:35:59 +01:00
Cole Robinson 8ded6ff93e Fix dep for f23 polkit packaging changes 2015-07-14 14:05:12 -04:00
Cole Robinson 1ef96f3488 Disable test suite, currently crashing on i686 2015-07-14 12:42:13 -04:00
Cole Robinson ee3bf37900 Update spec for 1.2.17 2015-07-14 12:23:04 -04:00
Peter Robinson 7452a06938 Rebuild (aarch64) 2015-07-12 22:27:12 +01:00
Daniel Veillard fe8f9ed9c4 Upstream release 1.2.17 2015-07-02 13:40:30 +08:00
Daniel P. Berrange 1b64f74c82 Rebuild for libwsman soname change
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-06-16 14:49:54 +01:00
Daniel P. Berrange c81949046d Update to 1.2.16 release 2015-06-01 10:05:32 +01:00
Daniel Veillard 19dcb913e6 Upstream release 1.2.16 2015-06-01 10:49:59 +08:00
Richard W.M. Jones e4b5ba1a9d Add Cole Robinson's patch to fix arch selection (bz# 1219198, bz#1219191) 2015-05-07 15:08:12 +01:00
Cole Robinson 5f1a422d83 Rebased to version 1.2.15 2015-05-04 13:28:39 -04:00
Cole Robinson c5b0b3ef9d Fix LXC domain startup (bz #1210397)
Fix race starting multiple session daemons (bz #1200149)
Fix change-media success messages
Strip invalid control codes from XML (bz #1066564, bz #1184131)
2015-04-15 14:40:41 -04:00
Cole Robinson c0a04cb876 Rebased to version 1.2.14 2015-04-02 12:44:09 -04:00
Daniel Veillard 3cc7cdf12f Upstream release 1.2.14 2015-04-02 15:56:44 +08:00
Cole Robinson 6b531d9967 Fix connecting to qemu:///session (bz #1198244) 2015-03-10 11:10:16 -04:00
Cole Robinson 4d05ac021c Rebased to version 1.2.13
lot of improvements around NUMA code
a lot of improvement and bug fixes
2015-03-02 11:36:45 -05:00
Daniel Veillard d29aa84b17 upstream release of libvirt-1.2.13 2015-03-02 11:46:49 +08:00
Daniel P. Berrange a075adc818 Rebuild for changed xen soname 2015-02-03 09:21:55 +00:00
Daniel P. Berrange 4d0e63f99c Update to 1.2.12 release 2015-01-27 10:53:52 +00:00
Daniel P. Berrange 9e11936ec5 Disable -Werror 2014-12-15 15:29:30 +00:00
Daniel P. Berrange a4075ec632 Update to 1.2.11 release 2014-12-15 12:01:37 +00:00
Cole Robinson dadb59c95f Allow arm/aarch64 with UEFI 2014-11-21 10:15:51 -05:00
Cole Robinson e73cc6a9d8 Fix caps probing when KVM is disabled (bz #1160318)
ppc64le fixes (bz #1163439)
2014-11-15 18:33:55 -05:00
Cole Robinson 10cd84e37f Remove unused patches 2014-11-15 15:21:48 -05:00
Daniel Veillard e63e2040cd Upstream release of 1.2.10 2014-11-03 15:13:32 +08:00
Cole Robinson 91063332d7 Fix creating i686 guest with x86_64 emulator (bz #1153797)
Fix tests with latest libxml2
2014-10-30 11:01:41 -04:00
Cole Robinson 503330ba5d Fix selinux errors with /dev/net/tun (bz #1147057) 2014-10-09 13:00:53 -04:00
Cole Robinson 0a64085f47 Fix specifying CPU for qemu aarch64 2014-10-03 09:32:42 -04:00
Daniel P. Berrange 1073e2447a Update to 1.2.9 release 2014-10-01 17:09:48 +01:00
Cole Robinson 5b1a906ace Fix labelling host devices (bz #1145968) 2014-09-24 12:15:49 -04:00
Cole Robinson aff97e0146 Fix specifying CPU for qemu aarch64 2014-09-23 17:27:47 -04:00
Cole Robinson a4b41a378b Rerun autotools for new patches 2014-09-18 16:06:49 -04:00
Cole Robinson 3ec523d168 Don't mess up labelling of /dev/net/tun (bz #1141879)
pflash/nvram support for UEFI/OVMF
2014-09-18 15:36:06 -04:00
Cole Robinson 622cf0d642 Fix preun script (bz #1142367) 2014-09-17 10:55:26 -04:00
Cole Robinson a540751e83 Generate non-colliding network IP range at RPM install time (bz #811967)
Fix directory creation at session daemon startup (bz #1139672)
Disable wireshark building, currently broken on f21/rawhide
2014-09-15 14:52:07 -04:00
Daniel P. Berrange 11b596669a Re-disable wireshark 2014-09-05 16:42:57 +01:00
Daniel P. Berrange fefbae879b Update to 1.2.8 release 2014-09-05 16:15:21 +01:00
Peter Robinson 695b281409 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild 2014-08-17 06:38:41 +00:00
Cole Robinson 9f9eae34c1 Rebased to version 1.2.7 2014-08-12 13:58:50 -04:00
Peter Robinson ae37ed3500 Enable kvm on aarch64, Cleanup F-16/18 conditionals 2014-07-15 17:52:18 +01:00
Daniel P. Berrange f7f509999b Update to 1.2.6 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2014-07-02 17:21:15 +01:00
Daniel Veillard 419bcc4b2f new release 2014-07-02 14:25:52 +08:00
Dennis Gilmore 7b59d4f7eb - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild 2014-06-07 00:55:30 -05:00
Daniel P. Berrange 03326e9c04 Update to 1.2.5 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2014-06-02 10:42:59 +01:00
Daniel P. Berrange f40b464d1e Update to 1.2.4 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2014-05-06 15:54:45 +01:00
Cole Robinson 810ca6c207 Fix LXC from throwing error System lacks NETNS support (bz #1084902) 2014-04-11 15:53:56 -04:00
Cole Robinson 8df3aef6aa Add sources 2014-04-01 18:00:14 -04:00
Cole Robinson 0223d5a656 Rebased to version 1.2.3 2014-04-01 17:50:30 -04:00
Cole Robinson aad810a204 Rebuild for xen 4.4 2014-03-24 08:53:56 -04:00
Daniel P. Berrange 1b8b7567b1 Update to 1.2.2 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2014-03-03 11:19:24 +00:00
Cole Robinson 442040caac Rebuild for openwsman soname bump 2014-01-27 13:21:35 -05:00
Daniel P. Berrange 65efaafca2 Update to 1.2.1 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2014-01-21 11:18:53 +00:00
Cole Robinson e87c8ab0c7 Remove unused patch 2014-01-16 20:36:40 -05:00
Daniel Veillard be6bda45b4 Updated to new tarball, but not the spec file 2014-01-16 18:17:37 +08:00
Daniel P. Berrange 8c9e40d383 Update to 1.2.0 release with python binding split off
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-12-03 15:10:43 +00:00
Daniel Veillard 0f6f9b973a New release, but do not build until libvirt-python is in git too 2013-12-02 13:31:49 +08:00
Cole Robinson 3db6039b2b virsh nodedev-detach fails if device has no driver (bz #1028629) 2013-11-12 09:46:29 -05:00
Daniel P. Berrange 4051217c8b Remove obsolete sources files
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-11-05 12:03:07 +08:00
Daniel Veillard c5c28baba1 Upstream release of libvirt-1.1.4 2013-11-04 14:27:40 +08:00
Cole Robinson 43618df1d4 Allow QoS change with update-device (bz #1014200)
Fix nwfilter crash during firewalld install (bz #1014762)
Fix crash with nographics (bz #1014088)
2013-10-06 15:14:15 -04:00
Daniel Veillard a2951dccb5 Rebase ot upstream 1.1.3 2013-10-01 15:51:28 +08:00
Cole Robinson b884323c03 Fix snapshot restore when VM has disabled usb support (bz #1011520) 2013-09-24 10:27:38 -04:00
Cole Robinson adeaf839fd Sync with v1.1.2-maint
Rebuild for libswan soname bump (bz #1009701)
CVE-2013-4311: Insecure polkit usage (bz #1009539, bz #1005332)
CVE-2013-4296: Invalid free memory stats (bz #1006173, bz #1009667)
CVE-2013-4297: Invalid free in NBDDeviceAssociate (bz #1006505, bz #1006511)
Fix virsh block-commit abort (bz #1010056)
2013-09-23 14:35:01 -04:00
Daniel P. Berrange 40d99010e1 Rebuild for soname break in openswman package 2013-09-18 14:44:25 +01:00
Daniel P. Berrange 11755d8663 Update to 1.1.2 release, rebasing ARM patches
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-09-02 11:48:17 +01:00
Cole Robinson 2daa92daf9 Fix launching ARM guests on x86 (patches posted upstream, F20 feature) 2013-08-20 15:25:47 -04:00
Cole Robinson db2858c661 CVE-2013-4239: xen: memory corruption in legacy driver (bz #996241, bz #996244) 2013-08-14 20:00:13 -04:00
Daniel P. Berrange 53adb9aaba Re-add code to delete python tests
Upstream mistakenly deleted code to remove the python test
files from the docs dir

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-30 11:27:28 +01:00
Daniel P. Berrange 168df8b606 Update to 1.1.1 release
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-30 10:59:15 +01:00
Dennis Gilmore f9085f2538 fix doc path in libvirt-python 2013-07-28 22:28:27 -05:00
Cole Robinson b159bbdc98 CVE-2013-4153: Fix double free of returned JSON (bz #986408, bz #986383)
CVE-2013-4154: Crash of libvirtd if guest agent not configured (bz #986386, bz #986406)
2013-07-25 17:53:26 -04:00
Daniel P. Berrange a5af3cf105 Rebuild for change in Xen library ABI/soname 2013-07-17 13:15:58 +01:00
Cole Robinson 27ca069db7 CVE-2013-2230 libvirt: multiple registered events crash 2013-07-11 16:47:16 -04:00
Daniel Veillard 000a3274d2 Release of libvirt-1.1.0 2013-07-01 19:30:25 +08:00
Peter Robinson 19c7799c31 Enable KVM support on ARM 2013-06-14 14:30:53 +01:00
Cole Robinson 198ff818c6 Drop bogus dep on vbox 2013-06-08 18:44:16 -04:00
Daniel P. Berrange e80c83ad06 Update to 1.0.6 release 2013-06-03 16:27:28 +01:00
Cole Robinson 660e0112c6 Rebased to version 1.0.5.1
Follow updated packaging guidelines for user alloc (bz #924501)
CVE-2013-1962 Open files DoS (bz #963789, bz #953107)
2013-05-19 18:33:15 -04:00
Cole Robinson 45c1cabef6 Fix stream operations like screenshot (bz #960879) 2013-05-14 17:32:09 -04:00
Richard W.M. Jones 56be2c5e38 Fix network driver when using qemu:///session (bz #958907). 2013-05-03 15:15:22 +01:00
Daniel Veillard 4aa9c4f1a3 Upstream release of libvirt-1.0.5 2013-05-02 18:39:42 +08:00
Daniel Veillard 7be420ad22 Update to 1.0.4 release 2013-04-01 15:54:31 +08:00
Daniel P. Berrange 40b00623a4 Update to 1.0.3 release 2013-03-05 16:00:44 +00:00
Richard W.M. Jones ce09ec66c7 Fix bogus dates in libvirt.spec by comparing changelog to true dates in git log. 2013-02-28 13:22:28 +00:00
Richard W.M. Jones 97d7c80e2e Disable virnettlscontexttest which apparently fails because of a broken gnutls3.
Note since this patch touches Makefile.am, I have enabled autoreconf
(enable_autotools).
2013-02-28 13:02:27 +00:00
Richard W.M. Jones b856ae03bf Backport "qemu: check backing chains even when cgroup is omitted"
(RHBZ#896685).
2013-02-28 09:58:19 +00:00
Daniel P. Berrange 803b3b891a Fix missing python binding constants 2013-02-05 15:51:47 +00:00
Daniel P. Berrange 350081d1a9 Update to 1.0.2 release 2013-02-01 10:48:53 +00:00
Cole Robinson 1b71b68bb9 Fix network persistence after define (bz #890492) 2013-01-29 20:17:02 -05:00
Cole Robinson 4084288dd5 CVE-2013-0170 libvirt: use-after-free in virNetMessageFree() (bz #893450, bz #905173) 2013-01-28 15:11:38 -05:00
Richard W.M. Jones d1cd1b7ceb Rebuild for libnl soname breakage (RHBZ#901569). 2013-01-20 19:56:14 +00:00
Daniel P. Berrange 5ed69704b9 Work around kernel headers problem 2013-01-18 20:01:53 +00:00
Daniel P. Berrange be6e136cb1 Rebuild for libnl3 soname change 2013-01-18 14:46:40 +00:00
Cole Robinson d3109abfa4 Fix scriplet warning when uninstalling libvirt-client (bz #888071) 2012-12-17 18:48:44 -05:00
Daniel Veillard f5ff4a2393 Update to upstream 1.0.1 release 2012-12-17 14:24:00 +08:00
Daniel P. Berrange 8cc50838dc Update to 1.0.0 release 2012-11-08 22:21:41 +01:00
Cole Robinson 2c2e71c0ce Disable libxl on F18 too 2012-10-30 20:54:40 -04:00
Cole Robinson 96b1b18b42 Rebased to version 0.10.2.1
Fix lvm volume creation when alloc=0 (bz #866481)
Clarify virsh send-keys man page example (bz #860004)
Fix occasional deadlock via virDomainDestroy (bz #859009)
Fix LXC deadlock from ctrl-c (bz #848119)
Fix occasional selinux denials with macvtap (bz #798605)
Fix multilib conflict with systemtap files (bz #831425)
Don't trigger keytab warning in system logs (bz #745203)
Fix qemu domxml-2-native NIC model out (bz #636832)
Fix error message if not enough space for lvm vol (bz #609104)
2012-10-27 17:56:09 -04:00
Cole Robinson f7763bfd17 Disable libxl driver, since it doesn't build with xen 4.2 in rawhide 2012-10-25 17:16:59 -04:00
Richard W.M. Jones 404e58cb18 Add upstream patches: don't duplicate environment variables (RHBZ#859596). 2012-09-24 20:59:05 +01:00
Richard W.M. Jones cd3767e3b9 Re-add 0001-Use-qemu-system-i386-as-binary-instead-of-qemu.patch
NB: This patch is Fedora-specific and not upstream.
2012-09-24 18:36:40 +01:00
Daniel Veillard f1867a5ecc Upstream release 0.10.2 2012-09-24 14:22:55 +08:00
Richard W.M. Jones b5548f62cb Add (upstream) patches to label sockets for SELinux (RHBZ#853393). 2012-09-21 18:58:41 +01:00
Richard W.M. Jones 52f3bedee7 Fix for 32 bit qemu renamed to qemu-system-i386 (RHBZ#857026).
The difference in the output of virsh capabilities (non-root)
before and after is:

 <capabilities>

   <host>
-    <uuid>9ecd5b8f-4b44-5dae-f4c6-4b9cf108e47a</uuid>
+    <uuid>4cae6f0f-dd64-8d9a-bc36-b3f2e62844cf</uuid>
     <cpu>
       <arch>i686</arch>
       <model>Westmere</model>
@@ -34,7 +34,7 @@
     <os_type>hvm</os_type>
     <arch name='i686'>
       <wordsize>32</wordsize>
-      <emulator>/bin/qemu-system-x86_64</emulator>
+      <emulator>/bin/qemu-system-i386</emulator>
       <machine>pc-1.2</machine>
       <machine>none</machine>
       <machine canonical='pc-1.2'>pc</machine>
2012-09-13 15:03:19 +01:00
Cole Robinson f87237919c Drop unneeded dnsmasq --filterwin2k
Fix unwanted connection closing, needed for boxes
Fix libvirtd segfault with old netcf-libs (bz 853381)
2012-09-12 08:18:36 -04:00
Daniel P. Berrange e8969fb913 Remove dep on ceph RPM (rhbz #854360) 2012-09-05 11:01:22 +01:00
Daniel Veillard 74d46bc7dd Release of libvirt-0.10.1
Brown paper bag release
2012-08-31 21:52:10 +08:00
Daniel Veillard 4b6ea94306 Upstream release of 0.10.0
- agent: add qemuAgentArbitraryCommand() for general qemu agent command
- Introduce virDomainPinEmulator and virDomainGetEmulatorPinInfo functions
- network: use firewalld instead of iptables, when available
- network: make network driver vlan-aware
- esx: Implement network driver
- driver for parallels hypervisor
- Various LXC improvements
- Add virDomainGetHostname
- a lot of bug fixes, improvements and portability work
2012-08-29 14:32:06 +08:00
Daniel Veillard 963754bc8c Fix a missing build requirement on dbus-devel 2012-08-23 16:14:20 +08:00
Daniel Veillard 7b5483236c release candidate 1 of 0.10.0 2012-08-23 15:53:24 +08:00
Daniel P. Berrange 438006407c Add correct patch for fixing module linkage & enable autotools
Add the correct patch to fix the module linkage problems
and enable autotools, so the Makefile.am changes actually
get applied
2012-08-14 16:21:02 +01:00
Daniel Veillard 76c8282ee2 Fix missing symbols in libvirt daemon in rc0 snapshot 2012-08-14 20:06:04 +08:00
Daniel Veillard f463598b24 Prerelease for libvirt-0.10.0
Snapshot before 0.10.0 expected beginning of september
2012-08-08 22:45:35 +08:00
Richard W.M. Jones f4e752a385 Add upstream patch to fix RHBZ#842114. 2012-07-23 14:09:48 +01:00
Dennis Gilmore c37cb21dea - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild 2012-07-19 16:33:02 -05:00
Cole Robinson e0bfc1f8aa BuildRequires: openssl-devel for rbd 2012-07-15 13:26:31 -04:00
Daniel Veillard 544ad4a787 Release of libvirt-0.9.13
- S390: support for s390(x)
- snapshot: implement new APIs for esx and vbox
- snapshot: new query APIs and many improvements
- virsh: Allow users to reedit rejected XML
- nwfilter: add DHCP snooping
- Enable driver modules in libvirt RPM
- Default to enable driver modules for libvirtd
- storage backend: Add RBD (RADOS Block Device) support
- sVirt support for LXC domains inprovement
- a lot of bug fixes, improvements and portability work
2012-07-02 13:15:52 +08:00
Daniel Veillard 8f163760ed Update to 0.9.12 2012-05-14 22:23:10 +08:00
Cole Robinson 565427cf89 Remove all accidentally added patches 2012-04-27 17:01:40 -04:00
Cole Robinson e10da2f6d4 Rebased to version 0.9.11.3
Abide URI username when connecting to hypervisor (bz 811397)
Fix managed USB mode (bz 814866)
Fix crash connecting to ESX host (bz 811891)
2012-04-27 16:56:05 -04:00
Cole Robinson aa386576d5 Fix python doc filelist 2012-04-26 20:39:12 -04:00
Cole Robinson c73c129b48 Rebased to version 0.9.11.2
Abide URI username when connecting to hypervisor (bz 811397)
Fix managed USB mode (bz 814866)
Fix crash connecting to ESX host (bz 811891)
2012-04-26 20:14:34 -04:00
Daniel P. Berrange afe729ac3c Fix initial hypervisor conditionals 2012-04-04 11:42:12 +01:00
Daniel P. Berrange b6038bae4f Remove bogus xen-devel dep from libvirt-devel RPM 2012-04-04 11:42:00 +01:00
Daniel P. Berrange e6d9787587 Introduce per-hypervisor virtual RPMs 2012-04-04 11:41:48 +01:00
Daniel P. Berrange 44699dc495 Split config files & daemon off from main daemon RPM 2012-04-04 11:41:26 +01:00
Daniel P. Berrange 991d719dde Remove API XML files from libvirt RPM 2012-04-04 11:41:06 +01:00
Daniel P. Berrange 96a520b555 Move all documentation into a -docs sub-RPM 2012-04-04 11:40:53 +01:00
Daniel P. Berrange e31df5e9de Update to 0.9.11 release 2012-04-04 11:40:32 +01:00
Daniel P. Berrange 6763b267b9 Fix client only RPM build & other misc RPM problems 2012-04-04 11:39:42 +01:00
Daniel P. Berrange 24e91208a4 spec: Add missed dependancy for numad 2012-04-04 11:38:11 +01:00
Daniel P. Berrange 15dec999e7 Add qemu support for ppc64 on FC16 or above for rpm packaging 2012-04-04 11:37:55 +01:00
Daniel P. Berrange d6b0635d3d Fixed service handling in specfile 2012-04-04 11:37:36 +01:00
Daniel P. Berrange 336a93264e storage: Allow runtime detection of scrub 2012-04-04 11:36:56 +01:00
Daniel P. Berrange 6398d1cff5 Fix typos in API XML file paths 2012-04-04 11:36:26 +01:00
Daniel P. Berrange 6926ed26ea Install API XML desc to a standard location 2012-04-04 11:36:11 +01:00
Daniel P. Berrange 6253f97a2d Revert previous change 2012-04-03 11:02:04 +01:00
Daniel P. Berrange 37ddbd0eac Refactor RPM spec to allow install without default configs 2012-03-31 12:38:10 +01:00
Daniel P. Berrange 95fe7c8df2 Rebuild for libparted soname break 2012-03-15 15:10:56 +00:00
Peter Robinson 79ae809020 fix ix86 macros 2012-02-17 15:27:03 +00:00
Daniel P. Berrange f19e302ba9 Update to 0.9.10 2012-02-13 16:10:28 +00:00
Daniel P. Berrange e9c1d3f4b0 Update to 0.9.10-rc2 release 2012-02-08 11:34:10 +00:00
Daniel P. Berrange 0f577d932b Fix LXC I/O handling 2012-01-12 21:07:02 +00:00
Daniel P. Berrange 21a02c2e90 Fix LXC I/O handling 2012-01-12 21:04:43 +00:00
Daniel Veillard 4e460d5f09 Upstream release of 0.9.9 2012-01-07 21:53:09 +08:00
Peter Robinson f9de2f6bc6 update util-linux-ng -> util-linux 2011-12-29 16:21:18 +00:00
Daniel P. Berrange 2daa1b7814 Add BR on gettext-devel when autotools is enabled 2011-12-08 14:39:53 +00:00
Daniel P. Berrange f99eeb8567 Fix install of libvirt-guests.service and libvirtd.service 2011-12-08 13:50:55 +00:00
Daniel Veillard 7069f75cb8 update to libvirt-0.9.8
cleanup of old patches, of spec too
2011-12-08 17:03:16 +08:00
Justin M. Forbes 2cac7dac46 Remove versioning on yajl buildreq 2011-11-14 17:54:13 -06:00
Daniel P. Berrange 913c3c6554 Rebuild for yajl 2.0.1 release 2011-11-10 16:24:26 +00:00
Daniel P. Berrange a5a4c0c89b Another attempt to disable shunloadtest 2011-11-08 20:18:01 +00:00
Daniel P. Berrange 8c8aca2fab Update to 0.9.7 release 2011-11-08 19:52:05 +00:00
Dan Horák daf8e124ca xenlight available only on Xen arches (#745020) 2011-10-11 10:29:54 +02:00
Laine Stump 38c4b724fe release 0.9.6-2
* Make PCI multifunction support more manual - Bug 742836
* Builds on F15 should still use cgconfig - Bug 738725
2011-10-03 00:27:06 -04:00
Daniel Veillard 4d00487275 Upstream release of 0.9.6
Fix the qemu reboot bug from 0.9.5 and a few others bug fixes
2011-09-22 16:33:16 +08:00
Daniel Veillard a6831c26c1 Upstream release of libvirt-0.9.5 2011-09-20 14:51:18 +08:00
Daniel Veillard c363c7ebdb Upstream release of 0.9.4 2011-08-03 13:19:23 +08:00
Dan Horak 18ee6daf8a xenlight available only on Xen arches 2011-07-30 13:16:44 -04:00
Peter Robinson 459eb426c3 add ARM to NUMA platform exlcludes 2011-07-06 15:19:11 +01:00
Daniel Veillard a0d670d2bf Temporary disable sanlock as version is too old 2011-07-04 23:05:01 +08:00
Daniel Veillard d7b41212c1 Updating for 0.9.3 upstream release, Daniel 2011-07-04 21:22:51 +08:00
Richard W.M. Jones 2e1539eba4 Rebuild because of libparted soname bump (libparted.so.0 -> libparted.so.1). 2011-06-29 22:07:28 +01:00
Laine Stump ee9521d87c update to 0.9.2
- require netcf-0.1.8 so transactional network config APIs are included
- document that CVE-2011-2178 has been resolved
2011-06-21 20:25:22 -04:00
Daniel Veillard 8d8fc08bac Deactivate sanlock for now until Dan Berrange updates it 2011-06-06 17:06:09 +08:00
Daniel Veillard e79d304c79 Release of libvirt-0.9.2 upstream 2011-06-06 13:19:32 +08:00
Richard W.M. Jones db03f03fd9 Add patch so users can try out virt-dmesg. 2011-05-25 22:29:05 +01:00
Daniel Veillard 957403ebec Update to upstream release 0.9.1
- support various persistent domain updates
- improvements on memory APIs
- Add virDomainEventRebootNew
- various improvements to libxl driver
- Spice: support audio, images and stream compression
- Various improvements and bug fixes
2011-05-05 13:23:46 +08:00
Daniel Veillard 6c32e1aaeb Fix libvirt-0.9.0 build for rawhide, Daniel 2011-04-08 15:16:29 +08:00
Daniel Veillard 362e335c0b Try to force the buidl with libxenlight 2011-04-07 17:13:40 +08:00
Daniel Veillard ed6c49f874 Update to release 0.9.0 2011-04-07 15:47:13 +08:00
Daniel Veillard 47fcec5405 Fix for CVE-2011-1146, missing checks on read-only connections 2011-03-14 21:48:48 +08:00
Daniel P. Berrange d7239a45b6 Add patch to fix -kernel boot with latest QEMU 2011-02-21 14:34:17 +00:00
Daniel Veillard f13fb18c58 Release of libvirt-0.8.8 upstream
- expose new API for sysinfo extraction
- cgroup blkio weight support
- smartcard device support
- qemu: Support per-device boot ordering
- Various improvements and bug fixes
Daniel
2011-02-17 12:29:20 +08:00
Dennis Gilmore d29644418d - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild 2011-02-08 06:38:06 -06:00
Daniel Veillard ed9e426b26 Update to libvirt 0.8.7
- Preliminary support for VirtualBox 4.0
- IPv6 support
- Add VMware Workstation and Player driver driver
- Add network disk support
- Various improvements and bug fixes
- from 0.8.6:
- Add support for iSCSI target auto-discovery
- QED: Basic support for QED images
- remote console support
- support for SPICE graphics
- sysinfo and VMBIOS support
- virsh qemu-monitor-command
2011-01-06 10:45:38 +08:00
Daniel Veillard 659febf9ff Temporary disable xen support on fedora build
temporary workaround since 0.8.5 fails with xen on F15 missing
MAX_VIRT_CPUS, to fix once sorted out upstream
2010-10-29 18:11:45 +02:00
Daniel Veillard fca1fccfad Upstream release of 0.8.5
- Enable JSON and netdev features in QEMU >= 0.13
- framework for auditing integration
- framework DTrace/SystemTap integration
- Setting the number of vcpu at boot
- Enable support for nested SVM
- Virtio plan9fs filesystem QEMU
- Memory parameter controls
- various improvements and bug fixes
Daniel
2010-10-29 17:57:15 +02:00
Jesse Keating f713d63bab - Rebuilt for gcc bug 634757 2010-09-29 14:43:44 -07:00
Dan Horák 5a45e466cf - disable the nwfilterxml2xmltest also on s390(x) 2010-09-16 22:29:05 +02:00
Daniel Veillard 742b24eb23 Upstream release libvirt-0.8.4 2010-09-13 15:26:25 +02:00
Daniel P. Berrange 03369d2383 Fix potential overflow in boot menu code 2010-08-23 21:14:34 +01:00
Daniel P. Berrange 2605d662e0 Update to 0.8.3 sources 2010-08-23 19:50:11 +01:00
Daniel P. Berrange e8394ab5b5 Update 0.8.3 release 2010-08-23 19:45:47 +01:00
Fedora Release Engineering 8ad156a5c2 dist-git conversion 2010-07-29 07:20:27 +00:00
40 changed files with 4837 additions and 5621 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
*.rpm
i686
x86_64
libvirt-*.tar.gz
libvirt-*.tar.xz
@@ -0,0 +1,122 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:05:55 +0200
Subject: [PATCH] tests: Check default GIC version for aarch64/virt TCG guests
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit b24eaf6210ebaf5dc8d29621063873c8419c517e)
---
.../qemuxml2argv-aarch64-gic-none-tcg.args | 19 ++++++++++++++++
.../qemuxml2argv-aarch64-gic-none-tcg.xml | 17 +++++++++++++++
tests/qemuxml2argvtest.c | 3 +++
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 25 ++++++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
5 files changed, 65 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
new file mode 100644
index 000000000..975a01481
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -0,0 +1,19 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-aarch64 \
+-name guest \
+-S \
+-machine virt,accel=tcg,gic-version=3 \
+-cpu cortex-a57 \
+-m 1024 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-guest/monitor.sock,server,nowait \
+-no-acpi \
+-boot c
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..0aa33dbec
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.xml
@@ -0,0 +1,17 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom'>
+ <model>cortex-a57</model>
+ </cpu>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index cc4fb91cd..362b140ac 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2250,6 +2250,9 @@ mymain(void)
DO_TEST_GIC("aarch64-gic-none-both", GIC_BOTH,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACH_VIRT_GIC_VERSION);
+ DO_TEST_GIC("aarch64-gic-none-tcg", GIC_BOTH,
+ QEMU_CAPS_MACHINE_OPT,
+ QEMU_CAPS_MACH_VIRT_GIC_VERSION);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
QEMU_CAPS_KVM, QEMU_CAPS_MACHINE_OPT);
DO_TEST_GIC("aarch64-gic-default", GIC_NONE,
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
new file mode 100644
index 000000000..69510e281
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+ <name>guest</name>
+ <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <gic version='3'/>
+ </features>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='allow'>cortex-a57</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index eae999dd6..aae632afe 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1073,6 +1073,7 @@ mymain(void)
DO_TEST_FULL("aarch64-gic-none-v2", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-none-v3", WHEN_BOTH, GIC_V3, NONE);
DO_TEST_FULL("aarch64-gic-none-both", WHEN_BOTH, GIC_BOTH, NONE);
+ DO_TEST_FULL("aarch64-gic-none-tcg", WHEN_BOTH, GIC_BOTH, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_NONE, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V2, NONE);
DO_TEST_FULL("aarch64-gic-default", WHEN_BOTH, GIC_V3, NONE);
@@ -0,0 +1,85 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 13:29:57 +0200
Subject: [PATCH] qemu: Use GICv2 for aarch64/virt TCG guests
There are currently some limitations in the emulated GICv3
that make it unsuitable as a default. Use GICv2 instead.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1450433
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit bc07101a7c2cd2ce07ad1ca28c47e0a7cde5625d)
---
src/qemu/qemu_domain.c | 23 +++++++++++++++++++++-
.../qemuxml2argv-aarch64-gic-none-tcg.args | 2 +-
.../qemuxml2xmlout-aarch64-gic-none-tcg.xml | 2 +-
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 589eb1889..891f8258a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2527,6 +2527,24 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
for (version = VIR_GIC_VERSION_LAST - 1;
version > VIR_GIC_VERSION_NONE;
version--) {
+
+ /* We want to use the highest available GIC version for guests;
+ * however, the emulated GICv3 is currently lacking a MSI controller,
+ * making it unsuitable for the pure PCIe topology we aim for.
+ *
+ * For that reason, we skip this step entirely for TCG guests,
+ * and rely on the code below to pick the default version, GICv2,
+ * which supports all the features we need.
+ *
+ * We'll want to revisit this once MSI support for GICv3 has been
+ * implemented in QEMU.
+ *
+ * See https://bugzilla.redhat.com/show_bug.cgi?id=1414081 */
+ if (version == VIR_GIC_VERSION_3 &&
+ def->virtType == VIR_DOMAIN_VIRT_QEMU) {
+ continue;
+ }
+
if (virQEMUCapsSupportsGICVersion(qemuCaps,
def->virtType,
version)) {
@@ -2544,8 +2562,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
/* Use the default GIC version if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
- def->gic_version == VIR_GIC_VERSION_NONE)
+ def->gic_version == VIR_GIC_VERSION_NONE) {
+ VIR_DEBUG("Using GIC version %s (default)",
+ virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ }
}
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
index 975a01481..52b699696 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-gic-none-tcg.args
@@ -7,7 +7,7 @@ QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-aarch64 \
-name guest \
-S \
--machine virt,accel=tcg,gic-version=3 \
+-machine virt,accel=tcg \
-cpu cortex-a57 \
-m 1024 \
-smp 1,sockets=1,cores=1,threads=1 \
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
index 69510e281..a0cd0b768 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-aarch64-gic-none-tcg.xml
@@ -9,7 +9,7 @@
<boot dev='hd'/>
</os>
<features>
- <gic version='3'/>
+ <gic version='2'/>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='allow'>cortex-a57</model>
@@ -0,0 +1,67 @@
From: Andrea Bolognani <abologna@redhat.com>
Date: Fri, 12 May 2017 14:38:08 +0200
Subject: [PATCH] gic: Remove VIR_GIC_VERSION_DEFAULT
The QEMU default is GICv2, and some of the code in libvirt
relies on the exact value. Stop pretending that's not the
case and use GICv2 explicitly where needed.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
(cherry picked from commit 5645badd1fe04fee7237c2f95e7710e978e40770)
---
src/qemu/qemu_command.c | 6 +++---
src/qemu/qemu_domain.c | 7 +++----
src/util/virgic.h | 3 ---
3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2d1328cf9..5feddc523 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7321,9 +7321,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
goto cleanup;
}
- /* The default GIC version should not be specified on the
- * QEMU commandline for backwards compatibility reasons */
- if (def->gic_version != VIR_GIC_VERSION_DEFAULT) {
+ /* The default GIC version (GICv2) should not be specified on
+ * the QEMU commandline for backwards compatibility reasons */
+ if (def->gic_version != VIR_GIC_VERSION_2) {
if (!virQEMUCapsGet(qemuCaps,
QEMU_CAPS_MACH_VIRT_GIC_VERSION)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 891f8258a..4a127cedf 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2560,12 +2560,11 @@ qemuDomainDefEnableDefaultFeatures(virDomainDefPtr def,
def->features[VIR_DOMAIN_FEATURE_GIC] = VIR_TRISTATE_SWITCH_ON;
}
- /* Use the default GIC version if no version was specified */
+ /* Use the default GIC version (GICv2) if no version was specified */
if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON &&
def->gic_version == VIR_GIC_VERSION_NONE) {
- VIR_DEBUG("Using GIC version %s (default)",
- virGICVersionTypeToString(VIR_GIC_VERSION_DEFAULT));
- def->gic_version = VIR_GIC_VERSION_DEFAULT;
+ VIR_DEBUG("Using GIC version 2 (default)");
+ def->gic_version = VIR_GIC_VERSION_2;
}
}
diff --git a/src/util/virgic.h b/src/util/virgic.h
index 1c9efd60f..2d77fdd45 100644
--- a/src/util/virgic.h
+++ b/src/util/virgic.h
@@ -35,9 +35,6 @@ typedef enum {
VIR_ENUM_DECL(virGICVersion);
-/* Consider GIC v2 the default */
-# define VIR_GIC_VERSION_DEFAULT VIR_GIC_VERSION_2
-
typedef enum {
VIR_GIC_IMPLEMENTATION_NONE = 0,
VIR_GIC_IMPLEMENTATION_KERNEL = (1 << 1),
@@ -0,0 +1,198 @@
From: Laine Stump <laine@laine.org>
Date: Thu, 18 May 2017 14:16:27 -0400
Subject: [PATCH] Revert "qemu: propagate bridge MTU into qemu "host_mtu"
option"
This reverts commit 2841e675.
It turns out that adding the host_mtu field to the PCI capabilities in
the guest bumps the length of PCI capabilities beyond the 32 byte
boundary, so the virtio-net device gets 64 bytes of ioport space
instead of 32, which offsets the address of all the other following
devices. Migration doesn't work very well when the location and length
of PCI capabilities of devices is changed between source and
destination.
This means that we need to make sure that the absence/presence of
host_mtu on the qemu commandline always matches between source and
destination, which means that we need to make setting of host_mtu an
opt-in thing (it can't happen automatically when the bridge being used
has a non-default MTU, which is what commit 2841e675 implemented).
I do want to re-implement this feature with an <mtu auto='on'/>
setting, but probably won't backport that to any stable branches, so
I'm first reverting the original commit, and that revert can be pushed
to the few releases that have been made since the original (3.1.0 -
3.3.0)
Resolves: https://bugzilla.redhat.com/1449346
(cherry picked from commit 77780a29edace958a1f931d3281b962be4f5290e)
(cherry picked from commit a2f5e87dceb1725c16cd4df17a4b7381ecf65901)
---
src/qemu/qemu_command.c | 32 ++++++++++----------------------
src/qemu/qemu_command.h | 3 +--
src/qemu/qemu_hotplug.c | 5 ++---
src/qemu/qemu_interface.c | 5 ++---
src/qemu/qemu_interface.h | 3 +--
5 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5feddc523..3abfe7b55 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3629,8 +3629,7 @@ qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu)
+ virQEMUCapsPtr qemuCaps)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *nic = net->model;
@@ -3754,23 +3753,13 @@ qemuBuildNicDevStr(virDomainDefPtr def,
virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size);
}
- if (usingVirtio && mtu) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
-
- virBufferAsprintf(&buf, ",host_mtu=%u", mtu);
-
- } else {
- /* log an error if mtu was requested specifically for this
- * interface, otherwise, if it's just what was reported by
- * the attached network, ignore it.
- */
- if (net->mtu) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("setting MTU is not supported with "
- "this QEMU binary"));
- goto error;
- }
+ if (usingVirtio && net->mtu) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("setting MTU is not supported with this QEMU binary"));
+ goto error;
}
+ virBufferAsprintf(&buf, ",host_mtu=%u", net->mtu);
}
if (vlan == -1)
@@ -8213,7 +8202,7 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
VIR_FREE(netdev);
if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex,
- queues, qemuCaps, net->mtu))) {
+ queues, qemuCaps))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Error generating NIC -device string"));
goto error;
@@ -8259,7 +8248,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virDomainNetType actualType = virDomainNetGetActualType(net);
virNetDevBandwidthPtr actualBandwidth;
size_t i;
- unsigned int mtu = net->mtu;
if (!bootindex)
@@ -8314,7 +8302,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
if (qemuInterfaceBridgeConnect(def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
break;
@@ -8494,7 +8482,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
}
if (qemuDomainSupportsNicdev(def, net)) {
if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
- vhostfdSize, qemuCaps, mtu)))
+ vhostfdSize, qemuCaps)))
goto cleanup;
virCommandAddArgList(cmd, "-device", nic, NULL);
} else {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 7da92c8c9..09cb00ee9 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -101,8 +101,7 @@ char *qemuBuildNicDevStr(virDomainDefPtr def,
int vlan,
unsigned int bootindex,
size_t vhostfdSize,
- virQEMUCapsPtr qemuCaps,
- unsigned int mtu);
+ virQEMUCapsPtr qemuCaps);
char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f133d04a8..2a4159560 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -968,7 +968,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
bool charDevPlugged = false;
bool netdevPlugged = false;
bool hostPlugged = false;
- unsigned int mtu = net->mtu;
/* preallocate new slot for device */
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -1025,7 +1024,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
goto cleanup;
memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceBridgeConnect(vm->def, driver, net,
- tapfd, &tapfdSize, &mtu) < 0)
+ tapfd, &tapfdSize) < 0)
goto cleanup;
iface_connected = true;
if (qemuInterfaceOpenVhostNet(vm->def, net, priv->qemuCaps,
@@ -1239,7 +1238,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
VIR_FORCE_CLOSE(vhostfd[i]);
if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0,
- queueSize, priv->qemuCaps, mtu)))
+ queueSize, priv->qemuCaps)))
goto try_remove;
qemuDomainObjEnterMonitor(driver, vm);
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c5dca60f1..ce448d243 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -503,8 +503,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
{
const char *brname;
int ret = -1;
@@ -545,7 +544,7 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
def->uuid, tunpath, tapfd, *tapfdSize,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
- net->mtu, mtu,
+ 0, NULL,
tap_create_flags) < 0) {
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index ba74ac2cf..a7faa0b3d 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -51,8 +51,7 @@ int qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
int *tapfd,
- size_t *tapfdSize,
- unsigned int *mtu)
+ size_t *tapfdSize)
ATTRIBUTE_NONNULL(2);
int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
@@ -0,0 +1,145 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 14:45:44 +0200
Subject: [PATCH] cpu: Introduce virCPUCopyMigratable
This new internal API makes a copy of virCPUDef while removing all
features which would block migration. It uses cpu_map.xml as a database
of such features, which should only be used as a fallback when we cannot
get the data from a hypervisor. The main goal of this API is to decouple
this filtering from virCPUUpdate so that the hypervisor driver can
filter the features according to the hypervisor.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 05e91c79f19e0be96526098d58a3498dac3f8529)
---
src/cpu/cpu.c | 31 +++++++++++++++++++++++++++++++
src/cpu/cpu.h | 8 ++++++++
src/cpu/cpu_x86.c | 25 +++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
4 files changed, 65 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 93647a2ed..8a407ac18 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1130,3 +1130,34 @@ virCPUExpandFeatures(virArch arch,
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
}
+
+
+/**
+ * virCPUCopyMigratable:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be copied
+ *
+ * Makes a copy of @cpu with all features which would block migration removed.
+ * If this doesn't make sense for a given architecture, the function returns a
+ * plain copy of @cpu (i.e., a copy with no features removed).
+ *
+ * Returns the copy of the CPU or NULL on error.
+ */
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s",
+ virArchToString(arch), cpu, NULLSTR(cpu->model));
+
+ if (!(driver = cpuGetSubDriver(arch)))
+ return NULL;
+
+ if (driver->copyMigratable)
+ return driver->copyMigratable(cpu);
+ else
+ return virCPUDefCopy(cpu);
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 8c238ad55..352445c40 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -118,6 +118,9 @@ typedef int
typedef int
(*virCPUArchExpandFeatures)(virCPUDefPtr cpu);
+typedef virCPUDefPtr
+(*virCPUArchCopyMigratable)(virCPUDefPtr cpu);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -138,6 +141,7 @@ struct cpuArchDriver {
virCPUArchTranslate translate;
virCPUArchConvertLegacy convertLegacy;
virCPUArchExpandFeatures expandFeatures;
+ virCPUArchCopyMigratable copyMigratable;
};
@@ -254,6 +258,10 @@ int
virCPUExpandFeatures(virArch arch,
virCPUDefPtr cpu);
+virCPUDefPtr
+virCPUCopyMigratable(virArch arch,
+ virCPUDefPtr cpu);
+
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
* have no real-life usage
*/
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 48648a7f4..a771b251e 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2903,6 +2903,30 @@ virCPUx86ExpandFeatures(virCPUDefPtr cpu)
}
+static virCPUDefPtr
+virCPUx86CopyMigratable(virCPUDefPtr cpu)
+{
+ virCPUDefPtr copy;
+ virCPUx86MapPtr map;
+
+ if (!(map = virCPUx86GetMap()))
+ return NULL;
+
+ if (!(copy = virCPUDefCopyWithoutModel(cpu)))
+ return NULL;
+
+ if (virCPUDefCopyModelFilter(copy, cpu, false,
+ x86FeatureIsMigratable, map) < 0)
+ goto error;
+
+ return copy;
+
+ error:
+ virCPUDefFree(copy);
+ return NULL;
+}
+
+
int
virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
const virCPUx86CPUID *cpuid)
@@ -2978,4 +3002,5 @@ struct cpuArchDriver cpuDriverX86 = {
.getModels = virCPUx86GetModels,
.translate = virCPUx86Translate,
.expandFeatures = virCPUx86ExpandFeatures,
+ .copyMigratable = virCPUx86CopyMigratable,
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b551cb86a..dc6db3b28 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1016,6 +1016,7 @@ virCPUCheckFeature;
virCPUCompare;
virCPUCompareXML;
virCPUConvertLegacy;
+virCPUCopyMigratable;
virCPUDataCheckFeature;
virCPUDataFormat;
virCPUDataFree;
@@ -0,0 +1,78 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 30 Mar 2017 13:50:44 +0200
Subject: [PATCH] qemu: Move common code in virQEMUCapsInitCPUModel one layer
up
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit d84b93fad51b190238e18b1daac82ea6e28869e9)
---
src/qemu/qemu_capabilities.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b1245ad5d..1a15750a3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3111,17 +3111,11 @@ virQEMUCapsCPUFilterFeatures(const char *name,
*/
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr modelInfo,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr modelInfo;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- modelInfo = qemuCaps->kvmCPUModelInfo;
- else
- modelInfo = qemuCaps->tcgCPUModelInfo;
-
if (!modelInfo) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing host CPU model info from QEMU capabilities "
@@ -3163,9 +3157,9 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
+ qemuMonitorCPUModelInfoPtr model,
virCPUDefPtr cpu)
{
- qemuMonitorCPUModelInfoPtr model;
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
unsigned long long sigModel = 0;
@@ -3174,11 +3168,6 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
int ret = -1;
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
if (!model)
return 1;
@@ -3239,12 +3228,18 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
+ qemuMonitorCPUModelInfoPtr model;
int ret = 1;
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ model = qemuCaps->kvmCPUModelInfo;
+ else
+ model = qemuCaps->tcgCPUModelInfo;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -0,0 +1,139 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 13:33:50 +0200
Subject: [PATCH] qemu: Add migratable parameter to virQEMUCapsInitCPUModel
The caller can ask for a migratable CPU model by passing true for the
new parameter.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 00e0cbcb567a57c7b5a145d7fd3fb662779f6bec)
---
src/qemu/qemu_capabilities.c | 36 +++++++++++++++++++++++++-----------
src/qemu/qemu_capspriv.h | 3 ++-
tests/cputest.c | 2 +-
3 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1a15750a3..b8e4e47b6 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3112,7 +3112,8 @@ virQEMUCapsCPUFilterFeatures(const char *name,
static int
virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
qemuMonitorCPUModelInfoPtr modelInfo,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
size_t i;
@@ -3140,8 +3141,12 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
if (VIR_STRDUP(feature->name, prop->name) < 0)
return -1;
- feature->policy = prop->value.boolean ? VIR_CPU_FEATURE_REQUIRE
- : VIR_CPU_FEATURE_DISABLE;
+
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ feature->policy = VIR_CPU_FEATURE_DISABLE;
+ else
+ feature->policy = VIR_CPU_FEATURE_REQUIRE;
cpu->nfeatures++;
}
@@ -3158,7 +3163,8 @@ static int
virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr model,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0;
@@ -3179,9 +3185,13 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
switch (prop->type) {
case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
- if (prop->value.boolean &&
- virCPUx86DataAddFeature(data, prop->name) < 0)
+ if (!prop->value.boolean ||
+ (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO))
+ continue;
+
+ if (virCPUx86DataAddFeature(data, prop->name) < 0)
goto cleanup;
+
break;
case QEMU_MONITOR_CPU_PROPERTY_STRING:
@@ -3220,13 +3230,14 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
/**
* Returns 0 when host CPU model provided by QEMU was filled in qemuCaps,
- * 1 when the caller should fall back to using virCapsPtr->host.cpu,
+ * 1 when the caller should fall back to other methods
* -1 on error.
*/
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool migratable)
{
qemuMonitorCPUModelInfoPtr model;
int ret = 1;
@@ -3236,10 +3247,13 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
else
model = qemuCaps->tcgCPUModelInfo;
+ if (migratable && model && !model->migratability)
+ return 1;
+
if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu);
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu);
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3268,7 +3282,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index 61ccd4517..1baaaf334 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -81,7 +81,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
int
virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu);
+ virCPUDefPtr cpu,
+ bool migratable);
void
virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
diff --git a/tests/cputest.c b/tests/cputest.c
index 3d3e43f16..8c07cf4f6 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -709,7 +709,7 @@ cpuTestJSONCPUID(const void *arg)
cpu->match = VIR_CPU_MATCH_EXACT;
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
- if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu) != 0)
+ if (virQEMUCapsInitCPUModel(qemuCaps, VIR_DOMAIN_VIRT_KVM, cpu, false) != 0)
goto cleanup;
ret = cpuTestCompareXML(data->arch, cpu, result, false);
@@ -0,0 +1,47 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:03:38 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsSetHostModel
A simple helper as a complement to virQEMUCapsGetHostModel.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bffc3b9fe501ff122ad81ddf42ecdb69f70ff70a)
---
src/qemu/qemu_capabilities.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index b8e4e47b6..f6020b86d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2419,6 +2419,18 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
}
+static void
+virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type,
+ virCPUDefPtr cpu)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ qemuCaps->kvmCPUModel = cpu;
+ else
+ qemuCaps->tcgCPUModel = cpu;
+}
+
+
bool
virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
@@ -3295,10 +3307,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu);
cleanup:
virCPUDefFree(hostCPU);
@@ -0,0 +1,70 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:40:31 +0200
Subject: [PATCH] qemu: Move qemuCaps CPU data copying into a separate function
This introduces virQEMUCapsHostCPUDataCopy which will later be
refactored a bit and called twice from virQEMUCapsNewCopy.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 8be4346ca5ae4b568b3e8ce3de9cf46f2e94b416)
---
src/qemu/qemu_capabilities.c | 39 +++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f6020b86d..d17e0e8b8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2082,6 +2082,30 @@ virQEMUCapsNew(void)
}
+static int
+virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
+ virQEMUCapsPtr src)
+{
+ if (src->kvmCPUModel &&
+ !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ return -1;
+
+ if (src->tcgCPUModel &&
+ !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
+ return -1;
+
+ if (src->kvmCPUModelInfo &&
+ !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
+ return -1;
+
+ if (src->tcgCPUModelInfo &&
+ !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ return -1;
+
+ return 0;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2119,20 +2143,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (qemuCaps->kvmCPUModel &&
- !(ret->kvmCPUModel = virCPUDefCopy(qemuCaps->kvmCPUModel)))
- goto error;
-
- if (qemuCaps->tcgCPUModel &&
- !(ret->tcgCPUModel = virCPUDefCopy(qemuCaps->tcgCPUModel)))
- goto error;
-
- if (qemuCaps->kvmCPUModelInfo &&
- !(ret->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->kvmCPUModelInfo)))
- goto error;
-
- if (qemuCaps->tcgCPUModelInfo &&
- !(ret->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(qemuCaps->tcgCPUModelInfo)))
+ if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -0,0 +1,67 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 17:43:59 +0200
Subject: [PATCH] qemu: Introduce virQEMUCapsHostCPUDataClear
To keep freeing of host CPU data in one place.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0605e848724c5dc478382398b734398abff674c)
---
src/qemu/qemu_capabilities.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d17e0e8b8..2da53a60b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2106,6 +2106,21 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
}
+static void
+virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+{
+ qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
+ qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
+ qemuCaps->kvmCPUModelInfo = NULL;
+ qemuCaps->tcgCPUModelInfo = NULL;
+
+ virCPUDefFree(qemuCaps->kvmCPUModel);
+ virCPUDefFree(qemuCaps->tcgCPUModel);
+ qemuCaps->kvmCPUModel = NULL;
+ qemuCaps->tcgCPUModel = NULL;
+}
+
+
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
{
virQEMUCapsPtr ret = virQEMUCapsNew();
@@ -2192,10 +2207,7 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
void
@@ -4068,15 +4080,7 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ virQEMUCapsHostCPUDataClear(qemuCaps);
}
@@ -0,0 +1,342 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 18:15:26 +0200
Subject: [PATCH] qemu: Move qemuCaps host CPU data in a struct
We need to store several CPU related data structure for both KVM and
TCG. So instead of keeping two different copies of everything let's
make a virQEMUCapsHostCPUData struct and use it twice.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0a84ffb7f38f990120c231cfb74956a0ed10d95)
---
src/qemu/qemu_capabilities.c | 168 +++++++++++++++++++++----------------------
1 file changed, 82 insertions(+), 86 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2da53a60b..bbb234538 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -373,6 +373,19 @@ struct virQEMUCapsMachineType {
unsigned int maxCpus;
bool hotplugCpus;
};
+
+typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
+typedef virQEMUCapsHostCPUData *virQEMUCapsHostCPUDataPtr;
+struct _virQEMUCapsHostCPUData {
+ /* Only the "info" part is stored in the capabilities cache, the rest is
+ * re-computed from other fields and external data sources everytime we
+ * probe QEMU or load the cache.
+ */
+ qemuMonitorCPUModelInfoPtr info;
+ /* Host CPU definition reported in domain capabilities. */
+ virCPUDefPtr reported;
+};
+
/*
* Update the XML parser/formatter when adding more
* information to this struct so that it gets cached
@@ -407,15 +420,8 @@ struct _virQEMUCaps {
size_t ngicCapabilities;
virGICCapability *gicCapabilities;
- qemuMonitorCPUModelInfoPtr kvmCPUModelInfo;
- qemuMonitorCPUModelInfoPtr tcgCPUModelInfo;
-
- /* Anything below is not stored in the cache since the values are
- * re-computed from the other fields or external data sources every
- * time we probe QEMU or load the results from the cache.
- */
- virCPUDefPtr kvmCPUModel;
- virCPUDefPtr tcgCPUModel;
+ virQEMUCapsHostCPUData kvmCPU;
+ virQEMUCapsHostCPUData tcgCPU;
};
struct virQEMUCapsSearchData {
@@ -2083,23 +2089,15 @@ virQEMUCapsNew(void)
static int
-virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
- virQEMUCapsPtr src)
+virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
+ virQEMUCapsHostCPUDataPtr src)
{
- if (src->kvmCPUModel &&
- !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+ if (src->info &&
+ !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
return -1;
- if (src->tcgCPUModel &&
- !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
- return -1;
-
- if (src->kvmCPUModelInfo &&
- !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
- return -1;
-
- if (src->tcgCPUModelInfo &&
- !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+ if (src->reported &&
+ !(dst->reported = virCPUDefCopy(src->reported)))
return -1;
return 0;
@@ -2107,17 +2105,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
static void
-virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
- qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
- qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
- qemuCaps->kvmCPUModelInfo = NULL;
- qemuCaps->tcgCPUModelInfo = NULL;
-
- virCPUDefFree(qemuCaps->kvmCPUModel);
- virCPUDefFree(qemuCaps->tcgCPUModel);
- qemuCaps->kvmCPUModel = NULL;
- qemuCaps->tcgCPUModel = NULL;
+ qemuMonitorCPUModelInfoFree(cpuData->info);
+ virCPUDefFree(cpuData->reported);
+
+ memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2158,7 +2151,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error;
}
- if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
+ if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
+ virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -2207,7 +2201,8 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities);
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
void
@@ -2431,14 +2426,24 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
}
+static virQEMUCapsHostCPUDataPtr
+virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
+ virDomainVirtType type)
+{
+ if (type == VIR_DOMAIN_VIRT_KVM)
+ return &qemuCaps->kvmCPU;
+ else
+ return &qemuCaps->tcgCPU;
+}
+
+
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- return qemuCaps->kvmCPUModel;
- else
- return qemuCaps->tcgCPUModel;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ return cpuData->reported;
}
@@ -2447,10 +2452,9 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr cpu)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModel = cpu;
- else
- qemuCaps->tcgCPUModel = cpu;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->reported = cpu;
}
@@ -2841,24 +2845,28 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon,
bool tcg)
{
- qemuMonitorCPUModelInfoPtr *modelInfo;
+ qemuMonitorCPUModelInfoPtr modelInfo = NULL;
qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
virHashTablePtr hash = NULL;
const char *model;
qemuMonitorCPUModelExpansionType type;
+ virDomainVirtType virtType;
+ virQEMUCapsHostCPUDataPtr cpuData;
int ret = -1;
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
return 0;
if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
- modelInfo = &qemuCaps->tcgCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_QEMU;
model = "max";
} else {
- modelInfo = &qemuCaps->kvmCPUModelInfo;
+ virtType = VIR_DOMAIN_VIRT_KVM;
model = "host";
}
+ cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+
/* Some x86_64 features defined in cpu_map.xml use spelling which differ
* from the one preferred by QEMU. Static expansion would give us only the
* preferred spelling, thus we need to do a full expansion on the result of
@@ -2869,14 +2877,14 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
else
type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
- if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, modelInfo) < 0)
- return -1;
+ if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
+ goto cleanup;
/* Try to check migratability of each feature. */
- if (*modelInfo &&
+ if (modelInfo &&
qemuMonitorGetCPUModelExpansion(mon, type, model, false,
&nonMigratable) < 0)
- goto error;
+ goto cleanup;
if (nonMigratable) {
qemuMonitorCPUPropertyPtr prop;
@@ -2884,12 +2892,12 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
size_t i;
if (!(hash = virHashCreate(0, NULL)))
- goto error;
+ goto cleanup;
- for (i = 0; i < (*modelInfo)->nprops; i++) {
- prop = (*modelInfo)->props + i;
+ for (i = 0; i < modelInfo->nprops; i++) {
+ prop = modelInfo->props + i;
if (virHashAddEntry(hash, prop->name, prop) < 0)
- goto error;
+ goto cleanup;
}
for (i = 0; i < nonMigratable->nprops; i++) {
@@ -2907,21 +2915,18 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
}
}
- (*modelInfo)->migratability = true;
+ modelInfo->migratability = true;
}
+ VIR_STEAL_PTR(cpuData->info, modelInfo);
ret = 0;
cleanup:
virHashFree(hash);
qemuMonitorCPUModelInfoFree(nonMigratable);
+ qemuMonitorCPUModelInfoFree(modelInfo);
return ret;
-
- error:
- qemuMonitorCPUModelInfoFree(*modelInfo);
- *modelInfo = NULL;
- goto cleanup;
}
struct tpmTypeToCaps {
@@ -3274,21 +3279,19 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu,
bool migratable)
{
- qemuMonitorCPUModelInfoPtr model;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
int ret = 1;
- if (type == VIR_DOMAIN_VIRT_KVM)
- model = qemuCaps->kvmCPUModelInfo;
- else
- model = qemuCaps->tcgCPUModelInfo;
-
- if (migratable && model && !model->migratability)
+ if (migratable && cpuData->info && !cpuData->info->migratability)
return 1;
- if (ARCH_IS_S390(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
- else if (ARCH_IS_X86(qemuCaps->arch))
- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
+ if (ARCH_IS_S390(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
+ cpu, migratable);
+ } else if (ARCH_IS_X86(qemuCaps->arch)) {
+ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
+ cpu, migratable);
+ }
if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3348,10 +3351,9 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
qemuMonitorCPUModelInfoPtr modelInfo)
{
- if (type == VIR_DOMAIN_VIRT_KVM)
- qemuCaps->kvmCPUModelInfo = modelInfo;
- else
- qemuCaps->tcgCPUModelInfo = modelInfo;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+ cpuData->info = modelInfo;
}
@@ -3810,18 +3812,11 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
virBufferPtr buf,
virDomainVirtType type)
{
- qemuMonitorCPUModelInfoPtr model;
- const char *typeStr;
+ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+ qemuMonitorCPUModelInfoPtr model = cpuData->info;
+ const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
size_t i;
- if (type == VIR_DOMAIN_VIRT_KVM) {
- typeStr = "kvm";
- model = qemuCaps->kvmCPUModelInfo;
- } else {
- typeStr = "tcg";
- model = qemuCaps->tcgCPUModelInfo;
- }
-
if (!model)
return;
@@ -4080,7 +4075,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0;
- virQEMUCapsHostCPUDataClear(qemuCaps);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+ virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
}
@@ -0,0 +1,119 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 11:14:30 +0200
Subject: [PATCH] qemu: Prepare qemuCaps for multiple host CPU defs
Soon we will need to store multiple host CPU definitions in
virQEMUCapsHostCPUData and qemuCaps users will want to request the one
they need. This patch introduces virQEMUCapsHostCPUType enum which will
be used for specifying the requested CPU definition.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 1fe517c68df92eb7f379fa87cb0d29d566aad6f4)
---
src/qemu/qemu_capabilities.c | 16 ++++++++++++----
src/qemu/qemu_capabilities.h | 10 +++++++++-
src/qemu/qemu_command.c | 3 ++-
src/qemu/qemu_process.c | 6 ++++--
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index bbb234538..a6324a398 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2439,11 +2439,17 @@ virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type)
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- return cpuData->reported;
+ switch (cpuType) {
+ case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
+ return cpuData->reported;
+ }
+
+ return NULL;
}
@@ -2472,7 +2478,8 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch);
case VIR_CPU_MODE_HOST_MODEL:
- return !!virQEMUCapsGetHostModel(qemuCaps, type);
+ return !!virQEMUCapsGetHostModel(qemuCaps, type,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
case VIR_CPU_MODE_CUSTOM:
if (type == VIR_DOMAIN_VIRT_KVM)
@@ -5456,7 +5463,8 @@ virQEMUCapsFillDomainCPUCaps(virCapsPtr caps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, caps, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL)) {
- virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype);
+ virCPUDefPtr cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
domCaps->cpu.hostModel = virCPUDefCopy(cpu);
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d44682f2a..88e27855b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -449,8 +449,16 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
char ***names,
size_t *count);
+
+typedef enum {
+ /* Host CPU definition reported in domain capabilities. */
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+} virQEMUCapsHostCPUType;
+
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
- virDomainVirtType type);
+ virDomainVirtType type,
+ virQEMUCapsHostCPUType cpuType);
+
bool virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3abfe7b55..311edd13e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6879,7 +6879,8 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
if (def->cpu->mode == VIR_CPU_MODE_CUSTOM)
cpuDef = def->cpu;
else if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
- cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType);
+ cpuDef = virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
if (cpuDef) {
int svm = virCPUCheckFeature(def->os.arch, cpuDef, "svm");
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 26a668d27..07a88a3a7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5299,12 +5299,14 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType),
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED),
def->cpu, true) < 0)
return -1;
if (virCPUUpdate(def->os.arch, def->cpu,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType)) < 0)
+ virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
@@ -0,0 +1,210 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:31:17 +0200
Subject: [PATCH] qemu: Pass migratable host CPU model to virCPUUpdate
We already know from QEMU which CPU features will block migration. Let's
use this information to make a migratable copy of the host CPU model and
use it for updating guest CPU specification. This will allow us to drop
feature filtering from virCPUUpdate where it was just a hack.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 56bd7edcb5dc878beffb80d4e6a9cfb812378ded)
---
src/qemu/qemu_capabilities.c | 57 +++++++++++++++++++++++++++++++++++++-------
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_process.c | 2 +-
tests/cputest.c | 7 +++++-
4 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a6324a398..7fc577546 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -384,6 +384,8 @@ struct _virQEMUCapsHostCPUData {
qemuMonitorCPUModelInfoPtr info;
/* Host CPU definition reported in domain capabilities. */
virCPUDefPtr reported;
+ /* Migratable host CPU definition used for updating guest CPU. */
+ virCPUDefPtr migratable;
};
/*
@@ -2100,6 +2102,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->reported = virCPUDefCopy(src->reported)))
return -1;
+ if (src->migratable &&
+ !(dst->migratable = virCPUDefCopy(src->migratable)))
+ return -1;
+
return 0;
}
@@ -2109,6 +2115,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
+ virCPUDefFree(cpuData->migratable);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2447,6 +2454,9 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
switch (cpuType) {
case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
return cpuData->reported;
+
+ case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
+ return cpuData->migratable;
}
return NULL;
@@ -2456,11 +2466,13 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
- virCPUDefPtr cpu)
+ virCPUDefPtr reported,
+ virCPUDefPtr migratable)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
- cpuData->reported = cpu;
+ cpuData->reported = reported;
+ cpuData->migratable = migratable;
}
@@ -3307,26 +3319,39 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
}
+static virCPUDefPtr
+virQEMUCapsNewHostCPUModel(void)
+{
+ virCPUDefPtr cpu;
+
+ if (VIR_ALLOC(cpu) < 0)
+ return NULL;
+
+ cpu->type = VIR_CPU_TYPE_GUEST;
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
+ cpu->match = VIR_CPU_MATCH_EXACT;
+ cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
+
+ return cpu;
+}
+
+
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCapsPtr caps,
virDomainVirtType type)
{
virCPUDefPtr cpu = NULL;
+ virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
return;
- if (VIR_ALLOC(cpu) < 0)
+ if (!(cpu = virQEMUCapsNewHostCPUModel()))
goto error;
- cpu->type = VIR_CPU_TYPE_GUEST;
- cpu->mode = VIR_CPU_MODE_CUSTOM;
- cpu->match = VIR_CPU_MATCH_EXACT;
- cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
-
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
goto error;
} else if (rc == 1) {
@@ -3340,7 +3365,20 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu);
+ if (!(migCPU = virQEMUCapsNewHostCPUModel()))
+ goto error;
+
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+ goto error;
+ } else if (rc == 1) {
+ VIR_DEBUG("CPU migratability not provided by QEMU");
+
+ virCPUDefFree(migCPU);
+ if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
+ goto error;
+ }
+
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3348,6 +3386,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
+ virCPUDefFree(migCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 88e27855b..31818c940 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -453,6 +453,8 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
typedef enum {
/* Host CPU definition reported in domain capabilities. */
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+ /* Migratable host CPU definition used for updating guest CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 07a88a3a7..e67736638 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5306,7 +5306,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
goto cleanup;
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
diff --git a/tests/cputest.c b/tests/cputest.c
index 8c07cf4f6..efa891dc1 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -393,6 +393,7 @@ cpuTestUpdate(const void *arg)
const struct data *data = arg;
int ret = -1;
virCPUDefPtr host = NULL;
+ virCPUDefPtr migHost = NULL;
virCPUDefPtr cpu = NULL;
char *result = NULL;
@@ -400,7 +401,10 @@ cpuTestUpdate(const void *arg)
!(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup;
- if (virCPUUpdate(host->arch, cpu, host) < 0)
+ if (!(migHost = virCPUCopyMigratable(data->arch, host)))
+ goto cleanup;
+
+ if (virCPUUpdate(host->arch, cpu, migHost) < 0)
goto cleanup;
if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
@@ -411,6 +415,7 @@ cpuTestUpdate(const void *arg)
cleanup:
virCPUDefFree(host);
virCPUDefFree(cpu);
+ virCPUDefFree(migHost);
VIR_FREE(result);
return ret;
}
@@ -0,0 +1,49 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 29 Mar 2017 15:00:21 +0200
Subject: [PATCH] cpu: Drop feature filtering from virCPUUpdate
Because of the changes done in the previous commit, @host is already a
migratable CPU and there's no need to do any additional filtering.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 232d87c7dd081d126a079fb45178e0be096cc680)
---
src/cpu/cpu_x86.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index a771b251e..53359ff9b 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2549,8 +2549,7 @@ x86Baseline(virCPUDefPtr *cpus,
static int
x86UpdateHostModel(virCPUDefPtr guest,
- const virCPUDef *host,
- virCPUx86MapPtr map)
+ const virCPUDef *host)
{
virCPUDefPtr updated = NULL;
size_t i;
@@ -2559,11 +2558,9 @@ x86UpdateHostModel(virCPUDefPtr guest,
if (!(updated = virCPUDefCopyWithoutModel(host)))
goto cleanup;
- /* Remove non-migratable features by default */
updated->type = VIR_CPU_TYPE_GUEST;
updated->mode = VIR_CPU_MODE_CUSTOM;
- if (virCPUDefCopyModelFilter(updated, host, true,
- x86FeatureIsMigratable, map) < 0)
+ if (virCPUDefCopyModel(updated, host, true) < 0)
goto cleanup;
if (guest->vendor_id) {
@@ -2627,7 +2624,7 @@ virCPUx86Update(virCPUDefPtr guest,
if (guest->mode == VIR_CPU_MODE_HOST_MODEL ||
guest->match == VIR_CPU_MATCH_MINIMUM)
- ret = x86UpdateHostModel(guest, host, map);
+ ret = x86UpdateHostModel(guest, host);
else
ret = 0;
@@ -0,0 +1,74 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:45:07 +0200
Subject: [PATCH] cpu: Introduce virCPUGetHostIsSupported
Sometimes we want to call virCPUGetHost only when it is implemented for
a given architecture to avoid logging expected and possibly misleading
errors. The new virCPUGetHostIsSupported API may be used to guard such
calls to virCPUGetHost.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bf1a881715c905c67f7d38dcd5bd6c2afbff1f9b)
---
src/cpu/cpu.c | 20 ++++++++++++++++++++
src/cpu/cpu.h | 3 +++
src/libvirt_private.syms | 1 +
3 files changed, 24 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 8a407ac18..702b14dbb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -357,6 +357,26 @@ virCPUDataFree(virCPUDataPtr data)
}
+/**
+ * virCPUGetHostIsSupported:
+ *
+ * @arch: CPU architecture
+ *
+ * Check whether virCPUGetHost is supported for @arch.
+ *
+ * Returns true if virCPUGetHost is supported, false otherwise.
+ */
+bool
+virCPUGetHostIsSupported(virArch arch)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s", virArchToString(arch));
+
+ return (driver = cpuGetSubDriver(arch)) && driver->getHost;
+}
+
+
/**
* virCPUGetHost:
*
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 352445c40..c6ca111e9 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -183,6 +183,9 @@ virCPUDataNew(virArch arch);
void
virCPUDataFree(virCPUDataPtr data);
+bool
+virCPUGetHostIsSupported(virArch arch);
+
virCPUDefPtr
virCPUGetHost(virArch arch,
virCPUType type,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc6db3b28..2d8a9ddec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1024,6 +1024,7 @@ virCPUDataNew;
virCPUDataParse;
virCPUExpandFeatures;
virCPUGetHost;
+virCPUGetHostIsSupported;
virCPUGetModels;
virCPUProbeHost;
virCPUTranslate;
@@ -0,0 +1,164 @@
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 11 Apr 2017 20:46:05 +0200
Subject: [PATCH] qemu: Use more data for comparing CPUs
With QEMU older than 2.9.0 libvirt uses CPUID instruction to determine
what CPU features are supported on the host. This was later used when
checking compatibility of guest CPUs. Since QEMU 2.9.0 we ask QEMU for
the host CPU data. But the two methods we use usually provide disjoint
sets of CPU features because QEMU/KVM does not support all features
provided by the host CPU and on the other hand it can enable some
feature even if the host CPU does not support them.
So if there is a domain which requires a CPU features disabled by
QEMU/KVM, libvirt will refuse to start it with QEMU > 2.9.0 as its guest
CPU is incompatible with the host CPU data we got from QEMU. But such
domain would happily start on older QEMU (of course, the features would
be missing the guest CPU). To fix this regression, we need to combine
both CPU feature sets when checking guest CPU compatibility.
https://bugzilla.redhat.com/show_bug.cgi?id=1439933
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 5b4a6adb5ca24a6cb91cdc55c31506fb278d3a91)
---
src/qemu/qemu_capabilities.c | 35 +++++++++++++++++++++++++++++++++--
src/qemu/qemu_capabilities.h | 4 ++++
src/qemu/qemu_process.c | 2 +-
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7fc577546..01bd4750c 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -386,6 +386,10 @@ struct _virQEMUCapsHostCPUData {
virCPUDefPtr reported;
/* Migratable host CPU definition used for updating guest CPU. */
virCPUDefPtr migratable;
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ virCPUDefPtr full;
};
/*
@@ -2106,6 +2110,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
!(dst->migratable = virCPUDefCopy(src->migratable)))
return -1;
+ if (src->full &&
+ !(dst->full = virCPUDefCopy(src->full)))
+ return -1;
+
return 0;
}
@@ -2116,6 +2124,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
virCPUDefFree(cpuData->migratable);
+ virCPUDefFree(cpuData->full);
memset(cpuData, 0, sizeof(*cpuData));
}
@@ -2457,6 +2466,11 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
return cpuData->migratable;
+
+ case VIR_QEMU_CAPS_HOST_CPU_FULL:
+ /* 'full' is non-NULL only if we have data from both QEMU and
+ * virCPUGetHost */
+ return cpuData->full ? cpuData->full : cpuData->reported;
}
return NULL;
@@ -2467,12 +2481,14 @@ static void
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type,
virCPUDefPtr reported,
- virCPUDefPtr migratable)
+ virCPUDefPtr migratable,
+ virCPUDefPtr full)
{
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
cpuData->reported = reported;
cpuData->migratable = migratable;
+ cpuData->full = full;
}
@@ -3344,6 +3360,8 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu = NULL;
virCPUDefPtr migCPU = NULL;
virCPUDefPtr hostCPU = NULL;
+ virCPUDefPtr fullCPU = NULL;
+ size_t i;
int rc;
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
@@ -3363,6 +3381,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virQEMUCapsCPUFilterFeatures,
qemuCaps) < 0)
goto error;
+ } else if (type == VIR_DOMAIN_VIRT_KVM &&
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
+ if (!(fullCPU = virCPUGetHost(qemuCaps->arch, VIR_CPU_TYPE_GUEST,
+ NULL, NULL, 0)))
+ goto error;
+
+ for (i = 0; i < cpu->nfeatures; i++) {
+ if (cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE &&
+ virCPUDefUpdateFeature(fullCPU, cpu->features[i].name,
+ VIR_CPU_FEATURE_REQUIRE) < 0)
+ goto error;
+ }
}
if (!(migCPU = virQEMUCapsNewHostCPUModel()))
@@ -3378,7 +3408,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
goto error;
}
- virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU);
cleanup:
virCPUDefFree(hostCPU);
@@ -3387,6 +3417,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
error:
virCPUDefFree(cpu);
virCPUDefFree(migCPU);
+ virCPUDefFree(fullCPU);
virResetLastError();
goto cleanup;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 31818c940..4e9561c0a 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -455,6 +455,10 @@ typedef enum {
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
/* Migratable host CPU definition used for updating guest CPU. */
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
+ /* CPU definition with features detected by libvirt using virCPUGetHost
+ * combined with features reported by QEMU. This is used for backward
+ * compatible comparison between a guest CPU and a host CPU. */
+ VIR_QEMU_CAPS_HOST_CPU_FULL,
} virQEMUCapsHostCPUType;
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e67736638..992a7174b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5300,7 +5300,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
virCPUCompare(caps->host.arch,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED),
+ VIR_QEMU_CAPS_HOST_CPU_FULL),
def->cpu, true) < 0)
return -1;
@@ -0,0 +1,123 @@
From: Neal Gompa <ngompa13@gmail.com>
Date: Mon, 17 Jul 2017 11:32:46 -0400
Subject: [PATCH] spec: Add support for building the zfs storage driver
Where it can be supported in Fedora, the driver is built and made
available as a subpackage.
Signed-off-by: Neal Gompa <ngompa13@gmail.com>
(cherry picked from commit 9af764e86aef7dfb0191a9561bf1d1abf941da05)
---
libvirt.spec.in | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 079b5f386..46a3e97d1 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -71,6 +71,13 @@
%define with_storage_gluster 0%{!?_without_storage_gluster:1}
%define with_numactl 0%{!?_without_numactl:1}
+# F25+ has zfs-fuse
+%if 0%{?fedora} >= 25
+ %define with_storage_zfs 0%{!?_without_storage_zfs:1}
+%else
+ %define with_storage_zfs 0
+%endif
+
# A few optional bits off by default, we enable later
%define with_fuse 0%{!?_without_fuse:0}
%define with_cgconfig 0%{!?_without_cgconfig:0}
@@ -115,6 +122,12 @@
%endif
%endif
+# zfs-fuse is not available on some architectures
+%ifarch s390 s390x aarch64
+ %define with_storage_zfs 0
+%endif
+
+
# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor,
# VMware, libxenserver (xenapi), libxenlight (Xen 4.1 and newer),
# or HyperV.
@@ -373,6 +386,12 @@ BuildRequires: glusterfs-devel >= 3.4.1
%if %{with_storage_sheepdog}
BuildRequires: sheepdog
%endif
+%if %{with_storage_zfs}
+# Support any conforming implementation of zfs. On stock Fedora
+# this is zfs-fuse, but could be zfsonlinux upstream RPMs
+BuildRequires: /sbin/zfs
+BuildRequires: /sbin/zpool
+%endif
%if %{with_numactl}
# For QEMU/LXC numa info
BuildRequires: numactl-devel
@@ -705,6 +724,21 @@ sheepdog volumes using.
%endif
+%if %{with_storage_zfs}
+%package daemon-driver-storage-zfs
+Summary: Storage driver plugin for ZFS
+Group: Development/Libraries
+Requires: libvirt-daemon-driver-storage-core = %{version}-%{release}
+# Support any conforming implementation of zfs
+Requires: /sbin/zfs
+Requires: /sbin/zpool
+
+%description daemon-driver-storage-zfs
+The storage driver backend adding implementation of the storage APIs for
+ZFS volumes.
+%endif
+
+
%package daemon-driver-storage
Summary: Storage driver plugin including all backends for the libvirtd daemon
Group: Development/Libraries
@@ -723,6 +757,9 @@ Requires: libvirt-daemon-driver-storage-rbd = %{version}-%{release}
%if %{with_storage_sheepdog}
Requires: libvirt-daemon-driver-storage-sheepdog = %{version}-%{release}
%endif
+%if %{with_storage_zfs}
+Requires: libvirt-daemon-driver-storage-zfs = %{version}-%{release}
+%endif
%description daemon-driver-storage
The storage driver plugin for the libvirtd daemon, providing
@@ -1180,6 +1217,12 @@ rm -rf .git
%define arg_storage_gluster --without-storage-gluster
%endif
+%if %{with_storage_zfs}
+ %define arg_storage_zfs --with-storage-zfs
+%else
+ %define arg_storage_zfs --without-storage-zfs
+%endif
+
%if %{with_numactl}
%define arg_numactl --with-numactl
%else
@@ -1288,7 +1331,7 @@ rm -f po/stamp-po
%{?arg_storage_rbd} \
%{?arg_storage_sheepdog} \
%{?arg_storage_gluster} \
- --without-storage-zfs \
+ %{?arg_storage_zfs} \
--without-storage-vstorage \
%{?arg_numactl} \
%{?arg_numad} \
@@ -1850,6 +1893,11 @@ exit 0
%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_sheepdog.so
%endif
+%if %{with_storage_zfs}
+%files daemon-driver-storage-zfs
+%{_libdir}/%{name}/storage-backend/libvirt_storage_backend_zfs.so
+%endif
+
%if %{with_qemu}
%files daemon-driver-qemu
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/
+150
View File
@@ -0,0 +1,150 @@
From: Juan Hernandez <jhernand@redhat.com>
Date: Thu, 6 Jul 2017 17:03:31 +0200
Subject: [PATCH] Avoid hidden cgroup mount points
Currently the scan of the /proc/mounts file used to find cgroup mount
points doesn't take into account that mount points may hidden by other
mount points. For, example in certain Kubernetes environments the
/proc/mounts contains the following lines:
cgroup /sys/fs/cgroup/net_prio,net_cls cgroup ...
tmpfs /sys/fs/cgroup tmpfs ...
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup ...
In this particular environment the first mount point is hidden by the
second one. The correct mount point is the third one, but libvirt will
never process it because it only checks the first mount point for each
controller (net_cls in this case). So libvirt will try to use the first
mount point, which doesn't actually exist, and the complete detection
process will fail.
To avoid that issue this patch changes the virCgroupDetectMountsFromFile
function so that when there are duplicates it takes the information from
the last line in /proc/mounts. This requires removing the previous
explicit condition to skip duplicates, and adding code to free the
memory used by the processing of duplicated lines.
Related-To: https://bugzilla.redhat.com/1468214
Related-To: https://github.com/kubevirt/libvirt/issues/4
Signed-off-by: Juan Hernandez <jhernand@redhat.com>
(cherry picked from commit dacd160d7479e0ec2d8a63f102145fd30636a1c8)
---
src/util/vircgroup.c | 23 ++++++++++++++---------
tests/vircgroupdata/kubevirt.mounts | 25 +++++++++++++++++++++++++
tests/vircgroupdata/kubevirt.parsed | 10 ++++++++++
tests/vircgrouptest.c | 1 +
4 files changed, 50 insertions(+), 9 deletions(-)
create mode 100644 tests/vircgroupdata/kubevirt.mounts
create mode 100644 tests/vircgroupdata/kubevirt.parsed
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5aa1db5b1..a53908fc9 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -397,6 +397,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr);
char *tmp = entry.mnt_opts;
+ struct virCgroupController *controller = &group->controllers[i];
while (tmp) {
char *next = strchr(tmp, ',');
int len;
@@ -406,18 +407,22 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
} else {
len = strlen(tmp);
}
- /* NB, the same controller can appear >1 time in mount list
- * due to bind mounts from one location to another. Pick the
- * first entry only
- */
- if (typelen == len && STREQLEN(typestr, tmp, len) &&
- !group->controllers[i].mountPoint) {
+
+ if (typelen == len && STREQLEN(typestr, tmp, len)) {
char *linksrc;
struct stat sb;
char *tmp2;
- if (VIR_STRDUP(group->controllers[i].mountPoint,
- entry.mnt_dir) < 0)
+ /* Note that the lines in /proc/mounts have the same
+ * order than the mount operations, and that there may
+ * be duplicates due to bind mounts. This means
+ * that the same mount point may be processed more than
+ * once. We need to save the results of the last one,
+ * and we need to be careful to release the memory used
+ * by previous processing. */
+ VIR_FREE(controller->mountPoint);
+ VIR_FREE(controller->linkPoint);
+ if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0)
goto error;
tmp2 = strrchr(entry.mnt_dir, '/');
@@ -453,7 +458,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
VIR_WARN("Expecting a symlink at %s for controller %s",
linksrc, typestr);
} else {
- group->controllers[i].linkPoint = linksrc;
+ controller->linkPoint = linksrc;
}
}
}
diff --git a/tests/vircgroupdata/kubevirt.mounts b/tests/vircgroupdata/kubevirt.mounts
new file mode 100644
index 000000000..ca036196b
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.mounts
@@ -0,0 +1,25 @@
+rootfs / rootfs rw 0 0
+proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
+udev /dev devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=1006404,mode=755 0 0
+devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
+sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
+/dev/sda1 / ext4 rw,noatime,data=ordered 0 0
+tmpfs /run tmpfs rw,nodev,relatime,size=812296k,mode=755 0 0
+mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0
+shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0
+debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0
+cgroup_root /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0
+openrc /sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc 0 0
+cpuset /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpuset /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
+cpu /sys/fs/cgroup/cpu cgroup rw,nosuid,nodev,noexec,relatime,cpu 0 0
+cpuacct /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+cpuacct /sys/fs/cgroup/cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
+memory /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
+devices /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
+freezer /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
+blkio /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
+perf_event /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
+hugetlb /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
+binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
+freezer /some/random/location/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
diff --git a/tests/vircgroupdata/kubevirt.parsed b/tests/vircgroupdata/kubevirt.parsed
new file mode 100644
index 000000000..694870723
--- /dev/null
+++ b/tests/vircgroupdata/kubevirt.parsed
@@ -0,0 +1,10 @@
+cpu /sys/fs/cgroup/cpu
+cpuacct /sys/fs/cgroup/cpuacct
+cpuset /sys/fs/cgroup/cpuset
+memory /sys/fs/cgroup/memory
+devices /sys/fs/cgroup/devices
+freezer /some/random/location/freezer
+blkio /sys/fs/cgroup/blkio
+net_cls <null>
+perf_event /sys/fs/cgroup/perf_event
+name=systemd <null>
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index f55ef74a1..cf0315f16 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -885,6 +885,7 @@ mymain(void)
DETECT_MOUNTS("cgroups3");
DETECT_MOUNTS("all-in-one");
DETECT_MOUNTS("no-cgroups");
+ DETECT_MOUNTS("kubevirt");
if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
ret = -1;
@@ -0,0 +1,53 @@
From: Jim Fehlig <jfehlig@suse.com>
Date: Tue, 18 Jul 2017 10:20:35 -0600
Subject: [PATCH] docs: schema: make disk driver name attribute optional
/domain/devices/disk/driver/@name is not a required or mandatory
attribute according to formatdomain, and indeed it was agreed on
IRC that the attribute is "optional for input, recommended (but
not required) for output". Currently the schema requires the
attribute, causing virt-xml-validate to fail on disk config where
the driver name is not explicitly specified. E.g.
# cat test.xml | grep -A 5 cdrom
<disk type='file' device='cdrom'>
<driver type='raw'/>
<target dev='hdb' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
# virt-xml-validate test.xml
Relax-NG validity error : Extra element devices in interleave
test.xml:21: element devices: Relax-NG validity error : Element domain failed to validate content
test.xml fails to validate
Relaxing the name attribute to be optional fixes the validation
# virt-xml-validate test.xml
test.xml validates
(cherry picked from commit b494e09d058f09b48d0fd8855edd557101294671)
---
docs/schemas/domaincommon.rng | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index edc225fe5..dfc7e2470 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1720,9 +1720,11 @@
</element>
</define>
<define name="driverFormat">
- <attribute name="name">
- <ref name="genericName"/>
- </attribute>
+ <optional>
+ <attribute name="name">
+ <ref name="genericName"/>
+ </attribute>
+ </optional>
<optional>
<attribute name='type'>
<choice>
@@ -0,0 +1,34 @@
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Thu, 29 Jun 2017 14:01:11 -0400
Subject: [PATCH] tpm: Use /dev/null for cancel path if none was found
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TPM 2 does not implement sysfs files for cancellation of commands.
We therefore use /dev/null for the cancel path passed to QEMU.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Tested-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit dfbb15b75433e520fb1b905c1c3e28753e53e4a5)
---
src/util/virtpm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/util/virtpm.c b/src/util/virtpm.c
index 6d9b0657a..d5c10da38 100644
--- a/src/util/virtpm.c
+++ b/src/util/virtpm.c
@@ -61,9 +61,7 @@ virTPMCreateCancelPath(const char *devpath)
VIR_FREE(path);
}
if (!path)
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("No usable sysfs TPM cancel file could be "
- "found"));
+ ignore_value(VIR_STRDUP(path, "/dev/null"));
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("TPM device path %s is invalid"), devpath);
@@ -0,0 +1,108 @@
From: Cole Robinson <crobinso@redhat.com>
Date: Sun, 27 Aug 2017 11:23:47 -0400
Subject: [PATCH] security: add MANAGER_MOUNT_NAMESPACE flag
The VIR_SECURITY_MANAGER_MOUNT_NAMESPACE flag informs the DAC driver
if mount namespaces are in use for the VM. Will be used for future
changes.
Wire it up in the qemu driver
(cherry picked from commit 321031e482425dfeae0f125cdac6df870f079efd)
---
src/qemu/qemu_driver.c | 2 ++
src/security/security_dac.c | 10 ++++++++++
src/security/security_dac.h | 3 +++
src/security/security_manager.c | 4 +++-
src/security/security_manager.h | 1 +
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ce844bb04..555a1009b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -417,6 +417,8 @@ qemuSecurityInit(virQEMUDriverPtr driver)
if (virQEMUDriverIsPrivileged(driver)) {
if (cfg->dynamicOwnership)
flags |= VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP;
+ if (virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT))
+ flags |= VIR_SECURITY_MANAGER_MOUNT_NAMESPACE;
if (!(mgr = qemuSecurityNewDAC(QEMU_DRIVER_NAME,
cfg->user,
cfg->group,
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 922e48494..1f8d279bf 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -57,6 +57,7 @@ struct _virSecurityDACData {
gid_t *groups;
int ngroups;
bool dynamicOwnership;
+ bool mountNamespace;
char *baselabel;
virSecurityManagerDACChownCallback chownCallback;
};
@@ -237,6 +238,15 @@ virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
priv->dynamicOwnership = dynamicOwnership;
}
+void
+virSecurityDACSetMountNamespace(virSecurityManagerPtr mgr,
+ bool mountNamespace)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->mountNamespace = mountNamespace;
+}
+
+
void
virSecurityDACSetChownCallback(virSecurityManagerPtr mgr,
virSecurityManagerDACChownCallback chownCallback)
diff --git a/src/security/security_dac.h b/src/security/security_dac.h
index 846cefbb5..97681c961 100644
--- a/src/security/security_dac.h
+++ b/src/security/security_dac.h
@@ -32,6 +32,9 @@ int virSecurityDACSetUserAndGroup(virSecurityManagerPtr mgr,
void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
bool dynamic);
+void virSecurityDACSetMountNamespace(virSecurityManagerPtr mgr,
+ bool mountNamespace);
+
void virSecurityDACSetChownCallback(virSecurityManagerPtr mgr,
virSecurityManagerDACChownCallback chownCallback);
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 6c777db1e..b2d04d4b9 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -146,7 +146,8 @@ virSecurityManagerNewDAC(const char *virtDriver,
virSecurityManagerPtr mgr;
virCheckFlags(VIR_SECURITY_MANAGER_NEW_MASK |
- VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP, NULL);
+ VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP |
+ VIR_SECURITY_MANAGER_MOUNT_NAMESPACE, NULL);
mgr = virSecurityManagerNewDriver(&virSecurityDriverDAC,
virtDriver,
@@ -161,6 +162,7 @@ virSecurityManagerNewDAC(const char *virtDriver,
}
virSecurityDACSetDynamicOwnership(mgr, flags & VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP);
+ virSecurityDACSetMountNamespace(mgr, flags & VIR_SECURITY_MANAGER_MOUNT_NAMESPACE);
virSecurityDACSetChownCallback(mgr, chownCallback);
return mgr;
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index 238e66cd0..96937a892 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -36,6 +36,7 @@ typedef enum {
VIR_SECURITY_MANAGER_REQUIRE_CONFINED = 1 << 2,
VIR_SECURITY_MANAGER_PRIVILEGED = 1 << 3,
VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP = 1 << 4,
+ VIR_SECURITY_MANAGER_MOUNT_NAMESPACE = 1 << 5,
} virSecurityManagerNewFlags;
# define VIR_SECURITY_MANAGER_NEW_MASK \
@@ -0,0 +1,101 @@
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 17 Jul 2017 08:57:57 -0400
Subject: [PATCH] security: dac: relabel spice rendernode
For a logged in user this a path like /dev/dri/renderD128 will have
default ownership root:video which won't work for the qemu:qemu user,
so we need to chown it.
We only do this when mount namespaces are enabled in the qemu driver,
so the chown'ing doesn't interfere with other users of the shared
render node path
https://bugzilla.redhat.com/show_bug.cgi?id=1460804
(cherry picked from commit 98931187eefdec6f2dea5cb82ab6d23a3ffa6634)
---
src/security/security_dac.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 1f8d279bf..5f13bcee8 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1379,6 +1379,54 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
}
+static int
+virSecurityDACSetGraphicsLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def,
+ virDomainGraphicsDefPtr gfx)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr seclabel;
+ uid_t user;
+ gid_t group;
+
+ /* Skip chowning the shared render file if namespaces are disabled */
+ if (!priv->mountNamespace)
+ return 0;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel && !seclabel->relabel)
+ return 0;
+
+ if (virSecurityDACGetIds(seclabel, priv, &user, &group, NULL, NULL) < 0)
+ return -1;
+
+ if (gfx->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
+ gfx->data.spice.gl == VIR_TRISTATE_BOOL_YES &&
+ gfx->data.spice.rendernode) {
+ if (virSecurityDACSetOwnership(priv, NULL,
+ gfx->data.spice.rendernode,
+ user, group) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+virSecurityDACRestoreGraphicsLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainGraphicsDefPtr gfx ATTRIBUTE_UNUSED)
+
+{
+ /* The only graphics labelling we do is dependent on mountNamespaces,
+ in which case 'restoring' the label doesn't actually accomplish
+ anything, so there's nothing to do here */
+ return 0;
+}
+
+
static int
virSecurityDACSetInputLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
@@ -1489,6 +1537,11 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
}
+ for (i = 0; i < def->ngraphics; i++) {
+ if (virSecurityDACRestoreGraphicsLabel(mgr, def, def->graphics[i]) < 0)
+ return -1;
+ }
+
for (i = 0; i < def->ninputs; i++) {
if (virSecurityDACRestoreInputLabel(mgr, def, def->inputs[i]) < 0)
rc = -1;
@@ -1602,6 +1655,11 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
return -1;
}
+ for (i = 0; i < def->ngraphics; i++) {
+ if (virSecurityDACSetGraphicsLabel(mgr, def, def->graphics[i]) < 0)
+ return -1;
+ }
+
for (i = 0; i < def->ninputs; i++) {
if (virSecurityDACSetInputLabel(mgr, def, def->inputs[i]) < 0)
return -1;
+63
View File
@@ -0,0 +1,63 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 31 Jul 2017 16:55:58 +0200
Subject: [PATCH] qemu: Honour <on_reboot/>
https://bugzilla.redhat.com/show_bug.cgi?id=1476866
For some reason, we completely ignore <on_reboot/> setting for
domains. The implementation is simply not there. It never was.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3ee9bdbe351c0b80d4c469571ef31df3f1b148ea)
---
src/qemu/qemu_process.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 992a7174b..7588212ba 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -487,6 +487,7 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virObjectEventPtr event;
qemuDomainObjPrivatePtr priv;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ int ret = -1;
virObjectLock(vm);
@@ -498,12 +499,32 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
VIR_WARN("Failed to save status on vm %s", vm->def->name);
- virObjectUnlock(vm);
+ if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_DESTROY ||
+ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_PRESERVE) {
- qemuDomainEventQueue(driver, event);
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Ignoring RESET event from inactive domain %s",
+ vm->def->name);
+ goto endjob;
+ }
+
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED,
+ QEMU_ASYNC_JOB_NONE, 0);
+ virDomainAuditStop(vm, "destroyed");
+ qemuDomainRemoveInactive(driver, vm);
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+ }
+ ret = 0;
+ cleanup:
+ virObjectUnlock(vm);
+ qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+ return ret;
}
@@ -0,0 +1,113 @@
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 27 Apr 2017 16:29:21 +0200
Subject: [PATCH] qemuDomainBuildNamespace: Move /dev/* mountpoints later
When setting up mount namespace for a qemu domain the following
steps are executed:
1) get list of mountpoints under /dev/
2) move them to /var/run/libvirt/qemu/$domName.ext
3) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 2)
Note the problem with this approach is that if some device in step
3) requires access to a mountpoint from step 2) it will fail as
the mountpoint is not there anymore. For instance consider the
following domain disk configuration:
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/dev/shm/vhostmd0'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</disk>
In this case operation fails as we are unable to create vhostmd0
in the new device tree because after step 2) there is no /dev/shm
anymore. Leave aside fact that we shouldn't try to create devices
living in other mountpoints. That's a separate bug that will be
addressed later.
Currently, the order described above is rearranged to:
1) get list of mountpoints under /dev/
2) start constructing new device tree under /var/run/libvirt/qemu/$domName.dev
3) move them to /var/run/libvirt/qemu/$domName.ext
4) move the mountpoint of the new device tree to /dev
5) restore original mountpoints from step 3)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cedric Bosdonnat <cbosdonnat@suse.com>
(cherry picked from commit a7cc039dc796f541793955598377807af48341fb)
(cherry picked from commit 469bf7cb7a44a0798c63e4b5e4682d8e38bce66e)
---
src/qemu/qemu_domain.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4a127cedf..64f18f493 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7854,6 +7854,30 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
if (qemuDomainSetupDev(cfg, mgr, vm, devPath) < 0)
goto cleanup;
+ if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
+ if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
+ goto cleanup;
+
/* Save some mount points because we want to share them with the host */
for (i = 0; i < ndevMountsPath; i++) {
struct stat sb;
@@ -7881,30 +7905,6 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
goto cleanup;
}
- if (qemuDomainSetupAllDisks(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllHostdevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllMemories(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllChardevs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupTPM(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllGraphics(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllInputs(cfg, vm, devPath) < 0)
- goto cleanup;
-
- if (qemuDomainSetupAllRNGs(cfg, vm, devPath) < 0)
- goto cleanup;
-
if (virFileMoveMount(devPath, "/dev") < 0)
goto cleanup;
@@ -0,0 +1,71 @@
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 5 Oct 2017 17:54:28 +0100
Subject: [PATCH] qemu: ensure TLS clients always verify the server certificate
The default_tls_x509_verify (and related) parameters in qemu.conf
control whether the QEMU TLS servers request & verify certificates
from clients. This works as a simple access control system for
servers by requiring the CA to issue certs to permitted clients.
This use of client certificates is disabled by default, since it
requires extra work to issue client certificates.
Unfortunately the code was using this configuration parameter when
setting up both TLS clients and servers in QEMU. The result was that
TLS clients for character devices and disk devices had verification
turned off, meaning they would ignore errors while validating the
server certificate.
This allows for trivial MITM attacks between client and server,
as any certificate returned by the attacker will be accepted by
the client.
This is assigned CVE-2017-1000256 / LSN-2017-0002
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 441d3eb6d1be940a67ce45a286602a967601b157)
---
src/qemu/qemu_command.c | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args | 2 +-
.../qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 311edd13e..141831635 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -727,7 +727,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
if (virJSONValueObjectCreate(propsret,
"s:dir", path,
"s:endpoint", (isListen ? "server": "client"),
- "b:verify-peer", verifypeer,
+ "b:verify-peer", (isListen ? verifypeer : true),
NULL) < 0)
goto cleanup;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
index b456cce30..003d11de7 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-chardev.args
@@ -26,7 +26,7 @@ server,nowait \
localport=1111 \
-device isa-serial,chardev=charserial0,id=serial0 \
-object tls-creds-x509,id=objcharserial1_tls0,dir=/etc/pki/libvirt-chardev,\
-endpoint=client,verify-peer=no \
+endpoint=client,verify-peer=yes \
-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
tls-creds=objcharserial1_tls0 \
-device isa-serial,chardev=charserial1,id=serial1 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
index 7f9fedb6c..a020ff006 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-tlsx509-secret-chardev.args
@@ -31,7 +31,7 @@ localport=1111 \
data=9eao5F8qtkGt+seB1HYivWIxbtwUu6MQtg1zpj/oDtUsPr1q8wBYM91uEHCn6j/1,\
keyid=masterKey0,iv=AAECAwQFBgcICQoLDA0ODw==,format=base64 \
-object tls-creds-x509,id=objcharserial1_tls0,dir=/etc/pki/libvirt-chardev,\
-endpoint=client,verify-peer=no,passwordid=charserial1-secret0 \
+endpoint=client,verify-peer=yes,passwordid=charserial1-secret0 \
-chardev socket,id=charserial1,host=127.0.0.1,port=5555,\
tls-creds=objcharserial1_tls0 \
-device isa-serial,chardev=charserial1,id=serial1 \
@@ -1,356 +0,0 @@
From 953440bd12608a20007ee5da5ab69fbbe910bd28 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 15:53:59 +0100
Subject: [PATCH 01/11] Extract the backing store format as well as name, if available
When QEMU opens a backing store for a QCow2 file, it will
normally auto-probe for the format of the backing store,
rather than assuming it has the same format as the referencing
file. There is a QCow2 extension that allows an explicit format
for the backing store to be embedded in the referencing file.
This closes the auto-probing security hole in QEMU.
This backing store format can be useful for libvirt users
of virStorageFileGetMetadata, so extract this data and report
it.
QEMU does not require disk image backing store files to be in
the same format the file linkee. It will auto-probe the disk
format for the backing store when opening it. If the backing
store was intended to be a raw file this could be a security
hole, because a guest may have written data into its disk that
then makes the backing store look like a qcow2 file. If it can
trick QEMU into thinking the raw file is a qcow2 file, it can
access arbitrary files on the host by adding further backing
store links.
To address this, callers of virStorageFileGetMeta need to be
told of the backing store format. If no format is declared,
they can make a decision whether to allow format probing or
not.
---
src/util/storage_file.c | 206 +++++++++++++++++++++++++++++++++++++++++------
src/util/storage_file.h | 2 +
2 files changed, 183 insertions(+), 25 deletions(-)
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 0adea40..80f743e 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -78,12 +78,33 @@ struct FileTypeInfo {
int qcowCryptOffset; /* Byte offset from start of file
* where to find encryption mode,
* -1 if encryption is not used */
- int (*getBackingStore)(char **res, const unsigned char *buf, size_t buf_size);
+ int (*getBackingStore)(char **res, int *format,
+ const unsigned char *buf, size_t buf_size);
};
-static int cowGetBackingStore(char **, const unsigned char *, size_t);
-static int qcowXGetBackingStore(char **, const unsigned char *, size_t);
-static int vmdk4GetBackingStore(char **, const unsigned char *, size_t);
+static int cowGetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int qcow1GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int qcow2GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int vmdk4GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+
+#define QCOWX_HDR_VERSION (4)
+#define QCOWX_HDR_BACKING_FILE_OFFSET (QCOWX_HDR_VERSION+4)
+#define QCOWX_HDR_BACKING_FILE_SIZE (QCOWX_HDR_BACKING_FILE_OFFSET+8)
+#define QCOWX_HDR_IMAGE_SIZE (QCOWX_HDR_BACKING_FILE_SIZE+4+4)
+
+#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1)
+#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8)
+
+#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8)
+#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8)
+
+#define QCOW2_HDR_EXTENSION_END 0
+#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
+
static struct FileTypeInfo const fileTypeInfo[] = {
@@ -119,11 +140,11 @@ static struct FileTypeInfo const fileTypeInfo[] = {
/* QCow */
{ VIR_STORAGE_FILE_QCOW, "QFI", NULL,
LV_BIG_ENDIAN, 4, 1,
- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore },
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
/* QCow 2 */
{ VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
LV_BIG_ENDIAN, 4, 2,
- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore },
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
/* VMDK 3 */
/* XXX Untested
{ VIR_STORAGE_FILE_VMDK, "COWD", NULL,
@@ -142,11 +163,14 @@ static struct FileTypeInfo const fileTypeInfo[] = {
static int
cowGetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
size_t buf_size)
{
#define COW_FILENAME_MAXLEN 1024
*res = NULL;
+ *format = VIR_STORAGE_FILE_AUTO;
+
if (buf_size < 4+4+ COW_FILENAME_MAXLEN)
return BACKING_STORE_INVALID;
if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */
@@ -160,31 +184,98 @@ cowGetBackingStore(char **res,
return BACKING_STORE_OK;
}
+
+static int
+qcow2GetBackingStoreFormat(int *format,
+ const unsigned char *buf,
+ size_t buf_size,
+ size_t extension_start,
+ size_t extension_end)
+{
+ size_t offset = extension_start;
+
+ /*
+ * The extensions take format of
+ *
+ * int32: magic
+ * int32: length
+ * byte[length]: payload
+ *
+ * Unknown extensions can be ignored by skipping
+ * over "length" bytes in the data stream.
+ */
+ while (offset < (buf_size-8) &&
+ offset < (extension_end-8)) {
+ unsigned int magic =
+ (buf[offset] << 24) +
+ (buf[offset+1] << 16) +
+ (buf[offset+2] << 8) +
+ (buf[offset+3]);
+ unsigned int len =
+ (buf[offset+4] << 24) +
+ (buf[offset+5] << 16) +
+ (buf[offset+6] << 8) +
+ (buf[offset+7]);
+
+ offset += 8;
+
+ if ((offset + len) < offset)
+ break;
+
+ if ((offset + len) > buf_size)
+ break;
+
+ switch (magic) {
+ case QCOW2_HDR_EXTENSION_END:
+ goto done;
+
+ case QCOW2_HDR_EXTENSION_BACKING_FORMAT:
+ if (buf[offset+len] != '\0')
+ break;
+ *format = virStorageFileFormatTypeFromString(
+ ((const char *)buf)+offset);
+ break;
+ }
+
+ offset += len;
+ }
+
+done:
+
+ return 0;
+}
+
+
static int
qcowXGetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
- size_t buf_size)
+ size_t buf_size,
+ bool isQCow2)
{
unsigned long long offset;
unsigned long size;
*res = NULL;
- if (buf_size < 4+4+8+4)
+ if (format)
+ *format = VIR_STORAGE_FILE_AUTO;
+
+ if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4)
return BACKING_STORE_INVALID;
- offset = (((unsigned long long)buf[4+4] << 56)
- | ((unsigned long long)buf[4+4+1] << 48)
- | ((unsigned long long)buf[4+4+2] << 40)
- | ((unsigned long long)buf[4+4+3] << 32)
- | ((unsigned long long)buf[4+4+4] << 24)
- | ((unsigned long long)buf[4+4+5] << 16)
- | ((unsigned long long)buf[4+4+6] << 8)
- | buf[4+4+7]); /* QCowHeader.backing_file_offset */
+ offset = (((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET] << 56)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+1] << 48)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+2] << 40)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+3] << 32)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+4] << 24)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+5] << 16)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+6] << 8)
+ | buf[QCOWX_HDR_BACKING_FILE_OFFSET+7]); /* QCowHeader.backing_file_offset */
if (offset > buf_size)
return BACKING_STORE_INVALID;
- size = ((buf[4+4+8] << 24)
- | (buf[4+4+8+1] << 16)
- | (buf[4+4+8+2] << 8)
- | buf[4+4+8+3]); /* QCowHeader.backing_file_size */
+ size = ((buf[QCOWX_HDR_BACKING_FILE_SIZE] << 24)
+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16)
+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8)
+ | buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */
if (size == 0)
return BACKING_STORE_OK;
if (offset + size > buf_size || offset + size < offset)
@@ -197,12 +288,63 @@ qcowXGetBackingStore(char **res,
}
memcpy(*res, buf + offset, size);
(*res)[size] = '\0';
+
+ /*
+ * Traditionally QCow2 files had a layout of
+ *
+ * [header]
+ * [backingStoreName]
+ *
+ * Although the backingStoreName typically followed
+ * the header immediately, this was not required by
+ * the format. By specifying a higher byte offset for
+ * the backing file offset in the header, it was
+ * possible to leave space between the header and
+ * start of backingStore.
+ *
+ * This hack is now used to store extensions to the
+ * qcow2 format:
+ *
+ * [header]
+ * [extensions]
+ * [backingStoreName]
+ *
+ * Thus the file region to search for extensions is
+ * between the end of the header (QCOW2_HDR_TOTAL_SIZE)
+ * and the start of the backingStoreName (offset)
+ */
+ if (isQCow2)
+ qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset);
+
return BACKING_STORE_OK;
}
static int
+qcow1GetBackingStore(char **res,
+ int *format,
+ const unsigned char *buf,
+ size_t buf_size)
+{
+ /* QCow1 doesn't have the extensions capability
+ * used to store backing format */
+ *format = VIR_STORAGE_FILE_AUTO;
+ return qcowXGetBackingStore(res, NULL, buf, buf_size, false);
+}
+
+static int
+qcow2GetBackingStore(char **res,
+ int *format,
+ const unsigned char *buf,
+ size_t buf_size)
+{
+ return qcowXGetBackingStore(res, format, buf, buf_size, true);
+}
+
+
+static int
vmdk4GetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
size_t buf_size)
{
@@ -212,6 +354,14 @@ vmdk4GetBackingStore(char **res,
size_t len;
*res = NULL;
+ /*
+ * Technically this should have been VMDK, since
+ * VMDK spec / VMWare impl only support VMDK backed
+ * by VMDK. QEMU isn't following this though and
+ * does probing on VMDK backing files, hence we set
+ * AUTO
+ */
+ *format = VIR_STORAGE_FILE_AUTO;
if (buf_size <= 0x200)
return BACKING_STORE_INVALID;
@@ -358,9 +508,12 @@ virStorageFileGetMetadataFromFD(const char *path,
/* Validation passed, we know the file format now */
meta->format = fileTypeInfo[i].type;
if (fileTypeInfo[i].getBackingStore != NULL) {
- char *base;
+ char *backing;
+ int backingFormat;
- switch (fileTypeInfo[i].getBackingStore(&base, head, len)) {
+ switch (fileTypeInfo[i].getBackingStore(&backing,
+ &backingFormat,
+ head, len)) {
case BACKING_STORE_OK:
break;
@@ -370,13 +523,16 @@ virStorageFileGetMetadataFromFD(const char *path,
case BACKING_STORE_ERROR:
return -1;
}
- if (base != NULL) {
- meta->backingStore = absolutePathFromBaseFile(path, base);
- VIR_FREE(base);
+ if (backing != NULL) {
+ meta->backingStore = absolutePathFromBaseFile(path, backing);
+ VIR_FREE(backing);
if (meta->backingStore == NULL) {
virReportOOMError();
return -1;
}
+ meta->backingStoreFormat = backingFormat;
+ } else {
+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
}
}
return 0;
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 58533ee..6328ba7 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -28,6 +28,7 @@
# include <stdbool.h>
enum virStorageFileFormat {
+ VIR_STORAGE_FILE_AUTO = -1,
VIR_STORAGE_FILE_RAW = 0,
VIR_STORAGE_FILE_DIR,
VIR_STORAGE_FILE_BOCHS,
@@ -47,6 +48,7 @@ VIR_ENUM_DECL(virStorageFileFormat);
typedef struct _virStorageFileMetadata {
int format;
char *backingStore;
+ int backingStoreFormat;
unsigned long long capacity;
bool encrypted;
} virStorageFileMetadata;
--
1.7.1.1
-159
View File
@@ -1,159 +0,0 @@
From cab428b1d4d432965cee6f5afb67265557706715 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 16:39:32 +0100
Subject: [PATCH 02/11] Remove 'type' field from FileTypeInfo struct
Instead of including a field in FileTypeInfo struct for the
disk format, rely on the array index matching the format.
Use verify() to assert the correct number of elements in the
array.
* src/util/storage_file.c: remove type field from FileTypeInfo
---
src/util/storage_file.c | 108 +++++++++++++++++++++++-----------------------
1 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 80f743e..df0e3a1 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -58,7 +58,6 @@ enum {
/* Either 'magic' or 'extension' *must* be provided */
struct FileTypeInfo {
- int type; /* One of the constants above */
const char *magic; /* Optional string of file magic
* to check at head of file */
const char *extension; /* Optional file extension to check */
@@ -108,58 +107,59 @@ static int vmdk4GetBackingStore(char **, int *,
static struct FileTypeInfo const fileTypeInfo[] = {
- /* Bochs */
- /* XXX Untested
- { VIR_STORAGE_FILE_BOCHS, "Bochs Virtual HD Image", NULL,
- LV_LITTLE_ENDIAN, 64, 0x20000,
- 32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/
- /* CLoop */
- /* XXX Untested
- { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL,
- LV_LITTLE_ENDIAN, -1, 0,
- -1, 0, 0, -1, NULL }, */
- /* Cow */
- { VIR_STORAGE_FILE_COW, "OOOM", NULL,
- LV_BIG_ENDIAN, 4, 2,
- 4+4+1024+4, 8, 1, -1, cowGetBackingStore },
- /* DMG */
- /* XXX QEMU says there's no magic for dmg, but we should check... */
- { VIR_STORAGE_FILE_DMG, NULL, ".dmg",
- 0, -1, 0,
- -1, 0, 0, -1, NULL },
- /* XXX there's probably some magic for iso we can validate too... */
- { VIR_STORAGE_FILE_ISO, NULL, ".iso",
- 0, -1, 0,
- -1, 0, 0, -1, NULL },
- /* Parallels */
- /* XXX Untested
- { VIR_STORAGE_FILE_PARALLELS, "WithoutFreeSpace", NULL,
- LV_LITTLE_ENDIAN, 16, 2,
- 16+4+4+4+4, 4, 512, -1, NULL },
- */
- /* QCow */
- { VIR_STORAGE_FILE_QCOW, "QFI", NULL,
- LV_BIG_ENDIAN, 4, 1,
- QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
- /* QCow 2 */
- { VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
- LV_BIG_ENDIAN, 4, 2,
- QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
- /* VMDK 3 */
- /* XXX Untested
- { VIR_STORAGE_FILE_VMDK, "COWD", NULL,
- LV_LITTLE_ENDIAN, 4, 1,
- 4+4+4, 4, 512, -1, NULL },
- */
- /* VMDK 4 */
- { VIR_STORAGE_FILE_VMDK, "KDMV", NULL,
- LV_LITTLE_ENDIAN, 4, 1,
- 4+4+4, 8, 512, -1, vmdk4GetBackingStore },
- /* Connectix / VirtualPC */
- { VIR_STORAGE_FILE_VPC, "conectix", NULL,
- LV_BIG_ENDIAN, 12, 0x10000,
- 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL},
+ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
+ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
+ [VIR_STORAGE_FILE_BOCHS] = {
+ /*"Bochs Virtual HD Image", */ /* Untested */ NULL,
+ NULL,
+ LV_LITTLE_ENDIAN, 64, 0x20000,
+ 32+16+16+4+4+4+4+4, 8, 1, -1, NULL
+ },
+ [VIR_STORAGE_FILE_CLOOP] = {
+ /*"#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", */ /* Untested */ NULL,
+ NULL,
+ LV_LITTLE_ENDIAN, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_COW] = {
+ "OOOM", NULL,
+ LV_BIG_ENDIAN, 4, 2,
+ 4+4+1024+4, 8, 1, -1, cowGetBackingStore
+ },
+ [VIR_STORAGE_FILE_DMG] = {
+ NULL, /* XXX QEMU says there's no magic for dmg, but we should check... */
+ ".dmg",
+ 0, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_ISO] = {
+ NULL, /* XXX there's probably some magic for iso we can validate too... */
+ ".iso",
+ 0, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_QCOW] = {
+ "QFI", NULL,
+ LV_BIG_ENDIAN, 4, 1,
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore,
+ },
+ [VIR_STORAGE_FILE_QCOW2] = {
+ "QFI", NULL,
+ LV_BIG_ENDIAN, 4, 2,
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore,
+ },
+ [VIR_STORAGE_FILE_VMDK] = {
+ "KDMV", NULL,
+ LV_LITTLE_ENDIAN, 4, 1,
+ 4+4+4, 8, 512, -1, vmdk4GetBackingStore
+ },
+ [VIR_STORAGE_FILE_VPC] = {
+ "conectix", NULL,
+ LV_BIG_ENDIAN, 12, 0x10000,
+ 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL
+ },
};
+verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
static int
cowGetBackingStore(char **res,
@@ -506,7 +506,7 @@ virStorageFileGetMetadataFromFD(const char *path,
}
/* Validation passed, we know the file format now */
- meta->format = fileTypeInfo[i].type;
+ meta->format = i;
if (fileTypeInfo[i].getBackingStore != NULL) {
char *backing;
int backingFormat;
@@ -546,7 +546,7 @@ virStorageFileGetMetadataFromFD(const char *path,
if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
continue;
- meta->format = fileTypeInfo[i].type;
+ meta->format = i;
return 0;
}
--
1.7.1.1
@@ -1,585 +0,0 @@
From 57482ca0be29e9e92e242c9acb577e0b770c01d1 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 14:58:10 +0100
Subject: [PATCH 03/11] Refactor virStorageFileGetMetadataFromFD to separate functionality
The virStorageFileGetMetadataFromFD did two jobs in one. First
it probed for storage type, then it extracted metadata for the
type. It is desirable to be able to separate these jobs, allowing
probing without querying metadata, and querying metadata without
probing.
To prepare for this, split out probing code into a new pair of
methods
virStorageFileProbeFormatFromFD
virStorageFileProbeFormat
* src/util/storage_file.c, src/util/storage_file.h,
src/libvirt_private.syms: Introduce virStorageFileProbeFormat
and virStorageFileProbeFormatFromFD
---
src/libvirt_private.syms | 2 +
src/util/storage_file.c | 460 +++++++++++++++++++++++++++++++++-------------
src/util/storage_file.h | 4 +
3 files changed, 335 insertions(+), 131 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 778ceb1..4607f49 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -628,6 +628,8 @@ virStorageGenerateQcowPassphrase;
# storage_file.h
virStorageFileFormatTypeToString;
virStorageFileFormatTypeFromString;
+virStorageFileProbeFormat;
+virStorageFileProbeFormatFromFD;
virStorageFileGetMetadata;
virStorageFileGetMetadataFromFD;
virStorageFileIsSharedFS;
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index df0e3a1..221268b 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -104,6 +104,9 @@ static int vmdk4GetBackingStore(char **, int *,
#define QCOW2_HDR_EXTENSION_END 0
#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
+/* VMDK needs at least this to find backing store,
+ * other formats are less */
+#define STORAGE_MAX_HEAD (20*512)
static struct FileTypeInfo const fileTypeInfo[] = {
@@ -349,9 +352,14 @@ vmdk4GetBackingStore(char **res,
size_t buf_size)
{
static const char prefix[] = "parentFileNameHint=\"";
-
- char desc[20*512 + 1], *start, *end;
+ char *desc, *start, *end;
size_t len;
+ int ret = BACKING_STORE_ERROR;
+
+ if (VIR_ALLOC_N(desc, STORAGE_MAX_HEAD + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
*res = NULL;
/*
@@ -363,29 +371,42 @@ vmdk4GetBackingStore(char **res,
*/
*format = VIR_STORAGE_FILE_AUTO;
- if (buf_size <= 0x200)
- return BACKING_STORE_INVALID;
+ if (buf_size <= 0x200) {
+ ret = BACKING_STORE_INVALID;
+ goto cleanup;
+ }
len = buf_size - 0x200;
- if (len > sizeof(desc) - 1)
- len = sizeof(desc) - 1;
+ if (len > STORAGE_MAX_HEAD)
+ len = STORAGE_MAX_HEAD;
memcpy(desc, buf + 0x200, len);
desc[len] = '\0';
start = strstr(desc, prefix);
- if (start == NULL)
- return BACKING_STORE_OK;
+ if (start == NULL) {
+ ret = BACKING_STORE_OK;
+ goto cleanup;
+ }
start += strlen(prefix);
end = strchr(start, '"');
- if (end == NULL)
- return BACKING_STORE_INVALID;
- if (end == start)
- return BACKING_STORE_OK;
+ if (end == NULL) {
+ ret = BACKING_STORE_INVALID;
+ goto cleanup;
+ }
+ if (end == start) {
+ ret = BACKING_STORE_OK;
+ goto cleanup;
+ }
*end = '\0';
*res = strdup(start);
if (*res == NULL) {
virReportOOMError();
- return BACKING_STORE_ERROR;
+ goto cleanup;
}
- return BACKING_STORE_OK;
+
+ ret = BACKING_STORE_OK;
+
+cleanup:
+ VIR_FREE(desc);
+ return ret;
}
/**
@@ -411,148 +432,325 @@ absolutePathFromBaseFile(const char *base_file, const char *path)
return res;
}
-/**
- * Probe the header of a file to determine what type of disk image
- * it is, and info about its capacity if available.
- */
-int
-virStorageFileGetMetadataFromFD(const char *path,
- int fd,
- virStorageFileMetadata *meta)
+
+static bool
+virStorageFileMatchesMagic(int format,
+ unsigned char *buf,
+ size_t buflen)
{
- unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */
- int len, i;
+ int mlen;
- memset(meta, 0, sizeof (*meta));
+ if (fileTypeInfo[format].magic == NULL)
+ return false;
- /* If all else fails, call it a raw file */
- meta->format = VIR_STORAGE_FILE_RAW;
+ /* Validate magic data */
+ mlen = strlen(fileTypeInfo[format].magic);
+ if (mlen > buflen)
+ return false;
- if ((len = read(fd, head, sizeof(head))) < 0) {
- virReportSystemError(errno, _("cannot read header '%s'"), path);
- return -1;
+ if (memcmp(buf, fileTypeInfo[format].magic, mlen) != 0)
+ return false;
+
+ return true;
+}
+
+
+static bool
+virStorageFileMatchesExtension(int format,
+ const char *path)
+{
+ if (fileTypeInfo[format].extension == NULL)
+ return false;
+
+ if (virFileHasSuffix(path, fileTypeInfo[format].extension))
+ return true;
+
+ return false;
+}
+
+
+static bool
+virStorageFileMatchesVersion(int format,
+ unsigned char *buf,
+ size_t buflen)
+{
+ int version;
+
+ /* Validate version number info */
+ if (fileTypeInfo[format].versionOffset == -1)
+ return false;
+
+ if ((fileTypeInfo[format].versionOffset + 4) > buflen)
+ return false;
+
+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
+ version =
+ (buf[fileTypeInfo[format].versionOffset+3] << 24) |
+ (buf[fileTypeInfo[format].versionOffset+2] << 16) |
+ (buf[fileTypeInfo[format].versionOffset+1] << 8) |
+ (buf[fileTypeInfo[format].versionOffset]);
+ } else {
+ version =
+ (buf[fileTypeInfo[format].versionOffset] << 24) |
+ (buf[fileTypeInfo[format].versionOffset+1] << 16) |
+ (buf[fileTypeInfo[format].versionOffset+2] << 8) |
+ (buf[fileTypeInfo[format].versionOffset+3]);
}
+ if (version != fileTypeInfo[format].versionNumber)
+ return false;
- /* First check file magic */
- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
- int mlen;
-
- if (fileTypeInfo[i].magic == NULL)
- continue;
-
- /* Validate magic data */
- mlen = strlen(fileTypeInfo[i].magic);
- if (mlen > len)
- continue;
- if (memcmp(head, fileTypeInfo[i].magic, mlen) != 0)
- continue;
-
- /* Validate version number info */
- if (fileTypeInfo[i].versionNumber != -1) {
- int version;
-
- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
- version = (head[fileTypeInfo[i].versionOffset+3] << 24) |
- (head[fileTypeInfo[i].versionOffset+2] << 16) |
- (head[fileTypeInfo[i].versionOffset+1] << 8) |
- head[fileTypeInfo[i].versionOffset];
- } else {
- version = (head[fileTypeInfo[i].versionOffset] << 24) |
- (head[fileTypeInfo[i].versionOffset+1] << 16) |
- (head[fileTypeInfo[i].versionOffset+2] << 8) |
- head[fileTypeInfo[i].versionOffset+3];
- }
- if (version != fileTypeInfo[i].versionNumber)
- continue;
- }
+ return true;
+}
- /* Optionally extract capacity from file */
- if (fileTypeInfo[i].sizeOffset != -1) {
- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
- meta->capacity =
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7] << 56) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 48) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 40) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 32) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 24) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 16) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 8) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset]);
- } else {
- meta->capacity =
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset] << 56) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 48) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 40) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 32) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 24) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 16) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 8) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7]);
- }
- /* Avoid unlikely, but theoretically possible overflow */
- if (meta->capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier))
- continue;
- meta->capacity *= fileTypeInfo[i].sizeMultiplier;
- }
- if (fileTypeInfo[i].qcowCryptOffset != -1) {
- int crypt_format;
+static int
+virStorageFileGetMetadataFromBuf(int format,
+ const char *path,
+ unsigned char *buf,
+ size_t buflen,
+ virStorageFileMetadata *meta)
+{
+ /* XXX we should consider moving virStorageBackendUpdateVolInfo
+ * code into this method, for non-magic files
+ */
+ if (!fileTypeInfo[format].magic) {
+ return 0;
+ }
- crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) |
- (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) |
- (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) |
- head[fileTypeInfo[i].qcowCryptOffset+3];
- meta->encrypted = crypt_format != 0;
+ /* Optionally extract capacity from file */
+ if (fileTypeInfo[format].sizeOffset != -1) {
+ if ((fileTypeInfo[format].sizeOffset + 8) > buflen)
+ return 1;
+
+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
+ meta->capacity =
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7] << 56) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 48) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 40) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 32) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 24) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 16) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 8) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset]);
+ } else {
+ meta->capacity =
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset] << 56) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 48) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 40) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 32) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 24) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 16) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 8) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7]);
}
+ /* Avoid unlikely, but theoretically possible overflow */
+ if (meta->capacity > (ULLONG_MAX / fileTypeInfo[format].sizeMultiplier))
+ return 1;
+ meta->capacity *= fileTypeInfo[format].sizeMultiplier;
+ }
- /* Validation passed, we know the file format now */
- meta->format = i;
- if (fileTypeInfo[i].getBackingStore != NULL) {
- char *backing;
- int backingFormat;
+ if (fileTypeInfo[format].qcowCryptOffset != -1) {
+ int crypt_format;
- switch (fileTypeInfo[i].getBackingStore(&backing,
- &backingFormat,
- head, len)) {
- case BACKING_STORE_OK:
- break;
+ crypt_format =
+ (buf[fileTypeInfo[format].qcowCryptOffset] << 24) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+1] << 16) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+2] << 8) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+3]);
+ meta->encrypted = crypt_format != 0;
+ }
- case BACKING_STORE_INVALID:
- continue;
+ if (fileTypeInfo[format].getBackingStore != NULL) {
+ char *backing;
+ int backingFormat;
+ int ret = fileTypeInfo[format].getBackingStore(&backing,
+ &backingFormat,
+ buf, buflen);
+ if (ret == BACKING_STORE_INVALID)
+ return 1;
+
+ if (ret == BACKING_STORE_ERROR)
+ return -1;
- case BACKING_STORE_ERROR:
+ if (backing != NULL) {
+ meta->backingStore = absolutePathFromBaseFile(path, backing);
+ VIR_FREE(backing);
+ if (meta->backingStore == NULL) {
+ virReportOOMError();
return -1;
}
- if (backing != NULL) {
- meta->backingStore = absolutePathFromBaseFile(path, backing);
- VIR_FREE(backing);
- if (meta->backingStore == NULL) {
- virReportOOMError();
- return -1;
- }
- meta->backingStoreFormat = backingFormat;
- } else {
- meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
- }
+ meta->backingStoreFormat = backingFormat;
+ } else {
+ meta->backingStore = NULL;
+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+virStorageFileProbeFormatFromBuf(const char *path,
+ unsigned char *buf,
+ size_t buflen)
+{
+ int format = VIR_STORAGE_FILE_RAW;
+ int i;
+
+ /* First check file magic */
+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
+ if (virStorageFileMatchesMagic(i, buf, buflen) &&
+ virStorageFileMatchesVersion(i, buf, buflen)) {
+ format = i;
+ goto cleanup;
}
- return 0;
}
/* No magic, so check file extension */
- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
- if (fileTypeInfo[i].extension == NULL)
- continue;
+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
+ if (virStorageFileMatchesExtension(i, path)) {
+ format = i;
+ goto cleanup;
+ }
+ }
- if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
- continue;
+cleanup:
+ return format;
+}
- meta->format = i;
- return 0;
+
+/**
+ * virStorageFileProbeFormatFromFD:
+ *
+ * Probe for the format of 'fd' (which is an open file descriptor
+ * pointing to 'path'), returning the detected disk format.
+ *
+ * Callers are advised never to trust the returned 'format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a file into any other non-raw
+ * format at will.
+ *
+ * Best option: Don't use this function
+ */
+int
+virStorageFileProbeFormatFromFD(const char *path, int fd)
+{
+ unsigned char *head;
+ ssize_t len = STORAGE_MAX_HEAD;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(head, len) < 0) {
+ virReportOOMError();
+ return -1;
}
- return 0;
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot set to start of '%s'"), path);
+ goto cleanup;
+ }
+
+ if ((len = read(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot read header '%s'"), path);
+ goto cleanup;
+ }
+
+ ret = virStorageFileProbeFormatFromBuf(path, head, len);
+
+cleanup:
+ VIR_FREE(head);
+ return ret;
+}
+
+
+/**
+ * virStorageFileProbeFormat:
+ *
+ * Probe for the format of 'path', returning the detected
+ * disk format.
+ *
+ * Callers are advised never to trust the returned 'format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ *
+ * Best option: Don't use this function
+ */
+int
+virStorageFileProbeFormat(const char *path)
+{
+ int fd, ret;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ virReportSystemError(errno, _("cannot open file '%s'"), path);
+ return -1;
+ }
+
+ ret = virStorageFileProbeFormatFromFD(path, fd);
+
+ close(fd);
+
+ return ret;
}
+/**
+ * virStorageFileGetMetadataFromFD:
+ *
+ * Probe for the format of 'fd' (which is an open file descriptor
+ * for the file 'path'), filling 'meta' with the detected
+ * format and other associated metadata.
+ *
+ * Callers are advised never to trust the returned 'meta->format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ */
+int
+virStorageFileGetMetadataFromFD(const char *path,
+ int fd,
+ virStorageFileMetadata *meta)
+{
+ unsigned char *head;
+ ssize_t len = STORAGE_MAX_HEAD;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(head, len) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ memset(meta, 0, sizeof (*meta));
+
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot set to start of '%s'"), path);
+ goto cleanup;
+ }
+
+ if ((len = read(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot read header '%s'"), path);
+ goto cleanup;
+ }
+
+ meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
+
+ ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
+
+cleanup:
+ VIR_FREE(head);
+ return ret;
+}
+
+/**
+ * virStorageFileGetMetadata:
+ *
+ * Probe for the format of 'path', filling 'meta' with the detected
+ * format and other associated metadata.
+ *
+ * Callers are advised never to trust the returned 'meta->format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ */
int
virStorageFileGetMetadata(const char *path,
virStorageFileMetadata *meta)
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 6328ba7..3420d44 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -57,6 +57,10 @@ typedef struct _virStorageFileMetadata {
# define DEV_BSIZE 512
# endif
+int virStorageFileProbeFormat(const char *path);
+int virStorageFileProbeFormatFromFD(const char *path,
+ int fd);
+
int virStorageFileGetMetadata(const char *path,
virStorageFileMetadata *meta);
int virStorageFileGetMetadataFromFD(const char *path,
--
1.7.1.1
@@ -1,285 +0,0 @@
From 726a63a437efd96510ce316bf30d16f213d4db27 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 16:15:51 +0100
Subject: [PATCH 04/11] Require format to be passed into virStorageFileGetMetadata
Require the disk image to be passed into virStorageFileGetMetadata.
If this is set to VIR_STORAGE_FILE_AUTO, then the format will be
resolved using probing. This makes it easier to control when
probing will be used
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata.
* src/storage/storage_backend_fs.c: Probe for disk format before
calling virStorageFileGetMetadata.
* src/util/storage_file.h, src/util/storage_file.c: Remove format
from virStorageFileMeta struct & require it to be passed into
method.
---
src/qemu/qemu_driver.c | 27 +++++++++++++++++---
src/qemu/qemu_security_dac.c | 4 ++-
src/security/security_selinux.c | 4 ++-
src/security/virt-aa-helper.c | 4 ++-
src/storage/storage_backend_fs.c | 11 ++++++--
src/util/storage_file.c | 50 +++++++++++++++++++++++++------------
src/util/storage_file.h | 3 +-
7 files changed, 76 insertions(+), 27 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 487bfa3..97f2990 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3069,7 +3069,9 @@ static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
}
}
- rc = virStorageFileGetMetadata(path, &meta);
+ rc = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (rc < 0)
VIR_WARN("Unable to lookup parent image for %s", path);
@@ -3119,7 +3121,9 @@ static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
}
}
- rc = virStorageFileGetMetadata(path, &meta);
+ rc = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (rc < 0)
VIR_WARN("Unable to lookup parent image for %s", path);
@@ -9614,6 +9618,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
virDomainDiskDefPtr disk = NULL;
struct stat sb;
int i;
+ int format;
virCheckFlags(0, -1);
@@ -9658,7 +9663,21 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
}
/* Probe for magic formats */
- if (virStorageFileGetMetadataFromFD(path, fd, &meta) < 0)
+ if (disk->driverType) {
+ if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk format %s for %s"),
+ disk->driverType, disk->src);
+ goto cleanup;
+ }
+ } else {
+ if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ goto cleanup;
+ }
+
+ if (virStorageFileGetMetadataFromFD(path, fd,
+ format,
+ &meta) < 0)
goto cleanup;
/* Get info for normal formats */
@@ -9706,7 +9725,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
highest allocated extent from QEMU */
if (virDomainObjIsActive(vm) &&
disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
- meta.format != VIR_STORAGE_FILE_RAW &&
+ format != VIR_STORAGE_FILE_RAW &&
S_ISBLK(sb.st_mode)) {
qemuDomainObjPrivatePtr priv = vm->privateData;
if (qemuDomainObjBeginJob(vm) < 0)
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index 95015b0..acfe48e 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -115,7 +115,9 @@ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
virStorageFileMetadata meta;
int ret;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != disk->src)
VIR_FREE(path);
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e5eef19..5c0f002 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -457,7 +457,9 @@ SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
virStorageFileMetadata meta;
int ret;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != disk->src)
VIR_FREE(path);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index c66f107..2c045e6 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -830,7 +830,9 @@ get_files(vahControl * ctl)
do {
virStorageFileMetadata meta;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != ctl->def->disks[i]->src)
VIR_FREE(path);
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index f0cd770..d3ac0fe 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -75,14 +75,19 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
memset(&meta, 0, sizeof(meta));
- if (virStorageFileGetMetadataFromFD(target->path, fd, &meta) < 0) {
+ if ((target->format = virStorageFileProbeFormatFromFD(target->path, fd)) < 0) {
close(fd);
return -1;
}
- close(fd);
+ if (virStorageFileGetMetadataFromFD(target->path, fd,
+ target->format,
+ &meta) < 0) {
+ close(fd);
+ return -1;
+ }
- target->format = meta.format;
+ close(fd);
if (backingStore) {
*backingStore = meta.backingStore;
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 221268b..9712d92 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -696,18 +696,23 @@ virStorageFileProbeFormat(const char *path)
/**
* virStorageFileGetMetadataFromFD:
*
- * Probe for the format of 'fd' (which is an open file descriptor
- * for the file 'path'), filling 'meta' with the detected
- * format and other associated metadata.
+ * Extract metadata about the storage volume with the specified
+ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
+ * will probe to automatically identify the format.
*
- * Callers are advised never to trust the returned 'meta->format'
- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
- * malicious guest can turn a raw file into any other non-raw
- * format at will.
+ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
+ * format, since a malicious guest can turn a raw file into any
+ * other non-raw format at will.
+ *
+ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
+ * it indicates the image didn't specify an explicit format for its
+ * backing store. Callers are advised against probing for the
+ * backing store format in this case.
*/
int
virStorageFileGetMetadataFromFD(const char *path,
int fd,
+ int format,
virStorageFileMetadata *meta)
{
unsigned char *head;
@@ -731,9 +736,16 @@ virStorageFileGetMetadataFromFD(const char *path,
goto cleanup;
}
- meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
+ if (format == VIR_STORAGE_FILE_AUTO)
+ format = virStorageFileProbeFormatFromBuf(path, head, len);
+
+ if (format < 0 ||
+ format >= VIR_STORAGE_FILE_LAST) {
+ virReportSystemError(EINVAL, _("unknown storage file format %d"), format);
+ return -1;
+ }
- ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
+ ret = virStorageFileGetMetadataFromBuf(format, path, head, len, meta);
cleanup:
VIR_FREE(head);
@@ -743,16 +755,22 @@ cleanup:
/**
* virStorageFileGetMetadata:
*
- * Probe for the format of 'path', filling 'meta' with the detected
- * format and other associated metadata.
+ * Extract metadata about the storage volume with the specified
+ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
+ * will probe to automatically identify the format.
*
- * Callers are advised never to trust the returned 'meta->format'
- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
- * malicious guest can turn a raw file into any other non-raw
- * format at will.
+ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
+ * format, since a malicious guest can turn a raw file into any
+ * other non-raw format at will.
+ *
+ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
+ * it indicates the image didn't specify an explicit format for its
+ * backing store. Callers are advised against probing for the
+ * backing store format in this case.
*/
int
virStorageFileGetMetadata(const char *path,
+ int format,
virStorageFileMetadata *meta)
{
int fd, ret;
@@ -762,7 +780,7 @@ virStorageFileGetMetadata(const char *path,
return -1;
}
- ret = virStorageFileGetMetadataFromFD(path, fd, meta);
+ ret = virStorageFileGetMetadataFromFD(path, fd, format, meta);
close(fd);
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 3420d44..6853182 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -46,7 +46,6 @@ enum virStorageFileFormat {
VIR_ENUM_DECL(virStorageFileFormat);
typedef struct _virStorageFileMetadata {
- int format;
char *backingStore;
int backingStoreFormat;
unsigned long long capacity;
@@ -62,9 +61,11 @@ int virStorageFileProbeFormatFromFD(const char *path,
int fd);
int virStorageFileGetMetadata(const char *path,
+ int format,
virStorageFileMetadata *meta);
int virStorageFileGetMetadataFromFD(const char *path,
int fd,
+ int format,
virStorageFileMetadata *meta);
int virStorageFileIsSharedFS(const char *path);
--
1.7.1.1
-170
View File
@@ -1,170 +0,0 @@
From ac5067f1e2e98181ee0e9230f756697f50d853eb Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 18:09:15 +0100
Subject: [PATCH 05/11] Add an API for iterating over disk paths
There is duplicated code which iterates over disk backing stores
performing some action. Provide a convenient helper for doing
this to eliminate duplication & risk of mistakes with disk format
probing
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/libvirt_private.syms: Add virDomainDiskDefForeachPath()
---
src/conf/domain_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 11 +++++
src/libvirt_private.syms | 1 +
3 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 378c06e..b20ca97 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -45,6 +45,7 @@
#include "macvtap.h"
#include "nwfilter_conf.h"
#include "ignore-value.h"
+#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -7273,4 +7274,102 @@ done:
}
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
+ bool allowProbing,
+ bool ignoreOpenFailure,
+ virDomainDiskDefPathIterator iter,
+ void *opaque)
+{
+ virHashTablePtr paths;
+ int format;
+ int ret = -1;
+ size_t depth = 0;
+ char *nextpath = NULL;
+
+ if (!disk->src)
+ return 0;
+
+ if (disk->driverType) {
+ const char *formatStr = disk->driverType;
+ if (STREQ(formatStr, "aio"))
+ formatStr = "raw"; /* Xen compat */
+
+ if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk format '%s' for %s"),
+ disk->driverType, disk->src);
+ return -1;
+ }
+ } else {
+ if (allowProbing) {
+ format = VIR_STORAGE_FILE_AUTO;
+ } else {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no disk format for %s and probing is disabled"),
+ disk->src);
+ return -1;
+ }
+ }
+
+ paths = virHashCreate(5);
+
+ do {
+ virStorageFileMetadata meta;
+ const char *path = nextpath ? nextpath : disk->src;
+ int fd;
+
+ if (iter(disk, path, depth, opaque) < 0)
+ goto cleanup;
+
+ if (virHashLookup(paths, path)) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("backing store for %s is self-referential"),
+ disk->src);
+ goto cleanup;
+ }
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ if (ignoreOpenFailure) {
+ char ebuf[1024];
+ VIR_WARN("Ignoring open failure on %s: %s", path,
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ break;
+ } else {
+ virReportSystemError(errno,
+ _("unable to open disk path %s"),
+ path);
+ goto cleanup;
+ }
+ }
+
+ if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) {
+ close(fd);
+ goto cleanup;
+ }
+ close(fd);
+
+ if (virHashAddEntry(paths, path, (void*)0x1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ depth++;
+ nextpath = meta.backingStore;
+
+ format = meta.backingStoreFormat;
+
+ if (format == VIR_STORAGE_FILE_AUTO &&
+ !allowProbing)
+ format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
+ } while (nextpath);
+
+ ret = 0;
+
+cleanup:
+ virHashFree(paths, NULL);
+ VIR_FREE(nextpath);
+
+ return ret;
+}
+
#endif /* ! PROXY */
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 01da17e..d46869e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1079,6 +1079,17 @@ int virDomainChrDefForeach(virDomainDefPtr def,
void *opaque);
+typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque);
+
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
+ bool allowProbing,
+ bool ignoreOpenFailure,
+ virDomainDiskDefPathIterator iter,
+ void *opaque);
+
VIR_ENUM_DECL(virDomainVirt)
VIR_ENUM_DECL(virDomainBoot)
VIR_ENUM_DECL(virDomainFeature)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4607f49..b5f3695 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -225,6 +225,7 @@ virDomainSnapshotDefFormat;
virDomainSnapshotAssignDef;
virDomainObjAssignDef;
virDomainChrDefForeach;
+virDomainDiskDefForeachPath;
# domain_event.h
--
1.7.1.1
-506
View File
@@ -1,506 +0,0 @@
From 54c1bb731d2b19a46a594cf9682c022f1e1114d2 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 16:40:47 +0100
Subject: [PATCH 06/11] Convert all disk backing store loops to shared helper API
Update the QEMU cgroups code, QEMU DAC security driver, SELinux
and AppArmour security drivers over to use the shared helper API
virDomainDiskDefForeachPath().
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Convert over to use virDomainDiskDefForeachPath()
---
src/qemu/qemu_driver.c | 161 ++++++++++++++++----------------------
src/qemu/qemu_security_dac.c | 47 ++++--------
src/security/security_selinux.c | 67 +++++++----------
src/security/virt-aa-helper.c | 71 ++++++++----------
4 files changed, 142 insertions(+), 204 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97f2990..99aeffa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3040,107 +3040,82 @@ static const char *const defaultDeviceACL[] = {
#define DEVICE_PTY_MAJOR 136
#define DEVICE_SND_MAJOR 116
-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- char *path = disk->src;
- int ret = -1;
- while (path != NULL) {
- virStorageFileMetadata meta;
- int rc;
+static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virCgroupPtr cgroup = opaque;
+ int rc;
- VIR_DEBUG("Process path '%s' for disk", path);
- rc = virCgroupAllowDevicePath(cgroup, path);
- if (rc != 0) {
- /* Get this for non-block devices */
- if (rc == -EINVAL) {
- VIR_DEBUG("Ignoring EINVAL for %s", path);
- } else if (rc == -EACCES) { /* Get this for root squash NFS */
- VIR_DEBUG("Ignoring EACCES for %s", path);
- } else {
- virReportSystemError(-rc,
- _("Unable to allow device %s for %s"),
- path, vm->def->name);
- if (path != disk->src)
- VIR_FREE(path);
- goto cleanup;
- }
+ VIR_DEBUG("Process path %s for disk", path);
+ /* XXX RO vs RW */
+ rc = virCgroupAllowDevicePath(cgroup, path);
+ if (rc != 0) {
+ /* Get this for non-block devices */
+ if (rc == -EINVAL) {
+ VIR_DEBUG("Ignoring EINVAL for %s", path);
+ } else if (rc == -EACCES) { /* Get this for root squash NFS */
+ VIR_DEBUG("Ignoring EACCES for %s", path);
+ } else {
+ virReportSystemError(-rc,
+ _("Unable to allow access for disk path %s"),
+ path);
+ return -1;
}
-
- rc = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
- if (rc < 0)
- VIR_WARN("Unable to lookup parent image for %s", path);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (rc < 0)
- break; /* Treating as non fatal */
-
- path = meta.backingStore;
}
+ return 0;
+}
- ret = 0;
-cleanup:
- return ret;
+static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ true,
+ qemuSetupDiskPathAllow,
+ cgroup);
}
-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
+static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
{
- char *path = disk->src;
- int ret = -1;
-
- while (path != NULL) {
- virStorageFileMetadata meta;
- int rc;
+ virCgroupPtr cgroup = opaque;
+ int rc;
- VIR_DEBUG("Process path '%s' for disk", path);
- rc = virCgroupDenyDevicePath(cgroup, path);
- if (rc != 0) {
- /* Get this for non-block devices */
- if (rc == -EINVAL) {
- VIR_DEBUG("Ignoring EINVAL for %s", path);
- } else if (rc == -EACCES) { /* Get this for root squash NFS */
- VIR_DEBUG("Ignoring EACCES for %s", path);
- } else {
- virReportSystemError(-rc,
- _("Unable to deny device %s for %s"),
- path, vm->def->name);
- if (path != disk->src)
- VIR_FREE(path);
- goto cleanup;
- }
+ VIR_DEBUG("Process path %s for disk", path);
+ /* XXX RO vs RW */
+ rc = virCgroupDenyDevicePath(cgroup, path);
+ if (rc != 0) {
+ /* Get this for non-block devices */
+ if (rc == -EINVAL) {
+ VIR_DEBUG("Ignoring EINVAL for %s", path);
+ } else if (rc == -EACCES) { /* Get this for root squash NFS */
+ VIR_DEBUG("Ignoring EACCES for %s", path);
+ } else {
+ virReportSystemError(-rc,
+ _("Unable to allow access for disk path %s"),
+ path);
+ return -1;
}
-
- rc = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
- if (rc < 0)
- VIR_WARN("Unable to lookup parent image for %s", path);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (rc < 0)
- break; /* Treating as non fatal */
-
- path = meta.backingStore;
}
+ return 0;
+}
- ret = 0;
-cleanup:
- return ret;
+static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ true,
+ qemuTeardownDiskPathDeny,
+ cgroup);
}
@@ -3204,7 +3179,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
}
for (i = 0; i < vm->def->ndisks ; i++) {
- if (qemuSetupDiskCgroup(cgroup, vm, vm->def->disks[i]) < 0)
+ if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
goto cleanup;
}
@@ -8035,7 +8010,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8080,7 +8055,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
/* Fallthrough */
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8280,7 +8255,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8303,7 +8278,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8430,7 +8405,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8493,7 +8468,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index acfe48e..770010d 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -98,45 +98,28 @@ err:
static int
+qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
+}
+
+
+static int
qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
virDomainDiskDefPtr disk)
{
- const char *path;
-
if (!driver->privileged || !driver->dynamicOwnership)
return 0;
- if (!disk->src)
- return 0;
-
- path = disk->src;
- do {
- virStorageFileMetadata meta;
- int ret;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0)
- return -1;
-
- if (meta.backingStore != NULL &&
- qemuSecurityDACSetOwnership(meta.backingStore,
- driver->user, driver->group) < 0) {
- VIR_FREE(meta.backingStore);
- return -1;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- return qemuSecurityDACSetOwnership(disk->src, driver->user, driver->group);
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ false,
+ qemuSecurityDACSetSecurityFileLabel,
+ NULL);
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5c0f002..d191118 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -439,54 +439,43 @@ SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
static int
+SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque)
+{
+ const virSecurityLabelDefPtr secdef = opaque;
+
+ if (depth == 0) {
+ if (disk->shared) {
+ return SELinuxSetFilecon(path, default_image_context);
+ } else if (disk->readonly) {
+ return SELinuxSetFilecon(path, default_content_context);
+ } else if (secdef->imagelabel) {
+ return SELinuxSetFilecon(path, secdef->imagelabel);
+ } else {
+ return 0;
+ }
+ } else {
+ return SELinuxSetFilecon(path, default_content_context);
+ }
+}
+
+static int
SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- const char *path;
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- if (!disk->src)
- return 0;
-
- path = disk->src;
- do {
- virStorageFileMetadata meta;
- int ret;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0)
- break;
-
- if (meta.backingStore != NULL &&
- SELinuxSetFilecon(meta.backingStore,
- default_content_context) < 0) {
- VIR_FREE(meta.backingStore);
- return -1;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- if (disk->shared) {
- return SELinuxSetFilecon(disk->src, default_image_context);
- } else if (disk->readonly) {
- return SELinuxSetFilecon(disk->src, default_content_context);
- } else if (secdef->imagelabel) {
- return SELinuxSetFilecon(disk->src, secdef->imagelabel);
- }
-
- return 0;
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ false,
+ SELinuxSetSecurityFileLabel,
+ secdef);
}
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 2c045e6..9ed0cd3 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -36,7 +36,6 @@
#include "uuid.h"
#include "hostusb.h"
#include "pci.h"
-#include "storage_file.h"
static char *progname;
@@ -801,6 +800,28 @@ file_iterate_pci_cb(pciDevice *dev ATTRIBUTE_UNUSED,
}
static int
+add_file_path(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque)
+{
+ virBufferPtr buf = opaque;
+ int ret;
+
+ if (depth == 0) {
+ if (disk->readonly)
+ ret = vah_add_file(buf, path, "r");
+ else
+ ret = vah_add_file(buf, path, "rw");
+ } else {
+ ret = vah_add_file(buf, path, "r");
+ }
+
+ return ret;
+}
+
+
+static int
get_files(vahControl * ctl)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -821,45 +842,15 @@ get_files(vahControl * ctl)
goto clean;
}
- for (i = 0; i < ctl->def->ndisks; i++)
- if (ctl->def->disks[i] && ctl->def->disks[i]->src) {
- int ret;
- const char *path;
-
- path = ctl->def->disks[i]->src;
- do {
- virStorageFileMetadata meta;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != ctl->def->disks[i]->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0) {
- vah_warning("could not open path, skipping");
- continue;
- }
-
- if (meta.backingStore != NULL &&
- (ret = vah_add_file(&buf, meta.backingStore, "rw")) != 0) {
- VIR_FREE(meta.backingStore);
- goto clean;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- if (ctl->def->disks[i]->readonly)
- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "r");
- else
- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "rw");
-
- if (ret != 0)
- goto clean;
- }
+ for (i = 0; i < ctl->def->ndisks; i++) {
+ int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
+ true,
+ false,
+ add_file_path,
+ &buf);
+ if (ret != 0)
+ goto clean;
+ }
for (i = 0; i < ctl->def->nserials; i++)
if (ctl->def->serials[i] && ctl->def->serials[i]->data.file.path)
--
1.7.1.1
File diff suppressed because it is too large Load Diff
-468
View File
@@ -1,468 +0,0 @@
From dac2b936e77f6c76c11f162e4b175492e4803acb Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 17:58:58 +0100
Subject: [PATCH 08/11] Disable all disk probing in QEMU driver & add config option to re-enable
Disk format probing is now disabled by default. A new config
option in /etc/qemu/qemu.conf will re-enable it for existing
deployments where this causes trouble
---
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 12 ++++++++++++
src/qemu/qemu_conf.c | 4 ++++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 36 +++++++++++++++++++++++-------------
src/qemu/qemu_security_dac.c | 2 +-
src/qemu/test_libvirtd_qemu.aug | 4 ++++
src/security/security_apparmor.c | 12 ++++++++----
src/security/security_driver.c | 16 ++++++++++++++--
src/security/security_driver.h | 10 ++++++++--
src/security/security_selinux.c | 9 ++++++---
src/security/virt-aa-helper.c | 10 +++++++++-
tests/seclabeltest.c | 2 +-
13 files changed, 92 insertions(+), 27 deletions(-)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 7c9f271..47d0525 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -40,6 +40,7 @@ module Libvirtd_qemu =
| bool_entry "relaxed_acs_check"
| bool_entry "vnc_allow_host_audio"
| bool_entry "clear_emulator_capabilities"
+ | bool_entry "allow_disk_format_probing"
(* Each enty in the config is one of the following three ... *)
let entry = vnc_entry
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 93934f3..dc8eb83 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -187,3 +187,15 @@
# exploit the privileges and possibly do damage to the host.
#
# clear_emulator_capabilities = 1
+
+
+
+# If allow_disk_format_probing is enabled, libvirt will probe disk
+# images to attempt to identify their format, when not otherwise
+# specified in the XML. This is disabled by default.
+#
+# WARNING: Enabling probing is a security hole in almost all
+# deployments. It is strongly recommended that users update their
+# guest XML <disk> elements to include <driver type='XXXX'/>
+# elements instead of enabling this option.
+# allow_disk_format_probing = 1
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 988220b..3ba48bf 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -365,6 +365,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
if (p) driver->clearEmulatorCapabilities = p->l;
+ p = virConfGetValue (conf, "allow_disk_format_probing");
+ CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
+ if (p) driver->allowDiskFormatProbing = p->l;
+
virConfFree (conf);
return 0;
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index ab5f158..30e9f20 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -141,6 +141,7 @@ struct qemud_driver {
unsigned int relaxedACS : 1;
unsigned int vncAllowHostAudio : 1;
unsigned int clearEmulatorCapabilities : 1;
+ unsigned int allowDiskFormatProbing : 1;
virCapsPtr caps;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 616547c..3c479c5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1322,7 +1322,8 @@ qemudSecurityInit(struct qemud_driver *qemud_drv)
qemuSecurityDACSetDriver(qemud_drv);
ret = virSecurityDriverStartup(&security_drv,
- qemud_drv->securityDriverName);
+ qemud_drv->securityDriverName,
+ qemud_drv->allowDiskFormatProbing);
if (ret == -1) {
VIR_ERROR0(_("Failed to start security driver"));
return -1;
@@ -3070,11 +3071,12 @@ static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
}
-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+static int qemuSetupDiskCgroup(struct qemud_driver *driver,
+ virCgroupPtr cgroup,
virDomainDiskDefPtr disk)
{
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
true,
qemuSetupDiskPathAllow,
cgroup);
@@ -3109,11 +3111,12 @@ static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
}
-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+static int qemuTeardownDiskCgroup(struct qemud_driver *driver,
+ virCgroupPtr cgroup,
virDomainDiskDefPtr disk)
{
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
true,
qemuTeardownDiskPathDeny,
cgroup);
@@ -3180,7 +3183,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
}
for (i = 0; i < vm->def->ndisks ; i++) {
- if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, vm->def->disks[i]) < 0)
goto cleanup;
}
@@ -8033,7 +8036,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8078,7 +8081,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
/* Fallthrough */
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8278,7 +8281,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8301,7 +8304,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8429,7 +8432,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8493,7 +8496,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -9672,8 +9675,15 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
goto cleanup;
}
} else {
- if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ if (driver->allowDiskFormatProbing) {
+ if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ goto cleanup;
+ } else {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no disk format for %s and probing is disabled"),
+ disk->src);
goto cleanup;
+ }
}
if (virStorageFileGetMetadataFromFD(path, fd,
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index 0bbcf69..55dc0c6 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -117,7 +117,7 @@ qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
return 0;
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
false,
qemuSecurityDACSetSecurityFileLabel,
NULL);
diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug
index 3326cc5..f0c4a0d 100644
--- a/src/qemu/test_libvirtd_qemu.aug
+++ b/src/qemu/test_libvirtd_qemu.aug
@@ -101,6 +101,8 @@ relaxed_acs_check = 1
vnc_allow_host_audio = 1
clear_emulator_capabilities = 0
+
+allow_disk_format_probing = 1
"
test Libvirtd_qemu.lns get conf =
@@ -212,3 +214,5 @@ clear_emulator_capabilities = 0
{ "vnc_allow_host_audio" = "1" }
{ "#empty" }
{ "clear_emulator_capabilities" = "0" }
+{ "#empty" }
+{ "allow_disk_format_probing" = "1" }
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index cb5c739..c5f9829 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -157,6 +157,8 @@ load_profile(virSecurityDriverPtr drv,
char *xml = NULL;
int pipefd[2];
pid_t child;
+ const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+ ? "1" : "0";
if (pipe(pipefd) < -1) {
virReportSystemError(errno, "%s", _("unable to create pipe"));
@@ -172,19 +174,19 @@ load_profile(virSecurityDriverPtr drv,
if (create) {
const char *const argv[] = {
- VIRT_AA_HELPER, "-c", "-u", profile, NULL
+ VIRT_AA_HELPER, "-p", probe, "-c", "-u", profile, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
} else if (fn) {
const char *const argv[] = {
- VIRT_AA_HELPER, "-r", "-u", profile, "-f", fn, NULL
+ VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, "-f", fn, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
} else {
const char *const argv[] = {
- VIRT_AA_HELPER, "-r", "-u", profile, NULL
+ VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
@@ -347,9 +349,11 @@ AppArmorSecurityDriverProbe(void)
* currently not used.
*/
static int
-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv)
+AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
{
virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
+ virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return 0;
}
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index aac9f78..9e32fa4 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -56,7 +56,8 @@ virSecurityDriverVerify(virDomainDefPtr def)
int
virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name)
+ const char *name,
+ bool allowDiskFormatProbing)
{
unsigned int i;
@@ -72,7 +73,7 @@ virSecurityDriverStartup(virSecurityDriverPtr *drv,
switch (tmp->probe()) {
case SECURITY_DRIVER_ENABLE:
virSecurityDriverInit(tmp);
- if (tmp->open(tmp) == -1) {
+ if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
return -1;
} else {
*drv = tmp;
@@ -125,3 +126,14 @@ virSecurityDriverGetModel(virSecurityDriverPtr drv)
{
return drv->name;
}
+
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
+{
+ drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
+}
+
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
+{
+ return drv->_private.allowDiskFormatProbing;
+}
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index 61c9eb0..d768f32 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -33,7 +33,8 @@ typedef struct _virSecurityDriverState virSecurityDriverState;
typedef virSecurityDriverState *virSecurityDriverStatePtr;
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv);
+typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing);
typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
@@ -102,12 +103,14 @@ struct _virSecurityDriver {
*/
struct {
char doi[VIR_SECURITY_DOI_BUFLEN];
+ bool allowDiskFormatProbing;
} _private;
};
/* Global methods */
int virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name);
+ const char *name,
+ bool allowDiskFormatProbing);
int
virSecurityDriverVerify(virDomainDefPtr def);
@@ -120,7 +123,10 @@ virSecurityDriverVerify(virDomainDefPtr def);
void virSecurityDriverInit(virSecurityDriverPtr drv);
int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
const char *doi);
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing);
const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
#endif /* __VIR_SECURITY_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index cc3812b..a9dd836 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -266,13 +266,15 @@ SELinuxSecurityDriverProbe(void)
}
static int
-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv)
+SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
+ virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return SELinuxInitialize();
}
@@ -467,18 +469,19 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
}
static int
-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+ bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
return virDomainDiskDefForeachPath(disk,
- true,
+ allowDiskFormatProbing,
false,
SELinuxSetSecurityFileLabel,
secdef);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 9ed0cd3..521545d 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -40,6 +40,7 @@
static char *progname;
typedef struct {
+ bool allowDiskFormatProbing;
char uuid[PROFILE_NAME_SIZE]; /* UUID of vm */
bool dryrun; /* dry run */
char cmd; /* 'c' create
@@ -844,7 +845,7 @@ get_files(vahControl * ctl)
for (i = 0; i < ctl->def->ndisks; i++) {
int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
- true,
+ ctl->allowDiskFormatProbing,
false,
add_file_path,
&buf);
@@ -943,6 +944,7 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
{
int arg, idx = 0;
struct option opt[] = {
+ {"probing", 1, 0, 'p' },
{"add", 0, 0, 'a'},
{"create", 0, 0, 'c'},
{"dryrun", 0, 0, 'd'},
@@ -991,6 +993,12 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
PROFILE_NAME_SIZE) == NULL)
vah_error(ctl, 1, "error copying UUID");
break;
+ case 'p':
+ if (STREQ(optarg, "1"))
+ ctl->allowDiskFormatProbing = true;
+ else
+ ctl->allowDiskFormatProbing = false;
+ break;
default:
vah_error(ctl, 1, "unsupported option");
break;
diff --git a/tests/seclabeltest.c b/tests/seclabeltest.c
index 26d1f86..ef3f026 100644
--- a/tests/seclabeltest.c
+++ b/tests/seclabeltest.c
@@ -15,7 +15,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
const char *doi, *model;
virSecurityDriverPtr security_drv;
- ret = virSecurityDriverStartup (&security_drv, "selinux");
+ ret = virSecurityDriverStartup (&security_drv, "selinux", false);
if (ret == -1)
{
fprintf (stderr, "Failed to start security driver");
--
1.7.1.1
-94
View File
@@ -1,94 +0,0 @@
From 3534cd47a57ee9cf7041472511444784f14d6939 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 16:08:55 +0100
Subject: [PATCH 09/11] Add ability to set a default driver name/type when parsing disks
Record a default driver name/type in capabilities struct. Use this
when parsing disks if value is not set in XML config.
* src/conf/capabilities.h: Record default driver name/type for disks
* src/conf/domain_conf.c: Fallback to default driver name/type
when parsing disks
* src/qemu/qemu_driver.c: Set default driver name/type to raw
---
src/conf/capabilities.h | 2 ++
src/conf/domain_conf.c | 16 +++++++++++++++-
src/qemu/qemu_driver.c | 8 ++++++++
3 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 9290c82..f676eb8 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -123,6 +123,8 @@ struct _virCaps {
virCapsGuestPtr *guests;
unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN];
unsigned int emulatorRequired : 1;
+ const char *defaultDiskDriverName;
+ const char *defaultDiskDriverType;
void *(*privateDataAllocFunc)(void);
void (*privateDataFreeFunc)(void *);
int (*privateDataXMLFormat)(virBufferPtr, void *);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b20ca97..f3b8cfa 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1639,6 +1639,16 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->serial = serial;
serial = NULL;
+ if (!def->driverType &&
+ caps->defaultDiskDriverType &&
+ !(def->driverType = strdup(caps->defaultDiskDriverType)))
+ goto no_memory;
+
+ if (!def->driverName &&
+ caps->defaultDiskDriverName &&
+ !(def->driverName = strdup(caps->defaultDiskDriverName)))
+ goto no_memory;
+
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&& virDomainDiskDefAssignAddress(caps, def) < 0)
goto error;
@@ -1659,6 +1669,9 @@ cleanup:
return def;
+no_memory:
+ virReportOOMError();
+
error:
virDomainDiskDefFree(def);
def = NULL;
@@ -4275,7 +4288,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (n && VIR_ALLOC_N(def->disks, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) {
- virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i],
+ virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
+ nodes[i],
flags);
if (!disk)
goto error;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3c479c5..14b790e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1357,6 +1357,14 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
return NULL;
}
+ if (driver->allowDiskFormatProbing) {
+ caps->defaultDiskDriverName = NULL;
+ caps->defaultDiskDriverType = NULL;
+ } else {
+ caps->defaultDiskDriverName = "qemu";
+ caps->defaultDiskDriverType = "raw";
+ }
+
/* Domain XML parser hooks */
caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc;
caps->privateDataFreeFunc = qemuDomainObjPrivateFree;
--
1.7.1.1
@@ -1,291 +0,0 @@
From 2ba8625d6d148fa489586efabdfaf2ef20903762 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Wed, 16 Jun 2010 14:14:05 +0100
Subject: [PATCH 10/11] Rewrite qemu-img backing store format handling
When creating qcow2 files with a backing store, it is important
to set an explicit format to prevent QEMU probing. The storage
backend was only doing this if it found a 'kvm-img' binary. This
is wrong because plenty of kvm-img binaries don't support an
explicit format, and plenty of 'qemu-img' binaries do support
a format. The result was that most qcow2 files were not getting
a backing store format.
This patch runs 'qemu-img -h' to check for the two support
argument formats
'-o backing_format=raw'
'-F raw'
and use whichever option it finds
* src/storage/storage_backend.c: Query binary to determine
how to set the backing store format
---
src/storage/storage_backend.c | 214 +++++++++++++++++++++++++++++------------
1 files changed, 152 insertions(+), 62 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index aba8937..c185693 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -561,6 +561,69 @@ static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
return 0;
}
+enum {
+ QEMU_IMG_BACKING_FORMAT_NONE = 0,
+ QEMU_IMG_BACKING_FORMAT_FLAG,
+ QEMU_IMG_BACKING_FORMAT_OPTIONS,
+};
+
+static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
+{
+ const char *const qemuarg[] = { qemuimg, "-h", NULL };
+ const char *const qemuenv[] = { "LC_ALL=C", NULL };
+ pid_t child = 0;
+ int status;
+ int newstdout = -1;
+ char *help = NULL;
+ enum { MAX_HELP_OUTPUT_SIZE = 1024*8 };
+ int len;
+ char *start;
+ char *end;
+ char *tmp;
+ int ret = -1;
+
+ if (virExec(qemuarg, qemuenv, NULL,
+ &child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0)
+ goto cleanup;
+
+ if ((len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to read '%s -h' output"),
+ qemuimg);
+ goto cleanup;
+ }
+
+ start = strstr(help, " create ");
+ end = strstr(start, "\n");
+ if ((tmp = strstr(start, "-F fmt")) && tmp < end)
+ ret = QEMU_IMG_BACKING_FORMAT_FLAG;
+ else if ((tmp = strstr(start, "[-o options]")) && tmp < end)
+ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
+ else
+ ret = QEMU_IMG_BACKING_FORMAT_NONE;
+
+cleanup:
+ VIR_FREE(help);
+ close(newstdout);
+rewait:
+ if (child) {
+ if (waitpid(child, &status, 0) != child) {
+ if (errno == EINTR)
+ goto rewait;
+
+ VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"),
+ WEXITSTATUS(status), (unsigned long)child);
+ }
+ if (WEXITSTATUS(status) != 0) {
+ VIR_WARN("Unexpected exit status '%d', qemu probably failed",
+ WEXITSTATUS(status));
+ }
+ }
+
+ return ret;
+}
+
+
static int
virStorageBackendCreateQemuImg(virConnectPtr conn,
virStoragePoolObjPtr pool,
@@ -568,10 +631,9 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virStorageVolDefPtr inputvol,
unsigned int flags ATTRIBUTE_UNUSED)
{
- int ret;
+ int ret = -1;
char size[100];
char *create_tool;
- short use_kvmimg;
const char *type = virStorageFileFormatTypeToString(vol->target.format);
const char *backingType = vol->backingStore.path ?
@@ -582,41 +644,10 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
const char *inputPath = inputvol ? inputvol->target.path : NULL;
/* Treat input block devices as 'raw' format */
const char *inputType = inputPath ?
- virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) :
- NULL;
-
- const char **imgargv;
- /* The extra NULL field is for indicating encryption (-e). */
- const char *imgargvnormal[] = {
- NULL, "create",
- "-f", type,
- vol->target.path,
- size,
- NULL,
- NULL
- };
- /* Extra NULL fields are for including "backingType" when using
- * kvm-img (-F backingType), and for indicating encryption (-e).
- */
- const char *imgargvbacking[] = {
- NULL, "create",
- "-f", type,
- "-b", vol->backingStore.path,
- vol->target.path,
- size,
- NULL,
- NULL,
- NULL,
- NULL
- };
- const char *convargv[] = {
- NULL, "convert",
- "-f", inputType,
- "-O", type,
- inputPath,
- vol->target.path,
- NULL,
- };
+ virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ?
+ VIR_STORAGE_FILE_RAW :
+ inputvol->target.format) :
+ NULL;
if (type == NULL) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
@@ -690,44 +721,103 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
}
}
- if ((create_tool = virFindFileInPath("kvm-img")) != NULL)
- use_kvmimg = 1;
- else if ((create_tool = virFindFileInPath("qemu-img")) != NULL)
- use_kvmimg = 0;
- else {
+ /* Size in KB */
+ snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
+
+ /* KVM is usually ahead of qemu on features, so try that first */
+ create_tool = virFindFileInPath("kvm-img");
+ if (!create_tool)
+ create_tool = virFindFileInPath("qemu-img");
+
+ if (!create_tool) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("unable to find kvm-img or qemu-img"));
return -1;
}
if (inputvol) {
- convargv[0] = create_tool;
- imgargv = convargv;
+ const char *imgargv[] = {
+ create_tool,
+ "convert",
+ "-f", inputType,
+ "-O", type,
+ inputPath,
+ vol->target.path,
+ NULL,
+ };
+
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
} else if (vol->backingStore.path) {
- imgargvbacking[0] = create_tool;
- if (use_kvmimg) {
- imgargvbacking[6] = "-F";
- imgargvbacking[7] = backingType;
- imgargvbacking[8] = vol->target.path;
- imgargvbacking[9] = size;
+ const char *imgargv[] = {
+ create_tool,
+ "create",
+ "-f", type,
+ "-b", vol->backingStore.path,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ int imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
+ char *optflag = NULL;
+ if (imgformat < 0)
+ goto cleanup;
+
+ switch (imgformat) {
+ case QEMU_IMG_BACKING_FORMAT_FLAG:
+ imgargv[6] = "-F";
+ imgargv[7] = backingType;
+ imgargv[8] = vol->target.path;
+ imgargv[9] = size;
+ if (vol->target.encryption != NULL)
+ imgargv[10] = "-e";
+ break;
+
+ case QEMU_IMG_BACKING_FORMAT_OPTIONS:
+ if (virAsprintf(&optflag, "backing_fmt=%s", backingType) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ imgargv[6] = "-o";
+ imgargv[7] = optflag;
+ imgargv[8] = vol->target.path;
+ imgargv[9] = size;
if (vol->target.encryption != NULL)
- imgargvbacking[10] = "-e";
- } else if (vol->target.encryption != NULL)
- imgargvbacking[8] = "-e";
- imgargv = imgargvbacking;
+ imgargv[10] = "-e";
+ break;
+
+ default:
+ VIR_INFO("Unable to set backing store format for %s with %s",
+ vol->target.path, create_tool);
+ imgargv[6] = vol->target.path;
+ imgargv[7] = size;
+ if (vol->target.encryption != NULL)
+ imgargv[8] = "-e";
+ }
+
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+ VIR_FREE(optflag);
} else {
- imgargvnormal[0] = create_tool;
- imgargv = imgargvnormal;
+ /* The extra NULL field is for indicating encryption (-e). */
+ const char *imgargv[] = {
+ create_tool,
+ "create",
+ "-f", type,
+ vol->target.path,
+ size,
+ NULL,
+ NULL
+ };
if (vol->target.encryption != NULL)
imgargv[6] = "-e";
- }
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+ }
- /* Size in KB */
- snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
-
- ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
- VIR_FREE(imgargv[0]);
+ cleanup:
+ VIR_FREE(create_tool);
return ret;
}
--
1.7.1.1
-165
View File
@@ -1,165 +0,0 @@
From d33f44c2e74de28c89b64cdc2c0a6564662e075c Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Fri, 9 Jul 2010 11:28:40 +0100
Subject: [PATCH 11/11] Use the extract backing store format in storage volume lookup
The storage volume lookup code was probing for the backing store
format, instead of using the format extracted from the file
itself. This meant it could report in accurate information. If
a format is included in the file, then use that in preference,
with probing as a fallback.
* src/storage/storage_backend_fs.c: Use extracted backing store
format
---
src/storage/storage_backend_fs.c | 80 +++++++++++++++++---------------------
1 files changed, 36 insertions(+), 44 deletions(-)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index d3ac0fe..ffb0071 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -51,6 +51,7 @@
static int
virStorageBackendProbeTarget(virStorageVolTargetPtr target,
char **backingStore,
+ int *backingStoreFormat,
unsigned long long *allocation,
unsigned long long *capacity,
virStorageEncryptionPtr *encryption)
@@ -58,6 +59,10 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
int fd, ret;
virStorageFileMetadata meta;
+ if (backingStore)
+ *backingStore = NULL;
+ if (backingStoreFormat)
+ *backingStoreFormat = VIR_STORAGE_FILE_AUTO;
if (encryption)
*encryption = NULL;
@@ -89,22 +94,30 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
close(fd);
- if (backingStore) {
- *backingStore = meta.backingStore;
- meta.backingStore = NULL;
+ if (meta.backingStore) {
+ if (backingStore) {
+ *backingStore = meta.backingStore;
+ meta.backingStore = NULL;
+ if (meta.backingStoreFormat == VIR_STORAGE_FILE_AUTO) {
+ if ((*backingStoreFormat = virStorageFileProbeFormat(*backingStore)) < 0) {
+ close(fd);
+ goto cleanup;
+ }
+ } else {
+ *backingStoreFormat = meta.backingStoreFormat;
+ }
+ } else {
+ VIR_FREE(meta.backingStore);
+ }
}
- VIR_FREE(meta.backingStore);
-
if (capacity && meta.capacity)
*capacity = meta.capacity;
if (encryption != NULL && meta.encrypted) {
if (VIR_ALLOC(*encryption) < 0) {
virReportOOMError();
- if (backingStore)
- VIR_FREE(*backingStore);
- return -1;
+ goto cleanup;
}
switch (target->format) {
@@ -124,6 +137,11 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
}
return 0;
+
+cleanup:
+ if (backingStore)
+ VIR_FREE(*backingStore);
+ return -1;
}
#if WITH_STORAGE_FS
@@ -585,6 +603,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
while ((ent = readdir(dir)) != NULL) {
int ret;
char *backingStore;
+ int backingStoreFormat;
if (VIR_ALLOC(vol) < 0)
goto no_memory;
@@ -604,6 +623,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
if ((ret = virStorageBackendProbeTarget(&vol->target,
&backingStore,
+ &backingStoreFormat,
&vol->allocation,
&vol->capacity,
&vol->target.encryption)) < 0) {
@@ -619,46 +639,18 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
}
if (backingStore != NULL) {
- if (vol->target.format == VIR_STORAGE_FILE_QCOW2 &&
- STRPREFIX("fmt:", backingStore)) {
- char *fmtstr = backingStore + 4;
- char *path = strchr(fmtstr, ':');
- if (!path) {
- VIR_FREE(backingStore);
- } else {
- *path = '\0';
- if ((vol->backingStore.format =
- virStorageFileFormatTypeFromString(fmtstr)) < 0) {
- VIR_FREE(backingStore);
- } else {
- memmove(backingStore, path, strlen(path) + 1);
- vol->backingStore.path = backingStore;
-
- if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
- NULL,
- NULL) < 0)
- VIR_FREE(vol->backingStore);
- }
- }
- } else {
- vol->backingStore.path = backingStore;
-
- if ((ret = virStorageBackendProbeTarget(&vol->backingStore,
- NULL, NULL, NULL,
- NULL)) < 0) {
- if (ret == -1)
- goto cleanup;
- else {
- /* Silently ignore non-regular files,
- * eg '.' '..', 'lost+found' */
- VIR_FREE(vol->backingStore);
- }
- }
+ vol->backingStore.path = backingStore;
+ vol->backingStore.format = backingStoreFormat;
+
+ if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
+ NULL,
+ NULL) < 0) {
+ VIR_FREE(vol->backingStore.path);
+ goto cleanup;
}
}
-
if (VIR_REALLOC_N(pool->volumes.objs,
pool->volumes.count+1) < 0)
goto no_memory;
--
1.7.1.1
@@ -1,265 +0,0 @@
From 112a309bc7839e95c558b535143f855ce89cca8c Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 10 Jun 2010 12:50:38 -0400
Subject: [PATCH] CVE-2010-2242 Apply a source port mapping to virtual network masquerading
IPtables will seek to preserve the source port unchanged when
doing masquerading, if possible. NFS has a pseudo-security
option where it checks for the source port <= 1023 before
allowing a mount request. If an admin has used this to make the
host OS trusted for mounts, the default iptables behaviour will
potentially allow NAT'd guests access too. This needs to be
stopped.
With this change, the iptables -t nat -L -n -v rules for the
default network will be
Chain POSTROUTING (policy ACCEPT 95 packets, 9163 bytes)
pkts bytes target prot opt in out source destination
14 840 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
75 5752 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
* src/network/bridge_driver.c: Add masquerade rules for TCP
and UDP protocols
* src/util/iptables.c, src/util/iptables.c: Add source port
mappings for TCP & UDP protocols when masquerading.
---
src/network/bridge_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++--
src/util/iptables.c | 70 +++++++++++++++++++++++++++++------------
src/util/iptables.h | 6 ++-
3 files changed, 122 insertions(+), 27 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 72255c1..80ed57a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -638,18 +638,74 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
goto masqerr2;
}
- /* enable masquerading */
+ /*
+ * Enable masquerading.
+ *
+ * We need to end up with 3 rules in the table in this order
+ *
+ * 1. protocol=tcp with sport mapping restricton
+ * 2. protocol=udp with sport mapping restricton
+ * 3. generic any protocol
+ *
+ * The sport mappings are required, because default IPtables
+ * MASQUERADE is maintain port number unchanged where possible.
+ *
+ * NFS can be configured to only "trust" port numbers < 1023.
+ *
+ * Guests using NAT thus need to be prevented from having port
+ * numbers < 1023, otherwise they can bypass the NFS "security"
+ * check on the source port number.
+ *
+ * Since we use '--insert' to add rules to the header of the
+ * chain, we actually need to add them in the reverse of the
+ * order just mentioned !
+ */
+
+ /* First the generic masquerade rule for other protocols */
if ((err = iptablesAddForwardMasquerade(driver->iptables,
network->def->network,
- network->def->forwardDev))) {
+ network->def->forwardDev,
+ NULL))) {
virReportSystemError(err,
_("failed to add iptables rule to enable masquerading to '%s'"),
network->def->forwardDev ? network->def->forwardDev : NULL);
goto masqerr3;
}
+ /* UDP with a source port restriction */
+ if ((err = iptablesAddForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp"))) {
+ virReportSystemError(err,
+ _("failed to add iptables rule to enable UDP masquerading to '%s'"),
+ network->def->forwardDev ? network->def->forwardDev : NULL);
+ goto masqerr4;
+ }
+
+ /* TCP with a source port restriction */
+ if ((err = iptablesAddForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "tcp"))) {
+ virReportSystemError(err,
+ _("failed to add iptables rule to enable TCP masquerading to '%s'"),
+ network->def->forwardDev ? network->def->forwardDev : NULL);
+ goto masqerr5;
+ }
+
return 1;
+ masqerr5:
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp");
+ masqerr4:
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ NULL);
masqerr3:
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
network->def->network,
@@ -814,8 +870,17 @@ networkRemoveIptablesRules(struct network_driver *driver,
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
- network->def->forwardDev);
+ network->def->network,
+ network->def->forwardDev,
+ "tcp");
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp");
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ NULL);
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
network->def->network,
network->def->bridge,
diff --git a/src/util/iptables.c b/src/util/iptables.c
index d06b857..f63e8c6 100644
--- a/src/util/iptables.c
+++ b/src/util/iptables.c
@@ -692,25 +692,49 @@ iptablesRemoveForwardRejectIn(iptablesContext *ctx,
*/
static int
iptablesForwardMasquerade(iptablesContext *ctx,
- const char *network,
- const char *physdev,
- int action)
+ const char *network,
+ const char *physdev,
+ const char *protocol,
+ int action)
{
- if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--out-interface", physdev,
- "--jump", "MASQUERADE",
- NULL);
+ if (protocol && protocol[0]) {
+ if (physdev && physdev[0]) {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "-p", protocol,
+ "!", "--destination", network,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
+ } else {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "-p", protocol,
+ "!", "--destination", network,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
+ }
} else {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--jump", "MASQUERADE",
- NULL);
+ if (physdev && physdev[0]) {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "!", "--destination", network,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ NULL);
+ } else {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "!", "--destination", network,
+ "--jump", "MASQUERADE",
+ NULL);
+ }
}
}
@@ -719,6 +743,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
* @ctx: pointer to the IP table context
* @network: the source network name
* @physdev: the physical input device or NULL
+ * @protocol: the network protocol or NULL
*
* Add rules to the IP table context to allow masquerading
* network @network on @physdev. This allow the bridge to
@@ -729,9 +754,10 @@ iptablesForwardMasquerade(iptablesContext *ctx,
int
iptablesAddForwardMasquerade(iptablesContext *ctx,
const char *network,
- const char *physdev)
+ const char *physdev,
+ const char *protocol)
{
- return iptablesForwardMasquerade(ctx, network, physdev, ADD);
+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, ADD);
}
/**
@@ -739,6 +765,7 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
* @ctx: pointer to the IP table context
* @network: the source network name
* @physdev: the physical input device or NULL
+ * @protocol: the network protocol or NULL
*
* Remove rules from the IP table context to stop masquerading
* network @network on @physdev. This stops the bridge from
@@ -749,7 +776,8 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
int
iptablesRemoveForwardMasquerade(iptablesContext *ctx,
const char *network,
- const char *physdev)
+ const char *physdev,
+ const char *protocol)
{
- return iptablesForwardMasquerade(ctx, network, physdev, REMOVE);
+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, REMOVE);
}
diff --git a/src/util/iptables.h b/src/util/iptables.h
index 7d55a6d..b47d854 100644
--- a/src/util/iptables.h
+++ b/src/util/iptables.h
@@ -85,9 +85,11 @@ int iptablesRemoveForwardRejectIn (iptablesContext *ctx,
int iptablesAddForwardMasquerade (iptablesContext *ctx,
const char *network,
- const char *physdev);
+ const char *physdev,
+ const char *protocol);
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
const char *network,
- const char *physdev);
+ const char *physdev,
+ const char *protocol);
#endif /* __QEMUD_IPTABLES_H__ */
--
1.6.6.1
+2043 -1123
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1 +1 @@
14164638fe0e7f65e425acc85dabc517 libvirt-0.8.2.tar.gz
SHA512 (libvirt-3.2.1.tar.xz) = 4ec4faceedcad3a5419e91444b0c83adcbed0ff6482fb53c058a75412064de69e09fd096de4a30b8c1149da6ba03287b10e8af925b01d725e655658035e43d9a