diff --git a/docs/Makefile.am b/docs/Makefile.am
index db4bc5933f..59ae6855f5 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -60,7 +60,7 @@ gif = \
architecture.gif \
node.gif
-dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) todo.html.in \
+dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) todo.html.in hvsupport.html.in \
$(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
dot_html = $(dot_html_in:%.html.in=%.html)
@@ -86,7 +86,7 @@ EXTRA_DIST= \
$(xml) $(fig) $(png) $(css) \
$(patches) \
sitemap.html.in \
- todo.pl todo.cfg-example
+ todo.pl hvsupport.pl todo.cfg-example
MAINTAINERCLEANFILES = \
$(addprefix $(srcdir)/,$(dot_html)) \
@@ -113,6 +113,10 @@ todo:
rm -f todo.html.in
$(MAKE) todo.html
+hvsupport.html.in: $(srcdir)/hvsupport.pl $(srcdir)/../src/libvirt_public.syms \
+ $(srcdir)/../src/libvirt_qemu.syms $(srcdir)/../src/driver.h
+ $(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(srcdir)/../src > $@ || { rm $@ && exit 1; }
+
.PHONY: todo
%.png: %.fig
@@ -183,7 +187,7 @@ clean-local:
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
maintainer-clean-local: clean-local
- rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in
+ rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in hvsupport.html.in
rebuild: api all
diff --git a/docs/hvsupport.html.in b/docs/hvsupport.html.in
deleted file mode 100644
index 4cc2634bfd..0000000000
--- a/docs/hvsupport.html.in
+++ /dev/null
@@ -1,801 +0,0 @@
-
-
-
- Driver support matrix
-
-This page documents which libvirt calls work on
-which libvirt drivers / hypervisors, and which version the API appeared
-in.
-
-
-This information changes frequently. This page was last checked or
-updated on 2008-06-05.
-
- Domain functions
- x = not supported; empty cell means no information
-
-
- Function |
- Since |
- Xen |
- QEMU |
- KVM |
- Remote |
- VirtualBox |
- ONE |
- ESX |
-
-
- virConnectClose |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectGetCapabilities |
- 0.2.1 |
- ≥ 0.2.1 |
- ≥ 0.2.1 |
- ≥ 0.2.1 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.1 |
-
-
- virConnectGetHostname |
- 0.3.0 |
- ≥ 0.3.0 |
- ≥ 0.3.3 |
- ≥ 0.3.3 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virConnectGetMaxVcpus |
- 0.2.1 |
- ≥ 0.2.1 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virConnectGetType |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectGetURI |
- 0.3.0 |
- ≥ 0.3.0 |
- ≥ 0.3.0 |
- ≥ 0.3.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectGetVersion |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectListDefinedDomains |
- 0.1.5 |
- ≥ 0.1.9 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectListDomains |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectNumOfDefinedDomains |
- 0.1.5 |
- ≥ 0.1.9 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectNumOfDomains |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virConnectOpen |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- x |
-
-
- virConnectOpenAuth |
- |
- |
- |
- |
- |
- |
- |
- ≥ 0.7.0 |
-
-
- virConnectOpenReadOnly |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainAttachDevice |
- 0.1.9 |
- ≥ 0.1.9 |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- x |
-
-
- virDomainBlockPeek |
- 0.4.3 |
- 0.4.3 |
- 0.4.3 |
- 0.4.3 |
- x |
- x |
- x |
- x |
-
-
- virDomainBlockStats |
- 0.3.2 |
- ≥ 0.3.2 |
- x |
- x |
- ≥ 0.3.2 |
- x |
- x |
- x |
-
-
- virDomainCoreDump |
- 0.1.9 |
- ≥ 0.1.9 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainCreate |
- 0.1.5 |
- ≥ 0.1.9 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainCreateLinux |
- All |
- ≥ 0.0.5 |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- x |
-
-
- virDomainDefineXML |
- 0.1.5 |
- ≥ 0.1.9 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.2 |
-
-
- virDomainDestroy |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainDetachDevice |
- 0.1.9 |
- ≥ 0.1.9 |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- x |
-
-
- virDomainFree |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetAutostart |
- 0.2.1 |
- x |
- ≥ 0.2.1 |
- ≥ 0.2.1 |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainGetConnect |
- 0.3.0 |
- not a HV function |
-
-
- virDomainGetID |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetInfo |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetMaxMemory |
- All |
- All |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virDomainGetMaxVcpus |
- 0.2.1 |
- ≥ 0.2.1 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainGetName |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetOSType |
- All |
- All |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetSchedulerParameters |
- 0.2.3 |
- ≥ 0.2.3 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainGetSchedulerType |
- 0.2.3 |
- ≥ 0.2.3 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainGetUUID |
- 0.1.10 |
- ≥ 0.1.10 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetUUIDString |
- 0.1.10 |
- ≥ 0.1.10 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainGetVcpus |
- 0.1.4 |
- ≥ 0.1.4 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainInterfaceStats |
- 0.3.2 |
- ≥ 0.3.2 |
- x |
- x |
- ≥ 0.3.2 |
- x |
- x |
- x |
-
-
- virDomainGetXMLDesc |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virDomainLookupByID |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainLookupByName |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainLookupByUUID |
- 0.1.10 |
- ≥ 0.1.10 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainLookupByUUIDString |
- 0.1.10 |
- ≥ 0.1.10 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainMigrate |
- 0.3.2 |
- ≥ 0.3.2 |
- x |
- x |
- 0.3.2 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainPinVcpu |
- 0.1.4 |
- ≥ 0.1.4 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainReboot |
- 0.1.0 |
- ≥ 0.1.0 |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virDomainRestore |
- All |
- All |
- x |
- ≥ 0.3.2 |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainResume |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainSave |
- All |
- All |
- x |
- ≥ 0.3.2 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- x |
-
-
- virDomainSetAutostart |
- 0.2.1 |
- x |
- ≥ 0.2.1 |
- ≥ 0.2.1 |
- ≥ 0.3.0 |
- x |
- x |
- x |
-
-
- virDomainSetMaxMemory |
- All |
- All |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainSetMemory |
- 0.1.1 |
- ≥ 0.1.1 |
- x |
- x |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virDomainSetSchedulerParameters |
- 0.2.3 |
- ≥ 0.2.3 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainSetVcpus |
- 0.1.4 |
- ≥ 0.1.4 |
- x |
- x |
- ≥ 0.3.0 |
- x |
- x |
- ≥ 0.7.0 |
-
-
- virDomainShutdown |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainSuspend |
- All |
- All |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.0 |
-
-
- virDomainUndefine |
- 0.1.5 |
- ≥ 0.1.9 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- ≥ 0.6.4 |
- ≥ 0.7.1 |
-
-
- virGetVersion |
- All |
- All |
- Returns -1 if HV unsupported. |
-
-
- virInitialize |
- 0.1.0 |
- not a HV function |
-
-
- virDomainMemoryPeek |
- 0.4.3 |
- x |
- 0.4.3 |
- 0.4.3 |
- x |
- x |
- x |
- x |
-
-
- virNodeGetInfo |
- 0.1.0 |
- ≥ 0.1.0 |
- ≥ 0.2.0 |
- ≥ 0.2.0 |
- ≥ 0.3.0 |
- ≥ 0.6.3 |
- x |
- ≥ 0.7.0 |
-
-
- virNodeGetFreeMemory |
- 0.3.3 |
- ≥ 0.3.3 |
- x |
- x |
- x |
- x |
- x |
- ≥ 0.7.2 |
-
-
- virNodeGetCellsFreeMemory |
- 0.3.3 |
- ≥ 0.3.3 |
- x |
- x |
- x |
- x |
- x |
- x |
-
-
- Network functions
-
-Network functions are not hypervisor-specific.They require the libvirtd
-daemon to be running. Most network functions first appeared in libvirt 0.2.0.
-
-
-
- Function |
- Since |
-
-
- virConnectNumOfNetworks |
- 0.2.0 |
-
-
- virConnectListNetworks |
- 0.2.0 |
-
-
- virConnectNumOfDefinedNetworks |
- 0.2.0 |
-
-
- virConnectListDefinedNetworks |
- 0.2.0 |
-
-
- virNetworkCreate |
- 0.2.0 |
-
-
- virNetworkCreateXML |
- 0.2.0 |
-
-
- virNetworkDefineXML |
- 0.2.0 |
-
-
- virNetworkDestroy |
- 0.2.0 |
-
-
- virNetworkFree |
- 0.2.0 |
-
-
- virNetworkGetAutostart |
- 0.2.1 |
-
-
- virNetworkGetConnect |
- 0.3.0 |
-
-
- virNetworkGetBridgeName |
- 0.2.0 |
-
-
- virNetworkGetName |
- 0.2.0 |
-
-
- virNetworkGetUUID |
- 0.2.0 |
-
-
- virNetworkGetUUIDString |
- 0.2.0 |
-
-
- virNetworkGetXMLDesc |
- 0.2.0 |
-
-
- virNetworkLookupByName |
- 0.2.0 |
-
-
- virNetworkLookupByUUID |
- 0.2.0 |
-
-
- virNetworkLookupByUUIDString |
- 0.2.0 |
-
-
- virNetworkSetAutostart |
- 0.2.1 |
-
-
- virNetworkUndefine |
- 0.2.0 |
-
-
-
-
diff --git a/docs/hvsupport.pl b/docs/hvsupport.pl
new file mode 100644
index 0000000000..08ed368911
--- /dev/null
+++ b/docs/hvsupport.pl
@@ -0,0 +1,383 @@
+#!/usr/bin/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 $drivertable = "$srcdir/driver.h";
+
+my %groupheaders = (
+ "virDriver" => "Hypervisor APIs",
+ "virNetworkDriver" => "Virtual Network APIs",
+ "virInterfaceDriver" => "Host Interface APIs",
+ "virDeviceMonitor" => "Host Device APIs",
+ "virStorageDriver" => "Storage Pool APIs",
+ "virSecretDriver" => "Secret APIs",
+ "virNWFilterDriver" => "Network Filter APIs",
+ );
+
+
+my @srcs;
+find({
+ wanted => sub {
+ if (m!$srcdir/.*/\w+_(driver|tmpl)\.c$!) {
+ push @srcs, $_ if $_ !~ /vbox_driver\.c/;
+ }
+ }, no_chdir => 1}, $srcdir);
+my $line;
+
+# Get the list of all public APIs and their corresponding version
+
+my %apis;
+open FILE, "<$symslibvirt"
+ or die "cannot read $symslibvirt: $!";
+
+my $vers;
+my $prevvers;
+while (defined($line = )) {
+ chomp $line;
+ next if $line =~ /^\s*#/;
+ next if $line =~ /^\s*$/;
+ next if $line =~ /^\s*(global|local):/;
+ if ($line =~ /^\s*LIBVIRT_(\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*LIBVIRT_(\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*$/) {
+ $apis{$1} = $vers;
+ } else {
+ die "unexpected data $line\n";
+ }
+}
+
+close FILE;
+
+
+# And the same for the QEMU specific APIs
+
+open FILE, "<$symsqemu"
+ or die "cannot read $symsqemu: $!";
+
+$prevvers = undef;
+$vers = undef;
+while (defined($line = )) {
+ chomp $line;
+ next if $line =~ /^\s*#/;
+ next if $line =~ /^\s*$/;
+ next if $line =~ /^\s*(global|local):/;
+ if ($line =~ /^\s*LIBVIRT_QEMU_(\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*LIBVIRT_QEMU_(\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*$/) {
+ $apis{$1} = $vers;
+ } else {
+ die "unexpected data $line\n";
+ }
+}
+
+close FILE;
+
+
+# Some special things which aren't public APIs,
+# but we want to report
+$apis{virConnectDrvSupportsFeature} = "0.3.2";
+$apis{virDomainMigratePrepare} = "0.3.2";
+$apis{virDomainMigratePerform} = "0.3.2";
+$apis{virDomainMigrateFinish} = "0.3.2";
+$apis{virDomainMigratePrepare2} = "0.5.0";
+$apis{virDomainMigrateFinish2} = "0.5.0";
+$apis{virDomainMigratePrepareTunnel} = "0.7.2";
+
+$apis{virDomainMigrateBegin3} = "0.9.2";
+$apis{virDomainMigratePrepare3} = "0.9.2";
+$apis{virDomainMigratePrepareTunnel3} = "0.9.2";
+$apis{virDomainMigratePerform3} = "0.9.2";
+$apis{virDomainMigrateFinish3} = "0.9.2";
+$apis{virDomainMigrateConfirm} = "0.9.2";
+
+
+
+# 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.
+
+open FILE, "<$drivertable"
+ or die "cannot read $drivertable: $!";
+
+# Group name -> hash of APIs { fields -> api name }
+my %groups;
+my $ingrp;
+while (defined($line = )) {
+ 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*virDrv(\w+)\s+(\w+);\s*$/) {
+ my $field = $2;
+ my $name = $1;
+
+ my $api;
+ if (exists $apis{"vir$name"}) {
+ $api = "vir$name";
+ } elsif (exists $apis{"virConnect$name"}) {
+ $api = "virConnect$name";
+ } 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: $!";
+
+ $ingrp = undef;
+ my $impl;
+ while (defined($line = )) {
+ if (!$ingrp) {
+ foreach my $grp (keys %groups) {
+ if ($line =~ /^\s*(?:static\s+)?$grp\s+(\w+)\s*=\s*{/ ||
+ $line =~ /^\s*(?:static\s+)?$grp\s+NAME\(\w+\)\s*=\s*{/) {
+ $ingrp = $grp;
+ $impl = $src;
+ $impl =~ s,.*/(\w+?)_((\w+)_)?(\w+)\.c,$1,;
+ $groups{$ingrp}->{drivers}->{$impl} = {};
+ }
+ }
+
+ } else {
+ if ($line =~ m!\s*\.(\w+)\s*=\s*(\w+)\s*,?\s*(?:/\*\s*(\d+\.\d+\.\d+)\s*\*/\s*)?$!) {
+ my $api = $1;
+ my $meth = $2;
+ my $vers = $3;
+
+ next if $api eq "no" || $api eq "name";
+
+ die "Method $meth in $src is missing version" unless defined $vers;
+
+ die "Driver method for $api is NULL in $src" if $meth eq "NULL";
+
+ if (!exists($groups{$ingrp}->{apis}->{$api})) {
+ die "Found unexpected driver $api in $ingrp\n";
+ }
+
+ $groups{$ingrp}->{drivers}->{$impl}->{$api} = $vers;
+ if ($api eq "domainMigratePrepare" ||
+ $api eq "domainMigratePrepare2" ||
+ $api eq "domainMigratePrepare3") {
+ $groups{$ingrp}->{drivers}->{$impl}->{"domainMigrate"} = $vers
+ unless $groups{$ingrp}->{drivers}->{$impl}->{"domainMigrate"};
+ }
+
+ } 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{virDriver}->{apis}->{"openAuth"} = "virConnectOpenAuth";
+$groups{virDriver}->{apis}->{"openReadOnly"} = "virConnectOpenReadOnly";
+$groups{virDriver}->{apis}->{"domainMigrate"} = "virDomainMigrate";
+
+my $openAuthVers = (0 * 1000 * 1000) + (4 * 1000) + 0;
+
+foreach my $drv (keys %{$groups{"virDriver"}->{drivers}}) {
+ my $openVersStr = $groups{"virDriver"}->{drivers}->{$drv}->{"open"};
+ my $openVers;
+ if ($openVersStr =~ /(\d+)\.(\d+)\.(\d+)/) {
+ $openVers = ($1 * 1000 * 1000) + ($2 * 1000) + $3;
+ }
+
+ # virConnectOpenReadOnly always matches virConnectOpen version
+ $groups{"virDriver"}->{drivers}->{$drv}->{"openReadOnly"} =
+ $groups{"virDriver"}->{drivers}->{$drv}->{"open"};
+
+ # 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{"virDriver"}->{drivers}->{$drv}->{"openAuth"} = $openVersStr;
+ } else {
+ $groups{"virDriver"}->{drivers}->{$drv}->{"openAuth"} = "0.4.0";
+ }
+}
+
+
+# Another special case for the virDomainCreateLinux which was replaced
+# with virDomainCreateXML
+$groups{virDriver}->{apis}->{"domainCreateLinux"} = "virDomainCreateLinux";
+
+my $createAPIVers = (0 * 1000 * 1000) + (0 * 1000) + 3;
+
+foreach my $drv (keys %{$groups{"virDriver"}->{drivers}}) {
+ my $createVersStr = $groups{"virDriver"}->{drivers}->{$drv}->{"domainCreateXML"};
+ next unless defined $createVersStr;
+ my $createVers;
+ if ($createVersStr =~ /(\d+)\.(\d+)\.(\d+)/) {
+ $createVers = ($1 * 1000 * 1000) + ($2 * 1000) + $3;
+ }
+
+ # 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{"virDriver"}->{drivers}->{$drv}->{"domainCreateLinux"} = $createVersStr;
+ } else {
+ $groups{"virDriver"}->{drivers}->{$drv}->{"domainCreateLinux"} = "0.0.3";
+ }
+}
+
+
+# Finally we generate the HTML file with the tables
+
+print <
+
+libvirt API support matrix
+
+
+libvirt API support matrix
+
+
+
+
+This page documents which libvirt calls work on
+which libvirt drivers / hypervisors, and which version the API appeared
+in.
+
+
+EOF
+
+foreach my $grp (sort { $a cmp $b } keys %groups) {
+ print "\n";
+ print <
+
+
+API |
+Version |
+EOF
+
+ foreach my $drv (sort { $a cmp $b } keys %{$groups{$grp}->{drivers}}) {
+ print " $drv | \n";
+ }
+
+ print <
+
+
+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};
+ print <
+$api |
+$vers |
+EOF
+
+ foreach my $drv (sort {$a cmp $b } keys %{$groups{$grp}->{drivers}}) {
+ if (exists $groups{$grp}->{drivers}->{$drv}->{$field}) {
+ print "", $groups{$grp}->{drivers}->{$drv}->{$field}, " | \n";
+ } else {
+ print " | \n";
+ }
+ }
+
+ print <
+EOF
+
+ $row++;
+ if (($row % 15) == 0) {
+ print <
+API |
+Version |
+EOF
+
+ foreach my $drv (sort { $a cmp $b } keys %{$groups{$grp}->{drivers}}) {
+ print " $drv | \n";
+ }
+
+ print <
+EOF
+ }
+
+ }
+
+ print <
+
+EOF
+}
+
+print <
+
+EOF