[libvirt] [PATCH] hostdev: skip ACS check when using VFIO for device assignment
by Laine Stump
The ACS checks are meaningless when using the more modern VFIO driver
for device assignment since VFIO has its own more complete and exact
checks, but I didn't realize that when I added support for VFIO. This
patch eliminates the ACS check when preparing PCI devices for
assignment if VFIO is being used.
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1256486
---
src/util/virhostdev.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 529753c..0bc5120 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -1,6 +1,6 @@
/* virhostdev.c: hostdev management
*
- * Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2007, 2009-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
* Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
@@ -230,7 +230,6 @@ virHostdevGetPCIHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs)
virObjectUnref(list);
return NULL;
}
-
if (virPCIDeviceListAdd(list, dev) < 0) {
virPCIDeviceFree(dev);
virObjectUnref(list);
@@ -579,7 +578,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, dom_name,
usesVfio};
- if (!virPCIDeviceIsAssignable(dev, strict_acs_check)) {
+ if (!usesVfio && !virPCIDeviceIsAssignable(dev, strict_acs_check)) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("PCI device %s is not assignable"),
virPCIDeviceGetName(dev));
--
2.1.0
9 years, 3 months
[libvirt] [PATCH] Start daemon only after filesystems are mounted
by Martin Kletzander
When images are on mounted filesystems, there is no guarantee libvirtd
will start before they are mounted. In systemd world, this is done
with 'After=systemd.mount' in the service file.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
daemon/libvirtd.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/daemon/libvirtd.service.in b/daemon/libvirtd.service.in
index 1759ac8a0946..c461f9462ae5 100644
--- a/daemon/libvirtd.service.in
+++ b/daemon/libvirtd.service.in
@@ -5,6 +5,7 @@ After=network.target
After=dbus.service
After=iscsid.service
After=apparmor.service
+After=systemd.mount
Documentation=man:libvirtd(8)
Documentation=http://libvirt.org
--
2.5.0
9 years, 3 months
[libvirt] [PATCH v4] lxc: Inherit namespace feature
by ik.nitk
This patch adds feature for lxc containers to inherit namespaces.
This is very similar to what lxc-tools or docker provides. Look
for "man lxc-start" and you will find that you can pass command
args as [ --share-[net|ipc|uts] name|pid ]. Or check out docker
networking option in which you can give --net=container:NAME_or_ID
as an option for sharing +namespace.
>From this patch you can add extra libvirt option to share
namespace in following way.
<lxc:namespace>
<lxc:sharenet type='netns' value='red'/>
<lxc:shareipc type='pid' value='12345'/>
<lxc:shareuts type='name' value='container1'/>
</lxc:namespace>
The netns option is specific to sharenet. It can be used to
inherit from existing network namespace.
---
docs/drvlxc.html.in | 21 +++++
docs/schemas/domaincommon.rng | 42 +++++++++
po/POTFILES.in | 1 +
src/Makefile.am | 7 +-
src/lxc/lxc_conf.c | 2 +-
src/lxc/lxc_container.c | 71 +++++++++++++--
src/lxc/lxc_container.h | 2 +
src/lxc/lxc_controller.c | 57 +++++++++++-
src/lxc/lxc_domain.c | 149 ++++++++++++++++++++++++++++++++
src/lxc/lxc_domain.h | 26 ++++++
src/lxc/lxc_process.c | 157 ++++++++++++++++++++++++++++++++++
tests/lxcxml2xmldata/lxc-sharenet.xml | 33 +++++++
tests/lxcxml2xmltest.c | 1 +
13 files changed, 560 insertions(+), 9 deletions(-)
create mode 100644 tests/lxcxml2xmldata/lxc-sharenet.xml
diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in
index a094bd9..d6c57c4 100644
--- a/docs/drvlxc.html.in
+++ b/docs/drvlxc.html.in
@@ -590,6 +590,27 @@ Note that allowing capabilities that are normally dropped by default can serious
affect the security of the container and the host.
</p>
+<h2><a name="share">Inherit namespaces</a></h2>
+
+<p>
+Libvirt allows you to inherit the namespace from container/process just like lxc tools
+or docker provides to share the network namespace. The following can be used to share
+required namespaces. If we want to share only one then the other namespaces can be ignored.
+The netns option is specific to sharenet. It can be used in cases we want to use existing network namespace
+rather than creating new network namespace for the container. In this case privnet option will be
+ignored.
+</p>
+<pre>
+<domain type='lxc' xmlns:lxc='http://libvirt.org/schemas/domain/lxc/1.0'>
+...
+<lxc:namespace>
+ <lxc:sharenet type='netns' value='red'/>
+ <lxc:shareuts type='name' value='container1'/>
+ <lxc:shareipc type='pid' value='12345'/>
+</lxc:namespace>
+</domain>
+</pre>
+
<h2><a name="usage">Container usage / management</a></h2>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 043c975..fa026cd 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -68,6 +68,9 @@
<ref name='qemucmdline'/>
</optional>
<optional>
+ <ref name='lxcsharens'/>
+ </optional>
+ <optional>
<ref name='keywrap'/>
</optional>
</interleave>
@@ -5057,6 +5060,45 @@
</element>
</define>
+ <!--
+ Optional hypervisor extensions in their own namespace:
+ LXC
+ -->
+ <define name="lxcsharens">
+ <element name="namespace" ns="http://libvirt.org/schemas/domain/lxc/1.0">
+ <zeroOrMore>
+ <element name="sharenet">
+ <attribute name="type">
+ <choice>
+ <value>netns</value>
+ <value>name</value>
+ <value>pid</value>
+ </choice>
+ </attribute>
+ <attribute name='value'/>
+ </element>
+ <element name="shareipc">
+ <attribute name="type">
+ <choice>
+ <value>name</value>
+ <value>pid</value>
+ </choice>
+ </attribute>
+ <attribute name='value'/>
+ </element>
+ <element name="shareuts">
+ <attribute name="type">
+ <choice>
+ <value>name</value>
+ <value>pid</value>
+ </choice>
+ </attribute>
+ <attribute name='value'/>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
<define name="metadata">
<element name="metadata">
<zeroOrMore>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1e52e6a..46220f7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -85,6 +85,7 @@ src/lxc/lxc_native.c
src/lxc/lxc_container.c
src/lxc/lxc_conf.c
src/lxc/lxc_controller.c
+src/lxc/lxc_domain.c
src/lxc/lxc_driver.c
src/lxc/lxc_process.c
src/libxl/libxl_domain.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c4d49a5..24d31e1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1320,7 +1320,12 @@ libvirt_driver_lxc_impl_la_CFLAGS = \
-I$(srcdir)/access \
-I$(srcdir)/conf \
$(AM_CFLAGS)
-libvirt_driver_lxc_impl_la_LIBADD = $(CAPNG_LIBS) $(LIBNL_LIBS) $(FUSE_LIBS)
+libvirt_driver_lxc_impl_la_LIBADD = \
+ $(CAPNG_LIBS) \
+ $(LIBNL_LIBS) \
+ $(LIBXML_LIBS) \
+ $(FUSE_LIBS)
+
if WITH_BLKID
libvirt_driver_lxc_impl_la_CFLAGS += $(BLKID_CFLAGS)
libvirt_driver_lxc_impl_la_LIBADD += $(BLKID_LIBS)
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index b689b92..8ada531 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -213,7 +213,7 @@ lxcDomainXMLConfInit(void)
{
return virDomainXMLOptionNew(&virLXCDriverDomainDefParserConfig,
&virLXCDriverPrivateDataCallbacks,
- NULL);
+ &virLXCDriverDomainXMLNamespace);
}
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 11e9514..8011ed0 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -27,6 +27,7 @@
#include <config.h>
#include <fcntl.h>
+#include <sched.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
@@ -38,7 +39,6 @@
#include <mntent.h>
#include <sys/reboot.h>
#include <linux/reboot.h>
-
/* Yes, we want linux private one, for _syscall2() macro */
#include <linux/unistd.h>
@@ -111,6 +111,7 @@ struct __lxc_child_argv {
size_t nttyPaths;
char **ttyPaths;
int handshakefd;
+ int *nsInheritFDs;
};
static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
@@ -2144,6 +2145,35 @@ static int lxcContainerDropCapabilities(virDomainDefPtr def ATTRIBUTE_UNUSED,
/**
+ * lxcAttach_ns:
+ * @ns_fd: array of namespaces to attach
+ */
+static int lxcAttachNS(int *ns_fd)
+{
+ size_t i;
+ if (ns_fd)
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
+ if (ns_fd[i] < 0)
+ continue;
+ VIR_DEBUG("Setting into namespace\n");
+ /* We get EINVAL if new NS is same as the current
+ * NS, or if the fd namespace doesn't match the
+ * type passed to setns()'s second param. Since we
+ * pass 0, we know the EINVAL is harmless
+ */
+ if (setns(ns_fd[i], 0) < 0 &&
+ errno != EINVAL) {
+ virReportSystemError(errno, _("failed to set namespace '%s'"),
+ virLXCDomainNamespaceTypeToString(i));
+ return -1;
+ }
+ VIR_FORCE_CLOSE(ns_fd[i]);
+ }
+ return 0;
+}
+
+
+/**
* lxcContainerChild:
* @data: pointer to container arguments
*
@@ -2172,6 +2202,12 @@ static int lxcContainerChild(void *data)
goto cleanup;
}
+ if (lxcAttachNS(argv->nsInheritFDs) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("failed to attach the namespace"));
+ return -1;
+ }
+
/* Wait for controller to finish setup tasks, including
* things like move of network interfaces, uid/gid mapping
*/
@@ -2342,6 +2378,7 @@ int lxcContainerStart(virDomainDefPtr def,
int *passFDs,
int control,
int handshakefd,
+ int *nsInheritFDs,
size_t nttyPaths,
char **ttyPaths)
{
@@ -2359,7 +2396,8 @@ int lxcContainerStart(virDomainDefPtr def,
.monitor = control,
.nttyPaths = nttyPaths,
.ttyPaths = ttyPaths,
- .handshakefd = handshakefd
+ .handshakefd = handshakefd,
+ .nsInheritFDs = nsInheritFDs,
};
/* allocate a stack for the container */
@@ -2368,7 +2406,7 @@ int lxcContainerStart(virDomainDefPtr def,
stacktop = stack + stacksize;
- cflags = CLONE_NEWPID|CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|SIGCHLD;
+ cflags = CLONE_NEWPID|CLONE_NEWNS|SIGCHLD;
if (userns_required(def)) {
if (userns_supported()) {
@@ -2381,10 +2419,31 @@ int lxcContainerStart(virDomainDefPtr def,
return -1;
}
}
+ if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHARENET] == -1) {
+ if (lxcNeedNetworkNamespace(def)) {
+ VIR_DEBUG("Enable network namespaces");
+ cflags |= CLONE_NEWNET;
+ }
+ } else {
+ if (lxcNeedNetworkNamespace(def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Config askes for inherit net namespace "
+ "as well as private network interfaces"));
+ return -1;
+ }
+ VIR_DEBUG("Inheriting a net namespace");
+ }
+
+ if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC] == -1) {
+ cflags |= CLONE_NEWIPC;
+ } else {
+ VIR_DEBUG("Inheriting an IPC namespace");
+ }
- if (lxcNeedNetworkNamespace(def)) {
- VIR_DEBUG("Enable network namespaces");
- cflags |= CLONE_NEWNET;
+ if (!nsInheritFDs || nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS] == -1) {
+ cflags |= CLONE_NEWUTS;
+ } else {
+ VIR_DEBUG("Inheriting a UTS namespace");
}
VIR_DEBUG("Cloning container init process");
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index 67292ab..33eaab4 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -25,6 +25,7 @@
# define LXC_CONTAINER_H
# include "lxc_conf.h"
+# include "lxc_domain.h"
# include "security/security_manager.h"
enum {
@@ -60,6 +61,7 @@ int lxcContainerStart(virDomainDefPtr def,
int *passFDs,
int control,
int handshakefd,
+ int *nsInheritFDs,
size_t nttyPaths,
char **ttyPaths);
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 48a3597..a94e819 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -119,6 +119,8 @@ struct _virLXCController {
size_t npassFDs;
int *passFDs;
+ int *nsFDs;
+
size_t nconsoles;
virLXCControllerConsolePtr consoles;
char *devptmx;
@@ -287,6 +289,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
VIR_FREE(ctrl->nbdpids);
+ VIR_FREE(ctrl->nsFDs);
virCgroupFree(&ctrl->cgroup);
/* This must always be the last thing to be closed */
@@ -2391,6 +2394,7 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
ctrl->passFDs,
control[1],
containerhandshake[1],
+ ctrl->nsFDs,
ctrl->nconsoles,
containerTTYPaths)) < 0)
goto cleanup;
@@ -2400,6 +2404,10 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
for (i = 0; i < ctrl->npassFDs; i++)
VIR_FORCE_CLOSE(ctrl->passFDs[i]);
+ if (ctrl->nsFDs)
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ VIR_FORCE_CLOSE(ctrl->nsFDs[i]);
+
if (virLXCControllerSetupCgroupLimits(ctrl) < 0)
goto cleanup;
@@ -2468,6 +2476,7 @@ int main(int argc, char *argv[])
const char *name = NULL;
size_t nveths = 0;
char **veths = NULL;
+ int ns_fd[VIR_LXC_DOMAIN_NAMESPACE_LAST];
int handshakeFd = -1;
bool bg = false;
const struct option options[] = {
@@ -2478,6 +2487,9 @@ int main(int argc, char *argv[])
{ "passfd", 1, NULL, 'p' },
{ "handshakefd", 1, NULL, 's' },
{ "security", 1, NULL, 'S' },
+ { "share-net", 1, NULL, 'N' },
+ { "share-ipc", 1, NULL, 'I' },
+ { "share-uts", 1, NULL, 'U' },
{ "help", 0, NULL, 'h' },
{ 0, 0, 0, 0 },
};
@@ -2489,6 +2501,9 @@ int main(int argc, char *argv[])
size_t i;
const char *securityDriver = "none";
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ ns_fd[i] = -1;
+
if (setlocale(LC_ALL, "") == NULL ||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
textdomain(PACKAGE) == NULL ||
@@ -2504,7 +2519,7 @@ int main(int argc, char *argv[])
while (1) {
int c;
- c = getopt_long(argc, argv, "dn:v:p:m:c:s:h:S:",
+ c = getopt_long(argc, argv, "dn:v:p:m:c:s:h:S:N:I:U:",
options, NULL);
if (c == -1)
@@ -2552,6 +2567,30 @@ int main(int argc, char *argv[])
}
break;
+ case 'N':
+ if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHARENET]) < 0) {
+ fprintf(stderr, "malformed --share-net argument '%s'",
+ optarg);
+ goto cleanup;
+ }
+ break;
+
+ case 'I':
+ if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC]) < 0) {
+ fprintf(stderr, "malformed --share-ipc argument '%s'",
+ optarg);
+ goto cleanup;
+ }
+ break;
+
+ case 'U':
+ if (virStrToLong_i(optarg, NULL, 10, &ns_fd[VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS]) < 0) {
+ fprintf(stderr, "malformed --share-uts argument '%s'",
+ optarg);
+ goto cleanup;
+ }
+ break;
+
case 'S':
securityDriver = optarg;
break;
@@ -2569,6 +2608,9 @@ int main(int argc, char *argv[])
fprintf(stderr, " -v VETH, --veth VETH\n");
fprintf(stderr, " -s FD, --handshakefd FD\n");
fprintf(stderr, " -S NAME, --security NAME\n");
+ fprintf(stderr, " -N FD, --share-net FD\n");
+ fprintf(stderr, " -I FD, --share-ipc FD\n");
+ fprintf(stderr, " -U FD, --share-uts FD\n");
fprintf(stderr, " -h, --help\n");
fprintf(stderr, "\n");
goto cleanup;
@@ -2621,6 +2663,19 @@ int main(int argc, char *argv[])
ctrl->passFDs = passFDs;
ctrl->npassFDs = npassFDs;
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
+ if (ns_fd[i] != -1) {
+ if (!ctrl->nsFDs) {/*allocate only once */
+ size_t j = 0;
+ if (VIR_ALLOC_N(ctrl->nsFDs, VIR_LXC_DOMAIN_NAMESPACE_LAST) < 0)
+ goto cleanup;
+ for (j = 0; j < VIR_LXC_DOMAIN_NAMESPACE_LAST; j++)
+ ctrl->nsFDs[j] = -1;
+ }
+ ctrl->nsFDs[i] = ns_fd[i];
+ }
+ }
+
for (i = 0; i < nttyFDs; i++) {
if (virLXCControllerAddConsole(ctrl, ttyFDs[i]) < 0)
goto cleanup;
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 2f377d8..e3da9f0 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -26,8 +26,13 @@
#include "viralloc.h"
#include "virlog.h"
#include "virerror.h"
+#include <libxml/xpathInternals.h>
+#include "virstring.h"
+#include "virutil.h"
+#include "virfile.h"
#define VIR_FROM_THIS VIR_FROM_LXC
+#define LXC_NAMESPACE_HREF "http://libvirt.org/schemas/domain/lxc/1.0"
VIR_LOG_INIT("lxc.lxc_domain");
@@ -41,6 +46,150 @@ static void *virLXCDomainObjPrivateAlloc(void)
return priv;
}
+VIR_ENUM_IMPL(virLXCDomainNamespace,
+ VIR_LXC_DOMAIN_NAMESPACE_LAST,
+ "sharenet",
+ "shareipc",
+ "shareuts")
+
+VIR_ENUM_IMPL(virLXCDomainNamespaceSource,
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_LAST,
+ "none",
+ "name",
+ "pid",
+ "netns")
+
+static void
+lxcDomainDefNamespaceFree(void *nsdata)
+{
+ size_t i;
+ lxcDomainDefPtr lxcDef = nsdata;
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ VIR_FREE(lxcDef->ns_val[i]);
+ VIR_FREE(nsdata);
+}
+
+static int
+lxcDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED,
+ xmlNodePtr root ATTRIBUTE_UNUSED,
+ xmlXPathContextPtr ctxt,
+ void **data)
+{
+ lxcDomainDefPtr lxcDef = NULL;
+ xmlNodePtr *nodes = NULL;
+ bool uses_lxc_ns = false;
+ xmlNodePtr node;
+ int feature;
+ int n;
+ char *tmp = NULL;
+ size_t i;
+
+ if (xmlXPathRegisterNs(ctxt, BAD_CAST "lxc", BAD_CAST LXC_NAMESPACE_HREF) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to register xml namespace '%s'"),
+ LXC_NAMESPACE_HREF);
+ return -1;
+ }
+
+ if (VIR_ALLOC(lxcDef) < 0)
+ return -1;
+
+ node = ctxt->node;
+ if ((n = virXPathNodeSet("./lxc:namespace/*", ctxt, &nodes)) < 0)
+ goto error;
+ uses_lxc_ns |= n > 0;
+
+ for (i = 0; i < n; i++) {
+ if ((feature = virLXCDomainNamespaceTypeFromString(
+ (const char *) nodes[i]->name)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported Namespace feature: %s"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ ctxt->node = nodes[i];
+
+ if (!(tmp = virXMLPropString(nodes[i], "type"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No lxc environment type specified"));
+ goto error;
+ }
+ if ((lxcDef->ns_source[feature] =
+ virLXCDomainNamespaceSourceTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown LXC namespace source '%s'"),
+ tmp);
+ VIR_FREE(tmp);
+ goto error;
+ }
+ VIR_FREE(tmp);
+
+ if (!(lxcDef->ns_val[feature] =
+ virXMLPropString(nodes[i], "value"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("No lxc environment type specified"));
+ goto error;
+ }
+ }
+ VIR_FREE(nodes);
+ ctxt->node = node;
+ if (uses_lxc_ns)
+ *data = lxcDef;
+ else
+ VIR_FREE(lxcDef);
+ return 0;
+ error:
+ VIR_FREE(nodes);
+ lxcDomainDefNamespaceFree(lxcDef);
+ return -1;
+}
+
+
+static int
+lxcDomainDefNamespaceFormatXML(virBufferPtr buf,
+ void *nsdata)
+{
+ lxcDomainDefPtr lxcDef = nsdata;
+ size_t i;
+
+ if (!lxcDef)
+ return 0;
+
+ virBufferAddLit(buf, "<lxc:namespace>\n");
+ virBufferAdjustIndent(buf, 2);
+
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
+ if (lxcDef->ns_source[i] == VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE)
+ continue;
+
+ virBufferAsprintf(buf, "<lxc:%s type='%s' value='%s'/>\n",
+ virLXCDomainNamespaceTypeToString(i),
+ virLXCDomainNamespaceSourceTypeToString(
+ lxcDef->ns_source[i]),
+ lxcDef->ns_val[i]);
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</lxc:namespace>\n");
+ return 0;
+}
+
+static const char *
+lxcDomainDefNamespaceHref(void)
+{
+ return "xmlns:lxc='" LXC_NAMESPACE_HREF "'";
+}
+
+
+virDomainXMLNamespace virLXCDriverDomainXMLNamespace = {
+ .parse = lxcDomainDefNamespaceParse,
+ .free = lxcDomainDefNamespaceFree,
+ .format = lxcDomainDefNamespaceFormatXML,
+ .href = lxcDomainDefNamespaceHref,
+};
+
+
static void virLXCDomainObjPrivateFree(void *data)
{
virLXCDomainObjPrivatePtr priv = data;
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 751aece..2119c78 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -27,6 +27,31 @@
# include "lxc_conf.h"
# include "lxc_monitor.h"
+typedef enum {
+ VIR_LXC_DOMAIN_NAMESPACE_SHARENET = 0,
+ VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC,
+ VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS,
+ VIR_LXC_DOMAIN_NAMESPACE_LAST,
+} virLXCDomainNamespace;
+
+typedef enum {
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE,
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NAME,
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_PID,
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NETNS,
+
+ VIR_LXC_DOMAIN_NAMESPACE_SOURCE_LAST,
+} virLXCDomainNamespaceSource;
+
+VIR_ENUM_DECL(virLXCDomainNamespace)
+VIR_ENUM_DECL(virLXCDomainNamespaceSource)
+
+typedef struct _lxcDomainDef lxcDomainDef;
+typedef lxcDomainDef *lxcDomainDefPtr;
+struct _lxcDomainDef {
+ int ns_source[VIR_LXC_DOMAIN_NAMESPACE_LAST]; /* virLXCDomainNamespaceSource */
+ char *ns_val[VIR_LXC_DOMAIN_NAMESPACE_LAST];
+};
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
@@ -41,6 +66,7 @@ struct _virLXCDomainObjPrivate {
virCgroupPtr cgroup;
};
+extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index e99b039..ade0ed7 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -359,6 +359,143 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
return ret;
}
+static const char *nsInfoLocal[VIR_LXC_DOMAIN_NAMESPACE_LAST] = {
+ [VIR_LXC_DOMAIN_NAMESPACE_SHARENET] = "net",
+ [VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC] = "ipc",
+ [VIR_LXC_DOMAIN_NAMESPACE_SHAREUTS] = "uts",
+};
+
+static int virLXCProcessSetupNamespaceName(virConnectPtr conn, int ns_type, const char *name)
+{
+ virLXCDriverPtr driver = conn->privateData;
+ int fd = -1;
+ virDomainObjPtr vm;
+ virLXCDomainObjPrivatePtr priv;
+ char *path;
+
+ vm = virDomainObjListFindByName(driver->domains, name);
+ if (!vm) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching name '%s'"), name);
+ return -1;
+ }
+
+ priv = vm->privateData;
+ if (!priv->initpid) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Init pid is not yet available"));
+ goto cleanup;
+ }
+
+ if (virAsprintf(&path, "/proc/%lld/ns/%s",
+ (long long int)priv->initpid,
+ nsInfoLocal[ns_type]) < 0)
+ goto cleanup;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ virReportSystemError(errno,
+ _("failed to open ns %s"),
+ virLXCDomainNamespaceTypeToString(ns_type));
+ goto cleanup;
+ }
+
+ cleanup:
+ VIR_FREE(path);
+ virObjectUnlock(vm);
+ virObjectUnref(vm);
+ return fd;
+}
+
+
+static int virLXCProcessSetupNamespacePID(int ns_type, const char *name)
+{
+ int fd;
+ char *path;
+
+ if (virAsprintf(&path, "/proc/%s/ns/%s",
+ name,
+ nsInfoLocal[ns_type]) < 0)
+ return -1;
+ fd = open(path, O_RDONLY);
+ VIR_FREE(path);
+ if (fd < 0) {
+ virReportSystemError(errno,
+ _("failed to open ns %s"),
+ virLXCDomainNamespaceTypeToString(ns_type));
+ return -1;
+ }
+ return fd;
+}
+
+
+static int virLXCProcessSetupNamespaceNet(int ns_type, const char *name)
+{
+ char *path;
+ int fd;
+ if (ns_type != VIR_LXC_DOMAIN_NAMESPACE_SHARENET) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("'netns' namespace source can only be "
+ "used with sharenet"));
+ return -1;
+ }
+
+ if (virAsprintf(&path, "/var/run/netns/%s", name) < 0)
+ return -1;
+ fd = open(path, O_RDONLY);
+ VIR_FREE(path);
+ if (fd < 0) {
+ virReportSystemError(errno,
+ _("failed to open netns %s"), name);
+ return -1;
+ }
+ return fd;
+}
+
+
+/**
+ * virLXCProcessSetupNamespaces:
+ * @conn: pointer to connection
+ * @def: pointer to virtual machines namespaceData
+ * @nsFDs: out parameter to store the namespace FD
+ *
+ * Opens the specified namespace that needs to be shared and
+ * will moved into the container namespace later after clone has been called.
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+static int virLXCProcessSetupNamespaces(virConnectPtr conn,
+ lxcDomainDefPtr lxcDef,
+ int *nsFDs)
+{
+ size_t i;
+
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++)
+ nsFDs[i] = -1;
+ /*If there are no namespace to be opened just return success*/
+ if (lxcDef == NULL)
+ return 0;
+
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
+ switch (lxcDef->ns_source[i]) {
+ case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NONE:
+ continue;
+ case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NAME:
+ if ((nsFDs[i] = virLXCProcessSetupNamespaceName(conn, i, lxcDef->ns_val[i])) < 0)
+ return -1;
+ break;
+ case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_PID:
+ if ((nsFDs[i] = virLXCProcessSetupNamespacePID(i, lxcDef->ns_val[i])) < 0)
+ return -1;
+ break;
+ case VIR_LXC_DOMAIN_NAMESPACE_SOURCE_NETNS:
+ if ((nsFDs[i] = virLXCProcessSetupNamespaceNet(i, lxcDef->ns_val[i])) < 0)
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
/**
* virLXCProcessSetupInterfaces:
@@ -764,6 +901,7 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
char **veths,
int *ttyFDs,
size_t nttyFDs,
+ int *nsInheritFDs,
int *files,
size_t nfiles,
int handshakefd,
@@ -825,6 +963,19 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
virCommandPassFD(cmd, files[i], 0);
}
+ for (i = 0; i < VIR_LXC_DOMAIN_NAMESPACE_LAST; i++) {
+ if (nsInheritFDs[i] > 0) {
+ char *tmp = NULL;
+ if (virAsprintf(&tmp, "--share-%s",
+ nsInfoLocal[i]) < 0)
+ goto cleanup;
+ virCommandAddArg(cmd, tmp);
+ virCommandAddArgFormat(cmd, "%d", nsInheritFDs[i]);
+ virCommandPassFD(cmd, nsInheritFDs[i], 0);
+ VIR_FREE(tmp);
+ }
+ }
+
virCommandAddArgPair(cmd, "--security",
virSecurityManagerGetModel(driver->securityManager));
@@ -1032,6 +1183,7 @@ int virLXCProcessStart(virConnectPtr conn,
off_t pos = -1;
char ebuf[1024];
char *timestamp;
+ int nsInheritFDs[VIR_LXC_DOMAIN_NAMESPACE_LAST];
virCommandPtr cmd = NULL;
virLXCDomainObjPrivatePtr priv = vm->privateData;
virCapsPtr caps = NULL;
@@ -1204,6 +1356,10 @@ int virLXCProcessStart(virConnectPtr conn,
if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
goto cleanup;
+ VIR_DEBUG("Setting up namespaces if any");
+ if (virLXCProcessSetupNamespaces(conn, vm->def->namespaceData, nsInheritFDs) < 0)
+ goto cleanup;
+
VIR_DEBUG("Preparing to launch");
if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
S_IRUSR|S_IWUSR)) < 0) {
@@ -1223,6 +1379,7 @@ int virLXCProcessStart(virConnectPtr conn,
vm,
nveths, veths,
ttyFDs, nttyFDs,
+ nsInheritFDs,
files, nfiles,
handshakefds[1],
&logfd,
diff --git a/tests/lxcxml2xmldata/lxc-sharenet.xml b/tests/lxcxml2xmldata/lxc-sharenet.xml
new file mode 100644
index 0000000..a2b8d1b
--- /dev/null
+++ b/tests/lxcxml2xmldata/lxc-sharenet.xml
@@ -0,0 +1,33 @@
+<domain type='lxc' xmlns:lxc='http://libvirt.org/schemas/domain/lxc/1.0'>
+ <name>jessie</name>
+ <uuid>e21987a5-e98e-9c99-0e35-803e4d9ad1fe</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <resource>
+ <partition>/machine</partition>
+ </resource>
+ <os>
+ <type arch='x86_64'>exe</type>
+ <init>/sbin/init</init>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/libexec/libvirt_lxc</emulator>
+ <filesystem type='mount' accessmode='passthrough'>
+ <source dir='/mach/jessie'/>
+ <target dir='/'/>
+ </filesystem>
+ <console type='pty'>
+ <target type='lxc' port='0'/>
+ </console>
+ </devices>
+ <lxc:namespace>
+ <lxc:sharenet type='netns' value='red'/>
+ <lxc:shareipc type='pid' value='12345'/>
+ <lxc:shareuts type='name' value='container1'/>
+ </lxc:namespace>
+</domain>
diff --git a/tests/lxcxml2xmltest.c b/tests/lxcxml2xmltest.c
index 3e00347..8d824b9 100644
--- a/tests/lxcxml2xmltest.c
+++ b/tests/lxcxml2xmltest.c
@@ -133,6 +133,7 @@ mymain(void)
DO_TEST("filesystem-root");
DO_TEST("idmap");
DO_TEST("capabilities");
+ DO_TEST("sharenet");
virObjectUnref(caps);
virObjectUnref(xmlopt);
--
1.9.1
9 years, 3 months
[libvirt] [PATCH] qemu: Label correct per-VM path when starting
by Martin Kletzander
Commit f1f68ca33433825ce0deed2d96f1990200bc6618 overused mdir_name()
event though it was not needed in the latest version, hence labelling
directory one level up in the tree and not the one it should.
If anyone with SElinux managed to try run a domain with guest agent set
up, it's highly possible that they will need to run 'restorecon -F
/var/lib/libvirt/qemu/channel/target' to fix what was done.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/qemu/qemu_process.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 93ccd2a706b9..f7eb2b609437 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -46,7 +46,6 @@
#include "cpu/cpu.h"
#include "datatypes.h"
-#include "dirname.h"
#include "virlog.h"
#include "virerror.h"
#include "viralloc.h"
@@ -4390,7 +4389,7 @@ int qemuProcessStart(virConnectPtr conn,
unsigned int hostdev_flags = 0;
size_t nnicindexes = 0;
int *nicindexes = NULL;
- char *tmppath = NULL, *tmpdirpath = NULL;
+ char *tmppath = NULL;
VIR_DEBUG("vm=%p name=%s id=%d asyncJob=%d migrateFrom=%s stdin_fd=%d "
"stdin_path=%s snapshot=%p vmop=%d flags=0x%x",
@@ -4738,15 +4737,11 @@ int qemuProcessStart(virConnectPtr conn,
if (virFileMakePath(tmppath) < 0)
goto cleanup;
- if (!(tmpdirpath = mdir_name(tmppath)))
- goto cleanup;
-
if (virSecurityManagerDomainSetDirLabel(driver->securityManager,
- vm->def, tmpdirpath) < 0)
+ vm->def, tmppath) < 0)
goto cleanup;
VIR_FREE(tmppath);
- VIR_FREE(tmpdirpath);
if (virAsprintf(&tmppath, "%s/domain-%s",
cfg->channelTargetDir, vm->def->name) < 0)
@@ -4755,14 +4750,10 @@ int qemuProcessStart(virConnectPtr conn,
if (virFileMakePath(tmppath) < 0)
goto cleanup;
- if (!(tmpdirpath = mdir_name(tmppath)))
- goto cleanup;
-
if (virSecurityManagerDomainSetDirLabel(driver->securityManager,
- vm->def, tmpdirpath) < 0)
+ vm->def, tmppath) < 0)
goto cleanup;
- VIR_FREE(tmpdirpath);
VIR_FREE(tmppath);
/* now that we know it is about to start call the hook if present */
@@ -5119,7 +5110,6 @@ int qemuProcessStart(virConnectPtr conn,
* if we failed to initialize the now running VM. kill it off and
* pretend we never started it */
VIR_FREE(tmppath);
- VIR_FREE(tmpdirpath);
VIR_FREE(nodeset);
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
--
2.5.0
9 years, 3 months
[libvirt] [PATCH] util: Don't save/set MAC address for macvtap+passthrough+802.1Qbh
by Laine Stump
Before libvirt sets the MAC address of the physdev (the physical
ethernet device) linked to a macvtap passthrough device, it always
saves the previous MAC address to restore when the guest is finished
(following a "leave nothing behind" policy). It has even done this for
macvtap devices that have an 802.1Qbh port profile attached to
them. It turns out that this is unnecessary, because the port profile
Associate/Disassociate operations do that for us.
Beyond that, with a recent change to the way we retrieve the MAC
address (commit cb3fe38c), all attempts to start a macvtap passthrough
device with an 802.1Qbh port profile attached to a Cisco VMFEX card
(which uses the "enic" driver in the kernel) to fail.
This patch puts extra qualifiers around both the save/set and the
restore of the physdev address, so that it isn't done if there is an
802.1Qbh port profile associated with it.
This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1257004
---
Stefan - do you know if this save/restore of MAC address is also
unnecessary/erroneous for 802.1Qbg? If so, I'll just disable it any
time a virtportprofile is present, since those are the only two port
profile types that are valid with macvtap anyway.
src/util/virnetdevmacvlan.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index 213b8eb..9c4da1f 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -777,11 +777,17 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
* address must be reset when the VM is shut down.
* This is especially important when using SRIOV capable cards that
* emulate their switch in firmware.
+ *
+ * Note that this saving/setting of the MAC address must *NOT* be
+ * done if the interface is setup with an 802.1Qbh. In that case,
+ * the 802.1Qbh "port associate" operation will take care of
+ * saving/setting the MAC address.
*/
- if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) {
- if (virNetDevReplaceNetConfig(linkdev, -1, macaddress, -1, stateDir) < 0)
- return -1;
- }
+ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU &&
+ !(virtPortProfile &&
+ virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH) &&
+ virNetDevReplaceNetConfig(linkdev, -1, macaddress, -1, stateDir) < 0)
+ return -1;
if (tgifname) {
if ((ret = virNetDevExists(tgifname)) < 0)
@@ -913,7 +919,9 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
int ret = 0;
int vf = -1;
- if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU)
+ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU &&
+ !(virtPortProfile &&
+ virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBH))
ignore_value(virNetDevRestoreNetConfig(linkdev, vf, stateDir));
if (ifname) {
--
2.1.0
9 years, 3 months
[libvirt] [PATCHv2] qemu: fix not update weight in def after success
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1253107
Call virCgroupGetBlkioWeight to re-read blkio.weight right
after it are set in order to keep our internal structures
up-to-date.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/qemu/qemu_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b6ac075..5cc38ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9183,7 +9183,8 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
virTypedParameterPtr param = ¶ms[i];
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
- if (virCgroupSetBlkioWeight(priv->cgroup, param->value.ui) < 0)
+ if (virCgroupSetBlkioWeight(priv->cgroup, param->value.ui) < 0 ||
+ virCgroupGetBlkioWeight(priv->cgroup, &def->blkio.weight) < 0)
ret = -1;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) ||
STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) ||
--
1.8.3.1
9 years, 3 months
[libvirt] [PATCHv2] utils: Remove the logging of errors from virNetDevSendEthtoolIoctl
by Moshe Levi
This patch remove the logging of errors of ioctl api and instead
let the caller to choose what errors to log
---
src/util/virnetdev.c | 56 ++++++++++++++-----------------------------------
1 files changed, 16 insertions(+), 40 deletions(-)
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 2f3690e..5fcf805 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -3032,39 +3032,15 @@ static int
virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
{
int ret = -1;
- int sock = -1;
- virIfreq ifr;
-
- sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (sock < 0) {
- virReportSystemError(errno, "%s", _("Cannot open control socket"));
- goto cleanup;
- }
+ int fd;
+ struct ifreq ifr;
- memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, ifname);
+ if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0)
+ return ret;
ifr.ifr_data = cmd;
- ret = ioctl(sock, SIOCETHTOOL, &ifr);
- if (ret != 0) {
- switch (errno) {
- case EPERM:
- VIR_DEBUG("ethtool ioctl: permission denied");
- break;
- case EINVAL:
- VIR_DEBUG("ethtool ioctl: invalid request");
- break;
- case EOPNOTSUPP:
- VIR_DEBUG("ethtool ioctl: request not supported");
- break;
- default:
- virReportSystemError(errno, "%s", _("ethtool ioctl error"));
- goto cleanup;
- }
- }
+ ret = ioctl(fd, SIOCETHTOOL, &ifr);
- cleanup:
- if (sock)
- VIR_FORCE_CLOSE(sock);
+ VIR_FORCE_CLOSE(fd);
return ret;
}
@@ -3081,12 +3057,12 @@ virNetDevSendEthtoolIoctl(const char *ifname, void *cmd)
static int
virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
{
- int ret = -1;
-
cmd = (void*)cmd;
- if (!virNetDevSendEthtoolIoctl(ifname, cmd))
- ret = cmd->data > 0 ? 1 : 0;
- return ret;
+ if (virNetDevSendEthtoolIoctl(ifname, cmd) < 0) {
+ virReportSystemError(errno, _("Cannot get device %s flags"), ifname);
+ return -1;
+ }
+ return cmd->data > 0 ? 1 : 0;
}
@@ -3103,12 +3079,12 @@ virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd)
static int
virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd)
{
- int ret = -1;
-
cmd = (void*)cmd;
- if (!virNetDevSendEthtoolIoctl(ifname, cmd))
- ret = FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active);
- return ret;
+ if (virNetDevSendEthtoolIoctl(ifname, cmd) < 0) {
+ virReportSystemError(errno, _("Cannot get device %s generic features"), ifname);
+ return -1;
+ }
+ return FEATURE_BIT_IS_SET(cmd->features, TX_UDP_TNL, active);
}
# endif
--
1.7.1
9 years, 3 months
[libvirt] [PATCH 2/2] Rename page about vz driver
by Sergey Bronnikov
---
docs/{drvparallels.html.in => drvvirtuozzo.html.in} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename docs/{drvparallels.html.in => drvvirtuozzo.html.in} (100%)
diff --git a/docs/drvparallels.html.in b/docs/drvvirtuozzo.html.in
similarity index 100%
rename from docs/drvparallels.html.in
rename to docs/drvvirtuozzo.html.in
--
2.3.2 (Apple Git-55)
9 years, 3 months