[libvirt] libvirt modification
by Patrick Raad
Hello,
I am not that expert in development, but I am working on a project for
migrating VM between hosts and I need to add a function to libvirt in order
to send a certain message.
What I am using is KVM-qemu as a hypervisor. When a VM "live" migrates from
a host A to a host B, I need that the host B sends a certain message
through a socket, once the live migration has been successfully completed
and the VM is running on host B.
Can you please tell me which file I must modify in order to add my
function? What does libvirt uses to notify the destination that the
migration is completed.
I thought about modifying qemu_migration.c, but it didn't seem to work, so
I was thinking about using virsh.c, but this way the destination host won't
be notified so I don't think it can work...
Any ideas??
Thank you
--
Patrick RAAD
12 years, 5 months
[libvirt] Error while installing a guest
by Pankaj Rawat
Hi all ,
I have SL6.2 x86_64 Installed on my system
I updated libvirt version from 0.9.4 to 0.9.11, I had removed previous libvirt via yum
I done this by compiling the source.
I started libvirt daemon created by compiling source :
# ./root/libvirt_0.9.11/build/daomen/libvirtd
Now I tried to create a guest:-
[root@localhost libvirt-0.9.11]# /usr/sbin/virt-install --accelerate --hvm --connect qemu:///system --name g3 --vcpu=1 --ram 1024 --os-type=linux --os-variant=rhel6 --network bridge:br0 --disk /var/lib/libvirt/images/g2 --disk=/opt/SL-62-x86_64-2012-02-06-Install-DVD.iso,device=cdrom,perms=ro --location=/mnt/ --nographics --serial pty --extra-args=console=ttyS0,115200n8 --keymap=en --force
The command line above normally works fine (I have created many vm by using same above command)
But here Following error comes
Starting install...
Retrieving file .treeinfo... | 768 B 00:00 ...
Retrieving file vmlinuz... | 7.5 MB 00:00 ...
Retrieving file initrd.img... 100% [=====================================================] 11 MB/s | 29 MB --:-- ETA
Retrieving file initrd.img... | 59 MB 00:09 ...
ERROR internal error Process exited while reading console log output:
Domain installation does not appear to have been successful.
If it was, you can restart your domain by running:
virsh --connect qemu:///system start g3
otherwise, please restart your installation.
at libvirtd console following output comes:
2012-06-12 13:58:55.239+0000: 17800: error : qemuProcessReadLogOutput:1298 : internal error Process exited while reading console log output:
2012-06-12 14:04:12.120+0000: 17802: warning : qemuDomainObjTaint:1227 : Domain id=3 name='g3' uuid=fec6cb5a-d4ea-d2c9-505c-611227fb4f4c is tainted: high-privileges
2012-06-12 13:58:55.239+0000: 17800: error : qemuProcessReadLogOutput:1298 : internal error Process exited while reading console lo
I don't know how to resolve this .
Regards
Pankaj Rawat
DISCLAIMER:
-----------------------------------------------------------------------------------------------------------------------
The contents of this e-mail and any attachment(s) are confidential and
intended
for the named recipient(s) only.
It shall not attach any liability on the originator or NECHCL or its
affiliates. Any views or opinions presented in
this email are solely those of the author and may not necessarily reflect the
opinions of NECHCL or its affiliates.
Any form of reproduction, dissemination, copying, disclosure, modification,
distribution and / or publication of
this message without the prior written consent of the author of this e-mail is
strictly prohibited. If you have
received this email in error please delete it and notify the sender
immediately. .
-----------------------------------------------------------------------------------------------------------------------
12 years, 5 months
[libvirt] [PATCH 0/7] Introduce API for dumping domain IP addresses
by Michal Privoznik
This feature has been requested for a very long time. However,
we had to wait for guest agent to obtain reliable results as
user might create totally different structure of interfaces than
seen from outside (e.g. bonding, virtual interfaces, etc.).
That's the main reason why sniffing for domain traffic can
return bogus results. Fortunately, qemu guest agent implement
requested part for a while so nothing holds us back anymore.
To make matters worse, guest OS can assign whatever name to
an interface and changing MAC inside guest isn't propagated
to the host which in the end see original one.
Therefore, finding correlation between interface within guest
and the host side end is left as exercise for mgmt applications.
This API is called virDomainInterfacesAddresses (okay, maybe
too many plurals) and returns a dynamically allocated array
of virDomainInterface struct. The great disadvantage once
this gets released, it's written in stone and we cannot change
or add an item into it. Therefore we might add a padding into
it - something like reserved for future use. On the other hand,
everything important is already there - what else we will want
to add? :)
There are basically two approaches:
1) two APIs: one for list interfaces names, the other for querying
addresses on singe interface
2) one API that returns everything
I've chosen the latter as it's race free (query for interface that
has gone meanwhile).
Michal Privoznik (7):
Introduce virDomainInterfacesAddresses API
virsh: Expose virDomainInterfacesAddresses
qemu_agent: Implement 'guest-network-get-interfaces' command handling
qemu: Implement virDomainInterfacesAddresses
remote: Implement virDomainInterfacesAddresses
python: Expose virDomainInterfacesAddresses
python: create example for dumping domain IP addresses
daemon/remote.c | 122 ++++++++++++++++++++++++++++++
examples/python/Makefile.am | 2 +-
examples/python/README | 1 +
examples/python/domipaddrs.py | 50 ++++++++++++
include/libvirt/libvirt.h.in | 32 ++++++++
python/generator.py | 1 +
python/libvirt-override-api.xml | 6 ++
python/libvirt-override.c | 116 ++++++++++++++++++++++++++++
src/driver.h | 6 ++
src/libvirt.c | 101 +++++++++++++++++++++++++
src/libvirt_public.syms | 5 +
src/qemu/qemu_agent.c | 158 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 4 +
src/qemu/qemu_driver.c | 76 +++++++++++++++++++
src/remote/remote_driver.c | 95 +++++++++++++++++++++++
src/remote/remote_protocol.x | 25 ++++++-
tools/virsh.c | 92 +++++++++++++++++++++++
tools/virsh.pod | 10 +++
18 files changed, 900 insertions(+), 2 deletions(-)
create mode 100644 examples/python/domipaddrs.py
--
1.7.8.5
12 years, 5 months
[libvirt] [PATCH 0/4] virsh snapshot-info
by Eric Blake
I'm working on a patch series to allow offline disk snapshots,
and in the process, I found that I either don't have enough
information ('virsh snapshot-list' is great for a summary, but not
for an individual snapshot) or too much ('virsh snapshot-dumpxml'
means I have to wade through the XML). This provides an intermediate
view, designed for ease of use.
Eric Blake (4):
snapshot: new query APIs
snapshot: add 'virsh snapshot-info'
snapshot: RPC for new query APIs
snapshot: implement new APIs for qemu, esx, and vbox
include/libvirt/libvirt.h.in | 9 +++
src/driver.h | 10 +++
src/esx/esx_driver.c | 71 ++++++++++++++++++++++++
src/libvirt.c | 85 ++++++++++++++++++++++++++++
src/libvirt_public.syms | 6 ++
src/qemu/qemu_driver.c | 83 ++++++++++++++++++++++++++++
src/remote/remote_driver.c | 2 +
src/remote/remote_protocol.x | 23 +++++++-
src/remote_protocol-structs | 16 +++++
src/vbox/vbox_tmpl.c | 97 ++++++++++++++++++++++++++++++++
tools/virsh.c | 125 ++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 5 ++
12 files changed, 531 insertions(+), 1 deletions(-)
--
1.7.7.6
12 years, 5 months
[libvirt] [PATCH] docs: minor fixes to domain interface documentation
by Laine Stump
A few examples for <interface> had a type='direct' interface with no
sub-elements. This is not allowed - a type='direct' interface must
have at least a source element. (Most likely the example was copied
from the type='user' or type='ethernet' examples - they *do* allow an
instance with no sub-elements).
There was also one place that mistakenly used %lt; ... %gt; instead of
< ... > (for some reason, I make that typo all the time).
---
Pushed under the trivial rule.
docs/formatdomain.html.in | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 95c3edc..b2e5db9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2364,7 +2364,6 @@
<pre>
...
<devices>
- <interface type='direct'/>
...
<interface type='direct'>
<source dev='eth0' mode='vepa'/>
@@ -2413,7 +2412,6 @@
<pre>
...
<devices>
- <interface type='direct'/>
...
<interface type='direct'>
<source dev='eth0.2' mode='vepa'/>
@@ -2441,7 +2439,6 @@
<pre>
...
<devices>
- <interface type='direct'/>
...
<interface type='direct'>
<source dev='eth0' mode='private'/>
@@ -2462,7 +2459,7 @@
passthrough, after first optionally setting the device's MAC
address to the configured value, and associating the device with
an 802.1Qgh capable switch using an optionally specified
- %lt;virtualport%gt; element (see the examples of virtualport
+ <virtualport> element (see the examples of virtualport
given above for type='direct' network devices). Note that - due
to limitations in standard single-port PCI ethernet card driver
design - only SR-IOV (Single Root I/O Virtualization) virtual
--
1.7.10.2
12 years, 5 months
[libvirt] [PATCH] Two RPM conditional fixes for RHEL-7
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Ensure systemd is used in RHEL-7 and cgconfig is not used in
RHEL-7
---
libvirt.spec.in | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index a78b117..f8e3b05 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -133,8 +133,9 @@
%define with_hyperv 0
%endif
-# Although earlier Fedora has systemd, libvirt still used sysvinit
-%if 0%{?fedora} >= 17
+# Fedora 17 / RHEL-7 are first where we use systemd. Although earlier
+# Fedora has systemd, libvirt still used sysvinit there.
+%if 0%{?fedora} >= 17 || 0{?rhel} >= 7
%define with_systemd 1
%endif
@@ -1348,9 +1349,9 @@ if [ $1 -eq 1 ] ; then
fi
%else
%if %{with_cgconfig}
-# Starting with Fedora 16, systemd automounts all cgroups, and cgconfig is
-# no longer a necessary service.
-%if 0%{?rhel} || (0%{?fedora} && 0%{?fedora} < 16)
+# Starting with Fedora 16/RHEL-7, systemd automounts all cgroups,
+# and cgconfig is no longer a necessary service.
+%if (0%{?rhel} && 0%{?rhel} < 7) || (0%{?fedora} && 0%{?fedora} < 16)
if [ "$1" -eq "1" ]; then
/sbin/chkconfig cgconfig on
fi
--
1.7.10.2
12 years, 5 months
[libvirt] [PATCH] nwfilter: Display detected IP address in domain XML
by Stefan Berger
Display detected IP addresses in the domain XML using the
IP_LEASE variable name. This variable name now becomes
a reserved variable name that can be read only but not set
by the user.
The format of the value is: <ip address>,<lease timeout in seconds>
An example of a displayed XML may then be:
<interface type='bridge'>
<mac address='52:54:00:68:e3:90'/>
<source bridge='virbr0'/>
<target dev='vnet1'/>
<model type='virtio'/>
<filterref filter='clean-traffic'>
<parameter name='CTRL_IP_LEARNING' value='dhcp'/>
<parameter name='IP_LEASE' value='192.168.122.210,100'/>
</filterref>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>
This patch now also offers a better (libvirt-internal) API for accessing
the detected IP addresses. The function virDomainConfNWFilterGetLeases can
be used to retrieve a list of IP leases associated with a given interface.
This function will then either retrieve the data from the DHCP snooping or
IP learning subsystems, depending on which detection algorithm has been
activated. If none is active, a NULL pointer for the array of leases will
be returned.
---
PS: This is the last remaining patch of the DHCP snooping series. I am
submitting it now as a stand-alone patch restarting the version counting.
---
docs/formatnwfilter.html.in | 27 +++++++++++
src/conf/domain_conf.c | 16 +++++--
src/conf/domain_nwfilter.c | 13 +++++
src/conf/domain_nwfilter.h | 15 ++++++
src/conf/nwfilter_conf.c | 3 -
src/conf/nwfilter_ipaddrmap.c | 51 ++++++++++++++++++++++
src/conf/nwfilter_ipaddrmap.h | 5 ++
src/conf/nwfilter_params.c | 75 ++++++++++++++++++++++++++++++++-
src/conf/nwfilter_params.h | 9 +++
src/libvirt_private.syms | 5 +-
src/nwfilter/nwfilter_dhcpsnoop.c | 59 +++++++++++++++++++++++++
src/nwfilter/nwfilter_dhcpsnoop.h | 4 +
src/nwfilter/nwfilter_driver.c | 10 ++++
src/nwfilter/nwfilter_gentech_driver.c | 26 +++++++++++
src/nwfilter/nwfilter_gentech_driver.h | 8 +++
src/nwfilter/nwfilter_learnipaddr.c | 9 +++
src/nwfilter/nwfilter_learnipaddr.h | 2
src/util/viriplease.h | 18 +++++++
18 files changed, 345 insertions(+), 10 deletions(-)
Index: libvirt-acl/src/conf/nwfilter_params.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_params.h
+++ libvirt-acl/src/conf/nwfilter_params.h
@@ -72,7 +72,10 @@ struct _virNWFilterHashTable {
virNWFilterHashTablePtr virNWFilterParseParamAttributes(xmlNodePtr cur);
int virNWFilterFormatParamAttributes(virBufferPtr buf,
virNWFilterHashTablePtr table,
- const char *filterref);
+ const char *filterref,
+ const unsigned char *vmuuid,
+ const unsigned char *mac,
+ const char *ifname);
virNWFilterHashTablePtr virNWFilterHashTableCreate(int n);
void virNWFilterHashTableFree(virNWFilterHashTablePtr table);
@@ -89,12 +92,14 @@ int virNWFilterHashTablePutAll(virNWFilt
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
# define VALID_VARVALUE \
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:,"
# define NWFILTER_VARNAME_IP "IP"
# define NWFILTER_VARNAME_MAC "MAC"
# define NWFILTER_VARNAME_CTRL_IP_LEARNING "CTRL_IP_LEARNING"
# define NWFILTER_VARNAME_DHCPSERVER "DHCPSERVER"
+# define NWFILTER_VARNAME_IP_LEASE "IP_LEASE"
+# define NWFILTER_VARNAME_IPV6_LEASE "IPV6_LEASE" /* future */
enum virNWFilterVarAccessType {
VIR_NWFILTER_VAR_ACCESS_ELEMENT = 0,
Index: libvirt-acl/src/conf/domain_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_conf.c
+++ libvirt-acl/src/conf/domain_conf.c
@@ -43,6 +43,7 @@
#include "buf.h"
#include "c-ctype.h"
#include "logging.h"
+#include "nwfilter_params.h"
#include "nwfilter_conf.h"
#include "ignore-value.h"
#include "storage_file.h"
@@ -11500,7 +11501,8 @@ error:
static int
virDomainNetDefFormat(virBufferPtr buf,
virDomainNetDefPtr def,
- unsigned int flags)
+ unsigned int flags,
+ const unsigned char *vmuuid)
{
const char *type = virDomainNetTypeToString(def->type);
@@ -11641,9 +11643,15 @@ virDomainNetDefFormat(virBufferPtr buf,
}
}
if (def->filter) {
+ const char *ifname = NULL;
+
+ if (!(flags & VIR_DOMAIN_XML_INACTIVE))
+ ifname = def->ifname;
+
virBufferAdjustIndent(buf, 6);
if (virNWFilterFormatParamAttributes(buf, def->filterparams,
- def->filter) < 0)
+ def->filter, vmuuid, def->mac,
+ ifname) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
}
@@ -12969,7 +12977,7 @@ virDomainDefFormatInternal(virDomainDefP
for (n = 0 ; n < def->nnets ; n++)
- if (virDomainNetDefFormat(buf, def->nets[n], flags) < 0)
+ if (virDomainNetDefFormat(buf, def->nets[n], flags, def->uuid) < 0)
goto cleanup;
for (n = 0 ; n < def->nsmartcards ; n++)
@@ -15222,7 +15230,7 @@ virDomainDeviceDefCopy(virCapsPtr caps,
rc = virDomainFSDefFormat(&buf, src->data.fs, flags);
break;
case VIR_DOMAIN_DEVICE_NET:
- rc = virDomainNetDefFormat(&buf, src->data.net, flags);
+ rc = virDomainNetDefFormat(&buf, src->data.net, flags, def->uuid);
break;
case VIR_DOMAIN_DEVICE_INPUT:
rc = virDomainInputDefFormat(&buf, src->data.input, flags);
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -3406,7 +3406,8 @@ virNWFilterIncludeDefFormat(virNWFilterI
virBufferAdjustIndent(&buf, 2);
if (virNWFilterFormatParamAttributes(&buf, inc->params,
- inc->filterref) < 0) {
+ inc->filterref,
+ NULL, NULL, NULL) < 0) {
virBufferFreeAndReset(&buf);
return NULL;
}
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -552,6 +552,7 @@ virDomainLockLeaseDetach;
# domain_nwfilter.h
+virDomainConfNWFiltetGetLeases;
virDomainConfNWFilterInstantiate;
virDomainConfNWFilterRegister;
virDomainConfNWFilterTeardown;
@@ -873,15 +874,17 @@ virNWFilterTestUnassignDef;
virNWFilterUnlockFilterUpdates;
-# nwfilter_ipaddrmap
+# nwfilter_ipaddrmap.h
virNWFilterIPAddrMapAddIPAddr;
virNWFilterIPAddrMapDelIPAddr;
virNWFilterIPAddrMapGetIPAddr;
+virNWFilterIPAddrMapGetIPLeases;
virNWFilterIPAddrMapInit;
virNWFilterIPAddrMapShutdown;
# nwfilter_params.h
+virNWFilterFormatParamAttributes;
virNWFilterHashTableCreate;
virNWFilterHashTableFree;
virNWFilterHashTablePut;
Index: libvirt-acl/src/conf/nwfilter_params.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_params.c
+++ libvirt-acl/src/conf/nwfilter_params.c
@@ -31,9 +31,16 @@
#include "nwfilter_params.h"
#include "domain_conf.h"
#include "logging.h"
+#include "domain_nwfilter.h"
+#include "nwfilter_ipaddrmap.h"
#define VIR_FROM_THIS VIR_FROM_NWFILTER
+static const char *virNWFilterReservedVarnames[] = {
+ NWFILTER_VARNAME_IP_LEASE,
+ NWFILTER_VARNAME_IPV6_LEASE,
+};
+
static bool isValidVarValue(const char *value);
static void virNWFilterVarAccessSetIntIterId(virNWFilterVarAccessPtr,
unsigned int);
@@ -784,6 +791,19 @@ virNWFilterParseVarValue(const char *val
return virNWFilterVarValueCreateSimpleCopyValue(val);
}
+static void
+virNWFilterDelReservedVarnames(virNWFilterHashTablePtr ht)
+{
+ unsigned int i;
+ virNWFilterVarValuePtr val;
+
+ for (i = 0; i < ARRAY_CARDINALITY(virNWFilterReservedVarnames); i++) {
+ val = virNWFilterHashTableRemoveEntry(ht,
+ virNWFilterReservedVarnames[i]);
+ virNWFilterVarValueFree(val);
+ }
+}
+
virNWFilterHashTablePtr
virNWFilterParseParamAttributes(xmlNodePtr cur)
{
@@ -834,6 +854,15 @@ skip_entry:
}
cur = cur->next;
}
+
+ /*
+ * read-only variables that may be usable in an incoming
+ * migration could be wired up here.
+ */
+
+ /* remove all reserved varnames from the table */
+ virNWFilterDelReservedVarnames(table);
+
return table;
err_exit:
@@ -855,10 +884,16 @@ virNWFilterFormatParameterNameSorter(con
int
virNWFilterFormatParamAttributes(virBufferPtr buf,
virNWFilterHashTablePtr table,
- const char *filterref)
+ const char *filterref,
+ const unsigned char *vmuuid,
+ const unsigned char *mac,
+ const char *ifname)
{
virHashKeyValuePairPtr items;
+ virIPLeasePtr leases = NULL;
+ size_t nLeases = 0;
int i, j, card, numKeys;
+ int ret = 0;
numKeys = virHashSize(table->hashTable);
@@ -889,14 +924,50 @@ virNWFilterFormatParamAttributes(virBuff
virNWFilterVarValueGetNthValue(value, j));
}
+ if (ifname) {
+ time_t now = time(0);
+ /* also display the IP addresses being used */
+ if (virDomainConfNWFilterGetLeases(&leases, &nLeases,
+ table,
+ ifname,
+ vmuuid,
+ mac) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < nLeases; i++) {
+ int64_t to;
+ char *ipbuf = virSocketAddrFormat(&leases[i].addr);
+
+ if (!ipbuf) {
+ virReportOOMError();
+ ret = -1;
+ goto cleanup;
+ }
+
+ to = (leases[i].timeout != VIR_IPLEASE_TIMEOUT_NONE)
+ ? (int64_t)(leases[i].timeout - now)
+ : -1;
+
+ virBufferAsprintf(buf,
+ " <parameter name='"
+ NWFILTER_VARNAME_IP_LEASE
+ "' value='%s,%ld'/>\n",
+ ipbuf, to);
+ VIR_FREE(ipbuf);
+ }
+ }
virBufferAddLit(buf, "</filterref>\n");
} else {
virBufferAddLit(buf, "/>\n");
}
+cleanup:
VIR_FREE(items);
+ VIR_FREE(leases);
- return 0;
+ return ret;
}
void
Index: libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_dhcpsnoop.c
+++ libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -1987,6 +1987,57 @@ virNWFilterSnoopLeaseFileLoad(void)
}
/*
+ * Get the detected IP addresses along with their absolute lease timeout.
+ */
+int
+virNWFilterSnoopGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const unsigned char *vmuuid,
+ const unsigned char *macaddr)
+{
+ int ret = 0;
+ char ifkey[VIR_IFKEY_LEN];
+ virNWFilterSnoopReqPtr req;
+ virNWFilterSnoopIPLeasePtr ipl;
+ size_t ctr = 0;
+ virIPLeasePtr myleases = NULL;
+
+ *leases = NULL;
+
+ virNWFilterSnoopIFKeyFMT(ifkey, vmuuid, macaddr);
+
+ req = virNWFilterSnoopReqGetByIFKey(ifkey);
+ if (req) {
+ time_t now = time(0);
+
+ /* protect req->start */
+ virNWFilterSnoopReqLock(req);
+
+ for (ipl = req->start; ipl; ipl = ipl->next) {
+ if (ipl->timeout <= now)
+ continue;
+
+ if (VIR_EXPAND_N(myleases, ctr, 1) < 0) {
+ VIR_FREE(myleases);
+ ret = -1;
+ goto cleanup;
+ }
+
+ myleases[ctr-1].addr = ipl->ipAddress;
+ myleases[ctr-1].timeout = ipl->timeout;
+ }
+
+ *leases = myleases;
+ *nLeases = ctr;
+
+cleanup:
+ virNWFilterSnoopReqUnlock(req);
+
+ virNWFilterSnoopReqPut(req);
+ }
+ return ret;
+}
+
+/*
* Wait until all threads have ended.
*/
static void
@@ -2174,6 +2225,14 @@ virNWFilterDHCPSnoopShutdown(void)
#else /* HAVE_LIBPCAP */
int
+virNWFilterSnoopGetLeases(virIPLeasePtr *leases ATTRIBUTE_UNUSED,
+ size_t *nLeases ATTRIBUTE_UNUSED,
+ const unsigned char *vmuuid ATTRIBUTE_UNUSED,
+ const unsigned char *macaddr ATTRIBUTE_UNUSED)
+{
+}
+
+int
virNWFilterDHCPSnoopInit(void)
{
return -1;
Index: libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_dhcpsnoop.h
+++ libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.h
@@ -36,4 +36,8 @@ int virNWFilterDHCPSnoopReq(virNWFilterT
virNWFilterHashTablePtr filterparams,
virNWFilterDriverStatePtr driver);
void virNWFilterDHCPSnoopEnd(const char *ifname);
+int virNWFilterSnoopGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const unsigned char *vmuuid,
+ const unsigned char *macaddr);
+
#endif /* __NWFILTER_DHCPSNOOP_H */
Index: libvirt-acl/src/conf/domain_nwfilter.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.c
+++ libvirt-acl/src/conf/domain_nwfilter.c
@@ -60,3 +60,16 @@ virDomainConfVMNWFilterTeardown(virDomai
virDomainConfNWFilterTeardown(vm->def->nets[i]);
}
}
+
+int
+virDomainConfNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ if (nwfilterDriver != NULL)
+ return nwfilterDriver->getLeases(leases, nLeases, table, ifname,
+ vmuuid, mac);
+ return 0;
+}
Index: libvirt-acl/src/conf/domain_nwfilter.h
===================================================================
--- libvirt-acl.orig/src/conf/domain_nwfilter.h
+++ libvirt-acl/src/conf/domain_nwfilter.h
@@ -23,14 +23,24 @@
#ifndef DOMAIN_NWFILTER_H
# define DOMAIN_NWFILTER_H
+# include "viriplease.h"
+
typedef int (*virDomainConfInstantiateNWFilter)(virConnectPtr conn,
const unsigned char *vmuuid,
virDomainNetDefPtr net);
typedef void (*virDomainConfTeardownNWFilter)(virDomainNetDefPtr net);
+typedef int (*virDomainConfGetLeases)(virIPLeasePtr *leases,
+ size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac);
+
typedef struct {
virDomainConfInstantiateNWFilter instantiateFilter;
virDomainConfTeardownNWFilter teardownFilter;
+ virDomainConfGetLeases getLeases;
} virDomainConfNWFilterDriver;
typedef virDomainConfNWFilterDriver *virDomainConfNWFilterDriverPtr;
@@ -41,5 +51,10 @@ int virDomainConfNWFilterInstantiate(vir
virDomainNetDefPtr net);
void virDomainConfNWFilterTeardown(virDomainNetDefPtr net);
void virDomainConfVMNWFilterTeardown(virDomainObjPtr vm);
+int virDomainConfNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr table,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac);
#endif /* DOMAIN_NWFILTER_H */
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -1209,3 +1209,29 @@ virNWFilterDomainFWUpdateCB(void *payloa
virDomainObjUnlock(obj);
}
+
+int
+virNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ virNWFilterVarValuePtr lv;
+ const char *learning = NULL;
+ int ret = 0;
+
+ if (!vars)
+ return 0;
+
+ lv = virHashLookup(vars->hashTable, NWFILTER_VARNAME_CTRL_IP_LEARNING);
+ if (lv)
+ learning = virNWFilterVarValueGetNthValue(lv, 0);
+
+ if (!learning || STRCASEEQ(learning, "any")) {
+ ret = virNWFilterLearnGetLeases(leases, nLeases, ifname);
+ } else if (STRCASEEQ(learning, "dhcp")) {
+ ret = virNWFilterSnoopGetLeases(leases, nLeases, vmuuid, mac);
+ }
+ return ret;
+}
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
@@ -23,6 +23,8 @@
#ifndef __NWFILTER_GENTECH_DRIVER_H
# define __NWFILTER_GENTECH_DRIVER_H
+# include "viriplease.h"
+
virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name);
int virNWFilterRuleInstAddData(virNWFilterRuleInstPtr res,
@@ -64,4 +66,10 @@ void virNWFilterDomainFWUpdateCB(void *p
const void *name,
void *data);
+int virNWFilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmmuid,
+ const unsigned char *mac);
+
#endif
Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_driver.c
@@ -463,6 +463,15 @@ nwfilterTeardownFilter(virDomainNetDefPt
virNWFilterTeardownFilter(net);
}
+static int
+nwfilterGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ virNWFilterHashTablePtr vars,
+ const char *ifname,
+ const unsigned char *vmuuid,
+ const unsigned char *mac)
+{
+ return virNWFilterGetLeases(leases, nLeases, vars, ifname, vmuuid, mac);
+}
static virNWFilterDriver nwfilterDriver = {
.name = "nwfilter",
@@ -490,6 +499,7 @@ static virStateDriver stateDriver = {
static virDomainConfNWFilterDriver domainNWFilterDriver = {
.instantiateFilter = nwfilterInstantiateFilter,
.teardownFilter = nwfilterTeardownFilter,
+ .getLeases = nwfilterGetLeases,
};
Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_ipaddrmap.h
+++ libvirt-acl/src/conf/nwfilter_ipaddrmap.h
@@ -26,6 +26,9 @@
#ifndef __VIR_NWFILTER_IPADDRMAP_H
# define __VIR_NWFILTER_IPADDRMAP_H
+# include "buf.h"
+# include "viriplease.h"
+
int virNWFilterIPAddrMapInit(void);
void virNWFilterIPAddrMapShutdown(void);
@@ -33,5 +36,7 @@ int virNWFilterIPAddrMapAddIPAddr(const
int virNWFilterIPAddrMapDelIPAddr(const char *ifname,
const char *ipaddr);
virNWFilterVarValuePtr virNWFilterIPAddrMapGetIPAddr(const char *ifname);
+int virNWFilterIPAddrMapGetIPLeases(const char *ifname,
+ virIPLeasePtr *leases, size_t *nLeases);
#endif /* __VIR_NWFILTER_IPADDRMAP_H */
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
@@ -771,6 +771,15 @@ virNWFilterLearnIPAddress(virNWFilterTec
}
#endif /* HAVE_LIBPCAP */
+/*
+ * Get the detected IP addresses along with their absolute lease timeout
+ */
+int
+virNWFilterLearnGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const char *ifname)
+{
+ return virNWFilterIPAddrMapGetIPLeases(ifname, leases, nLeases);
+}
/**
* virNWFilterLearnInit
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.h
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
@@ -71,5 +71,7 @@ void virNWFilterUnlockIface(const char *
int virNWFilterLearnInit(void);
void virNWFilterLearnShutdown(void);
void virNWFilterLearnThreadsTerminate(bool allowNewThreads);
+int virNWFilterLearnGetLeases(virIPLeasePtr *leases, size_t *nLeases,
+ const char *ifname);
#endif /* __NWFILTER_LEARNIPADDR_H */
Index: libvirt-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/docs/formatnwfilter.html.in
@@ -446,6 +446,22 @@
</interface>
</pre>
+ <p>
+ Once an IP address has been detected, the domain's interface XML
+ will display the detected IP address and its lease expiration time
+ in seconds. Note that the <code>IP_LEASE</code> variable is read-only
+ and cannot be set by the user.
+ </p>
+<pre>
+ <interface type='bridge'>
+ <source bridge='virbr0'/>
+ <filterref filter='clean-traffic'>
+ <parameter name='CTRL_IP_LEARNING' value='dhcp'/>
+ <parameter name='IP_LEASE' value='192.168.122.100,200'/>
+ </filterref>
+ </interface>
+</pre>
+
<h3><a name="nwfelemsReservedVars">Reserved Variables</a></h3>
<p>
The following table lists reserved variables in use by libvirt.
@@ -481,6 +497,17 @@
<td> CTRL_IP_LEARNING </td>
<td> The choice of the IP address detection mode </td>
</tr>
+ <tr>
+ <td> IP_LEASE (<span class="since">Since 0.9.13</span>)</td>
+ <td> Read-only variable displaying the detected IP lease in the
+ format IP address,lease expiration time in seconds </td>
+ </tr>
+ <tr>
+ <td> IPV6_LEASE </td>
+ <td> Not currently implemented:
+ Read-only variable displaying the detected IPV6 lease in the
+ format IPV6 address,lease expiration time in seconds </td>
+ </tr>
</table>
<h2><a name="nwfelems">Element and attribute overview</a></h2>
Index: libvirt-acl/src/util/viriplease.h
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/viriplease.h
@@ -0,0 +1,18 @@
+#ifndef __VIR_IPLEASE_H__
+# define __VIR_IPLEASE_H__
+
+# include <time.h>
+
+# include "virsocketaddr.h"
+
+typedef struct _virIPLease virIPLease;
+typedef virIPLease *virIPLeasePtr;
+
+struct _virIPLease {
+ virSocketAddr addr;
+ time_t timeout;
+};
+
+#define VIR_IPLEASE_TIMEOUT_NONE (-1)
+
+#endif /* __VIR_IP_LEASE_H__ */
Index: libvirt-acl/src/conf/nwfilter_ipaddrmap.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_ipaddrmap.c
+++ libvirt-acl/src/conf/nwfilter_ipaddrmap.c
@@ -28,6 +28,7 @@
#include "virterror_internal.h"
#include "datatypes.h"
+#include "memory.h"
#include "nwfilter_params.h"
#include "nwfilter_ipaddrmap.h"
@@ -142,6 +143,56 @@ virNWFilterIPAddrMapGetIPAddr(const char
return res;
}
+/*
+ * Get the IP addresses associated with the interface as an array
+ * of virIPLease. Since we don't know about lease timeouts here, we
+ * set the lease timeout to VIR_IPLEASE_TIMEOUT_NONE.
+ */
+int
+virNWFilterIPAddrMapGetIPLeases(const char *ifname,
+ virIPLeasePtr *leases, size_t *nLeases)
+{
+ int ret = 0;
+ virNWFilterVarValuePtr val;
+ virIPLeasePtr myleases = NULL;
+
+ *leases = NULL;
+
+ virMutexLock(&ipAddressMapLock);
+
+ val = virHashLookup(ipAddressMap->hashTable, ifname);
+
+ if (val) {
+ size_t card = virNWFilterVarValueGetCardinality(val);
+ unsigned int i;
+
+ if (VIR_ALLOC_N(myleases, card) < 0) {
+ virReportOOMError();
+ ret = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < card; i++) {
+ const char *value = virNWFilterVarValueGetNthValue(val, i);
+
+ if (virSocketAddrParse(&myleases[i].addr, value, AF_UNSPEC) < 0) {
+ VIR_FREE(myleases);
+ ret = -1;
+ goto cleanup;
+ }
+ myleases[i].timeout = VIR_IPLEASE_TIMEOUT_NONE;
+ }
+
+ *leases = myleases;
+ *nLeases = card;
+ }
+
+cleanup:
+ virMutexUnlock(&ipAddressMapLock);
+
+ return ret;
+}
+
int
virNWFilterIPAddrMapInit(void)
{
12 years, 5 months
[libvirt] [PATCH] rpc: Fix memleak in virNetMessageEncodeHeader
by Michal Privoznik
My latest patch for RPC rework (a2c304f6872) introduced a memory leak.
virNetMessageEncodeHeader() is calling VIR_ALLOC_N(msg->buffer, ...)
despite fact, that msg->buffer isn't VIR_FREE()'d on all paths calling
the function. Therefore, rather than injecting free statement switch to
VIR_REALLOC_N().
---
src/rpc/virnetmessage.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c
index dc4c212..82d5f8d 100644
--- a/src/rpc/virnetmessage.c
+++ b/src/rpc/virnetmessage.c
@@ -219,7 +219,7 @@ int virNetMessageEncodeHeader(virNetMessagePtr msg)
unsigned int len = 0;
msg->bufferLength = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX;
- if (VIR_ALLOC_N(msg->buffer, msg->bufferLength) < 0) {
+ if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) {
virReportOOMError();
goto cleanup;
}
--
1.7.8.5
12 years, 5 months