[libvirt] [PATCH] fix the failure of nodedev-reattach caused by the variables from nodedev-attach
by Guannan Ren
the "virsh nodedev-reattch" command could return successfully, but the pci device is still
bound to pci-stub driver. The reason is noddev-reattach trys to use the variables set by
nodedev-dettach commands. Becuase these variables is not persistent, this is not we expected.
the patch try to fix it.
---
src/util/pci.c | 74 +++++++++++++++++++------------------------------------
1 files changed, 26 insertions(+), 48 deletions(-)
diff --git a/src/util/pci.c b/src/util/pci.c
index 46a3a83..d345c3e 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -67,9 +67,6 @@ struct _pciDevice {
unsigned managed : 1;
/* used by reattach function */
- unsigned unbind_from_stub : 1;
- unsigned remove_slot : 1;
- unsigned reprobe : 1;
};
struct _pciDeviceList {
@@ -882,14 +879,23 @@ pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
if (pciDriverDir(&drvdir, driver) < 0)
goto cleanup;
- if (!dev->unbind_from_stub)
- goto remove_slot;
-
- /* If the device is bound to stub, unbind it.
- */
if (pciDeviceFile(&path, dev->name, "driver") < 0)
goto cleanup;
+ /* If the device is bound to a driver instead of pci-stub, do nothing.
+ */
+ if (virFileExists(path) && ! virFileLinkPointsTo(path, drvdir)){
+ result = 0;
+ goto cleanup;
+ }
+
+ /* If the device is not bound to any driver, reprobe it.
+ */
+ if (!virFileExists(path))
+ goto reprobe;
+
+ /* If the device is bound to stub, unbind it.
+ */
if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
if (pciDriverFile(&path, driver, "unbind") < 0) {
goto cleanup;
@@ -902,11 +908,6 @@ pciUnbindDeviceFromStub(pciDevice *dev, const char *driver)
goto cleanup;
}
}
- dev->unbind_from_stub = 0;
-
-remove_slot:
- if (!dev->remove_slot)
- goto reprobe;
/* Xen's pciback.ko wants you to use remove_slot on the specific device */
if (pciDriverFile(&path, driver, "remove_slot") < 0) {
@@ -919,14 +920,8 @@ remove_slot:
dev->name, driver);
goto cleanup;
}
- dev->remove_slot = 0;
reprobe:
- if (!dev->reprobe) {
- result = 0;
- goto cleanup;
- }
-
/* Trigger a re-probe of the device is not in the stub's dynamic
* ID table. If the stub is available, but 'remove_id' isn't
* available, then re-probing would just cause the device to be
@@ -935,6 +930,12 @@ reprobe:
if (pciDriverFile(&path, driver, "remove_id") < 0) {
goto cleanup;
}
+
+ /* If the device is still in stub's dynamic ID table,remove it,
+ * otherwise, ignore the error.
+ */
+ if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0){
+ }
if (!virFileExists(drvdir) || virFileExists(path)) {
if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) {
@@ -948,11 +949,6 @@ reprobe:
result = 0;
cleanup:
- /* do not do it again */
- dev->unbind_from_stub = 0;
- dev->remove_slot = 0;
- dev->reprobe = 0;
-
VIR_FREE(drvdir);
VIR_FREE(path);
@@ -966,7 +962,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
int result = -1;
char *drvdir = NULL;
char *path = NULL;
- int reprobe = 0;
/* check whether the device is already bound to a driver */
if (pciDriverDir(&drvdir, driver) < 0 ||
@@ -980,7 +975,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
result = 0;
goto cleanup;
}
- reprobe = 1;
}
/* Add the PCI device ID to the stub's dynamic ID table;
@@ -1011,8 +1005,7 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
}
if (virFileLinkPointsTo(path, drvdir)) {
- dev->unbind_from_stub = 1;
- dev->remove_slot = 1;
+ result = 0;
goto remove_id;
}
@@ -1022,7 +1015,7 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
* your root filesystem.
*/
if (pciDeviceFile(&path, dev->name, "driver/unbind") < 0) {
- goto cleanup;
+ goto remove_id;
}
if (virFileExists(path)) {
@@ -1030,9 +1023,8 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
virReportSystemError(errno,
_("Failed to unbind PCI device '%s'"),
dev->name);
- goto cleanup;
+ goto remove_id;
}
- dev->reprobe = reprobe;
}
/* If the device isn't already bound to pci-stub, try binding it now.
@@ -1054,7 +1046,6 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
dev->name, driver);
goto remove_id;
}
- dev->remove_slot = 1;
if (pciDriverFile(&path, driver, "bind") < 0) {
goto remove_id;
@@ -1066,20 +1057,15 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
dev->name, driver);
goto remove_id;
}
- dev->unbind_from_stub = 1;
}
+ result = 0;
remove_id:
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
* ID table so that 'drivers_probe' works below.
*/
if (pciDriverFile(&path, driver, "remove_id") < 0) {
- /* We do not remove PCI ID from pci-stub, and we cannot reprobe it */
- if (dev->reprobe) {
- VIR_WARN("Could not remove PCI ID '%s' from %s, and the device "
- "cannot be probed again.", dev->id, driver);
- }
- dev->reprobe = 0;
+ result = -1;
goto cleanup;
}
@@ -1087,18 +1073,10 @@ remove_id:
virReportSystemError(errno,
_("Failed to remove PCI ID '%s' from %s"),
dev->id, driver);
-
- /* remove PCI ID from pci-stub failed, and we cannot reprobe it */
- if (dev->reprobe) {
- VIR_WARN("Failed to remove PCI ID '%s' from %s, and the device "
- "cannot be probed again.", dev->id, driver);
- }
- dev->reprobe = 0;
+ result = -1;
goto cleanup;
}
- result = 0;
-
cleanup:
VIR_FREE(drvdir);
VIR_FREE(path);
--
1.7.1
13 years, 4 months
[libvirt] offline migration / vm cloning with libvirt/virsh
by Sethuraman Subbiah
Hi ,
I am trying to perform offline migration (i.e) Create an incremental image
using the qcow format, transfer the vm memory state to a state fie.Use the
image and statefile together as a template. Now create a new vm using the
template. I can successfully do it using the following commands :
Save phase :
stop
migrate "exec:gzip -c > STATEFILE.gz"
qemu-img
qemu-img create -b BASE_img -f qcow2 INCRE_img
Restore phase :
qemu-kvm -m 1024 -hda INCRE_img -incoming "exec: gzip -c -d STATEFILE.gz"
And it works fine. But I am not able to find the vm with virt-manager or
other libvirt based tools.
If I use :
virsh save <dom_id> STATEFILE
I can restore using "virsh restore STATEFILE" but I want to associate this
with the incremental image that I created, but I dont know how. I think it
saves the existing vm's xml file along with the STATEFILE, thus I am not
able to change the disk image to the incremental image.
Thus ,
1. Either I should find a way to make vms created using qemu-kvm appear in
libvirt-based tools.
OR
2. Find a way to associate the virsh save STATEFILE with a incremental
image.
Any help or hint with respect to these will be very helpful. I am try to do
cloning with minimal cost. This takes only 25 seconds ( to create STATEFILE)
and creating incremental image is instantatenous . But I want to use the vm
monitoring code based on libvirt. And it makes life difficult.
Thanks for your help.
-
Regards,
Sethuraman Subbiah
Graduate Student - NC state University
M.S in Computer Science
13 years, 4 months
[libvirt] [PATCH] build: fix virBufferVasprintf on mingw
by Eric Blake
Gnulib documents that mingw [v]snprintf is broken (it returns -1
on out-of-space, instead of the count of what would have been
printed); but while we were using the snprintf wrapper, we had
not yet been using the vsnprintf wrapper.
* bootstrap.conf (gnulib_modules): Add vsnprintf.
Reported by Matthias Bolte.
---
bootstrap.conf | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 581d60b..302cce8 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -97,6 +97,7 @@ usleep
vasprintf
verify
vc-list-files
+vsnprintf
waitpid
warnings
'
--
1.7.4.4
13 years, 4 months
[libvirt] [PATCH] Fix default value of security label 'relabel' attribute
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When no <seclabel> is present in the XML, the virDomainSeclabelDef
struct is left as all zeros. Unfortunately, this means it gets setup
as type=dynamic, with relabel=no, which is an illegal combination.
Change the 'bool relabel' attribute in virDomainSeclabelDef to
the inverse 'bool norelabel' so that the default initialization
is sensible
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/security/security_apparmor.c, src/security/security_selinux.c:
Replace 'relabel' with 'norelabel'
---
src/conf/domain_conf.c | 18 +++++++++---------
src/conf/domain_conf.h | 2 +-
src/security/security_apparmor.c | 8 ++++----
src/security/security_selinux.c | 20 ++++++++++----------
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 109a947..b74ab4d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5076,25 +5076,25 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p != NULL) {
if (STREQ(p, "yes")) {
- def->seclabel.relabel = true;
+ def->seclabel.norelabel = false;
} else if (STREQ(p, "no")) {
- def->seclabel.relabel = false;
+ def->seclabel.norelabel = true;
} else {
virDomainReportError(VIR_ERR_XML_ERROR,
_("invalid security relabel value %s"), p);
goto error;
}
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
- !def->seclabel.relabel) {
+ def->seclabel.norelabel) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("dynamic label type must use resource relabeling"));
goto error;
}
} else {
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
- def->seclabel.relabel = false;
+ def->seclabel.norelabel = true;
else
- def->seclabel.relabel = true;
+ def->seclabel.norelabel = false;
}
/* Only parse label, if using static labels, or
@@ -5114,7 +5114,7 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
}
/* Only parse imagelabel, if requested live XML with relabeling */
- if (def->seclabel.relabel &&
+ if (!def->seclabel.norelabel &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
p = virXPathStringLimit("string(./seclabel/imagelabel[1])",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
@@ -9890,15 +9890,15 @@ char *virDomainDefFormat(virDomainDefPtr def,
(flags & VIR_DOMAIN_XML_INACTIVE)) {
virBufferAsprintf(&buf, " <seclabel type='%s' model='%s' relabel='%s'/>\n",
sectype, def->seclabel.model,
- def->seclabel.relabel ? "yes" : "no");
+ def->seclabel.norelabel ? "no" : "yes");
} else {
virBufferAsprintf(&buf, " <seclabel type='%s' model='%s' relabel='%s'>\n",
sectype, def->seclabel.model,
- def->seclabel.relabel ? "yes" : "no");
+ def->seclabel.norelabel ? "no" : "yes");
if (def->seclabel.label)
virBufferEscapeString(&buf, " <label>%s</label>\n",
def->seclabel.label);
- if (def->seclabel.relabel && def->seclabel.imagelabel)
+ if (!def->seclabel.norelabel && def->seclabel.imagelabel)
virBufferEscapeString(&buf, " <imagelabel>%s</imagelabel>\n",
def->seclabel.imagelabel);
if (def->seclabel.baselabel &&
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 258289a..44d5bcd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -960,7 +960,7 @@ struct _virSecurityLabelDef {
char *imagelabel; /* security image label string */
char *baselabel; /* base name of label string */
int type; /* virDomainSeclabelType */
- bool relabel;
+ bool norelabel;
};
enum virDomainTimerNameType {
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 98995a8..76c6e3d 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -265,7 +265,7 @@ reload_profile(virSecurityManagerPtr mgr,
int rc = -1;
char *profile_name = NULL;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
if ((profile_name = get_profile_name(vm)) == NULL)
@@ -610,7 +610,7 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
int rc = -1;
char *profile_name;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
@@ -682,7 +682,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
struct SDPDOP *ptr;
int ret = -1;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -741,7 +741,7 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
return reload_profile(mgr, vm, NULL, false);
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 44e770e..50e1978 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -537,7 +537,7 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
/* Don't restore labels on readoly/shared disks, because
@@ -621,7 +621,7 @@ SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
return virDomainDiskDefForeachPath(disk,
@@ -661,7 +661,7 @@ SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int ret = -1;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -730,7 +730,7 @@ SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int ret = -1;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -784,7 +784,7 @@ SELinuxSetSecurityChardevLabel(virDomainObjPtr vm,
char *in = NULL, *out = NULL;
int ret = -1;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
switch (dev->type) {
@@ -830,7 +830,7 @@ SELinuxRestoreSecurityChardevLabel(virDomainObjPtr vm,
char *in = NULL, *out = NULL;
int ret = -1;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
switch (dev->type) {
@@ -918,7 +918,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
VIR_DEBUG("Restoring security label on %s", vm->def->name);
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
@@ -989,7 +989,7 @@ SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
return SELinuxSetFilecon(savefile, secdef->imagelabel);
@@ -1003,7 +1003,7 @@ SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
return SELinuxRestoreSecurityFileLabel(savefile);
@@ -1218,7 +1218,7 @@ SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int i;
- if (!secdef->relabel)
+ if (secdef->norelabel)
return 0;
for (i = 0 ; i < vm->def->ndisks ; i++) {
--
1.7.6
13 years, 4 months
[libvirt] networkxml2argvtest fails to compile
by Ruben Kerkhof
Hi all,
Building libvirt 0.9.3 from source with --without-network, make check
fails with:
CC networkxml2xmltest.o
CCLD networkxml2xmltest
CC networkxml2argvtest.o
make[2]: *** No rule to make target
`../src/libvirt_driver_network.la', needed by `networkxml2argvtest'.
Stop.
make[2]: Leaving directory `/home/ruben/src/libvirt/libvirt-0.9.3/tests'
make[1]: *** [check-am] Error 2
make[1]: Leaving directory `/home/ruben/src/libvirt/libvirt-0.9.3/tests'
make: *** [check-recursive] Error 1
Kind regards,
Ruben
13 years, 4 months
[libvirt] [PATCH] qemu: Fix virFileMakePath error handling in snapshot creation
by Matthias Bolte
virFileMakePath returns an errno value on error, that will never be
negative. So a virFileMakePath error whould have been ignored here.
---
src/qemu/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 363a361..aab3ab9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7498,7 +7498,7 @@ static int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
goto cleanup;
}
err = virFileMakePath(snapDir);
- if (err < 0) {
+ if (err != 0) {
virReportSystemError(err, _("cannot create snapshot directory '%s'"),
snapDir);
goto cleanup;
--
1.7.4.1
13 years, 4 months
[libvirt] problems with <seclabel> when restarting libvirtd
by Laine Stump
I had libvirtd build from 0.9.2+something running on my test machine.
There was a single guest running on it.
I grabbed the latest libvirt from git (0.9.3+??), built an rpm, and
installed it. My guest reconnected with no problems, but I was unable to
start new guests due to an selinux problem with the labeling of the
image file. Interestingly, I found that I could shutdown and restart the
one guest that had been running at the time of the upgrade. *Until* I
restarted libvirtd again while the guest was stopped. After this point,
I could no longer start that guest either.
I then set selinux to permissive mode and was able to start my original
guest. Then I restarted libvirtd and found that, although the qemu-kvm
process was still running, libvirtd couldn't reconnect to the guest.
When I looked at the logs, I saw this:
error: virSecurityLabelDefParseXML:5073 : unsupported configuration:
dynamic label type must use resource relabeling
In the domain state file, I see this:
| <seclabel type='dynamic' model='selinux' relabel='no'>
| <label>system_u:system_r:svirt_t:s-:c419,c955</label>
| </seclabel>
The data in the state file was written by the same version of libvirtd
that wrote it. So why did it write something it knows it doesn't support?
13 years, 4 months
[libvirt] Duplicate symbol error with 0.9.3 on OSX
by Justin Clift
Hi all,
Just went to update the OSX libvirt build for 0.9.3, but it's
giving a duplicate symbol error:
ld: duplicate symbol _virNetworkDNSHostsDef in ./.libs/libvirt_driver_test.a(libvirt_driver_test_la-test_driver.o) and ./.libs/libvirt_conf.a(libvirt_conf_la-network_conf.o)
"virNetworkDNSHostsDef" is definitely in src/conf/network_conf.*,
but not seeing it anywhere in src/test/test_driver.*.
Anyone have suggestions on what to look at?
Regards and best wishes,
Justin Clift
--
Aeolus Community Manager
http://www.aeolusproject.org
13 years, 4 months
[libvirt] [PATCH] Quieten build & ensure API build scripts exit with non-zero status
by Daniel P. Berrange
The current API build scripts will continue and exit with a zero
status even if they find problems. This has been the cause of many
build problems, or hidden build errors, in the past. Change the
scripts so they always exit with a non-zero status for any problems
they do not understand. Also turn off all debug output by default
so they respect $(AM_V_GEN)
* docs/Makefile.am: Use $(AM_V_GEN) for API/HTML scripts
* docs/apibuild.py, python/generator.py: Exit with non-zero status
if problems are found. Also be silent, not outputting any debug
messages.
* src/Makefile.am: Use $(AM_V_GEN) for ESX generator
* python/Makefile.am: Tweak rule
---
docs/Makefile.am | 11 ++----
docs/apibuild.py | 95 ++++++++++++++++++++++++++++++--------------------
python/Makefile.am | 6 ++--
python/generator.py | 16 +++++---
src/Makefile.am | 2 +-
5 files changed, 75 insertions(+), 55 deletions(-)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 050ebe1..e7d356e 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -153,21 +153,18 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
- -@if [ -x $(XSLTPROC) ] ; then \
- echo "Rebuilding the HTML pages from the XML API" ; \
+ $(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet -o $(srcdir)/ \
- $(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi
- -@if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
+ $(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi ; \
+ if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
if $(XMLCATALOG) '$(XML_CATALOG_FILE)' "-//W3C//DTD XHTML 1.0 Strict//EN" \
> /dev/null ; then \
- echo "Validating the resulting XHTML pages" ; \
SGML_CATALOG_FILES='$(XML_CATALOG_FILE)' \
$(XMLLINT) --catalogs --nonet --valid --noout $(srcdir)/html/*.html ; \
else echo "missing XHTML1 DTD" ; fi ; fi
$(addprefix $(srcdir)/,$(devhelphtml)): $(srcdir)/libvirt-api.xml $(devhelpxsl)
- -@echo Rebuilding devhelp files
- -@if [ -x $(XSLTPROC) ] ; then \
+ $(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet -o $(srcdir)/devhelp/ \
$(top_srcdir)/docs/devhelp/devhelp.xsl $(srcdir)/libvirt-api.xml ; fi
diff --git a/docs/apibuild.py b/docs/apibuild.py
index f31a853..cb273dc 100755
--- a/docs/apibuild.py
+++ b/docs/apibuild.py
@@ -11,6 +11,8 @@ import os, sys
import string
import glob
+quiet=1
+warnings=0
debug=0
debugsym=None
@@ -95,7 +97,7 @@ class identifier:
self.conditionals = None
else:
self.conditionals = conditionals[:]
- if self.name == debugsym:
+ if self.name == debugsym and not quiet:
print "=> define %s : %s" % (debugsym, (module, type, info,
extra, conditionals))
@@ -155,7 +157,7 @@ class identifier:
def update(self, header, module, type = None, info = None, extra=None,
conditionals=None):
- if self.name == debugsym:
+ if self.name == debugsym and not quiet:
print "=> update %s : %s" % (debugsym, (module, type, info,
extra, conditionals))
if header != None and self.header == None:
@@ -203,7 +205,7 @@ class index:
if d != None and name != None and type != None:
self.references[name] = d
- if name == debugsym:
+ if name == debugsym and not quiet:
print "New ref: %s" % (d)
return d
@@ -244,9 +246,9 @@ class index:
elif type == "macro":
self.macros[name] = d
else:
- print "Unable to register type ", type
+ self.warning("Unable to register type ", type)
- if name == debugsym:
+ if name == debugsym and not quiet:
print "New symbol: %s" % (d)
return d
@@ -260,8 +262,8 @@ class index:
if self.macros.has_key(id):
del self.macros[id]
if self.functions.has_key(id):
- print "function %s from %s redeclared in %s" % (
- id, self.functions[id].header, idx.functions[id].header)
+ self.warning("function %s from %s redeclared in %s" % (
+ id, self.functions[id].header, idx.functions[id].header))
else:
self.functions[id] = idx.functions[id]
self.identifiers[id] = idx.functions[id]
@@ -273,15 +275,15 @@ class index:
if self.macros.has_key(id):
del self.macros[id]
if self.variables.has_key(id):
- print "variable %s from %s redeclared in %s" % (
- id, self.variables[id].header, idx.variables[id].header)
+ self.warning("variable %s from %s redeclared in %s" % (
+ id, self.variables[id].header, idx.variables[id].header))
else:
self.variables[id] = idx.variables[id]
self.identifiers[id] = idx.variables[id]
for id in idx.structs.keys():
if self.structs.has_key(id):
- print "struct %s from %s redeclared in %s" % (
- id, self.structs[id].header, idx.structs[id].header)
+ self.warning("struct %s from %s redeclared in %s" % (
+ id, self.structs[id].header, idx.structs[id].header))
else:
self.structs[id] = idx.structs[id]
self.identifiers[id] = idx.structs[id]
@@ -294,8 +296,8 @@ class index:
self.identifiers[id] = idx.unions[id]
for id in idx.typedefs.keys():
if self.typedefs.has_key(id):
- print "typedef %s from %s redeclared in %s" % (
- id, self.typedefs[id].header, idx.typedefs[id].header)
+ self.warning("typedef %s from %s redeclared in %s" % (
+ id, self.typedefs[id].header, idx.typedefs[id].header))
else:
self.typedefs[id] = idx.typedefs[id]
self.identifiers[id] = idx.typedefs[id]
@@ -311,15 +313,15 @@ class index:
if self.enums.has_key(id):
continue
if self.macros.has_key(id):
- print "macro %s from %s redeclared in %s" % (
- id, self.macros[id].header, idx.macros[id].header)
+ self.warning("macro %s from %s redeclared in %s" % (
+ id, self.macros[id].header, idx.macros[id].header))
else:
self.macros[id] = idx.macros[id]
self.identifiers[id] = idx.macros[id]
for id in idx.enums.keys():
if self.enums.has_key(id):
- print "enum %s from %s redeclared in %s" % (
- id, self.enums[id].header, idx.enums[id].header)
+ self.warning("enum %s from %s redeclared in %s" % (
+ id, self.enums[id].header, idx.enums[id].header))
else:
self.enums[id] = idx.enums[id]
self.identifiers[id] = idx.enums[id]
@@ -330,10 +332,10 @@ class index:
# check that function condition agrees with header
if idx.functions[id].conditionals != \
self.functions[id].conditionals:
- print "Header condition differs from Function for %s:" \
- % id
- print " H: %s" % self.functions[id].conditionals
- print " C: %s" % idx.functions[id].conditionals
+ self.warning("Header condition differs from Function for %s:" \
+ % id)
+ self.warning(" H: %s" % self.functions[id].conditionals)
+ self.warning(" C: %s" % idx.functions[id].conditionals)
up = idx.functions[id]
self.functions[id].update(None, up.module, up.type, up.info, up.extra)
# else:
@@ -356,12 +358,13 @@ class index:
def analyze(self):
- self.analyze_dict("functions", self.functions)
- self.analyze_dict("variables", self.variables)
- self.analyze_dict("structs", self.structs)
- self.analyze_dict("unions", self.unions)
- self.analyze_dict("typedefs", self.typedefs)
- self.analyze_dict("macros", self.macros)
+ if not quiet:
+ self.analyze_dict("functions", self.functions)
+ self.analyze_dict("variables", self.variables)
+ self.analyze_dict("structs", self.structs)
+ self.analyze_dict("unions", self.unions)
+ self.analyze_dict("typedefs", self.typedefs)
+ self.analyze_dict("macros", self.macros)
class CLexer:
"""A lexer for the C language, tokenize the input by reading and
@@ -621,6 +624,8 @@ class CParser:
info, extra, self.conditionals)
def warning(self, msg):
+ global warnings
+ warnings = warnings + 1
if self.no_error:
return
print msg
@@ -1802,7 +1807,8 @@ class CParser:
return token
def parse(self):
- self.warning("Parsing %s" % (self.filename))
+ if not quiet:
+ print "Parsing %s" % (self.filename)
token = self.token()
while token != None:
if token[0] == 'name':
@@ -1869,7 +1875,8 @@ class docBuilder:
pass
def analyze(self):
- print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys()))
+ if not quiet:
+ print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys()))
self.idx.analyze()
def scanHeaders(self):
@@ -1995,7 +2002,7 @@ class docBuilder:
else:
output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc))
except:
- print "Failed to serialize struct %s" % (name)
+ self.warning("Failed to serialize struct %s" % (name))
output.write(" </struct>\n")
else:
output.write("/>\n");
@@ -2023,7 +2030,7 @@ class docBuilder:
def serialize_function(self, output, name):
id = self.idx.functions[name]
- if name == debugsym:
+ if name == debugsym and not quiet:
print "=>", id
output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type,
@@ -2059,7 +2066,7 @@ class docBuilder:
output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
self.indexString(name, param[2])
except:
- print "Failed to save function %s info: " % name, `id.info`
+ self.warning("Failed to save function %s info: " % name, `id.info`)
output.write(" </%s>\n" % (id.type))
def serialize_exports(self, output, file):
@@ -2074,7 +2081,7 @@ class docBuilder:
escape(dict.info[data]),
string.lower(data)))
except:
- print "Header %s lacks a %s description" % (module, data)
+ self.warning("Header %s lacks a %s description" % (module, data))
if dict.info.has_key('Description'):
desc = dict.info['Description']
if string.find(desc, "DEPRECATED") != -1:
@@ -2287,7 +2294,8 @@ class docBuilder:
def serialize(self):
filename = "%s/%s-api.xml" % (self.path, self.name)
- print "Saving XML description %s" % (filename)
+ if not quiet:
+ print "Saving XML description %s" % (filename)
output = open(filename, "w")
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
output.write("<api name='%s'>\n" % self.name)
@@ -2323,7 +2331,8 @@ class docBuilder:
output.close()
filename = "%s/%s-refs.xml" % (self.path, self.name)
- print "Saving XML Cross References %s" % (filename)
+ if not quiet:
+ print "Saving XML Cross References %s" % (filename)
output = open(filename, "w")
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
output.write("<apirefs name='%s'>\n" % self.name)
@@ -2336,7 +2345,8 @@ def rebuild():
builder = None
srcdir = os.environ["srcdir"]
if glob.glob(srcdir + "/../src/libvirt.c") != [] :
- print "Rebuilding API description for libvirt"
+ if not quiet:
+ print "Rebuilding API description for libvirt"
dirs = [srcdir + "/../src",
srcdir + "/../src/util",
srcdir + "/../include/libvirt"]
@@ -2344,12 +2354,13 @@ def rebuild():
dirs.append("../include/libvirt")
builder = docBuilder("libvirt", srcdir, dirs, [])
elif glob.glob("src/libvirt.c") != [] :
- print "Rebuilding API description for libvirt"
+ if not quiet:
+ print "Rebuilding API description for libvirt"
builder = docBuilder("libvirt", srcdir,
["src", "src/util", "include/libvirt"],
[])
else:
- print "rebuild() failed, unable to guess the module"
+ self.warning("rebuild() failed, unable to guess the module")
return None
builder.scan()
builder.analyze()
@@ -2368,5 +2379,13 @@ if __name__ == "__main__":
if len(sys.argv) > 1:
debug = 1
parse(sys.argv[1])
+ if warnings > 0:
+ sys.exit(2)
+ else:
+ sys.exit(0)
else:
rebuild()
+ if warnings > 0:
+ sys.exit(2)
+ else:
+ sys.exit(0)
diff --git a/python/Makefile.am b/python/Makefile.am
index 0edb3e4..a4c9a6b 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -53,11 +53,11 @@ GENERATED= libvirt-export.c \
libvirt.h \
libvirt.py
-generated.stamp: $(srcdir)/$(GENERATE) $(API_DESC)
- $(PYTHON) $(srcdir)/$(GENERATE) $(PYTHON)
+$(GENERATE).stamp: $(srcdir)/$(GENERATE) $(API_DESC)
+ $(AM_V_GEN)$(PYTHON) $(srcdir)/$(GENERATE) $(PYTHON) && \
touch $@
-$(GENERATED): generated.stamp
+$(GENERATED): $(GENERATE).stamp
$(libvirtmod_la_OBJECTS): $(GENERATED)
diff --git a/python/generator.py b/python/generator.py
index c27ff73..d3a3616 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -11,6 +11,8 @@ import sys
import string
import re
+quiet=1
+
if __name__ == "__main__":
# launched as a script
srcPref = os.path.dirname(sys.argv[0])
@@ -617,7 +619,8 @@ def buildStubs():
sys.exit(1)
n = len(functions.keys())
- print "Found %d functions in libvirt-api.xml" % (n)
+ if not quiet:
+ print "Found %d functions in libvirt-api.xml" % (n)
py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
try:
@@ -629,8 +632,8 @@ def buildStubs():
except IOError, msg:
print file, ":", msg
-
- print "Found %d functions in libvirt-override-api.xml" % (
+ if not quiet:
+ print "Found %d functions in libvirt-override-api.xml" % (
len(functions.keys()) - n)
nb_wrap = 0
failed = 0
@@ -662,20 +665,21 @@ def buildStubs():
export.close()
wrapper.close()
- print "Generated %d wrapper functions" % nb_wrap
+ if not quiet:
+ print "Generated %d wrapper functions" % nb_wrap
if unknown_types:
print "Missing type converters: "
for type in unknown_types.keys():
print "%s:%d " % (type, len(unknown_types[type])),
- print
-
for f in functions_failed:
print "ERROR: failed %s" % f
if failed > 0:
return -1
+ if len(unknown_types) > 0:
+ return -1
return 0
#######################################################################
diff --git a/src/Makefile.am b/src/Makefile.am
index cd8a7e9..844ec9d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -786,7 +786,7 @@ endif
BUILT_SOURCES += $(ESX_DRIVER_GENERATED)
$(ESX_DRIVER_GENERATED): $(srcdir)/esx/esx_vi_generator.input $(srcdir)/esx/esx_vi_generator.py
- -srcdir=$(srcdir) $(srcdir)/esx/esx_vi_generator.py
+ $(AM_V_GEN)srcdir=$(srcdir) $(srcdir)/esx/esx_vi_generator.py
if WITH_ESX
if WITH_DRIVER_MODULES
--
1.7.4.4
13 years, 4 months
[libvirt] [PATCH] qemu: Add support for SGA video
by Michal Privoznik
This patch extends possible values for <video> element. Serial Graphics
Adapter allows users to see BIOS messages from the very first moment
domain boots up. Therefore, users can choose boot medium, set PXE, etc.
However, to be able to use this, one need SGABIOS, which is accessible
here: http://code.google.com/p/sgabios/
---
docs/formatdomain.html.in | 5 +++--
docs/schemas/domain.rng | 1 +
src/conf/domain_conf.c | 43 ++++++++++++++++++++++++-------------------
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 28 ++++++++++++++++++++++------
5 files changed, 51 insertions(+), 27 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3a64983..2d89b37 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2005,8 +2005,9 @@ qemu-kvm -net nic,model=? /dev/null
<dd>
The <code>model</code> element has a mandatory <code>type</code>
attribute which takes the value "vga", "cirrus", "vmvga", "xen",
- "vbox", or "qxl" (<span class="since">since 0.8.6</span>)
- depending on the hypervisor features available.
+ "vbox", "qxl" (<span class="since">since 0.8.6</span>), or "sga"
+ (<span class="since">Since 0.9.4</span>) depending on the hypervisor
+ features available.
You can also provide the amount of video memory in kilobytes using
<code>vram</code> and the number of screen with <code>heads</code>.
</dd>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 891662d..74bc111 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1502,6 +1502,7 @@
<value>xen</value>
<value>vbox</value>
<value>qxl</value>
+ <value>sga</value>
</choice>
</attribute>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f9bf51e..9848359 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -299,7 +299,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"vmvga",
"xen",
"vbox",
- "qxl")
+ "qxl",
+ "sga")
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse",
@@ -4713,28 +4714,32 @@ virDomainVideoDefParseXML(const xmlNodePtr node,
}
}
- if (vram) {
- if (virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse video ram '%s'"), vram);
- goto error;
+ /* SGA video device does not support heads, vram
+ * or PCI address. It is not PCI device anyway */
+ if (def->type != VIR_DOMAIN_VIDEO_TYPE_SGA) {
+ if (vram) {
+ if (virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse video ram '%s'"), vram);
+ goto error;
+ }
+ } else {
+ def->vram = virDomainVideoDefaultRAM(dom, def->type);
}
- } else {
- def->vram = virDomainVideoDefaultRAM(dom, def->type);
- }
- if (heads) {
- if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse video heads '%s'"), heads);
- goto error;
+ if (heads) {
+ if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse video heads '%s'"), heads);
+ goto error;
+ }
+ } else {
+ def->heads = 1;
}
- } else {
- def->heads = 1;
- }
- if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
- goto error;
+ if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
+ goto error;
+ }
VIR_FREE(type);
VIR_FREE(vram);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e81977c..7f60754 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -605,6 +605,7 @@ enum virDomainVideoType {
VIR_DOMAIN_VIDEO_TYPE_XEN,
VIR_DOMAIN_VIDEO_TYPE_VBOX,
VIR_DOMAIN_VIDEO_TYPE_QXL,
+ VIR_DOMAIN_VIDEO_TYPE_SGA,
VIR_DOMAIN_VIDEO_TYPE_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6e4480e..7685d7e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -80,7 +80,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"vmware",
"", /* no arg needed for xen */
"", /* don't support vbox */
- "qxl");
+ "qxl",
+ "sga");
static void
uname_normalize (struct utsname *ut)
@@ -1213,7 +1214,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
/* Further non-primary video cards */
for (i = 1; i < def->nvideos ; i++) {
- if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+ if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
+ def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_SGA)
continue;
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0)
goto error;
@@ -2083,8 +2085,9 @@ qemuBuildVideoDevStr(virDomainVideoDefPtr video,
virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
}
- if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0)
- goto error;
+ if (video->type != VIR_DOMAIN_VIDEO_TYPE_SGA)
+ if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0)
+ goto error;
if (virBufferError(&buf)) {
virReportOOMError();
@@ -4254,6 +4257,11 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuCapsGet(qemuCaps, QEMU_CAPS_VGA)) {
if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) {
/* nothing - vga has no effect on Xen pvfb */
+ } else if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_SGA) {
+ if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
+ virCommandAddArgList(cmd, "-device", "sga", NULL);
+ else
+ virCommandAddArg(cmd, "-nographic");
} else {
if ((def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
!qemuCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) {
@@ -4309,6 +4317,13 @@ qemuBuildCommandLine(virConnectPtr conn,
/* No special args - this is the default */
break;
+ case VIR_DOMAIN_VIDEO_TYPE_SGA:
+ if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
+ virCommandAddArgList(cmd, "-device", "sga", NULL);
+ else
+ virCommandAddArg(cmd, "-nographic");
+ break;
+
default:
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("video type %s is not supported with this QEMU"),
@@ -4321,10 +4336,11 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
for (i = 1 ; i < def->nvideos ; i++) {
char *str;
- if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+ if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL &&
+ def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_SGA) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("video type %s is only valid as primary video card"),
- virDomainVideoTypeToString(def->videos[0]->type));
+ virDomainVideoTypeToString(def->videos[i]->type));
goto error;
}
--
1.7.5.rc3
13 years, 4 months