[libvirt] [PATCH 0/1] Rewrite virt-host-validate in Go & Go packaging complication
by Daniel P. Berrangé
This series contains code I mostly wrote some 6 months ago
as an experiment. I've tidied it up and attempted to integrate
it into the libvirt build system.
Overall I much prefer the new impl of virt-host-validate, as
explained in the commit message, I've wanted todo it this way
for a long time, but was put off by C's XML handling verbosity.
The main problem I've hit in integrating this work is the RPM
build process integration.
When building interactively, Go will dynamically download the
3rd party deps from git, similar to how we dynamically pull
down gnulib. The difference is that this must happen for end
users using tarballs too, not just devs usingn git.
We could bundle the deps with our tarball the same way we do
with gnulib, but Fedora would not accept using this, as it
wants unbundled Go deps.
I've done some things in the spec which makes this work
against unbundled sources, but this still fails in mock as
we don't get the build-id set in the resulting binary. I
have attempted to fix that by passing extra flags to go
build, but it still fails, so I've got some bug there. The
resulting spec rules are very very very unpleasant, having
to hardcode a bunch of build flags we should never touch.
I've spoken with Nichlos Mailhot who is the Fedora Go
packaging expert, who has basically confirmed my experiance
that there is no nice solution to what I'm trying todo with
the build process. He strongly recommends that we do *not*
try to integrate Go into our existing build process, and that
we instead keep any Go code as a completely seperate git repo
that we build & install separately. This would make the
RPM packaging much much simpler to deal with.
Given what I've tried here, I'm inclined to agree with his
recommendation.
In the case of virt-host-validate, this is actually quite
a straightforward thing to deal with, as the new impl of
virt-host-validate has no direct dep wrt existing lkibvirt
code in either direction. So we can trivially put it in a
separate git repo. We would merely need an RPM dep from
libvirt.spec.in to make the sure the external project
gets pulled in on install of libvirt-daemon.
Thus this patch is *NOT* something I'm proposing to merge
as is. The code itself is fine, but it will need to go into
a new git repo of its own.
Daniel P. Berrangé (1):
tools: rewrite virt-host-validate in Go to be data driven
configure.ac | 1 +
libvirt.spec.in | 23 +
m4/virt-golang.m4 | 46 ++
m4/virt-host-validate.m4 | 8 +-
po/POTFILES | 5 -
tools/Makefile.am | 59 +-
tools/host-validate/go.mod | 8 +
tools/host-validate/go.sum | 4 +
tools/host-validate/main.go | 98 +++
tools/host-validate/pkg/engine.go | 469 +++++++++++
tools/host-validate/pkg/facts.go | 784 +++++++++++++++++++
tools/host-validate/pkg/facts_test.go | 67 ++
tools/host-validate/pkg/xml_utils.go | 287 +++++++
tools/host-validate/rules/acpi.xml | 29 +
tools/host-validate/rules/builtin.xml | 33 +
tools/host-validate/rules/cgroups.xml | 403 ++++++++++
tools/host-validate/rules/cpu.xml | 148 ++++
tools/host-validate/rules/devices.xml | 54 ++
tools/host-validate/rules/freebsd-kernel.xml | 14 +
tools/host-validate/rules/iommu.xml | 93 +++
tools/host-validate/rules/namespaces.xml | 94 +++
tools/host-validate/rules/pci.xml | 9 +
tools/virt-host-validate-bhyve.c | 77 --
tools/virt-host-validate-bhyve.h | 24 -
tools/virt-host-validate-common.c | 419 ----------
tools/virt-host-validate-common.h | 85 --
tools/virt-host-validate-lxc.c | 87 --
tools/virt-host-validate-lxc.h | 24 -
tools/virt-host-validate-qemu.c | 116 ---
tools/virt-host-validate-qemu.h | 24 -
tools/virt-host-validate.c | 152 ----
tools/virt-host-validate.pod | 12 +-
32 files changed, 2693 insertions(+), 1063 deletions(-)
create mode 100644 m4/virt-golang.m4
create mode 100644 tools/host-validate/go.mod
create mode 100644 tools/host-validate/go.sum
create mode 100644 tools/host-validate/main.go
create mode 100644 tools/host-validate/pkg/engine.go
create mode 100644 tools/host-validate/pkg/facts.go
create mode 100644 tools/host-validate/pkg/facts_test.go
create mode 100644 tools/host-validate/pkg/xml_utils.go
create mode 100644 tools/host-validate/rules/acpi.xml
create mode 100644 tools/host-validate/rules/builtin.xml
create mode 100644 tools/host-validate/rules/cgroups.xml
create mode 100644 tools/host-validate/rules/cpu.xml
create mode 100644 tools/host-validate/rules/devices.xml
create mode 100644 tools/host-validate/rules/freebsd-kernel.xml
create mode 100644 tools/host-validate/rules/iommu.xml
create mode 100644 tools/host-validate/rules/namespaces.xml
create mode 100644 tools/host-validate/rules/pci.xml
delete mode 100644 tools/virt-host-validate-bhyve.c
delete mode 100644 tools/virt-host-validate-bhyve.h
delete mode 100644 tools/virt-host-validate-common.c
delete mode 100644 tools/virt-host-validate-common.h
delete mode 100644 tools/virt-host-validate-lxc.c
delete mode 100644 tools/virt-host-validate-lxc.h
delete mode 100644 tools/virt-host-validate-qemu.c
delete mode 100644 tools/virt-host-validate-qemu.h
delete mode 100644 tools/virt-host-validate.c
--
2.21.0
5 years, 2 months
[libvirt] [dockerfiles PATCH 0/2] Update libosinfo (& friends) dockerfiles
by Fabiano Fidêncio
As osinfo-db-tools has recently switched to using meson instead of
autotools, let's update the libosinfo-dockerfiles accordingly.
https://gitlab.com/fidencio/libvirt-dockerfiles/tree/wip/osinfo_db_tools_...
Fabiano Fidêncio (2):
refresh: Remove Dockerfiles from OSes not supported by osinfo-db-tools
refresh: Update Dockerfiles due to new osinfo-db-tools build system
buildenv-libosinfo-centos-7.zip | Bin 458 -> 0 bytes
buildenv-libosinfo-debian-10-cross-aarch64.zip | Bin 683 -> 688 bytes
buildenv-libosinfo-debian-10-cross-armv6l.zip | Bin 682 -> 687 bytes
buildenv-libosinfo-debian-10-cross-armv7l.zip | Bin 686 -> 690 bytes
buildenv-libosinfo-debian-10-cross-i686.zip | Bin 682 -> 688 bytes
buildenv-libosinfo-debian-10-cross-mips.zip | Bin 678 -> 683 bytes
buildenv-libosinfo-debian-10-cross-mips64el.zip | Bin 689 -> 694 bytes
buildenv-libosinfo-debian-10-cross-mipsel.zip | Bin 681 -> 685 bytes
buildenv-libosinfo-debian-10-cross-ppc64le.zip | Bin 687 -> 692 bytes
buildenv-libosinfo-debian-10-cross-s390x.zip | Bin 680 -> 686 bytes
buildenv-libosinfo-debian-10.zip | Bin 555 -> 559 bytes
buildenv-libosinfo-debian-9-cross-aarch64.zip | Bin 682 -> 0 bytes
buildenv-libosinfo-debian-9-cross-armv6l.zip | Bin 681 -> 0 bytes
buildenv-libosinfo-debian-9-cross-armv7l.zip | Bin 685 -> 0 bytes
buildenv-libosinfo-debian-9-cross-mips.zip | Bin 678 -> 0 bytes
buildenv-libosinfo-debian-9-cross-mips64el.zip | Bin 689 -> 0 bytes
buildenv-libosinfo-debian-9-cross-mipsel.zip | Bin 680 -> 0 bytes
buildenv-libosinfo-debian-9-cross-ppc64le.zip | Bin 687 -> 0 bytes
buildenv-libosinfo-debian-9-cross-s390x.zip | Bin 680 -> 0 bytes
buildenv-libosinfo-debian-9.zip | Bin 554 -> 0 bytes
buildenv-libosinfo-debian-sid-cross-aarch64.zip | Bin 683 -> 688 bytes
buildenv-libosinfo-debian-sid-cross-armv6l.zip | Bin 682 -> 687 bytes
buildenv-libosinfo-debian-sid-cross-armv7l.zip | Bin 686 -> 691 bytes
buildenv-libosinfo-debian-sid-cross-i686.zip | Bin 683 -> 689 bytes
buildenv-libosinfo-debian-sid-cross-mips.zip | Bin 678 -> 683 bytes
...denv-libosinfo-debian-sid-cross-mips64el.zip | Bin 689 -> 694 bytes
buildenv-libosinfo-debian-sid-cross-mipsel.zip | Bin 681 -> 685 bytes
buildenv-libosinfo-debian-sid-cross-ppc64le.zip | Bin 687 -> 692 bytes
buildenv-libosinfo-debian-sid-cross-s390x.zip | Bin 680 -> 686 bytes
buildenv-libosinfo-debian-sid.zip | Bin 555 -> 559 bytes
buildenv-libosinfo-fedora-29.zip | Bin 488 -> 492 bytes
buildenv-libosinfo-fedora-30.zip | Bin 551 -> 555 bytes
buildenv-libosinfo-fedora-rawhide.zip | Bin 507 -> 512 bytes
buildenv-libosinfo-ubuntu-16.zip | Bin 558 -> 0 bytes
buildenv-libosinfo-ubuntu-18.zip | Bin 558 -> 0 bytes
35 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 buildenv-libosinfo-centos-7.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-aarch64.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-armv6l.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-armv7l.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-mips.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-mips64el.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-mipsel.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-ppc64le.zip
delete mode 100644 buildenv-libosinfo-debian-9-cross-s390x.zip
delete mode 100644 buildenv-libosinfo-debian-9.zip
delete mode 100644 buildenv-libosinfo-ubuntu-16.zip
delete mode 100644 buildenv-libosinfo-ubuntu-18.zip
--
2.21.0
5 years, 2 months
[libvirt] [jenkins-ci PATCH] osinfo-db-tools: Don't try to build RPMs on CentOS 7
by Andrea Bolognani
It no longer is a supported target platform.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
guests/playbooks/build/projects/osinfo-db-tools.yml | 5 ++++-
jenkins/projects/osinfo-db-tools.yaml | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/guests/playbooks/build/projects/osinfo-db-tools.yml b/guests/playbooks/build/projects/osinfo-db-tools.yml
index 4bb6236..d142e0e 100644
--- a/guests/playbooks/build/projects/osinfo-db-tools.yml
+++ b/guests/playbooks/build/projects/osinfo-db-tools.yml
@@ -21,4 +21,7 @@
- include: '{{ playbook_base }}/jobs/meson-check-job.yml'
- include: '{{ playbook_base }}/jobs/meson-rpm-job.yml'
vars:
- machines: '{{ rpm_machines }}'
+ machines:
+ - libvirt-fedora-29
+ - libvirt-fedora-30
+ - libvirt-fedora-rawhide
diff --git a/jenkins/projects/osinfo-db-tools.yaml b/jenkins/projects/osinfo-db-tools.yaml
index 15a95d3..2a9ea11 100644
--- a/jenkins/projects/osinfo-db-tools.yaml
+++ b/jenkins/projects/osinfo-db-tools.yaml
@@ -22,4 +22,7 @@
parent_jobs: 'osinfo-db-tools-syntax-check'
- meson-rpm-job:
parent_jobs: 'osinfo-db-tools-check'
- machines: '{rpm_machines}'
+ machines:
+ - libvirt-fedora-29
+ - libvirt-fedora-30
+ - libvirt-fedora-rawhide
--
2.21.0
5 years, 2 months
[libvirt] [PATCH 0/2] Remove xenapi driver
by Jim Fehlig
Remove the xenapi driver is unmaintained and has no known user base.
We are stuck with references in include/libvirt/virterror.h and
src/util/virerror.c but otherwise I think I've nuked xenapi everywhere.
Jim Fehlig (2):
xenapi: remove driver
news: Mention removal of xenapi driver
cfg.mk | 4 +-
configure.ac | 4 -
docs/aclpolkit.html.in | 4 -
docs/auth.html.in | 2 -
docs/news.xml | 10 +
libvirt.spec.in | 4 +-
m4/virt-driver-xenapi.m4 | 48 -
po/POTFILES | 2 -
src/Makefile.am | 1 -
src/README | 1 -
src/libvirt.c | 10 -
src/util/virrandom.c | 3 +-
src/xenapi/Makefile.inc.am | 29 -
src/xenapi/xenapi_driver.c | 2125 ----------------------------
src/xenapi/xenapi_driver.h | 22 -
src/xenapi/xenapi_driver_private.h | 58 -
src/xenapi/xenapi_utils.c | 562 --------
src/xenapi/xenapi_utils.h | 76 -
tools/virsh.c | 3 -
19 files changed, 13 insertions(+), 2955 deletions(-)
delete mode 100644 m4/virt-driver-xenapi.m4
delete mode 100644 src/xenapi/Makefile.inc.am
delete mode 100644 src/xenapi/xenapi_driver.c
delete mode 100644 src/xenapi/xenapi_driver.h
delete mode 100644 src/xenapi/xenapi_driver_private.h
delete mode 100644 src/xenapi/xenapi_utils.c
delete mode 100644 src/xenapi/xenapi_utils.h
--
2.22.0
5 years, 2 months
[libvirt] [PATCH] docs: rewrite hvsupport.html page generator in python
by Daniel P. Berrangé
As part of an goal to eliminate Perl from libvirt build tools,
rewrite the hvsupport.pl tool in Python.
This was a straight conversion, manually going line-by-line to
change the syntax from Perl to Python. Thus the overall structure
of the file and approach is the same.
The new impl generates byte-for-byte identical output to the
old impl.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
docs/Makefile.am | 6 +-
docs/hvsupport.pl | 458 ---------------------------------------------
docs/hvsupport.py | 463 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 466 insertions(+), 461 deletions(-)
delete mode 100755 docs/hvsupport.pl
create mode 100755 docs/hvsupport.py
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 1cdb584b0b..f7aba5499d 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -194,7 +194,7 @@ EXTRA_DIST= \
$(internals_html_in) $(internals_html) $(fonts) \
$(kbase_html_in) $(kbase_html) \
aclperms.htmlinc \
- hvsupport.pl \
+ hvsupport.py \
$(schema_DATA)
acl_generated = aclperms.htmlinc
@@ -230,11 +230,11 @@ web: $(dot_html) $(internals_html) $(kbase_html) \
hvsupport.html: $(srcdir)/hvsupport.html.in
-$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl $(api_DATA) \
+$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.py $(api_DATA) \
$(top_srcdir)/src/libvirt_public.syms \
$(top_srcdir)/src/libvirt_qemu.syms $(top_srcdir)/src/libvirt_lxc.syms \
$(top_srcdir)/src/driver.h
- $(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(top_srcdir)/src > $@ \
+ $(AM_V_GEN)$(PYTHON) $(srcdir)/hvsupport.py $(top_srcdir)/src > $@ \
|| { rm $@ && exit 1; }
news.html.in: \
diff --git a/docs/hvsupport.pl b/docs/hvsupport.pl
deleted file mode 100755
index 494b8a27ec..0000000000
--- a/docs/hvsupport.pl
+++ /dev/null
@@ -1,458 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use File::Find;
-
-die "syntax: $0 SRCDIR\n" unless int(@ARGV) == 1;
-
-my $srcdir = shift @ARGV;
-
-my $symslibvirt = "$srcdir/libvirt_public.syms";
-my $symsqemu = "$srcdir/libvirt_qemu.syms";
-my $symslxc = "$srcdir/libvirt_lxc.syms";
-my @drivertable = (
- "$srcdir/driver-hypervisor.h",
- "$srcdir/driver-interface.h",
- "$srcdir/driver-network.h",
- "$srcdir/driver-nodedev.h",
- "$srcdir/driver-nwfilter.h",
- "$srcdir/driver-secret.h",
- "$srcdir/driver-state.h",
- "$srcdir/driver-storage.h",
- "$srcdir/driver-stream.h",
- );
-
-my %groupheaders = (
- "virHypervisorDriver" => "Hypervisor APIs",
- "virNetworkDriver" => "Virtual Network APIs",
- "virInterfaceDriver" => "Host Interface APIs",
- "virNodeDeviceDriver" => "Host Device APIs",
- "virStorageDriver" => "Storage Pool APIs",
- "virSecretDriver" => "Secret APIs",
- "virNWFilterDriver" => "Network Filter APIs",
- );
-
-
-my @srcs;
-find({
- wanted => sub {
- if (m!$srcdir/.*/\w+_(driver|common|tmpl|monitor|hal|udev)\.c$!) {
- push @srcs, $_ if $_ !~ /vbox_driver\.c/;
- }
- }, no_chdir => 1}, $srcdir);
-
-# Map API functions to the header and documentation files they're in
-# so that we can generate proper hyperlinks to their documentation.
-#
-# The function names are grep'd from the XML output of apibuild.py.
-sub getAPIFilenames {
- my $filename = shift;
-
- my %files;
- my $line;
-
- open FILE, "<", $filename or die "cannot read $filename: $!";
-
- while (defined($line = <FILE>)) {
- if ($line =~ /function name='([^']+)' file='([^']+)'/) {
- $files{$1} = $2;
- }
- }
-
- close FILE;
-
- if (keys %files == 0) {
- die "No functions found in $filename. Has the apibuild.py output changed?";
- }
- return \%files;
-}
-
-sub parseSymsFile {
- my $apisref = shift;
- my $prefix = shift;
- my $filename = shift;
- my $xmlfilename = shift;
-
- my $line;
- my $vers;
- my $prevvers;
-
- my $filenames = getAPIFilenames($xmlfilename);
-
- open FILE, "<$filename"
- or die "cannot read $filename: $!";
-
- while (defined($line = <FILE>)) {
- chomp $line;
- next if $line =~ /^\s*#/;
- next if $line =~ /^\s*$/;
- next if $line =~ /^\s*(global|local):/;
- if ($line =~ /^\s*${prefix}_(\d+\.\d+\.\d+)\s*{\s*$/) {
- if (defined $vers) {
- die "malformed syms file";
- }
- $vers = $1;
- } elsif ($line =~ /\s*}\s*;\s*$/) {
- if (defined $prevvers) {
- die "malformed syms file";
- }
- $prevvers = $vers;
- $vers = undef;
- } elsif ($line =~ /\s*}\s*${prefix}_(\d+\.\d+\.\d+)\s*;\s*$/) {
- if ($1 ne $prevvers) {
- die "malformed syms file $1 != $vers";
- }
- $prevvers = $vers;
- $vers = undef;
- } elsif ($line =~ /\s*(\w+)\s*;\s*$/) {
- $$apisref{$1} = {};
- $$apisref{$1}->{vers} = $vers;
- $$apisref{$1}->{file} = $$filenames{$1};
- } else {
- die "unexpected data $line\n";
- }
- }
-
- close FILE;
-}
-
-my %apis;
-# Get the list of all public APIs and their corresponding version
-parseSymsFile(\%apis, "LIBVIRT", $symslibvirt, "$srcdir/../docs/libvirt-api.xml");
-
-# And the same for the QEMU specific APIs
-parseSymsFile(\%apis, "LIBVIRT_QEMU", $symsqemu, "$srcdir/../docs/libvirt-qemu-api.xml");
-
-# And the same for the LXC specific APIs
-parseSymsFile(\%apis, "LIBVIRT_LXC", $symslxc, "$srcdir/../docs/libvirt-lxc-api.xml");
-
-
-# Some special things which aren't public APIs,
-# but we want to report
-$apis{virConnectSupportsFeature}->{vers} = "0.3.2";
-$apis{virDomainMigratePrepare}->{vers} = "0.3.2";
-$apis{virDomainMigratePerform}->{vers} = "0.3.2";
-$apis{virDomainMigrateFinish}->{vers} = "0.3.2";
-$apis{virDomainMigratePrepare2}->{vers} = "0.5.0";
-$apis{virDomainMigrateFinish2}->{vers} = "0.5.0";
-$apis{virDomainMigratePrepareTunnel}->{vers} = "0.7.2";
-
-$apis{virDomainMigrateBegin3}->{vers} = "0.9.2";
-$apis{virDomainMigratePrepare3}->{vers} = "0.9.2";
-$apis{virDomainMigratePrepareTunnel3}->{vers} = "0.9.2";
-$apis{virDomainMigratePerform3}->{vers} = "0.9.2";
-$apis{virDomainMigrateFinish3}->{vers} = "0.9.2";
-$apis{virDomainMigrateConfirm3}->{vers} = "0.9.2";
-
-$apis{virDomainMigrateBegin3Params}->{vers} = "1.1.0";
-$apis{virDomainMigratePrepare3Params}->{vers} = "1.1.0";
-$apis{virDomainMigratePrepareTunnel3Params}->{vers} = "1.1.0";
-$apis{virDomainMigratePerform3Params}->{vers} = "1.1.0";
-$apis{virDomainMigrateFinish3Params}->{vers} = "1.1.0";
-$apis{virDomainMigrateConfirm3Params}->{vers} = "1.1.0";
-
-
-
-# Now we want to get the mapping between public APIs
-# and driver struct fields. This lets us later match
-# update the driver impls with the public APis.
-
-my $line;
-
-# Group name -> hash of APIs { fields -> api name }
-my %groups;
-my $ingrp;
-foreach my $drivertable (@drivertable) {
- open FILE, "<$drivertable"
- or die "cannot read $drivertable: $!";
-
- while (defined($line = <FILE>)) {
- if ($line =~ /struct _(vir\w*Driver)/) {
- my $grp = $1;
- if ($grp ne "virStateDriver" &&
- $grp ne "virStreamDriver") {
- $ingrp = $grp;
- $groups{$ingrp} = { apis => {}, drivers => {} };
- }
- } elsif ($ingrp) {
- if ($line =~ /^\s*vir(?:Drv)(\w+)\s+(\w+);\s*$/) {
- my $field = $2;
- my $name = $1;
-
- my $api;
- if (exists $apis{"vir$name"}) {
- $api = "vir$name";
- } elsif ($name =~ /\w+(Open|Close|URIProbe)/) {
- next;
- } else {
- die "driver $name does not have a public API";
- }
- $groups{$ingrp}->{apis}->{$field} = $api;
- } elsif ($line =~ /};/) {
- $ingrp = undef;
- }
- }
- }
-
- close FILE;
-}
-
-
-# Finally, we read all the primary driver files and extract
-# the driver API tables from each one.
-
-foreach my $src (@srcs) {
- open FILE, "<$src" or
- die "cannot read $src: $!";
-
- my $groups_regex = join("|", keys %groups);
- $ingrp = undef;
- my $impl;
- while (defined($line = <FILE>)) {
- if (!$ingrp) {
- # skip non-matching lines early to save time
- next if not $line =~ /$groups_regex/;
-
- if ($line =~ /^\s*(?:static\s+)?($groups_regex)\s+(\w+)\s*=\s*{/ ||
- $line =~ /^\s*(?:static\s+)?($groups_regex)\s+NAME\(\w+\)\s*=\s*{/) {
- $ingrp = $1;
- $impl = $src;
-
- if ($impl =~ m,.*/node_device_(\w+)\.c,) {
- $impl = $1;
- } else {
- $impl =~ s,.*/(\w+?)_((\w+)_)?(\w+)\.c,$1,;
- }
-
- if ($groups{$ingrp}->{drivers}->{$impl}) {
- die "Group $ingrp already contains $impl";
- }
-
- $groups{$ingrp}->{drivers}->{$impl} = {};
- }
-
- } else {
- if ($line =~ m!\s*\.(\w+)\s*=\s*(\w+)\s*,?\s*(?:/\*\s*(\d+\.\d+\.\d+)\s*(?:-\s*(\d+\.\d+\.\d+))?\s*\*/\s*)?$!) {
- my $api = $1;
- my $meth = $2;
- my $vers = $3;
- my $deleted = $4;
-
- next if $api eq "no" || $api eq "name";
-
- if ($meth eq "NULL" && !defined $deleted) {
- die "Method impl for $api is NULL, but no deleted version is provided";
- }
- if ($meth ne "NULL" && defined $deleted) {
- die "Method impl for $api is non-NULL, but deleted version is provided";
- }
-
- die "Method $meth in $src is missing version" unless defined $vers || $api eq "connectURIProbe";
-
- if (!exists($groups{$ingrp}->{apis}->{$api})) {
- next if $api =~ /\w(Open|Close|URIProbe)/;
-
- die "Found unexpected method $api in $ingrp\n";
- }
-
- $groups{$ingrp}->{drivers}->{$impl}->{$api} = {};
- $groups{$ingrp}->{drivers}->{$impl}->{$api}->{vers} = $vers;
- $groups{$ingrp}->{drivers}->{$impl}->{$api}->{deleted} = $deleted;
- if ($api eq "domainMigratePrepare" ||
- $api eq "domainMigratePrepare2" ||
- $api eq "domainMigratePrepare3") {
- if (!$groups{$ingrp}->{drivers}->{$impl}->{"domainMigrate"}) {
- $groups{$ingrp}->{drivers}->{$impl}->{"domainMigrate"} = {};
- $groups{$ingrp}->{drivers}->{$impl}->{"domainMigrate"}->{vers} = $vers;
- }
- }
-
- } elsif ($line =~ /}/) {
- $ingrp = undef;
- }
- }
- }
-
- close FILE;
-}
-
-
-# The '.open' driver method is used for 3 public APIs, so we
-# have a bit of manual fixup todo with the per-driver versioning
-# and support matrix
-
-$groups{virHypervisorDriver}->{apis}->{"openAuth"} = "virConnectOpenAuth";
-$groups{virHypervisorDriver}->{apis}->{"openReadOnly"} = "virConnectOpenReadOnly";
-$groups{virHypervisorDriver}->{apis}->{"domainMigrate"} = "virDomainMigrate";
-
-my $openAuthVers = (0 * 1000 * 1000) + (4 * 1000) + 0;
-
-foreach my $drv (keys %{$groups{"virHypervisorDriver"}->{drivers}}) {
- my $openVersStr = $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpen"}->{vers};
- my $openVers;
- if ($openVersStr =~ /(\d+)\.(\d+)\.(\d+)/) {
- $openVers = ($1 * 1000 * 1000) + ($2 * 1000) + $3;
- }
-
- # virConnectOpenReadOnly always matches virConnectOpen version
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpenReadOnly"} =
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpen"};
-
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpenAuth"} = {};
-
- # virConnectOpenAuth is always 0.4.0 if the driver existed
- # before this time, otherwise it matches the version of
- # the driver's virConnectOpen entry
- if ($openVersStr eq "Y" ||
- $openVers >= $openAuthVers) {
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpenAuth"}->{vers} = $openVersStr;
- } else {
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"connectOpenAuth"}->{vers} = "0.4.0";
- }
-}
-
-
-# Another special case for the virDomainCreateLinux which was replaced
-# with virDomainCreateXML
-$groups{virHypervisorDriver}->{apis}->{"domainCreateLinux"} = "virDomainCreateLinux";
-
-my $createAPIVers = (0 * 1000 * 1000) + (0 * 1000) + 3;
-
-foreach my $drv (keys %{$groups{"virHypervisorDriver"}->{drivers}}) {
- my $createVersStr = $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"domainCreateXML"}->{vers};
- next unless defined $createVersStr;
- my $createVers;
- if ($createVersStr =~ /(\d+)\.(\d+)\.(\d+)/) {
- $createVers = ($1 * 1000 * 1000) + ($2 * 1000) + $3;
- }
-
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"domainCreateLinux"} = {};
-
- # virCreateLinux is always 0.0.3 if the driver existed
- # before this time, otherwise it matches the version of
- # the driver's virCreateXML entry
- if ($createVersStr eq "Y" ||
- $createVers >= $createAPIVers) {
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"domainCreateLinux"}->{vers} = $createVersStr;
- } else {
- $groups{"virHypervisorDriver"}->{drivers}->{$drv}->{"domainCreateLinux"}->{vers} = "0.0.3";
- }
-}
-
-
-# Finally we generate the HTML file with the tables
-
-print <<EOF;
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
-<body class="hvsupport">
-<h1>libvirt API support matrix</h1>
-
-<ul id="toc"></ul>
-
-<p>
-This page documents which <a href="html/">libvirt calls</a> work on
-which libvirt drivers / hypervisors, and which version the API appeared
-in. If a hypervisor driver later dropped support for the API, the version
-when it was removed is also mentioned (highlighted in
-<span class="removedhv">dark red</span>).
-</p>
-
-EOF
-
- foreach my $grp (sort { $a cmp $b } keys %groups) {
- print "<h2><a id=\"$grp\">", $groupheaders{$grp}, "</a></h2>\n";
- print <<EOF;
-<table class="top_table">
-<thead>
-<tr>
-<th>API</th>
-<th>Version</th>
-EOF
-
- foreach my $drv (sort { $a cmp $b } keys %{$groups{$grp}->{drivers}}) {
- print " <th>$drv</th>\n";
- }
-
- print <<EOF;
-</tr>
-</thead>
-<tbody>
-EOF
-
- my $row = 0;
- foreach my $field (sort {
- $groups{$grp}->{apis}->{$a}
- cmp
- $groups{$grp}->{apis}->{$b}
- } keys %{$groups{$grp}->{apis}}) {
- my $api = $groups{$grp}->{apis}->{$field};
- my $vers = $apis{$api}->{vers};
- my $htmlgrp = $apis{$api}->{file};
- print <<EOF;
-<tr>
-<td>
-EOF
-
- if (defined $htmlgrp) {
- print <<EOF;
-<a href=\"html/libvirt-$htmlgrp.html#$api\">$api</a>
-EOF
-
- } else {
- print $api;
- }
- print <<EOF;
-</td>
-<td>$vers</td>
-EOF
-
- foreach my $drv (sort {$a cmp $b } keys %{$groups{$grp}->{drivers}}) {
- print "<td>";
- if (exists $groups{$grp}->{drivers}->{$drv}->{$field}) {
- if ($groups{$grp}->{drivers}->{$drv}->{$field}->{vers}) {
- print $groups{$grp}->{drivers}->{$drv}->{$field}->{vers};
- }
- if ($groups{$grp}->{drivers}->{$drv}->{$field}->{deleted}) {
- print " - <span class=\"removedhv\">", $groups{$grp}->{drivers}->{$drv}->{$field}->{deleted}, "</span>";
- }
- }
- print "</td>\n";
- }
-
- print <<EOF;
-</tr>
-EOF
-
- $row++;
- if (($row % 15) == 0) {
- print <<EOF;
-<tr>
-<th>API</th>
-<th>Version</th>
-EOF
-
- foreach my $drv (sort { $a cmp $b } keys %{$groups{$grp}->{drivers}}) {
- print " <th>$drv</th>\n";
- }
-
- print <<EOF;
-</tr>
-EOF
- }
-
- }
-
- print <<EOF;
-</tbody>
-</table>
-EOF
-}
-
-print <<EOF;
-</body>
-</html>
-EOF
diff --git a/docs/hvsupport.py b/docs/hvsupport.py
new file mode 100755
index 0000000000..502389c25f
--- /dev/null
+++ b/docs/hvsupport.py
@@ -0,0 +1,463 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+
+import sys
+import os.path
+import re
+
+if len(sys.argv) != 2:
+ print("syntax: %s SRCDIR\n" % sys.argv[0], fh=sys.stderr)
+
+srcdir = sys.argv[1]
+
+symslibvirt = os.path.join(srcdir, "libvirt_public.syms")
+symsqemu = os.path.join(srcdir, "libvirt_qemu.syms")
+symslxc = os.path.join(srcdir, "libvirt_lxc.syms")
+drivertablefiles = [
+ os.path.join(srcdir, "driver-hypervisor.h"),
+ os.path.join(srcdir, "driver-interface.h"),
+ os.path.join(srcdir, "driver-network.h"),
+ os.path.join(srcdir, "driver-nodedev.h"),
+ os.path.join(srcdir, "driver-nwfilter.h"),
+ os.path.join(srcdir, "driver-secret.h"),
+ os.path.join(srcdir, "driver-state.h"),
+ os.path.join(srcdir, "driver-storage.h"),
+ os.path.join(srcdir, "driver-stream.h"),
+]
+
+groupheaders = {
+ "virHypervisorDriver": "Hypervisor APIs",
+ "virNetworkDriver": "Virtual Network APIs",
+ "virInterfaceDriver": "Host Interface APIs",
+ "virNodeDeviceDriver": "Host Device APIs",
+ "virStorageDriver": "Storage Pool APIs",
+ "virSecretDriver": "Secret APIs",
+ "virNWFilterDriver": "Network Filter APIs",
+}
+
+
+srcs = []
+for root, dirs, files in os.walk(srcdir):
+ for file in files:
+ if ((file.endswith("driver.c") and
+ not file.endswith("vbox_driver.c")) or
+ file.endswith("common.c") or
+ file.endswith("tmpl.c") or
+ file.endswith("monitor.c") or
+ file.endswith("hal.c") or
+ file.endswith("udev.c")):
+ srcs.append(os.path.join(root, file))
+
+
+# Map API functions to the header and documentation files they're in
+# so that we can generate proper hyperlinks to their documentation.
+#
+# The function names are grep'd from the XML output of apibuild.py.
+def getAPIFilenames(filename):
+ files = {}
+
+ with open(filename) as fh:
+ prog = re.compile(r"\s*<function name='([^']+)' file='([^']+)'.*")
+ for line in fh:
+ res = prog.match(line)
+ if res is not None:
+ files[res.group(1)] = res.group(2)
+
+ if len(files) == 0:
+ raise Exception("No functions found in %s. Has the apibuild.py output changed?" % filename)
+
+ return files;
+
+
+def parseSymsFile(apisref, prefix, filename, xmlfilename):
+ vers = None
+ prevvers = None
+
+ filenames = getAPIFilenames(xmlfilename)
+
+ with open(filename) as fh:
+ groupstartprog = re.compile(r"^\s*%s_(\d+\.\d+\.\d+)\s*{\s*$" % prefix)
+ groupendprog1 = re.compile(r"^\s*}\s*;\s*$")
+ groupendprog2 = re.compile(r"^\s*}\s*%s_(\d+\.\d+\.\d+)\s*;\s*$" % prefix)
+ symbolprog = re.compile(r"^\s*(\w+)\s*;\s*$")
+ for line in fh:
+ line = line.strip()
+
+ if line == "":
+ continue
+ if line[0] == '#':
+ continue
+ if line.startswith("global:"):
+ continue
+ if line.startswith("local:"):
+ continue
+
+ groupstartmatch = groupstartprog.match(line)
+ groupendmatch1 = groupendprog1.match(line)
+ groupendmatch2 = groupendprog2.match(line)
+ symbolmatch = symbolprog.match(line)
+ if groupstartmatch is not None:
+ if vers is not None:
+ raise Exception("malformed syms file when starting group")
+
+ vers = groupstartmatch.group(1)
+ elif groupendmatch1 is not None:
+ if prevvers is not None:
+ raise Exception("malformed syms file when ending group")
+
+ prevvers = vers
+ vers = None
+ elif groupendmatch2 is not None:
+ if groupendmatch2.group(1) != prevvers:
+ raise Exception("malformed syms file %s != %s when ending group" % (
+ groupendmatch2.group(1), prevvers))
+
+ prevvers = vers
+ vers = None
+ elif symbolmatch is not None:
+ name = symbolmatch.group(1)
+ apisref[name] = {
+ "vers": vers,
+ "file": filenames.get(name),
+ }
+ else:
+ raise Exception("unexpected data %s" % line)
+
+
+apis = {}
+# Get the list of all public APIs and their corresponding version
+parseSymsFile(apis, "LIBVIRT", symslibvirt, os.path.join(srcdir, "../docs/libvirt-api.xml"))
+
+# And the same for the QEMU specific APIs
+parseSymsFile(apis, "LIBVIRT_QEMU", symsqemu, os.path.join(srcdir, "../docs/libvirt-qemu-api.xml"))
+
+# And the same for the LXC specific APIs
+parseSymsFile(apis, "LIBVIRT_LXC", symslxc, os.path.join(srcdir, "../docs/libvirt-lxc-api.xml"))
+
+
+# Some special things which aren't public APIs,
+# but we want to report
+apis["virConnectSupportsFeature"] = {
+ "vers": "0.3.2"
+}
+apis["virDomainMigratePrepare"] = {
+ "vers": "0.3.2"
+}
+apis["virDomainMigratePerform"] = {
+ "vers": "0.3.2"
+}
+apis["virDomainMigrateFinish"] = {
+ "vers": "0.3.2"
+}
+apis["virDomainMigratePrepare2"] = {
+ "vers": "0.5.0"
+}
+apis["virDomainMigrateFinish2"] = {
+ "vers": "0.5.0"
+}
+apis["virDomainMigratePrepareTunnel"] = {
+ "vers": "0.7.2"
+}
+
+apis["virDomainMigrateBegin3"] = {
+ "vers": "0.9.2"
+}
+apis["virDomainMigratePrepare3"] = {
+ "vers": "0.9.2"
+}
+apis["virDomainMigratePrepareTunnel3"] = {
+ "vers": "0.9.2"
+}
+apis["virDomainMigratePerform3"] = {
+ "vers": "0.9.2"
+}
+apis["virDomainMigrateFinish3"] = {
+ "vers": "0.9.2"
+}
+apis["virDomainMigrateConfirm3"] = {
+ "vers": "0.9.2"
+}
+
+apis["virDomainMigrateBegin3Params"] = {
+ "vers": "1.1.0"
+}
+apis["virDomainMigratePrepare3Params"] = {
+ "vers": "1.1.0"
+}
+apis["virDomainMigratePrepareTunnel3Params"] = {
+ "vers": "1.1.0"
+}
+apis["virDomainMigratePerform3Params"] = {
+ "vers": "1.1.0"
+}
+apis["virDomainMigrateFinish3Params"] = {
+ "vers": "1.1.0"
+}
+apis["virDomainMigrateConfirm3Params"] = {
+ "vers": "1.1.0"
+}
+
+
+# Now we want to get the mapping between public APIs
+# and driver struct fields. This lets us later match
+# update the driver impls with the public APis.
+
+# Group name -> hash of APIs { fields -> api name }
+groups = {}
+ingrp = None
+for drivertablefile in drivertablefiles:
+ with open(drivertablefile) as fh:
+ starttableprog = re.compile(r"struct _(vir\w*Driver)")
+ endtableprog = re.compile(r"};")
+ callbackprog = re.compile(r"^\s*vir(?:Drv)(\w+)\s+(\w+);\s*$")
+ ignoreapiprog = re.compile(r"\w+(Open|Close|URIProbe)")
+ for line in fh:
+ starttablematch = starttableprog.match(line)
+ if starttablematch is not None:
+ grp = starttablematch.group(1)
+ if grp != "virStateDriver" and grp != "virStreamDriver":
+ ingrp = grp
+ groups[ingrp] = {
+ "apis": {},
+ "drivers": {}
+ }
+ elif ingrp != None:
+ callbackmatch = callbackprog.match(line)
+ if callbackmatch is not None:
+ name = callbackmatch.group(1)
+ field = callbackmatch.group(2)
+
+ api = "vir" + name
+ if api in apis:
+ groups[ingrp]["apis"][field] = api
+ elif ignoreapiprog.match(api) != None:
+ continue
+ else:
+ raise Exception("driver %s does not have a public API" % name)
+ elif endtableprog.match(line):
+ ingrp = None
+
+
+# Finally, we read all the primary driver files and extract
+# the driver API tables from each one.
+
+for src in srcs:
+ with open(src) as fh:
+ groupsre = "|".join(groups.keys())
+ groupsprog2 = re.compile(r"^\s*(static\s+)?(" + groupsre + r")\s+(\w+)\s*=\s*{")
+ groupsprog3 = re.compile(r"^\s*(static\s+)?(" + groupsre + r")\s+NAME\(\w+\)\s*=\s*{")
+ nodedevimplprog = re.compile(r".*/node_device_(\w+)\.c")
+ miscimplprog = re.compile(r".*/(\w+?)_((\w+)_)?(\w+)\.c")
+ callbackprog = re.compile(r"\s*\.(\w+)\s*=\s*(\w+)\s*,?\s*(?:/\*\s*(\d+\.\d+\.\d+)\s*(?:-\s*(\d+\.\d+\.\d+))?\s*\*/\s*)?$")
+ skipapiprog = re.compile(r"\w+(Open|Close|URIProbe)")
+
+ ingrp = None
+ impl = None
+ for line in fh:
+ if ingrp is None:
+ m = groupsprog2.match(line)
+ if m is None:
+ m = groupsprog3.match(line)
+ if m is not None:
+ ingrp = m.group(2)
+ impl = src
+
+ implmatch = nodedevimplprog.match(impl)
+ if implmatch is None:
+ implmatch = miscimplprog.match(impl)
+ if implmatch is None:
+ raise Exception("Unexpected impl format '%s'" % impl)
+ impl = implmatch.group(1)
+
+ if impl in groups[ingrp]["drivers"]:
+ raise Exception("Group %s already contains %s" % (ingrp, impl))
+
+ groups[ingrp]["drivers"][impl] = {}
+ else:
+ callbackmatch = callbackprog.match(line)
+ if callbackmatch is not None:
+ api = callbackmatch.group(1)
+ meth = callbackmatch.group(2)
+ vers = callbackmatch.group(3)
+ deleted = callbackmatch.group(4)
+
+ if api == "no" or api == "name":
+ continue
+
+ if meth == "NULL" and deleted is None:
+ raise Exception("Method impl for %s is NULL, but no deleted version is provided" % api)
+
+ if meth != "NULL" and deleted is not None:
+ raise Exception("Method impl for %s is non-NULL, but deleted version is provided" % api)
+
+ if vers is None and api != "connectURIProbe":
+ raise Exception("Method %s in %s is missing version" % (meth, src))
+
+ if api not in groups[ingrp]["apis"]:
+ if skipapiprog.match(api):
+ continue
+
+ raise Exception("Found unexpected method %s in %s" % (api, ingrp))
+
+ groups[ingrp]["drivers"][impl][api] = {
+ "vers": vers,
+ "deleted": deleted,
+ }
+
+ if (api == "domainMigratePrepare" or
+ api == "domainMigratePrepare2" or
+ api == "domainMigratePrepare3"):
+ if "domainMigrate" not in groups[ingrp]["drivers"][impl]:
+ groups[ingrp]["drivers"][impl]["domainMigrate"] = {
+ "vers": vers,
+ }
+ elif line.find("}") != -1:
+ ingrp = None
+
+
+# The '.open' driver method is used for 3 public APIs, so we
+# have a bit of manual fixup todo with the per-driver versioning
+# and support matrix
+
+groups["virHypervisorDriver"]["apis"]["openAuth"] = "virConnectOpenAuth"
+groups["virHypervisorDriver"]["apis"]["openReadOnly"] = "virConnectOpenReadOnly"
+groups["virHypervisorDriver"]["apis"]["domainMigrate"] = "virDomainMigrate"
+
+openAuthVers = (0 * 1000 * 1000) + (4 * 1000) + 0;
+
+for drv in groups["virHypervisorDriver"]["drivers"].keys():
+ openVersStr = groups["virHypervisorDriver"]["drivers"][drv]["connectOpen"]["vers"]
+ openVers = 0
+ if openVersStr != "Y":
+ openVersBits = openVersStr.split(".")
+ if len(openVersBits) != 3:
+ raise Exception("Expected 3 digit version for %s" % openVersStr)
+ openVers = (int(openVersBits[0]) * 1000 * 1000) + (int(openVersBits[1]) * 1000) + int(openVersBits[2])
+
+ # virConnectOpenReadOnly always matches virConnectOpen version
+ groups["virHypervisorDriver"]["drivers"][drv]["connectOpenReadOnly"] = \
+ groups["virHypervisorDriver"]["drivers"][drv]["connectOpen"]
+
+ # virConnectOpenAuth is always 0.4.0 if the driver existed
+ # before this time, otherwise it matches the version of
+ # the driver's virConnectOpen entry
+ if openVersStr == "Y" or openVers >= openAuthVers:
+ vers = openVersStr
+ else:
+ vers = "0.4.0"
+ groups["virHypervisorDriver"]["drivers"][drv]["connectOpenAuth"] = {
+ "vers": vers,
+ }
+
+
+# Another special case for the virDomainCreateLinux which was replaced
+# with virDomainCreateXML
+groups["virHypervisorDriver"]["apis"]["domainCreateLinux"] = "virDomainCreateLinux";
+
+createAPIVers = (0 * 1000 * 1000) + (0 * 1000) + 3;
+
+for drv in groups["virHypervisorDriver"]["drivers"].keys():
+ if "domainCreateXML" not in groups["virHypervisorDriver"]["drivers"][drv]:
+ continue
+ createVersStr = groups["virHypervisorDriver"]["drivers"][drv]["domainCreateXML"]["vers"]
+ createVers = 0
+ if createVersStr != "Y":
+ createVersBits = createVersStr.split(".")
+ if len(createVersBits) != 3:
+ raise Exception("Expected 3 digit version for %s" % createVersStr)
+ createVers = (int(createVersBits[0]) * 1000 * 1000) + (int(createVersBits[1]) * 1000) + int(createVersBits[2])
+
+ # virCreateLinux is always 0.0.3 if the driver existed
+ # before this time, otherwise it matches the version of
+ # the driver's virCreateXML entry
+ if createVersStr == "Y" or createVers >= createAPIVers:
+ vers = createVersStr
+ else:
+ vers = "0.0.3"
+
+ groups["virHypervisorDriver"]["drivers"][drv]["domainCreateLinux"] = {
+ "vers": vers,
+ }
+
+
+# Finally we generate the HTML file with the tables
+
+print('''<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body class="hvsupport">
+<h1>libvirt API support matrix</h1>
+
+<ul id="toc"></ul>
+
+<p>
+This page documents which <a href="html/">libvirt calls</a> work on
+which libvirt drivers / hypervisors, and which version the API appeared
+in. If a hypervisor driver later dropped support for the API, the version
+when it was removed is also mentioned (highlighted in
+<span class="removedhv">dark red</span>).
+</p>
+''')
+
+for grp in sorted(groups.keys()):
+ print("<h2><a id=\"%s\">%s</a></h2>" % (grp, groupheaders[grp]))
+ print('''<table class="top_table">
+<thead>
+<tr>
+<th>API</th>
+<th>Version</th>''')
+
+ for drv in sorted(groups[grp]["drivers"].keys()):
+ print(" <th>%s</th>" % drv)
+
+
+ print('''</tr>
+</thead>
+<tbody>''')
+
+ row = 0
+ def sortkey(field):
+ return groups[grp]["apis"][field]
+ for field in sorted(groups[grp]["apis"].keys(), key=sortkey):
+ api = groups[grp]["apis"][field]
+ vers = apis[api]["vers"]
+ htmlgrp = apis[api].get("file")
+ print("<tr>")
+
+ if htmlgrp is not None:
+ print('''<td>\n<a href=\"html/libvirt-%s.html#%s\">%s</a>\n</td>''' % (htmlgrp, api, api))
+ else:
+ print("<td>\n%s</td>" % api)
+
+ print("<td>%s</td>" % vers)
+
+ for drv in sorted(groups[grp]["drivers"].keys()):
+ info = ""
+ if field in groups[grp]["drivers"][drv]:
+ vers = groups[grp]["drivers"][drv][field]["vers"]
+ if vers is not None:
+ info = info + vers
+
+ deleted = groups[grp]["drivers"][drv][field].get("deleted")
+ if deleted is not None:
+ info = info + (''' - <span class="removedhv">%s</span>''' % deleted)
+
+ print("<td>%s</td>" % info)
+
+ print("</tr>")
+
+ row = row + 1
+ if (row % 15) == 0:
+ print('''<tr>
+<th>API</th>
+<th>Version</th>''')
+
+ for drv in sorted(groups[grp]["drivers"].keys()):
+ print(" <th>%s</th>" % drv)
+
+ print("</tr>")
+
+ print("</tbody>\n</table>")
+
+print("</body>\n</html>")
--
2.21.0
5 years, 2 months
[libvirt] [PATCH for 5.7.0 0/2] virsh: Rename --precopy-bandwidth migration option
by Jiri Denemark
The (pre-copy) bandwidth was historically the only bandwidth we
supported and thus it is called just "bandwidth" in all other places.
E.g., virsh migrate-setspeed or in the migration typed parameter name.
Let's make the new option for virsh migrate consistent.
Jiri Denemark (2):
virsh: Rename --precopy-bandwidth migration option
news: Rename --precopy-bandwidth migration option
docs/news.xml | 4 ++--
tools/virsh-domain.c | 6 +++---
tools/virsh.pod | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
--
2.23.0
5 years, 2 months
[libvirt] [PATCH] xenconfig: move contents to libxl driver and remove directory
by Jim Fehlig
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
cfg.mk | 2 +-
configure.ac | 2 --
po/POTFILES | 6 ++---
src/Makefile.am | 1 -
src/libvirt_xenconfig.syms | 12 ----------
src/libxl/Makefile.inc.am | 25 ++++++---------------
src/{xenconfig => libxl}/xen_common.c | 0
src/{xenconfig => libxl}/xen_common.h | 0
src/{xenconfig => libxl}/xen_xl.c | 0
src/{xenconfig => libxl}/xen_xl.h | 0
src/{xenconfig => libxl}/xen_xm.c | 0
src/{xenconfig => libxl}/xen_xm.h | 0
src/{xenconfig => libxl}/xenxs_private.h | 0
src/xenconfig/Makefile.inc.am | 28 ------------------------
tests/xlconfigtest.c | 2 +-
tests/xmconfigtest.c | 2 +-
16 files changed, 13 insertions(+), 67 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index c459ad443f..1f29729949 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -791,7 +791,7 @@ sc_prohibit_cross_inclusion:
access/ | conf/) safe="($$dir|conf|util)";; \
cpu/| network/| node_device/| rpc/| security/| storage/) \
safe="($$dir|util|conf|storage)";; \
- xenapi/ | xenconfig/ ) safe="($$dir|util|conf|xen|cpu)";; \
+ xenapi/) safe="($$dir|util|conf|xen|cpu)";; \
*) safe="($$dir|$(mid_dirs)|util)";; \
esac; \
in_vc_files="^src/$$dir" \
diff --git a/configure.ac b/configure.ac
index a60543072d..890702a89d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -465,8 +465,6 @@ LIBVIRT_DRIVER_CHECK_LIBVIRTD
LIBVIRT_DRIVER_CHECK_NETWORK
LIBVIRT_DRIVER_CHECK_INTERFACE
-AM_CONDITIONAL([WITH_XENCONFIG], [test "$with_libxl" = "yes"])
-
dnl
dnl in case someone want to build static binaries
diff --git a/po/POTFILES b/po/POTFILES
index c62bc32bb2..e466e1bc55 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -88,6 +88,9 @@ src/libxl/libxl_conf.c
src/libxl/libxl_domain.c
src/libxl/libxl_driver.c
src/libxl/libxl_migration.c
+src/libxl/xen_common.c
+src/libxl/xen_xl.c
+src/libxl/xen_xm.c
src/locking/lock_daemon.c
src/locking/lock_daemon_dispatch.c
src/locking/lock_driver_lockd.c
@@ -291,9 +294,6 @@ src/vz/vz_utils.c
src/vz/vz_utils.h
src/xenapi/xenapi_driver.c
src/xenapi/xenapi_utils.c
-src/xenconfig/xen_common.c
-src/xenconfig/xen_xl.c
-src/xenconfig/xen_xm.c
tests/virpolkittest.c
tools/libvirt-guests.sh.in
tools/virsh-checkpoint.c
diff --git a/src/Makefile.am b/src/Makefile.am
index adaf61350a..6626659113 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -118,7 +118,6 @@ include vbox/Makefile.inc.am
include openvz/Makefile.inc.am
include qemu/Makefile.inc.am
include bhyve/Makefile.inc.am
-include xenconfig/Makefile.inc.am
include libxl/Makefile.inc.am
include xenapi/Makefile.inc.am
include vz/Makefile.inc.am
diff --git a/src/libvirt_xenconfig.syms b/src/libvirt_xenconfig.syms
deleted file mode 100644
index 6e2e578b15..0000000000
--- a/src/libvirt_xenconfig.syms
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# These symbols are dependent upon --with-xen via WITH_XEN or --with-libxl via WITH_LIBXL.
-#
-
-# xenconfig/xen_xm.h
-xenFormatXM;
-xenParseXM;
-
-# Let emacs know we want case-insensitive sorting
-# Local Variables:
-# sort-fold-case: t
-# End:
diff --git a/src/libxl/Makefile.inc.am b/src/libxl/Makefile.inc.am
index 1587404586..560b214877 100644
--- a/src/libxl/Makefile.inc.am
+++ b/src/libxl/Makefile.inc.am
@@ -1,6 +1,13 @@
# vim: filetype=automake
LIBXL_DRIVER_SOURCES = \
+ libxl/xenxs_private.h \
+ libxl/xen_common.c \
+ libxl/xen_common.h \
+ libxl/xen_xl.c \
+ libxl/xen_xl.h \
+ libxl/xen_xm.c \
+ libxl/xen_xm.h \
libxl/libxl_conf.c \
libxl/libxl_conf.h \
libxl/libxl_capabilities.c \
@@ -15,29 +22,13 @@ LIBXL_DRIVER_SOURCES = \
libxl/libxl_migration.h \
$(NULL)
-XENCONFIG_LIBXL_SOURCES = \
- $(XENCONFIG_SOURCES) \
- xenconfig/xen_xl.c \
- xenconfig/xen_xl.h \
- $(NULL)
-
DRIVER_SOURCE_FILES += $(LIBXL_DRIVER_SOURCES)
STATEFUL_DRIVER_SOURCE_FILES += $(LIBXL_DRIVER_SOURCES)
EXTRA_DIST += \
$(LIBXL_DRIVER_SOURCES) \
- $(XENCONFIG_LIBXL_SOURCES) \
$(NULL)
if WITH_LIBXL
-noinst_LTLIBRARIES += libvirt_xenconfig_libxl.la
-libvirt_xenconfig_libxl_la_LIBADD = $(LIBXL_LIBS)
-libvirt_xenconfig_libxl_la_CFLAGS = \
- -I$(srcdir)/conf \
- -I$(srcdir)/libxl \
- $(AM_CFLAGS) \
- $(NULL)
-libvirt_xenconfig_libxl_la_SOURCES = $(XENCONFIG_LIBXL_SOURCES)
-
noinst_LTLIBRARIES += libvirt_driver_libxl_impl.la
libvirt_driver_libxl_la_SOURCES =
libvirt_driver_libxl_la_LIBADD = \
@@ -54,14 +45,12 @@ libvirt_driver_libxl_impl_la_CFLAGS = \
-I$(srcdir)/access \
-I$(srcdir)/conf \
-I$(srcdir)/secret \
- -I$(srcdir)/xenconfig \
$(AM_CFLAGS) \
$(NULL)
libvirt_driver_libxl_impl_la_LDFLAGS = $(AM_LDFLAGS)
libvirt_driver_libxl_impl_la_LIBADD = \
$(LIBXL_LIBS) \
$(LIBXML_LIBS) \
- libvirt_xenconfig_libxl.la \
$(NULL)
libvirt_driver_libxl_impl_la_SOURCES = $(LIBXL_DRIVER_SOURCES)
diff --git a/src/xenconfig/xen_common.c b/src/libxl/xen_common.c
similarity index 100%
rename from src/xenconfig/xen_common.c
rename to src/libxl/xen_common.c
diff --git a/src/xenconfig/xen_common.h b/src/libxl/xen_common.h
similarity index 100%
rename from src/xenconfig/xen_common.h
rename to src/libxl/xen_common.h
diff --git a/src/xenconfig/xen_xl.c b/src/libxl/xen_xl.c
similarity index 100%
rename from src/xenconfig/xen_xl.c
rename to src/libxl/xen_xl.c
diff --git a/src/xenconfig/xen_xl.h b/src/libxl/xen_xl.h
similarity index 100%
rename from src/xenconfig/xen_xl.h
rename to src/libxl/xen_xl.h
diff --git a/src/xenconfig/xen_xm.c b/src/libxl/xen_xm.c
similarity index 100%
rename from src/xenconfig/xen_xm.c
rename to src/libxl/xen_xm.c
diff --git a/src/xenconfig/xen_xm.h b/src/libxl/xen_xm.h
similarity index 100%
rename from src/xenconfig/xen_xm.h
rename to src/libxl/xen_xm.h
diff --git a/src/xenconfig/xenxs_private.h b/src/libxl/xenxs_private.h
similarity index 100%
rename from src/xenconfig/xenxs_private.h
rename to src/libxl/xenxs_private.h
diff --git a/src/xenconfig/Makefile.inc.am b/src/xenconfig/Makefile.inc.am
deleted file mode 100644
index 5785b49268..0000000000
--- a/src/xenconfig/Makefile.inc.am
+++ /dev/null
@@ -1,28 +0,0 @@
-# vim: filetype=automake
-
-XENCONFIG_SOURCES = \
- xenconfig/xenxs_private.h \
- xenconfig/xen_common.c \
- xenconfig/xen_common.h \
- xenconfig/xen_xm.c \
- xenconfig/xen_xm.h \
- $(NULL)
-
-EXTRA_DIST += $(XENCONFIG_SOURCES)
-
-if WITH_XENCONFIG
-noinst_LTLIBRARIES += libvirt_xenconfig.la
-libvirt_la_BUILT_LIBADD += libvirt_xenconfig.la
-libvirt_xenconfig_la_CFLAGS = \
- -I$(srcdir)/conf \
- $(AM_CFLAGS) \
- $(NULL)
-libvirt_xenconfig_la_SOURCES = $(XENCONFIG_SOURCES)
-
-endif WITH_XENCONFIG
-
-if WITH_XENCONFIG
-USED_SYM_FILES += $(srcdir)/libvirt_xenconfig.syms
-else ! WITH_XENCONFIG
-SYM_FILES += $(srcdir)/libvirt_xenconfig.syms
-endif ! WITH_XENCONFIG
diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c
index 59171606d1..ae0db71293 100644
--- a/tests/xlconfigtest.c
+++ b/tests/xlconfigtest.c
@@ -27,7 +27,7 @@
#include "internal.h"
#include "datatypes.h"
-#include "xenconfig/xen_xl.h"
+#include "libxl/xen_xl.h"
#include "viralloc.h"
#include "virstring.h"
#include "testutils.h"
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index 1de3c33f69..3137dc564c 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -25,7 +25,7 @@
#include "internal.h"
#include "datatypes.h"
-#include "xenconfig/xen_xm.h"
+#include "libxl/xen_xm.h"
#include "testutils.h"
#include "testutilsxen.h"
#include "viralloc.h"
--
2.22.0
5 years, 2 months
[libvirt] [PATCH] qemu: domain: Fix potential NULL deref when parsing job private data
by Peter Krempa
A specially crafted XML which would reference a non-existing disk but
request the mirror to be registered with the blockjob could potentially
make the parser dereference NULL. Fix it by moving the code slightly and
just treat it as a wrong job XML. Found by Coverity.
Reported-by: John Ferlan <jferlan(a)redhat.com>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_domain.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 657f3ecfe4..c7eb0b5e9a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3012,15 +3012,19 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
invalidData = true;
}
+ if (mirror) {
+ if (disk)
+ job->mirrorChain = virObjectRef(disk->mirror);
+ else
+ invalidData = true;
+ }
+
job->state = state;
job->newstate = newstate;
job->errmsg = virXPathString("string(./errmsg)", ctxt);
job->invalidData = invalidData;
job->disk = disk;
- if (mirror)
- job->mirrorChain = virObjectRef(job->disk->mirror);
-
qemuDomainObjPrivateXMLParseBlockjobDataSpecific(job, ctxt, xmlopt);
if (qemuBlockJobRegister(job, vm, disk, false) < 0)
--
2.21.0
5 years, 2 months
[libvirt] [PATCH] util: Set backing file name for LOOP_GET_STATUS64 queries.
by jcfaracco@gmail.com
From: Julio Faracco <jcfaracco(a)gmail.com>
This is an issue for LXC loop devices when you are trying to get loop
devices info using `ioctl`. Modern apps uses `/sys/dev/block` to grab
information about devices, but if you use the method mention you won't
be able to retrive the associated file with that loop device. See
example below from cryptsetup sources:
static char *_ioctl_backing_file(const char *loop)
{
struct loop_info64 lo64 = {0};
int loop_fd;
loop_fd = open(loop, O_RDONLY);
if (loop_fd < 0)
return NULL;
if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0) {
close(loop_fd);
return NULL;
}
lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
close(loop_fd);
return strdup((char*)lo64.lo_file_name);
}
It will return an empty string because lo_file_name was not set.
Signed-off-by: Julio Faracco <jcfaracco(a)gmail.com>
---
src/util/virfile.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 81a3c096eb..fe0aa54eb6 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -781,6 +781,16 @@ int virFileLoopDeviceAssociate(const char *file,
memset(&lo, 0, sizeof(lo));
lo.lo_flags = LO_FLAGS_AUTOCLEAR;
+ /* Set backing file name for LOOP_GET_STATUS64 queries */
+ if (virStrncpy((char *) lo.lo_file_name, file,
+ strlen(file), LO_NAME_SIZE) < 0) {
+ virReportSystemError(errno,
+ _("Unable to set backing file %s"), file);
+ goto cleanup;
+ }
+ lo.lo_file_name[LO_NAME_SIZE-2] = '*';
+ lo.lo_file_name[LO_NAME_SIZE-1] = 0;
+
if ((fsfd = open(file, O_RDWR)) < 0) {
virReportSystemError(errno,
_("Unable to open %s"), file);
--
2.20.1
5 years, 2 months
[libvirt] [RFC] On present using dummy hostdev usb device
by Nikolay Shirokovskiy
Hi, all!
We use an interesting approach when starting/migrating/etc domain with usb
hostdev with startupPolicy=optional. We add qemu usb-host device with
missing hostaddr/hostbus parameters (dummy device). I guess there are
2 reasons why we do it. First without dummy device migration will fail as
described in [1]. Second is an interesting property of dummy device that
qemu starts to monitor for attaching of usb devices and binds the first
attached to node to the dummy device. So one can start a domain with
missing hostdev and attach it later or migrate a domain then detach
hostdev on source and attach it on destination. But as qemu binds the
first attached device this is not reliable, to say the least. And after
all this does not work if domain uses distinct mount namespace which
is default.
So I question does it make sense to use dummy device at all? In case of
migration/resume from suspend/revert to snapshot we can either fix qemu to
ignore incoming missing hostdev data or add dummy device temporarily. The
latter solution is worse as it brings dummy device behaviour even for a short
period of time. However having a temporary dummy device is neccessary step
towards the time when all supported versions of qemu do the mentioned ignoring.
As to handling attaching of missing hostdev device to node it should be done in
libvirt which can do necessary mount namespace actions. (Actually I developing
such patches right now but some peculiarities of dummy device bring me here).
Nikolay
[1] https://www.redhat.com/archives/libvir-list/2012-October/msg00440.html
5 years, 2 months