[libvirt] Libvirt bite sized tasks
by Michal Privoznik
Dear lists,
I've just started new wiki page which aim is to summarize small and
trivial tasks, that starting contributors can take, investigate and
implement. The aim is to give them something easy to start with while
not scaring them out about complexity of our code. The page can be found
here:
http://wiki.libvirt.org/page/BiteSizedTasks
The name is copied from qemu wiki:
http://wiki.qemu.org/BiteSizedTasks
Please, feel free to extend the list. I plan to use it in the future
when interviewing GSoC candidates.
Michal
8 years, 9 months
[libvirt] [PATCH] nss: don't try to build nss plugin when disabled
by Roman Bogorodskiy
Even if nss is disabled, the build system tries to build some
targets like libnss_libvirt_impl.la and nsstest. Hide those
under the "if WITH_NSS" block like the rest of NSS plugin bits.
---
tests/Makefile.am | 8 ++++++--
tools/Makefile.am | 2 +-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d80b317..7d6b8a8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -158,7 +158,7 @@ EXTRA_DIST = \
xml2sexprdata \
xml2vmxdata
-test_helpers = commandhelper ssh test_conf nsslinktest
+test_helpers = commandhelper ssh test_conf
test_programs = virshtest sockettest \
nodeinfotest virbuftest \
commandtest seclabeltest \
@@ -191,7 +191,6 @@ test_programs = virshtest sockettest \
vircaps2xmltest \
virnetdevtest \
virtypedparamtest \
- nsstest \
$(NULL)
if WITH_REMOTE
@@ -330,6 +329,11 @@ if WITH_LINUX
test_programs += virscsitest
endif WITH_LINUX
+if WITH_NSS
+test_helpers += nsslinktest
+test_programs += nsstest
+endif
+
test_programs += storagevolxml2xmltest storagepoolxml2xmltest
test_programs += nodedevxml2xmltest
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 3218d2f..4320040 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -424,6 +424,7 @@ LIBVIRT_NSS_SOURCES = \
nss/libvirt_nss.c \
nss/libvirt_nss.h
+if WITH_NSS
noinst_LTLIBRARIES += nss/libnss_libvirt_impl.la
nss_libnss_libvirt_impl_la_SOURCES = \
$(LIBVIRT_NSS_SOURCES)
@@ -440,7 +441,6 @@ nss_libnss_libvirt_impl_la_LIBADD = \
../gnulib/lib/libgnu.la \
../src/libvirt-nss.la
-if WITH_NSS
nss_libnss_libvirt_la_SOURCES =
nss_libnss_libvirt_la_LDFLAGS = \
$(VERSION_SCRIPT_FLAGS)$(LIBVIRT_NSS_SYMBOL_FILE) \
--
2.7.2
8 years, 9 months
[libvirt] [PATCH] bhyve: caps: Log error message when CPU init fails
by Cole Robinson
virBhyveCapsInitCPU will raise a libvirt error; even though we treat
it as non-fatal we should log the actual message.
---
src/bhyve/bhyve_capabilities.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index d2970a2..93faaed 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -97,7 +97,7 @@ virBhyveCapsBuild(void)
goto error;
if (virBhyveCapsInitCPU(caps, virArchFromHost()) < 0)
- VIR_WARN("Failed to get host CPU");
+ VIR_WARN("Failed to get host CPU: %s", virGetLastErrorMessage());
return caps;
--
2.5.0
8 years, 9 months
[libvirt] [PATCH] bhyve: process: Log error message when kill fails
by Cole Robinson
virProcessKillPainfully will raise a libvirt error, so log it. We
can drop the manual pid logging since ProcessKill always reports
the pid in its error message.
---
src/bhyve/bhyve_process.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index 14588a9..f2ec712 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -283,9 +283,8 @@ virBhyveProcessStop(bhyveConnPtr driver,
/* First, try to kill 'bhyve' process */
if (virProcessKillPainfully(vm->pid, true) != 0)
- VIR_WARN("Failed to gracefully stop bhyve VM '%s' (pid: %d)",
- vm->def->name,
- (int)vm->pid);
+ VIR_WARN("Failed to gracefully stop bhyve VM '%s': %s",
+ vm->def->name, virGetLastErrorMessage());
/* Cleanup network interfaces */
bhyveNetCleanup(vm);
--
2.5.0
8 years, 9 months
[libvirt] Doubt on libvirtmod.so library functions
by Renju M
Hello,
I am doing a project on virtual machine migration and I am using
virt-manager for the vm maintenance. When I looked at the libvirt.py code I
understood that, once it calls migrate() function inside libvirt.py, it
then calls, libvirtmod.virDomainMigrate(self._o, dconn__o, flags, dname,
uri, bandwidth).
How can I check the definition of this function?
Also, which is the function that gets called at the destination to receive
the migrated data from the source and is there a way to see the definition
of this function as well?
And if I want to change the timeout period for the migration process,
should I change it in migrateSetMaxDowntime() function?
Thankfully,
--
*Renju* *M*
NIT-C
8 years, 9 months
[libvirt] autocreate tap device for VIR_DOMAIN_NET_TYPE_ETHERNET
by Vasiliy Tolstov
If a user specify ehernet device create it via libvirt and run
script if it provided. After this commit user does not need to
run external script to create tap device or add root to qemu
process.
Also now libvirt can manage ip address and routes for this device.
Signed-off-by: Vasiliy Tolstov <v.tolstov(a)selfip.ru>
---
docs/schemas/interface.rng | 6 ++
include/libvirt/libvirt-domain.h | 1 +
src/conf/domain_conf.c | 14 +++-
src/conf/domain_conf.h | 1 +
src/conf/network_conf.c | 26 ++++++-
src/conf/network_conf.h | 1 +
src/libvirt.c | 8 +-
src/lxc/lxc_container.c | 2 +-
src/network/bridge_driver.c | 2 +-
src/qemu/qemu_command.c | 38 +++++-----
src/qemu/qemu_hotplug.c | 36 +++++++--
src/qemu/qemu_interface.c | 158 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_interface.h | 5 ++
src/qemu/qemu_process.c | 6 ++
src/util/virnetdev.c | 43 +++++++----
src/util/virnetdev.h | 1 +
16 files changed, 306 insertions(+), 42 deletions(-)
diff --git a/docs/schemas/interface.rng b/docs/schemas/interface.rng
index 052703ce84aa..b81c38b9d07c 100644
--- a/docs/schemas/interface.rng
+++ b/docs/schemas/interface.rng
@@ -332,6 +332,9 @@
<optional>
<attribute name="prefix"><ref name="ipv4Prefix"/></attribute>
</optional>
+ <optional>
+ <attribute name="peer"><ref name="ipv4Addr"/></attribute>
+ </optional>
</element>
</zeroOrMore>
<optional>
@@ -361,6 +364,9 @@
<optional>
<attribute name="prefix"><ref name="ipv6Prefix"/></attribute>
</optional>
+ <optional>
+ <attribute name="peer"><ref name="ipv6Addr"/></attribute>
+ </optional>
</element>
</zeroOrMore>
<optional>
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 4ac29cd78816..d2cd45eba253 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3926,6 +3926,7 @@ typedef virDomainIPAddress *virDomainIPAddressPtr;
struct _virDomainInterfaceIPAddress {
int type; /* virIPAddrType */
char *addr; /* IP address */
+ char *peer; /* IP peer */
unsigned int prefix; /* IP address prefix */
};
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7d68096f0e55..fa62cda7a290 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5725,7 +5725,7 @@ virDomainNetIpParseXML(xmlNodePtr node)
unsigned int prefixValue = 0;
char *familyStr = NULL;
int family = AF_UNSPEC;
- char *address = NULL;
+ char *address = NULL, *peer = NULL;
if (!(prefixStr = virXMLPropString(node, "prefix")) ||
(virStrToLong_ui(prefixStr, NULL, 10, &prefixValue) < 0)) {
@@ -5739,6 +5739,9 @@ virDomainNetIpParseXML(xmlNodePtr node)
goto cleanup;
}
+ if ((peer = virXMLPropString(node, "peer")) == NULL)
+ VIR_DEBUG("Peer is empty");
+
familyStr = virXMLPropString(node, "family");
if (familyStr && STREQ(familyStr, "ipv4"))
family = AF_INET;
@@ -5756,6 +5759,14 @@ virDomainNetIpParseXML(xmlNodePtr node)
address);
goto cleanup;
}
+
+ if ((peer != NULL) && (virSocketAddrParse(&ip->peer, peer, family) < 0)) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("Failed to parse IP address: '%s'"),
+ peer);
+ goto cleanup;
+ }
+
ip->prefix = prefixValue;
ret = ip;
@@ -5765,6 +5776,7 @@ virDomainNetIpParseXML(xmlNodePtr node)
VIR_FREE(prefixStr);
VIR_FREE(familyStr);
VIR_FREE(address);
+ VIR_FREE(peer);
VIR_FREE(ip);
return ret;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 85c4f554a2e2..0feff47ac99e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -513,6 +513,7 @@ typedef struct _virDomainNetIpDef virDomainNetIpDef;
typedef virDomainNetIpDef *virDomainNetIpDefPtr;
struct _virDomainNetIpDef {
virSocketAddr address; /* ipv4 or ipv6 address */
+ virSocketAddr peer; /* ipv4 or ipv6 address of peer */
unsigned int prefix; /* number of 1 bits in the net mask */
};
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 4fb2e2a75b9d..baee3ad609f2 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1456,7 +1456,7 @@ virNetworkIPDefParseXML(const char *networkName,
*/
xmlNodePtr cur, save;
- char *address = NULL, *netmask = NULL;
+ char *address = NULL, *netmask = NULL, *peer = NULL;
unsigned long prefix = 0;
int prefixRc;
int result = -1;
@@ -1502,6 +1502,14 @@ virNetworkIPDefParseXML(const char *networkName,
else
def->prefix = prefix;
+ peer = virXPathString("string(./@peer)", ctxt);
+ if (peer && (virSocketAddrParse(&def->peer, peer, AF_UNSPEC) < 0)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid peer '%s' in network '%s'"),
+ netmask, networkName);
+ goto cleanup;
+ }
+
/* validate address, etc. for each family */
if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
@@ -1531,6 +1539,14 @@ virNetworkIPDefParseXML(const char *networkName,
prefix, networkName);
goto cleanup;
}
+ if (peer) {
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->peer, AF_INET)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Family 'ipv4' specified for non-IPv4 address '%s' in network '%s'"),
+ peer, networkName);
+ goto cleanup;
+ }
+ }
} else if (STREQ(def->family, "ipv6")) {
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -1550,6 +1566,14 @@ virNetworkIPDefParseXML(const char *networkName,
prefix, networkName);
goto cleanup;
}
+ if (peer) {
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->peer, AF_INET6)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Family 'ipv6' specified for non-IPv6 address '%s' in network '%s'"),
+ peer, networkName);
+ goto cleanup;
+ }
+ }
} else {
virReportError(VIR_ERR_XML_ERROR,
_("Unrecognized family '%s' in network '%s'"),
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index b72257b970a8..9b8e807fda3c 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -152,6 +152,7 @@ struct _virNetworkIpDef {
*/
unsigned int prefix; /* ipv6 - only prefix allowed */
virSocketAddr netmask; /* ipv4 - either netmask or prefix specified */
+ virSocketAddr peer; /* ipv4 or ipv6 peer address */
size_t nranges; /* Zero or more dhcp ranges */
virSocketAddrRangePtr ranges;
diff --git a/src/libvirt.c b/src/libvirt.c
index dd58e9c23d14..a0458e7004d9 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -274,6 +274,7 @@ winsock_init(void)
#ifdef WITH_GNUTLS_GCRYPT
+# if GCRYPT_VERSION_NUMBER < 0x010600
static int
virTLSMutexInit(void **priv)
{
@@ -318,8 +319,9 @@ virTLSMutexUnlock(void **priv)
virMutexUnlock(lock);
return 0;
}
+#endif
-
+# if GCRYPT_VERSION_NUMBER < 0x010600
static struct gcry_thread_cbs virTLSThreadImpl = {
/* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */
# ifdef GCRY_THREAD_OPTION_VERSION
@@ -335,7 +337,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif /* WITH_GNUTLS_GCRYPT */
-
+#endif
static bool virGlobalError;
static virOnceControl virGlobalOnce = VIR_ONCE_CONTROL_INITIALIZER;
@@ -361,6 +363,7 @@ virGlobalInit(void)
#endif
#ifdef WITH_GNUTLS_GCRYPT
+ # if GCRYPT_VERSION_NUMBER < 0x010600
/*
* This sequence of API calls it copied exactly from
* gnutls 2.12.23 source lib/gcrypt/init.c, with
@@ -374,6 +377,7 @@ virGlobalInit(void)
gcry_control(GCRYCTL_DISABLE_SECMEM, NULL, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
}
+ # endif
#endif
virLogSetFromEnv();
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 348bbfbc01fc..a909b660b3ae 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -520,7 +520,7 @@ static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef,
VIR_DEBUG("Adding IP address '%s/%u' to '%s'",
ipStr, ip->prefix, newname);
- if (virNetDevSetIPAddress(newname, &ip->address, prefix) < 0) {
+ if (virNetDevSetIPAddress(newname, &ip->address, NULL, prefix) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("Failed to set IP address '%s' on %s"),
ipStr, newname);
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index a09a7e474fc5..b3dbea13b58f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1970,7 +1970,7 @@ networkAddAddrToBridge(virNetworkObjPtr network,
}
if (virNetDevSetIPAddress(network->def->bridge,
- &ipdef->address, prefix) < 0)
+ &ipdef->address, NULL, prefix) < 0)
return -1;
return 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3e7f1fe3ddf1..30eeab79a608 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3220,6 +3220,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
virBufferAsprintf(&buf, "tap%c", type_sep);
/* for one tapfd 'fd=' shall be used,
* for more than one 'fds=' is the right choice */
@@ -3237,20 +3238,6 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
is_tap = true;
break;
- case VIR_DOMAIN_NET_TYPE_ETHERNET:
- virBufferAddLit(&buf, "tap");
- if (net->ifname) {
- virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
- type_sep = ',';
- }
- if (net->script) {
- virBufferAsprintf(&buf, "%cscript=%s", type_sep,
- net->script);
- type_sep = ',';
- }
- is_tap = true;
- break;
-
case VIR_DOMAIN_NET_TYPE_CLIENT:
virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
type_sep,
@@ -7783,7 +7770,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
- actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
+ actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -7793,7 +7781,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
/* and only TAP devices support nwfilter rules */
if (net->filter &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("filterref is not supported for "
"network interfaces of type %s"),
@@ -7803,7 +7792,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (net->backend.tap &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Custom tap device path is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -7841,6 +7831,20 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (qemuInterfaceDirectConnect(def, driver, net,
tapfd, tapfdSize, vmop) < 0)
goto cleanup;
+ } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+ tapfdSize = net->driver.virtio.queues;
+ if (!tapfdSize)
+ tapfdSize = 1;
+
+ if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
+ VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
+ goto cleanup;
+
+ memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
+
+ if (qemuInterfaceEthernetConnect(def, driver, net,
+ tapfd, tapfdSize) < 0)
+ goto cleanup;
}
/* For types whose implementations use a netdev on the host, add
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b580283d6273..4c224be25632 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -896,7 +896,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
- actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
+ actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -906,7 +907,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
/* and only TAP devices support nwfilter rules */
if (net->filter &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("filterref is not supported for "
"network interfaces of type %s"),
@@ -951,10 +953,19 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
vhostfd, &vhostfdSize) < 0)
goto cleanup;
} else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
- vhostfdSize = 1;
- if (VIR_ALLOC(vhostfd) < 0)
+ tapfdSize = vhostfdSize = net->driver.virtio.queues;
+ if (!tapfdSize)
+ tapfdSize = vhostfdSize = 1;
+ if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
goto cleanup;
- *vhostfd = -1;
+ memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
+ if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
+ goto cleanup;
+ memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
+ if (qemuInterfaceEthernetConnect(vm->def, driver, net,
+ tapfd, tapfdSize) < 0)
+ goto cleanup;
+ iface_connected = true;
if (qemuInterfaceOpenVhostNet(vm->def, net, priv->qemuCaps,
vhostfd, &vhostfdSize) < 0)
goto cleanup;
@@ -2205,6 +2216,21 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
if (ret < 0)
goto cleanup;
+ if (virDomainNetGetActualType(dev) == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+ switch (linkstate) {
+ case VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP:
+ case VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT:
+ if ((ret = virNetDevSetOnline(dev->ifname, true)) < 0)
+ goto cleanup;
+ break;
+
+ case VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN:
+ if ((ret = virNetDevSetOnline(dev->ifname, false)) < 0)
+ goto cleanup;
+ break;
+ }
+ }
+
/* modify the device configuration */
dev->linkstate = linkstate;
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index 08af13358113..bab0ff5b2006 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -387,6 +387,164 @@ qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
return *tapfd < 0 ? -1 : 0;
}
+/**
+ * qemuExecuteEthernetScript:
+ * @ifname: the interface name
+ * @script: the script name
+ *
+ * This function executes script for new tap device created by libvirt.
+ * Returns 0 in case of success or -1 on failure
+ */
+static int
+qemuExecuteEthernetScript(const char *ifname, const char *script)
+{
+ virCommandPtr cmd;
+ int ret;
+
+ cmd = virCommandNew(script);
+ virCommandAddArgFormat(cmd, "%s", ifname);
+ virCommandClearCaps(cmd);
+#ifdef CAP_NET_ADMIN
+ virCommandAllowCap(cmd, CAP_NET_ADMIN);
+#endif
+ virCommandAddEnvPassCommon(cmd);
+
+ ret = virCommandRun(cmd, NULL);
+
+ virCommandFree(cmd);
+ return ret;
+}
+
+/* qemuInterfaceEthernetConnect:
+ * @def: the definition of the VM
+ * @driver: qemu driver data
+ * @net: pointer to the VM's interface description
+ * @tapfd: array of file descriptor return value for the new device
+ * @tapfdsize: number of file descriptors in @tapfd
+ *
+ * Called *only* called if actualType is VIR_DOMAIN_NET_TYPE_ETHERNET
+ * (i.e. if the connection is made with a tap device)
+ */
+int
+qemuInterfaceEthernetConnect(virDomainDefPtr def,
+ virQEMUDriverPtr driver,
+ virDomainNetDefPtr net,
+ int *tapfd,
+ size_t tapfdSize)
+{
+ virMacAddr tapmac;
+ size_t j;
+ int ret = -1;
+ unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
+ bool template_ifname = false;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ const char *tunpath = "/dev/net/tun";
+
+ if (net->backend.tap) {
+ tunpath = net->backend.tap;
+ if (!(virQEMUDriverIsPrivileged(driver))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("cannot use custom tap device in session mode"));
+ goto cleanup;
+ }
+ }
+
+ if (!net->ifname ||
+ STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
+ strchr(net->ifname, '%')) {
+ VIR_FREE(net->ifname);
+ if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0)
+ goto cleanup;
+ /* avoid exposing vnet%d in getXMLDesc or error outputs */
+ template_ifname = true;
+ }
+
+ if (net->model && STREQ(net->model, "virtio"))
+ tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
+
+ if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize,
+ tap_create_flags) < 0) {
+ virDomainAuditNetDevice(def, net, tunpath, false);
+ goto cleanup;
+ }
+
+ virDomainAuditNetDevice(def, net, tunpath, true);
+ virMacAddrSet(&tapmac, &net->mac);
+ tapmac.addr[0] = 0xFE;
+
+ if (virNetDevSetMAC(net->ifname, &tapmac) < 0)
+ goto cleanup;
+
+ for (j = 0; j < net->nips; j++) {
+ virDomainNetIpDefPtr ip = net->ips[j];
+ unsigned int prefix = (ip->prefix > 0) ? ip->prefix :
+ VIR_SOCKET_ADDR_DEFAULT_PREFIX;
+ char *ipStr = virSocketAddrFormat(&ip->address);
+
+ VIR_DEBUG("Adding IP address '%s/%u' to '%s'",
+ ipStr, ip->prefix, net->ifname);
+
+ if (virNetDevSetIPAddress(net->ifname, &ip->address, &ip->peer, prefix) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Failed to set IP address '%s' on %s"),
+ ipStr, net->ifname);
+ VIR_FREE(ipStr);
+ goto cleanup;
+ }
+ VIR_FREE(ipStr);
+ }
+
+ if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP ||
+ net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT) {
+ if (virNetDevSetOnline(net->ifname, true) < 0)
+ goto cleanup;
+
+ /* Set the routes */
+ for (j = 0; j < net->nroutes; j++) {
+ virNetworkRouteDefPtr route = net->routes[j];
+
+ if (virNetDevAddRoute(net->ifname,
+ virNetworkRouteDefGetAddress(route),
+ virNetworkRouteDefGetPrefix(route),
+ virNetworkRouteDefGetGateway(route),
+ virNetworkRouteDefGetMetric(route)) < 0) {
+ goto cleanup;
+ }
+ }
+ }
+
+ if (net->script) {
+ if (qemuExecuteEthernetScript(net->ifname, net->script) < 0)
+ goto cleanup;
+ }
+
+ if (cfg->macFilter &&
+ ebtablesAddForwardAllowIn(driver->ebtables,
+ net->ifname,
+ &net->mac) < 0)
+ goto cleanup;
+
+ if (net->filter &&
+ virDomainConfNWFilterInstantiate(def->uuid, net) < 0) {
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (ret < 0) {
+ size_t i;
+ for (i = 0; i < tapfdSize && tapfd[i] >= 0; i++)
+ VIR_FORCE_CLOSE(tapfd[i]);
+ if (template_ifname)
+ VIR_FREE(net->ifname);
+ }
+ virObjectUnref(cfg);
+
+ return ret;
+}
+
+
/* qemuInterfaceBridgeConnect:
* @def: the definition of the VM
* @driver: qemu driver data
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index bf4dedf84ac9..66ead2aef81c 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -40,6 +40,11 @@ int qemuInterfaceDirectConnect(virDomainDefPtr def,
int *tapfd,
size_t tapfdSize,
virNetDevVPortProfileOp vmop);
+int qemuInterfaceEthernetConnect(virDomainDefPtr def,
+ virQEMUDriverPtr driver,
+ virDomainNetDefPtr net,
+ int *tapfd,
+ size_t tapfdSize);
int qemuInterfaceBridgeConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 14e4629e66f9..ef82581b130c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5699,6 +5699,12 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virDomainNetGetActualVirtPortProfile(net),
cfg->stateDir));
break;
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ if (net->ifname) {
+ ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
+ VIR_FREE(net->ifname);
+ }
+ break;
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index aed50f546263..d171f34e6058 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1039,21 +1039,28 @@ virNetDevCreateNetlinkAddressMessage(int messageType,
const char *ifname,
virSocketAddr *addr,
unsigned int prefix,
- virSocketAddr *broadcast)
+ virSocketAddr *broadcast,
+ virSocketAddr *peer)
{
struct nl_msg *nlmsg = NULL;
struct ifaddrmsg ifa;
unsigned int ifindex;
void *addrData = NULL;
+ void *peerData = NULL;
void *broadcastData = NULL;
size_t addrDataLen;
if (virNetDevGetIPAddressBinary(addr, &addrData, &addrDataLen) < 0)
return NULL;
- if (broadcast && virNetDevGetIPAddressBinary(broadcast, &broadcastData,
- &addrDataLen) < 0)
- return NULL;
+ if (peer && VIR_SOCKET_ADDR_VALID(peer)) {
+ if (virNetDevGetIPAddressBinary(peer, &peerData, &addrDataLen) < 0)
+ return NULL;
+ } else if (broadcast) {
+ if (virNetDevGetIPAddressBinary(broadcast, &broadcastData,
+ &addrDataLen) < 0)
+ return NULL;
+ }
/* Get the interface index */
if ((ifindex = if_nametoindex(ifname)) == 0)
@@ -1078,12 +1085,15 @@ virNetDevCreateNetlinkAddressMessage(int messageType,
if (nla_put(nlmsg, IFA_LOCAL, addrDataLen, addrData) < 0)
goto buffer_too_small;
- if (nla_put(nlmsg, IFA_ADDRESS, addrDataLen, addrData) < 0)
- goto buffer_too_small;
+ if (peerData) {
+ if (nla_put(nlmsg, IFA_ADDRESS, addrDataLen, peerData) < 0)
+ goto buffer_too_small;
+ }
- if (broadcastData &&
- nla_put(nlmsg, IFA_BROADCAST, addrDataLen, broadcastData) < 0)
- goto buffer_too_small;
+ if (broadcastData) {
+ if (nla_put(nlmsg, IFA_BROADCAST, addrDataLen, broadcastData) < 0)
+ goto buffer_too_small;
+ }
return nlmsg;
@@ -1098,6 +1108,7 @@ virNetDevCreateNetlinkAddressMessage(int messageType,
* virNetDevSetIPAddress:
* @ifname: the interface name
* @addr: the IP address (IPv4 or IPv6)
+ * @peer: The IP address of peer (IPv4 or IPv6)
* @prefix: number of 1 bits in the netmask
*
* Add an IP address to an interface. This function *does not* remove
@@ -1108,6 +1119,7 @@ virNetDevCreateNetlinkAddressMessage(int messageType,
*/
int virNetDevSetIPAddress(const char *ifname,
virSocketAddr *addr,
+ virSocketAddr *peer,
unsigned int prefix)
{
virSocketAddr *broadcast = NULL;
@@ -1116,9 +1128,8 @@ int virNetDevSetIPAddress(const char *ifname,
struct nlmsghdr *resp = NULL;
unsigned int recvbuflen;
-
/* The caller needs to provide a correct address */
- if (VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET) {
+ if (VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET && !VIR_SOCKET_ADDR_VALID(peer)) {
/* compute a broadcast address if this is IPv4 */
if (VIR_ALLOC(broadcast) < 0)
return -1;
@@ -1129,7 +1140,7 @@ int virNetDevSetIPAddress(const char *ifname,
if (!(nlmsg = virNetDevCreateNetlinkAddressMessage(RTM_NEWADDR, ifname,
addr, prefix,
- broadcast)))
+ broadcast, peer)))
goto cleanup;
if (virNetlinkCommand(nlmsg, &resp, &recvbuflen, 0, 0,
@@ -1288,7 +1299,7 @@ int virNetDevClearIPAddress(const char *ifname,
if (!(nlmsg = virNetDevCreateNetlinkAddressMessage(RTM_DELADDR, ifname,
addr, prefix,
- NULL)))
+ NULL, NULL)))
goto cleanup;
if (virNetlinkCommand(nlmsg, &resp, &recvbuflen, 0, 0,
@@ -1423,10 +1434,11 @@ virNetDevWaitDadFinish(virSocketAddrPtr *addrs, size_t count)
int virNetDevSetIPAddress(const char *ifname,
virSocketAddr *addr,
+ virSocketAddr *peer,
unsigned int prefix)
{
virCommandPtr cmd = NULL;
- char *addrstr = NULL, *bcaststr = NULL;
+ char *addrstr = NULL, *bcaststr = NULL, *peerstr = NULL;
virSocketAddr broadcast;
int ret = -1;
@@ -1453,6 +1465,8 @@ int virNetDevSetIPAddress(const char *ifname,
cmd = virCommandNew(IP_PATH);
virCommandAddArgList(cmd, "addr", "add", NULL);
virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+ if (peerstr)
+ virCommandAddArgList(cmd, "peer", peerstr, NULL);
if (bcaststr)
virCommandAddArgList(cmd, "broadcast", bcaststr, NULL);
virCommandAddArgList(cmd, "dev", ifname, NULL);
@@ -1465,6 +1479,7 @@ int virNetDevSetIPAddress(const char *ifname,
cleanup:
VIR_FREE(addrstr);
VIR_FREE(bcaststr);
+ VIR_FREE(peerstr);
virCommandFree(cmd);
return ret;
}
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index e7719d58a410..240fff774d30 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -90,6 +90,7 @@ int virNetDevGetOnline(const char *ifname,
int virNetDevSetIPAddress(const char *ifname,
virSocketAddr *addr,
+ virSocketAddr *peer,
unsigned int prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevAddRoute(const char *ifname,
--
2.7.3
8 years, 9 months
[libvirt] [PATCH] domain: Remove controller/net address whitelists
by Cole Robinson
Judging by how the whitelist has skewed quite far from the original
error message, I think it's better to just drop these.
If someone wants to revive this check I suggest implementing it on
a per-HV driver basis with PostParse callbacks.
---
src/conf/domain_conf.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d376a2c..ec14577 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7969,17 +7969,6 @@ virDomainControllerDefParseXML(xmlNodePtr node,
break;
}
- if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Controllers must use the 'pci' address type"));
- goto error;
- }
-
cleanup:
ctxt->node = saved;
VIR_FREE(typeStr);
@@ -8670,19 +8659,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error;
}
- /* XXX what about ISA/USB based NIC models - once we support
- * them we should make sure address type is correct */
- if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
- def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Network interfaces must use 'pci' address type"));
- goto error;
- }
-
switch (def->type) {
case VIR_DOMAIN_NET_TYPE_NETWORK:
if (network == NULL) {
--
2.5.0
8 years, 9 months
[libvirt] [libvirt-sandbox PATCH] Silence PyGIWarnings
by Guido Günther
This fixes
/usr/bin/virt-sandbox-service:22: PyGIWarning: LibvirtGObject was imported without specifying a version first. Use gi.require_version('LibvirtGObject', '1.0') before import to ensure that the right version gets loaded.
from gi.repository import LibvirtGObject
/usr/bin/virt-sandbox-service:23: PyGIWarning: LibvirtSandbox was imported without specifying a version first. Use gi.require_version('LibvirtSandbox', '1.0') before import to ensure that the right version gets loaded.
from gi.repository import LibvirtSandbox
---
bin/virt-sandbox-service | 3 +++
1 file changed, 3 insertions(+)
diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service
index a4a2154..45f4517 100755
--- a/bin/virt-sandbox-service
+++ b/bin/virt-sandbox-service
@@ -19,7 +19,10 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
+import gi
+gi.require_version('LibvirtGObject', '1.0')
from gi.repository import LibvirtGObject
+gi.require_version('LibvirtSandbox', '1.0')
from gi.repository import LibvirtSandbox
from gi.repository import GLib
import gi
--
2.7.0
8 years, 9 months
[libvirt] [PATCH 00/24] hostdev: Cleanups and fixes
by Andrea Bolognani
Part of an ongoing quest to fix:
libvirt management of VFIO devices can lead to host crashes
https://bugzilla.redhat.com/show_bug.cgi?id=1272300
Previous episode:
[PATCH v2 0/9] PCI hostdev refactoring
https://www.redhat.com/archives/libvir-list/2016-January/msg01066.html
The plan:
Once this is in, rebase the series mentioned above on top of it;
hopefully it will be smaller and easier to review. Once *that*
is in, rebase / rewrite the actual bug fix - probably the latter,
because the code has changed a lot since I posted it
In this episode:
01-06 Cleanups in the test cases; mostly unrelated, but commit
24 depends on them
07-17 More cleanups and (I believe) farily uncontroversial
changes, aimed at making the actual changes either
smaller or more obvious
18-19 Change in variable names that make the intended semantics
clearer, which should in turn make the follow-up changes
easier to review
Up until here there should be basically no change in behavior
20 Bug fix
21 Improvement to error reporting
22 The whole point of this series, and also the commit
where it's more likely that I might have gotten something
wrong :) I haven't been able to figure out a way to split
it into smaller chunks, sorry
23 Another bug fix
24 Test the changes made by the rest of the series
Cheers.
Andrea Bolognani (24):
tests: hostdev: Remove magic numbers
tests: hostdev: Use better variable names
tests: hostdev: Declare count inside CHECK_LIST_COUNT()
tests: hostdev: Use size_t for count variables
tests: hostdev: Add more checks on list size
tests: hostdev: Group test cases
hostdev: Make comments easier to change later
hostdev: Remove false comment
hostdev: Fix indentation
hostdev: Remove explicit NULL checks
hostdev: Remove redundant check
hostdev: virHostdevIsPCINetDevice() should return a bool
hostdev: Change argument order for virHostdevReattachPCIDevice()
hostdev: Look up devices using IDs when possible
hostdev: Remove virHostdevGetActivePCIHostDeviceList()
hostdev: Rename hostdev_mgr -> mgr
hostdev: Rename usesVfio -> usesVFIO
hostdev: Use consistent variable names
hostdev: Add more comments
hostdev: Save netdev configuration of actual device
hostdev: Stop early if unmanaged devices have not been detached
hostdev: Streamline device ownership tracking
hostdev: Use actual device when reattaching
tests: hostdev: Add more tests
src/util/virhostdev.c | 660 +++++++++++++++++++++++++------------------------
tests/virhostdevtest.c | 320 ++++++++++++++++++------
2 files changed, 576 insertions(+), 404 deletions(-)
--
2.5.0
8 years, 9 months
[libvirt] [PATCH v5 0/9] NSS module for libvirt
by Michal Privoznik
v5 of:
https://www.redhat.com/archives/libvir-list/2016-February/msg00693.html
diff to v4:
- Dropped the virjson const correctness patch
- Worked in Martin's review (small nits here and there)
- Dropped libxml2 dependency
Patches 1, 4, and 5 have been ACKed already, but I'm sending them for completeness.
Michal Privoznik (9):
Export virLease* functions for leases file handling
virLeaseReadCustomLeaseFile: Allow server_duid to be NULL
virsocketaddr: Introduce virSocketAddrSetIPv6Addr
Initial support for NSS plugin skeleton
libvirt.spec.in: Introduce libvirt-nss package
nss: Implement _nss_libvirt_gethostbyname3_r
Implement _nss_libvirt_gethostbyname4_r
nss: Introduce a test
tests: Introduce nsslinktest
cfg.mk | 2 +-
config-post.h | 24 +++
configure.ac | 2 +
libvirt.spec.in | 21 ++
m4/virt-nss.m4 | 51 +++++
po/POTFILES.in | 1 +
src/Makefile.am | 58 ++++++
src/libvirt_private.syms | 7 +
src/network/leaseshelper.c | 270 +-------------------------
src/util/virfile.c | 3 +-
src/util/virfile.h | 10 +-
src/util/virlease.c | 305 +++++++++++++++++++++++++++++
src/util/virlease.h | 44 +++++
src/util/virsocketaddr.c | 15 ++
src/util/virsocketaddr.h | 1 +
tests/Makefile.am | 31 ++-
tests/nssdata/virbr0.status | 20 ++
tests/nssdata/virbr1.status | 20 ++
tests/nsslinktest.c | 39 ++++
tests/nssmock.c | 140 ++++++++++++++
tests/nsstest.c | 208 ++++++++++++++++++++
tools/Makefile.am | 43 +++++
tools/nss/libvirt_nss.c | 458 ++++++++++++++++++++++++++++++++++++++++++++
tools/nss/libvirt_nss.h | 52 +++++
tools/nss/libvirt_nss.syms | 12 ++
25 files changed, 1562 insertions(+), 275 deletions(-)
create mode 100644 m4/virt-nss.m4
create mode 100644 src/util/virlease.c
create mode 100644 src/util/virlease.h
create mode 100644 tests/nssdata/virbr0.status
create mode 100644 tests/nssdata/virbr1.status
create mode 100644 tests/nsslinktest.c
create mode 100644 tests/nssmock.c
create mode 100644 tests/nsstest.c
create mode 100644 tools/nss/libvirt_nss.c
create mode 100644 tools/nss/libvirt_nss.h
create mode 100644 tools/nss/libvirt_nss.syms
--
2.4.10
8 years, 9 months