[libvirt] [PATCH] util:report diskchain as broken if without enough permission
by Guannan Ren
When backing files of a disk file are stored in NFS shared folder,
qemu process requires at least the read permission.
But in some rare situation, these backing files can not even be read
If so, we should treat the diskchains as broken.
This patch add a checking for this, report negative in such case.
---
src/util/virstoragefile.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 0b9cec3..3dee7ab 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1127,7 +1127,11 @@ virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
/* Break if no backing store or backing store is not file */
if (!tmp->backingStoreRaw)
break;
- if (!tmp->backingStore) {
+
+ if (tmp->backingStoreIsFile) {
+ if (!tmp->backingMeta)
+ goto error;
+ } else if (!tmp->backingStore) {
if (VIR_STRDUP(*brokenFile, tmp->backingStoreRaw) < 0)
goto error;
break;
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] selinux: distinguish failure to label from request to avoid label
by Eric Blake
https://bugzilla.redhat.com/show_bug.cgi?id=924153
Commit 904e05a2 (v0.9.9) added a per-<disk> seclabel element with
an attribute relabel='no' in order to try and minimize the
impact of shutdown delays when an NFS server disappears. The idea
was that if a disk is on NFS and can't be labeled in the first
place, there is no need to attempt the (no-op) relabel on domain
shutdown. Unfortunately, the way this was implemented was by
modifying the domain XML so that the optimization would survive
libvirtd restart, but in a way that is indistinguishable from an
explicit user setting. Furthermore, once the setting is turned
on, libvirt avoids attempts at labeling, even for operations like
snapshot or blockcopy where the chain is being extended or pivoted
onto non-NFS, where SELinux labeling is once again possible. As
a result, it was impossible to do a blockcopy to pivot from an
NFS image file onto a local file.
The solution is to separate the semantics of a chain that must
not be labeled (which the user can set even on persistent domains)
vs. the optimization of not attempting a relabel on cleanup (a
live-only annotation), and using only the user's explicit notation
rather than the optimization as the decision on whether to skip
a label attempt in the first place. When upgrading an older
libvirtd to a newer, an NFS volume will still attempt the relabel;
but as the avoidance of a relabel was only an optimization, this
shouldn't cause any problems.
In the ideal future, libvirt will eventually have XML describing
EVERY file in the backing chain, with each file having a separate
<seclabel> element. At that point, libvirt will be able to track
more closely which files need a relabel attempt at shutdown. But
until we reach that point, the single <seclabel> for the entire
<disk> chain is treated as a hint - when a chain has only one
file, then we know it is accurate; but if the chain has more than
one file, we have to attempt relabel in spite of the attribute,
in case part of the chain is local and SELinux mattered for that
portion of the chain.
* src/conf/domain_conf.h (_virSecurityDeviceLabelDef): Add new
member.
* src/conf/domain_conf.c (virSecurityDeviceLabelDefParseXML):
Parse it, for live images only.
(virSecurityDeviceLabelDefFormat): Output it.
(virDomainDiskDefParseXML, virDomainChrSourceDefParseXML)
(virDomainDiskSourceDefFormat, virDomainChrDefFormat)
(virDomainDiskDefFormat): Pass flags on through.
* src/security/security_selinux.c
(virSecuritySELinuxRestoreSecurityImageLabelInt): Honor labelskip
when possible.
(virSecuritySELinuxSetSecurityFileLabel): Set labelskip, not
norelabel, if labeling fails.
* docs/formatdomain.html.in (seclabel): Document new xml.
* docs/schemas/domaincommon.rng (devSeclabel): Allow it in RNG.
* tests/qemuxml2argvdata/qemuxml2argv-seclabel-*-skiplabel.xml:
* tests/qemuxml2argvdata/qemuxml2argv-seclabel-*-skiplabel.args:
* tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-*-skiplabel.xml:
New test files.
* tests/qemuxml2argvtest.c (mymain): Run the new tests.
* tests/qemuxml2xmltest.c (mymain): Likewise.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
docs/formatdomain.html.in | 6 ++-
docs/schemas/domaincommon.rng | 27 +++++++------
src/conf/domain_conf.c | 47 ++++++++++++++++------
src/conf/domain_conf.h | 3 +-
src/security/security_selinux.c | 10 ++++-
.../qemuxml2argv-seclabel-dynamic-skiplabel.args | 5 +++
.../qemuxml2argv-seclabel-dynamic-skiplabel.xml | 32 +++++++++++++++
.../qemuxml2argv-seclabel-static-skiplabel.args | 5 +++
.../qemuxml2argv-seclabel-static-skiplabel.xml | 33 +++++++++++++++
tests/qemuxml2argvtest.c | 2 +
.../qemuxml2xmlout-seclabel-dynamic-skiplabel.xml | 31 ++++++++++++++
tests/qemuxml2xmltest.c | 8 ++--
12 files changed, 178 insertions(+), 31 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-skiplabel.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 83d551a..cafa03f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5024,7 +5024,11 @@ qemu-kvm -net nic,model=? /dev/null
a <code>seclabel</code> element is attached to a specific path
rather than the top-level domain assignment, only the
attribute <code>relabel</code> or the
- sub-element <code>label</code> are supported.
+ sub-element <code>label</code> are supported. Additionally,
+ <span class="since">since 1.1.2</span>, an output-only
+ element <code>labelskip</code> will be present for active
+ domains on disks where labeling was skipped due to the image
+ being on a file system that lacks security labeling.
</p>
<h2><a name="examples">Example configs</a></h2>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index ac807e6..dfcd61c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -152,34 +152,35 @@
<define name="devSeclabel">
<element name="seclabel">
<!-- A per-device seclabel override is more limited, either
- relabel=no or a <label> must be present. -->
+ relabel=no or a <label> must be present on input;
+ output also can include labelskip=yes. -->
+ <optional>
+ <attribute name='model'>
+ <text/>
+ </attribute>
+ </optional>
<choice>
<group>
- <optional>
- <attribute name='model'>
- <text/>
- </attribute>
- </optional>
<attribute name='relabel'>
<value>no</value>
</attribute>
</group>
<group>
- <optional>
- <attribute name='model'>
- <text/>
- </attribute>
- </optional>
+ <attribute name='labelskip'>
+ <value>yes</value>
+ </attribute>
+ </group>
+ <group>
<optional>
<attribute name='relabel'>
<value>yes</value>
</attribute>
</optional>
- <zeroOrMore>
+ <oneOrMore>
<element name='label'>
<text/>
</element>
- </zeroOrMore>
+ </oneOrMore>
</group>
</choice>
</element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7309877..759f686 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4484,7 +4484,8 @@ static int
virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
size_t *nseclabels_rtn,
virSecurityLabelDefPtr *vmSeclabels,
- int nvmSeclabels, xmlXPathContextPtr ctxt)
+ int nvmSeclabels, xmlXPathContextPtr ctxt,
+ unsigned int flags)
{
virSecurityDeviceLabelDefPtr *seclabels;
size_t nseclabels = 0;
@@ -4492,7 +4493,7 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
size_t i, j;
xmlNodePtr *list = NULL;
virSecurityLabelDefPtr vmDef = NULL;
- char *model, *relabel, *label;
+ char *model, *relabel, *label, *labelskip;
if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) < 0)
goto error;
@@ -4547,6 +4548,13 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
seclabels[i]->norelabel = false;
}
+ /* labelskip is only parsed on live images */
+ labelskip = virXMLPropString(list[i], "labelskip");
+ seclabels[i]->labelskip = false;
+ if (labelskip && !(flags & VIR_DOMAIN_XML_INACTIVE))
+ seclabels[i]->labelskip = STREQ(labelskip, "yes");
+ VIR_FREE(labelskip);
+
ctxt->node = list[i];
label = virXPathStringLimit("string(./label)",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
@@ -5208,7 +5216,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
&def->nseclabels,
vmSeclabels,
nvmSeclabels,
- ctxt) < 0)
+ ctxt,
+ flags) < 0)
goto error;
ctxt->node = saved_node;
}
@@ -6884,7 +6893,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
&chr_def->nseclabels,
vmSeclabels,
nvmSeclabels,
- ctxt) < 0) {
+ ctxt,
+ flags) < 0) {
ctxt->node = saved_node;
goto error;
}
@@ -14018,14 +14028,23 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
static void
virSecurityDeviceLabelDefFormat(virBufferPtr buf,
- virSecurityDeviceLabelDefPtr def)
+ virSecurityDeviceLabelDefPtr def,
+ unsigned int flags)
{
+ /* For offline output, skip elements that allow labels but have no
+ * label specified (possible if labelskip was ignored on input). */
+ if ((flags & VIR_DOMAIN_XML_INACTIVE) && !def->label && !def->norelabel)
+ return;
+
virBufferAddLit(buf, "<seclabel");
if (def->model)
virBufferAsprintf(buf, " model='%s'", def->model);
- virBufferAsprintf(buf, " relabel='%s'", def->norelabel ? "no" : "yes");
+ if (def->labelskip)
+ virBufferAddLit(buf, " labelskip='yes'");
+ else
+ virBufferAsprintf(buf, " relabel='%s'", def->norelabel ? "no" : "yes");
if (def->label) {
virBufferAddLit(buf, ">\n");
@@ -14100,7 +14119,8 @@ virDomainDiskBlockIoDefFormat(virBufferPtr buf,
static int
virDomainDiskSourceDefFormat(virBufferPtr buf,
- virDomainDiskDefPtr def)
+ virDomainDiskDefPtr def,
+ unsigned int flags)
{
int n;
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
@@ -14119,7 +14139,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 8);
for (n = 0; n < def->nseclabels; n++)
- virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+ flags);
virBufferAdjustIndent(buf, -8);
virBufferAddLit(buf, " </source>\n");
} else {
@@ -14136,7 +14157,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 8);
for (n = 0; n < def->nseclabels; n++)
- virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+ flags);
virBufferAdjustIndent(buf, -8);
virBufferAddLit(buf, " </source>\n");
} else {
@@ -14201,7 +14223,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 8);
for (n = 0; n < def->nseclabels; n++)
- virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+ flags);
virBufferAdjustIndent(buf, -8);
virBufferAddLit(buf, " </source>\n");
} else {
@@ -14337,7 +14360,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " </auth>\n");
}
- if (virDomainDiskSourceDefFormat(buf, def) < 0)
+ if (virDomainDiskSourceDefFormat(buf, def, flags) < 0)
return -1;
virDomainDiskGeometryDefFormat(buf, def);
virDomainDiskBlockIoDefFormat(buf, def);
@@ -15189,7 +15212,7 @@ virDomainChrDefFormat(virBufferPtr buf,
if (def->seclabels && def->nseclabels > 0) {
virBufferAdjustIndent(buf, 2);
for (n = 0; n < def->nseclabels; n++)
- virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n], flags);
virBufferAdjustIndent(buf, -2);
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3e118d6..500a5be 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -343,7 +343,8 @@ typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr;
struct _virSecurityDeviceLabelDef {
char *model;
char *label; /* image label string */
- bool norelabel;
+ bool norelabel; /* true to skip label attempts */
+ bool labelskip; /* live-only; true if skipping failed label attempt */
};
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e3dce66a..b1372e6 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1135,6 +1135,14 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
if (seclabel->norelabel || (disk_seclabel && disk_seclabel->norelabel))
return 0;
+ /* If labelskip is true and there are no backing files, then we
+ * know it is safe to skip the restore. FIXME - backing files should
+ * be tracked in domain XML, at which point labelskip should be a
+ * per-file attribute instead of a disk attribute. */
+ if (disk_seclabel && disk_seclabel->labelskip &&
+ !disk->backingChain)
+ return 0;
+
/* Don't restore labels on readoly/shared disks, because
* other VMs may still be accessing these
* Alternatively we could iterate over all running
@@ -1219,7 +1227,7 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
disk_seclabel = virDomainDiskDefGenSecurityLabelDef(SECURITY_SELINUX_NAME);
if (!disk_seclabel)
return -1;
- disk_seclabel->norelabel = true;
+ disk_seclabel->labelskip = true;
if (VIR_APPEND_ELEMENT(disk->seclabels, disk->nseclabels,
disk_seclabel) < 0) {
virSecurityDeviceLabelDefFree(disk_seclabel);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.args b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.args
new file mode 100644
index 0000000..892c6b5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
+-hda /dev/HostVG/QEMUGuest1 \
+-net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.xml
new file mode 100644
index 0000000..e3bc700
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-skiplabel.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <seclabel type='dynamic' model='selinux' relabel='yes'>
+ <baselabel>system_u:system_r:svirt_custom_t:s0</baselabel>
+ </seclabel>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.args b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.args
new file mode 100644
index 0000000..892c6b5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
+-hda /dev/HostVG/QEMUGuest1 \
+-net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.xml
new file mode 100644
index 0000000..a743448
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-skiplabel.xml
@@ -0,0 +1,33 @@
+<domain type='qemu' id='1'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <seclabel type='static' model='selinux' relabel='yes'>
+ <label>system_u:system_r:svirt_custom_t:s0:c192,c392</label>
+ <imagelabel>system_u:system_r:svirt_custom_t:s0:c192,c392</imagelabel>
+ </seclabel>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 679124e..09cc516 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -923,8 +923,10 @@ mymain(void)
DO_TEST("seclabel-dynamic", QEMU_CAPS_NAME);
DO_TEST("seclabel-dynamic-baselabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-dynamic-override", QEMU_CAPS_NAME);
+ DO_TEST("seclabel-dynamic-skiplabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-static", QEMU_CAPS_NAME);
DO_TEST("seclabel-static-relabel", QEMU_CAPS_NAME);
+ DO_TEST("seclabel-static-skiplabel", QEMU_CAPS_NAME);
DO_TEST("seclabel-none", QEMU_CAPS_NAME);
DO_TEST("pseries-basic",
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-skiplabel.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-skiplabel.xml
new file mode 100644
index 0000000..0764691
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-skiplabel.xml
@@ -0,0 +1,31 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'>
+ </source>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <seclabel type='dynamic' model='selinux' relabel='yes'>
+ <baselabel>system_u:system_r:svirt_custom_t:s0</baselabel>
+ </seclabel>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 5c6730d..68fbdc5 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -30,6 +30,7 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml, bool live)
char *actual = NULL;
int ret = -1;
virDomainDefPtr def = NULL;
+ unsigned int flags = live ? 0 : VIR_DOMAIN_XML_INACTIVE;
if (virtTestLoadFile(inxml, &inXmlData) < 0)
goto fail;
@@ -37,11 +38,10 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml, bool live)
goto fail;
if (!(def = virDomainDefParseString(inXmlData, driver.caps, driver.xmlopt,
- QEMU_EXPECTED_VIRT_TYPES,
- live ? 0 : VIR_DOMAIN_XML_INACTIVE)))
+ QEMU_EXPECTED_VIRT_TYPES, flags)))
goto fail;
- if (!(actual = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE)))
+ if (!(actual = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE | flags)))
goto fail;
if (STRNEQ(outXmlData, actual)) {
@@ -257,7 +257,9 @@ mymain(void)
DO_TEST_FULL("seclabel-dynamic-baselabel", false, WHEN_INACTIVE);
DO_TEST_FULL("seclabel-dynamic-override", false, WHEN_INACTIVE);
+ DO_TEST_FULL("seclabel-dynamic-skiplabel", true, WHEN_INACTIVE);
DO_TEST("seclabel-static");
+ DO_TEST_FULL("seclabel-static-skiplabel", false, WHEN_ACTIVE);
DO_TEST("seclabel-none");
DO_TEST("numad-static-vcpu-no-numatune");
DO_TEST("disk-scsi-lun-passthrough-sgio");
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH 2/2 v3] Check for --no-copy-dt-needed linker flag
by Guido Günther
and use it when available
---
configure.ac | 1 +
daemon/Makefile.am | 1 +
m4/virt-linker-no-indirect.m4 | 30 ++++++++++++++++++++++++++++++
src/Makefile.am | 1 +
tests/Makefile.am | 1 +
tools/Makefile.am | 1 +
6 files changed, 35 insertions(+)
create mode 100644 m4/virt-linker-no-indirect.m4
diff --git a/configure.ac b/configure.ac
index ac8cfa1..25d91ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,6 +160,7 @@ AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
LIBVIRT_COMPILE_WARNINGS
LIBVIRT_COMPILE_PIE
LIBVIRT_LINKER_RELRO
+LIBVIRT_LINKER_NO_INDIRECT
LIBVIRT_CHECK_APPARMOR
LIBVIRT_CHECK_ATTR
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 5cd95aa..e34868b 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -129,6 +129,7 @@ libvirtd_LDFLAGS = \
$(PIE_LDFLAGS) \
$(RELRO_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
+ $(NO_INDIRECT_LDFLAGS) \
$(NULL)
libvirtd_LDADD = \
diff --git a/m4/virt-linker-no-indirect.m4 b/m4/virt-linker-no-indirect.m4
new file mode 100644
index 0000000..2ccd960
--- /dev/null
+++ b/m4/virt-linker-no-indirect.m4
@@ -0,0 +1,30 @@
+dnl
+dnl Check for --no-copy-dt-needed-entries
+dnl
+dnl Copyright (C) 2013 Guido Günther <agx(a)sigxcpu.org>
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library. If not, see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+
+AC_DEFUN([LIBVIRT_LINKER_NO_INDIRECT],[
+ AC_MSG_CHECKING([for how to avoid indirect lib deps])
+
+ NO_INDIRECT_LDFLAGS=
+ `$LD --help 2>&1 | grep -- "--no-copy-dt-needed-entries" >/dev/null` && \
+ NO_INDIRECT_LDFLAGS="-Wl,--no-copy-dt-needed-entries"
+ AC_SUBST([NO_INDIRECT_LDFLAGS])
+
+ AC_MSG_RESULT([$NO_INDIRECT_LDFLAGS])
+])
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c3d8a1..faa2cd6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,6 +35,7 @@ AM_CFLAGS = $(LIBXML_CFLAGS) \
AM_LDFLAGS = $(DRIVER_MODULE_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
$(RELRO_LDFLAGS) \
+ $(NO_INDIRECT_LDFLAGS) \
$(NULL)
EXTRA_DIST = $(conf_DATA) util/keymaps.csv
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9098dec..86c3e11 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -50,6 +50,7 @@ endif
LDADDS = \
$(WARN_CFLAGS) \
+ $(NO_INDIRECT_LDFLAGS) \
$(PROBES_O) \
../src/libvirt.la \
../gnulib/lib/libgnu.la
diff --git a/tools/Makefile.am b/tools/Makefile.am
index be7ed23..c5bd5bb 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -24,6 +24,7 @@ INCLUDES = \
AM_LDFLAGS = \
$(RELRO_LDFLAGS) \
+ $(NO_INDIRECT_LDFLAGS) \
$(NULL)
POD2MAN = pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)"
--
1.8.4.rc3
11 years, 2 months
[libvirt] [PATCH] python: return dictionay without value in case of no blockjob
by Guannan Ren
Currently, when there is no blockjob, dom.blockJobInfo('vda')
still reports error because it didn't distinguish return value 0 from -1.
libvirt.libvirtError: virDomainGetBlockJobInfo() failed
virDomainGetBlockJobInfo() API return value:
-1 in case of failure, 0 when nothing found, 1 found.
And use PyDict_SetItemString instead of PyDict_SetItem when key is
string type. PyDict_SetItemString increments key/value reference
count, so calling Py_DECREF() for value. For key, we don't need to
do this, because PyDict_SetItemString will handle it internally.
---
python/libvirt-override.c | 54 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 15 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index fd9ebb8..c1e8661 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4354,33 +4354,57 @@ libvirt_virDomainGetBlockJobInfo(PyObject *self ATTRIBUTE_UNUSED,
unsigned int flags;
virDomainBlockJobInfo info;
int c_ret;
- PyObject *ret;
+ PyObject *type = NULL, *bandwidth = NULL, *cur = NULL, *end = NULL;
+ PyObject *dict;
if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetBlockJobInfo",
&pyobj_domain, &path, &flags))
return NULL;
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
-LIBVIRT_BEGIN_ALLOW_THREADS;
+ if ((dict = PyDict_New()) == NULL)
+ return NULL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
c_ret = virDomainGetBlockJobInfo(domain, path, &info, flags);
-LIBVIRT_END_ALLOW_THREADS;
+ LIBVIRT_END_ALLOW_THREADS;
- if (c_ret != 1)
+ if (c_ret == 0) {
+ return dict;
+ } else if (c_ret < 0) {
+ Py_DECREF(dict);
return VIR_PY_NONE;
+ }
- if ((ret = PyDict_New()) == NULL)
- return VIR_PY_NONE;
+ if ((type = libvirt_intWrap(info.type)) == NULL ||
+ PyDict_SetItemString(dict, "type", type) < 0)
+ goto error;
+ Py_DECREF(type);
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("type"),
- libvirt_intWrap(info.type));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("bandwidth"),
- libvirt_ulongWrap(info.bandwidth));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("cur"),
- libvirt_ulonglongWrap(info.cur));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("end"),
- libvirt_ulonglongWrap(info.end));
+ if ((bandwidth = libvirt_ulongWrap(info.bandwidth)) == NULL ||
+ PyDict_SetItemString(dict, "bandwidth", bandwidth) < 0)
+ goto error;
+ Py_DECREF(bandwidth);
- return ret;
+ if ((cur = libvirt_ulonglongWrap(info.cur)) == NULL ||
+ PyDict_SetItemString(dict, "cur", cur) < 0)
+ goto error;
+ Py_DECREF(cur);
+
+ if ((end = libvirt_ulonglongWrap(info.end)) == NULL ||
+ PyDict_SetItemString(dict, "end", end) < 0)
+ goto error;
+ Py_DECREF(end);
+
+ return dict;
+
+error:
+ Py_DECREF(dict);
+ Py_XDECREF(type);
+ Py_XDECREF(bandwidth);
+ Py_XDECREF(cur);
+ Py_XDECREF(end);
+ return NULL;
}
static PyObject *
--
1.8.1.4
11 years, 2 months
[libvirt] [PATCH 0/6] Additional iSCSI/chap changes
by John Ferlan
These patches address a couple of issues I ran into while doing extra
testing on the iSCSI chap authentication patches:
https://www.redhat.com/archives/libvir-list/2013-July/msg01378.html
The first 2 or 3 patches should be candidiates to be put into rhel7.0
as updates/fixes to issues. The last 3 patches update the documentation
to show how to use secrets, pools, and iSCIS devices in the domain.
John Ferlan (6):
virsh: Print cephx and iscsi usage
qemu_conf: Fix broken logic for adding passthrough iscsi lun
Report secret usage error message similarly
docs: Update the formatdomain disk examples
docs: Update formatsecrets to include more examples of each type
docs: Update iSCSI storage pool example
docs/formatdomain.html.in | 57 +++++++++++--
docs/formatsecret.html.in | 156 +++++++++++++++++++++++++++++++++---
docs/formatstorage.html.in | 5 +-
src/qemu/qemu_command.c | 28 +++++--
src/qemu/qemu_conf.c | 2 +-
src/storage/storage_backend_iscsi.c | 28 +++++--
src/storage/storage_backend_rbd.c | 35 ++++++--
tools/virsh-secret.c | 17 ++--
8 files changed, 278 insertions(+), 50 deletions(-)
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] libxl: Resolve possible NULL dereference
by John Ferlan
If we reached cleanup: prior to allocating cpus, it was possible that
'nr_nodes' had a value, but cpus was NULL leading to a possible NULL
deref. Add a 'cpus' as an end condition to for loop
---
Will push based upon pre-approved ACK:
https://www.redhat.com/archives/libvir-list/2013-August/msg00981.html
src/libxl/libxl_conf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 01626b9..8129c7f 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -196,7 +196,7 @@ libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
cleanup:
if (ret != 0) {
- for (i = 0; i < nr_nodes; i++)
+ for (i = 0; cpus && i < nr_nodes; i++)
VIR_FREE(cpus[i]);
virCapabilitiesFreeNUMAInfo(caps);
}
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] libxl: implement NUMA capabilities reporting
by Jim Fehlig
From: Dario Faggioli <dario.faggioli(a)citrix.com>
Starting from Xen 4.2, libxl has all the bits and pieces in place
for retrieving an adequate amount of information about the host
NUMA topology. It is therefore possible, after a bit of shuffling,
to arrange those information in the way libvirt wants to present
them to the outside world.
Therefore, with this patch, the <topology> section of the host
capabilities is properly populated, when running on Xen, so that
we can figure out whether or not we're running on a NUMA host,
and what its characteristics are.
[raistlin@Zhaman ~]$ sudo virsh --connect xen:/// capabilities
<capabilities>
<host>
<cpu>
....
<topology>
<cells num='2'>
<cell id='0'>
<memory unit='KiB'>6291456</memory>
<cpus num='8'>
<cpu id='0' socket_id='1' core_id='0' siblings='0-1'/>
<cpu id='1' socket_id='1' core_id='0' siblings='0-1'/>
<cpu id='2' socket_id='1' core_id='1' siblings='2-3'/>
<cpu id='3' socket_id='1' core_id='1' siblings='2-3'/>
<cpu id='4' socket_id='1' core_id='9' siblings='4-5'/>
<cpu id='5' socket_id='1' core_id='9' siblings='4-5'/>
<cpu id='6' socket_id='1' core_id='10' siblings='6-7'/>
<cpu id='7' socket_id='1' core_id='10' siblings='6-7'/>
</cpus>
</cell>
<cell id='1'>
<memory unit='KiB'>6881280</memory>
<cpus num='8'>
<cpu id='8' socket_id='0' core_id='0' siblings='8-9'/>
<cpu id='9' socket_id='0' core_id='0' siblings='8-9'/>
<cpu id='10' socket_id='0' core_id='1' siblings='10-11'/>
<cpu id='11' socket_id='0' core_id='1' siblings='10-11'/>
<cpu id='12' socket_id='0' core_id='9' siblings='12-13'/>
<cpu id='13' socket_id='0' core_id='9' siblings='12-13'/>
<cpu id='14' socket_id='0' core_id='10' siblings='14-15'/>
<cpu id='15' socket_id='0' core_id='10' siblings='14-15'/>
</cpus>
</cell>
</cells>
</topology>
</host>
....
---
This would be a nice addtion to libvirt 1.1.2, wrapping up Dario's initial
work on NUMA support in the libxl driver. Since he is on vacation the next
weeks, I rebased his patch on the recent libxl capabilities cleanup.
src/libxl/libxl_conf.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 73e2d49..6b0e89e 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -101,6 +101,119 @@ libxlCapsInitHost(libxl_ctx *ctx, virCapsPtr caps)
}
static int
+libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
+{
+ libxl_numainfo *numa_info = NULL;
+ libxl_cputopology *cpu_topo = NULL;
+ int nr_nodes = 0, nr_cpus = 0;
+ virCapsHostNUMACellCPUPtr *cpus = NULL;
+ int *nr_cpus_node = NULL;
+ size_t i;
+ int ret = -1;
+
+ /* Let's try to fetch all the topology information */
+ numa_info = libxl_get_numainfo(ctx, &nr_nodes);
+ if (numa_info == NULL || nr_nodes == 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libxl_get_numainfo failed"));
+ goto cleanup;
+ } else {
+ cpu_topo = libxl_get_cpu_topology(ctx, &nr_cpus);
+ if (cpu_topo == NULL || nr_cpus == 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libxl_get_cpu_topology failed"));
+ goto cleanup;
+ }
+ }
+
+ if (VIR_ALLOC_N(cpus, nr_nodes) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(nr_cpus_node, nr_nodes) < 0)
+ goto cleanup;
+
+ /* For each node, prepare a list of CPUs belonging to that node */
+ for (i = 0; i < nr_cpus; i++) {
+ int node = cpu_topo[i].node;
+
+ if (cpu_topo[i].core == LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
+ continue;
+
+ nr_cpus_node[node]++;
+
+ if (nr_cpus_node[node] == 1) {
+ if (VIR_ALLOC(cpus[node]) < 0)
+ goto cleanup;
+ } else {
+ if (VIR_REALLOC_N(cpus[node], nr_cpus_node[node]) < 0)
+ goto cleanup;
+ }
+
+ /* Mapping between what libxl tells and what libvirt wants */
+ cpus[node][nr_cpus_node[node]-1].id = i;
+ cpus[node][nr_cpus_node[node]-1].socket_id = cpu_topo[i].socket;
+ cpus[node][nr_cpus_node[node]-1].core_id = cpu_topo[i].core;
+ /* Allocate the siblings maps. We will be filling them later */
+ cpus[node][nr_cpus_node[node]-1].siblings = virBitmapNew(nr_cpus);
+ if (!cpus[node][nr_cpus_node[node]-1].siblings) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ /* Let's now populate the siblings bitmaps */
+ for (i = 0; i < nr_cpus; i++) {
+ int node = cpu_topo[i].node;
+ size_t j;
+
+ if (cpu_topo[i].core == LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
+ continue;
+
+ for (j = 0; j < nr_cpus_node[node]; j++) {
+ if (cpus[node][j].socket_id == cpu_topo[i].socket &&
+ cpus[node][j].core_id == cpu_topo[i].core)
+ ignore_value(virBitmapSetBit(cpus[node][j].siblings, i));
+ }
+ }
+
+ for (i = 0; i < nr_nodes; i++) {
+ if (numa_info[i].size == LIBXL_NUMAINFO_INVALID_ENTRY)
+ continue;
+
+ if (virCapabilitiesAddHostNUMACell(caps, i, nr_cpus_node[i],
+ numa_info[i].size / 1024,
+ cpus[i]) < 0) {
+ virCapabilitiesClearHostNUMACellCPUTopology(cpus[i],
+ nr_cpus_node[i]);
+ goto cleanup;
+ }
+
+ /* This is safe, as the CPU list is now stored in the NUMA cell */
+ cpus[i] = NULL;
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (ret != 0) {
+ /* Something went wrong: deallocate everything and unref caps */
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libxenlight failed to build the NUMA topology"));
+
+ for (i = 0; i < nr_nodes; i++)
+ VIR_FREE(cpus[i]);
+ virCapabilitiesFreeNUMAInfo(caps);
+ }
+
+ VIR_FREE(cpus);
+ VIR_FREE(nr_cpus_node);
+ libxl_cputopology_list_free(cpu_topo, nr_cpus);
+ libxl_numainfo_list_free(numa_info, nr_nodes);
+
+ return ret;
+}
+
+static int
libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps)
{
const libxl_version_info *ver_info;
@@ -880,6 +993,9 @@ libxlMakeCapabilities(libxl_ctx *ctx)
if (libxlCapsInitHost(ctx, caps) < 0)
goto error;
+ if (libxlCapsInitNuma(ctx, caps) < 0)
+ goto error;
+
if (libxlCapsInitGuests(ctx, caps) < 0)
goto error;
--
1.8.1.4
11 years, 2 months
[libvirt] [PATCHv2 0/3] Clean up usage of vshStringToArray
by Peter Krempa
Fixed after review from Osier, please see individual patches.
Peter Krempa (3):
virsh: modify vshStringToArray to duplicate the elements too
virsh-pool: Improve error message in cmdPoolList
virsh: Don't leak list of volumes when undefining domain with storage
tools/virsh-domain.c | 134 ++++++++++++++++++++++++-------------------------
tools/virsh-nodedev.c | 18 ++-----
tools/virsh-pool.c | 12 ++---
tools/virsh-snapshot.c | 10 +---
tools/virsh.c | 15 +++---
tools/virsh.h | 1 +
6 files changed, 86 insertions(+), 104 deletions(-)
--
1.8.3.2
11 years, 2 months
[libvirt] [PATCH] Link to virdbustest against DBus libs
by Guido Günther
otherwise we fail like:
CCLD virdbustest
/usr/bin/ld: virdbustest-virdbustest.o: undefined reference to symbol 'dbus_message_unref'
/lib/x86_64-linux-gnu/libdbus-1.so.3: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Found by:
http://honk.sigxcpu.org:8001/job/libvirt-build-debian-sid-amd64/7/console
---
tests/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4aa02dd..d6f60a1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -673,7 +673,7 @@ if WITH_DBUS
virdbustest_SOURCES = \
virdbustest.c testutils.h testutils.c
virdbustest_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-virdbustest_LDADD = $(LDADDS)
+virdbustest_LDADD = $(LDADDS) $(DBUS_LIBS)
virsystemdtest_SOURCES = \
virsystemdtest.c testutils.h testutils.c
--
1.8.4.rc1
11 years, 2 months
[libvirt] Schedule for next release
by Daniel Veillard
To try to stay on the end of month release schedule, I am suggesting
to enter the freeze for 1.1.2 next Tuesday, i.e. the 27th Aug, and
then shoot for a release on the morning of Monday 2nd of Sep.
So unless I hear disagreements, that's the plan :-)
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
11 years, 2 months