[libvirt] [libvirt-glib PATCHv2 1/5] Add objects for dealing with <console> devices
by Christophe Fergeau
Add an abstract GVirConfigDomainChardev object for <console>,
<serial>, ... devices and a GVirConfigDomainConsole implementation.
This needs to be completed with a separate GVirConfigDomainChardevSource
inheritance tree which will be specialized to
GVirConfigDomainChardevSourcePty, ... and GVirConfigDomainChardev will
offer a helper function to attach a GVirConfigDomainChardevSource to
a GVirConfigDomainChardev
---
libvirt-gconfig/Makefile.am | 4 +
libvirt-gconfig/libvirt-gconfig-domain-chardev.c | 48 +++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain-chardev.h | 64 ++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain-console.c | 70 ++++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain-console.h | 67 +++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig.h | 2 +
libvirt-gconfig/libvirt-gconfig.sym | 6 ++
7 files changed, 261 insertions(+), 0 deletions(-)
create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-chardev.c
create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-chardev.h
create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-console.c
create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-console.h
diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 575715e..88fb556 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -13,7 +13,9 @@ GCONFIG_HEADER_FILES = \
libvirt-gconfig-object.h \
libvirt-gconfig-capabilities.h \
libvirt-gconfig-domain.h \
+ libvirt-gconfig-domain-chardev.h \
libvirt-gconfig-domain-clock.h \
+ libvirt-gconfig-domain-console.h \
libvirt-gconfig-domain-device.h \
libvirt-gconfig-domain-disk.h \
libvirt-gconfig-domain-filesys.h \
@@ -47,7 +49,9 @@ GCONFIG_SOURCE_FILES = \
libvirt-gconfig-main.c \
libvirt-gconfig-capabilities.c \
libvirt-gconfig-domain.c \
+ libvirt-gconfig-domain-chardev.c \
libvirt-gconfig-domain-clock.c \
+ libvirt-gconfig-domain-console.c \
libvirt-gconfig-domain-device.c \
libvirt-gconfig-domain-disk.c \
libvirt-gconfig-domain-filesys.c \
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-chardev.c b/libvirt-gconfig/libvirt-gconfig-domain-chardev.c
new file mode 100644
index 0000000..525fc2b
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-chardev.c
@@ -0,0 +1,48 @@
+/*
+ * libvirt-gconfig-domain-chardev.c: libvirt domain chardev configuration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Christophe Fergeau <cfergeau(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "libvirt-gconfig/libvirt-gconfig.h"
+
+#define GVIR_CONFIG_DOMAIN_CHARDEV_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV, GVirConfigDomainChardevPrivate))
+
+struct _GVirConfigDomainChardevPrivate
+{
+ gboolean unused;
+};
+
+G_DEFINE_ABSTRACT_TYPE(GVirConfigDomainChardev, gvir_config_domain_chardev, GVIR_TYPE_CONFIG_DOMAIN_DEVICE)
+
+static void gvir_config_domain_chardev_class_init(GVirConfigDomainChardevClass *klass)
+{
+ g_type_class_add_private(klass, sizeof(GVirConfigDomainChardevPrivate));
+}
+
+
+static void gvir_config_domain_chardev_init(GVirConfigDomainChardev *chardev)
+{
+ g_debug("Init GVirConfigDomainChardev=%p", chardev);
+
+ chardev->priv = GVIR_CONFIG_DOMAIN_CHARDEV_GET_PRIVATE(chardev);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-chardev.h b/libvirt-gconfig/libvirt-gconfig-domain-chardev.h
new file mode 100644
index 0000000..91b7f4e
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-chardev.h
@@ -0,0 +1,64 @@
+/*
+ * libvirt-gconfig-domain-chardev.h: libvirt domain chardev configuration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#if !defined(__LIBVIRT_GCONFIG_H__) && !defined(LIBVIRT_GCONFIG_BUILD)
+#error "Only <libvirt-gconfig/libvirt-gconfig.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_GCONFIG_DOMAIN_CHARDEV_H__
+#define __LIBVIRT_GCONFIG_DOMAIN_CHARDEV_H__
+
+G_BEGIN_DECLS
+
+#define GVIR_TYPE_CONFIG_DOMAIN_CHARDEV (gvir_config_domain_chardev_get_type ())
+#define GVIR_CONFIG_DOMAIN_CHARDEV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV, GVirConfigDomainChardev))
+#define GVIR_CONFIG_DOMAIN_CHARDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV, GVirConfigDomainChardevClass))
+#define GVIR_IS_CONFIG_DOMAIN_CHARDEV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV))
+#define GVIR_IS_CONFIG_DOMAIN_CHARDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV))
+#define GVIR_CONFIG_DOMAIN_CHARDEV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_CONFIG_DOMAIN_CHARDEV, GVirConfigDomainChardevClass))
+
+typedef struct _GVirConfigDomainChardev GVirConfigDomainChardev;
+typedef struct _GVirConfigDomainChardevPrivate GVirConfigDomainChardevPrivate;
+typedef struct _GVirConfigDomainChardevClass GVirConfigDomainChardevClass;
+
+struct _GVirConfigDomainChardev
+{
+ GVirConfigDomainDevice parent;
+
+ GVirConfigDomainChardevPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _GVirConfigDomainChardevClass
+{
+ GVirConfigDomainDeviceClass parent_class;
+
+ gpointer padding[20];
+};
+
+
+GType gvir_config_domain_chardev_get_type(void);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_GCONFIG_DOMAIN_CHARDEV_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-console.c b/libvirt-gconfig/libvirt-gconfig-domain-console.c
new file mode 100644
index 0000000..d85cc3e
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-console.c
@@ -0,0 +1,70 @@
+/*
+ * libvirt-gconfig-domain-console.c: libvirt domain console configuration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "libvirt-gconfig/libvirt-gconfig.h"
+
+#define GVIR_CONFIG_DOMAIN_CONSOLE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE, GVirConfigDomainConsolePrivate))
+
+struct _GVirConfigDomainConsolePrivate
+{
+ gboolean unused;
+};
+
+G_DEFINE_TYPE(GVirConfigDomainConsole, gvir_config_domain_console, GVIR_TYPE_CONFIG_DOMAIN_CHARDEV);
+
+
+static void gvir_config_domain_console_class_init(GVirConfigDomainConsoleClass *klass)
+{
+ g_type_class_add_private(klass, sizeof(GVirConfigDomainConsolePrivate));
+}
+
+
+static void gvir_config_domain_console_init(GVirConfigDomainConsole *console)
+{
+ g_debug("Init GVirConfigDomainConsole=%p", console);
+
+ console->priv = GVIR_CONFIG_DOMAIN_CONSOLE_GET_PRIVATE(console);
+}
+
+GVirConfigDomainConsole *gvir_config_domain_console_new(void)
+{
+ GVirConfigObject *object;
+
+ object = gvir_config_object_new(GVIR_TYPE_CONFIG_DOMAIN_CONSOLE,
+ "console", NULL);
+ return GVIR_CONFIG_DOMAIN_CONSOLE(object);
+}
+
+GVirConfigDomainConsole *gvir_config_domain_console_new_from_xml(const gchar *xml,
+ GError **error)
+{
+ GVirConfigObject *object;
+
+ object = gvir_config_object_new_from_xml(GVIR_TYPE_CONFIG_DOMAIN_CONSOLE,
+ "console", NULL, xml, error);
+ if (object == NULL)
+ return NULL;
+ return GVIR_CONFIG_DOMAIN_CONSOLE(object);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-console.h b/libvirt-gconfig/libvirt-gconfig-domain-console.h
new file mode 100644
index 0000000..6243ecf
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-console.h
@@ -0,0 +1,67 @@
+/*
+ * libvirt-gconfig-domain-console.h: libvirt domain console configuration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#if !defined(__LIBVIRT_GCONFIG_H__) && !defined(LIBVIRT_GCONFIG_BUILD)
+#error "Only <libvirt-gconfig/libvirt-gconfig.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_GCONFIG_DOMAIN_CONSOLE_H__
+#define __LIBVIRT_GCONFIG_DOMAIN_CONSOLE_H__
+
+G_BEGIN_DECLS
+
+#define GVIR_TYPE_CONFIG_DOMAIN_CONSOLE (gvir_config_domain_console_get_type ())
+#define GVIR_CONFIG_DOMAIN_CONSOLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE, GVirConfigDomainConsole))
+#define GVIR_CONFIG_DOMAIN_CONSOLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE, GVirConfigDomainConsoleClass))
+#define GVIR_IS_CONFIG_DOMAIN_CONSOLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE))
+#define GVIR_IS_CONFIG_DOMAIN_CONSOLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE))
+#define GVIR_CONFIG_DOMAIN_CONSOLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_TYPE_CONFIG_DOMAIN_CONSOLE, GVirConfigDomainConsoleClass))
+
+typedef struct _GVirConfigDomainConsole GVirConfigDomainConsole;
+typedef struct _GVirConfigDomainConsolePrivate GVirConfigDomainConsolePrivate;
+typedef struct _GVirConfigDomainConsoleClass GVirConfigDomainConsoleClass;
+
+struct _GVirConfigDomainConsole
+{
+ GVirConfigDomainChardev parent;
+
+ GVirConfigDomainConsolePrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _GVirConfigDomainConsoleClass
+{
+ GVirConfigDomainChardevClass parent_class;
+
+ gpointer padding[20];
+};
+
+
+GType gvir_config_domain_console_get_type(void);
+GVirConfigDomainConsole *gvir_config_domain_console_new(void);
+GVirConfigDomainConsole *gvir_config_domain_console_new_from_xml(const gchar *xml,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_GCONFIG_DOMAIN_CONSOLE_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig.h b/libvirt-gconfig/libvirt-gconfig.h
index c8df278..ca7d2dc 100644
--- a/libvirt-gconfig/libvirt-gconfig.h
+++ b/libvirt-gconfig/libvirt-gconfig.h
@@ -30,7 +30,9 @@
#include <libvirt-gconfig/libvirt-gconfig-object.h>
#include <libvirt-gconfig/libvirt-gconfig-capabilities.h>
#include <libvirt-gconfig/libvirt-gconfig-domain.h>
+#include <libvirt-gconfig/libvirt-gconfig-domain-chardev.h>
#include <libvirt-gconfig/libvirt-gconfig-domain-clock.h>
+#include <libvirt-gconfig/libvirt-gconfig-domain-console.h>
#include <libvirt-gconfig/libvirt-gconfig-domain-device.h>
#include <libvirt-gconfig/libvirt-gconfig-domain-disk.h>
#include <libvirt-gconfig/libvirt-gconfig-domain-filesys.h>
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 9547db1..345dd42 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -29,6 +29,8 @@ LIBVIRT_GCONFIG_0.0.1 {
gvir_config_domain_set_virt_type;
gvir_config_domain_virt_type_get_type;
+ gvir_config_domain_chardev_get_type;
+
gvir_config_domain_clock_get_type;
gvir_config_domain_clock_offset_get_type;
gvir_config_domain_clock_new;
@@ -37,6 +39,10 @@ LIBVIRT_GCONFIG_0.0.1 {
gvir_config_domain_clock_set_timezone;
gvir_config_domain_clock_set_variable_offset;
+ gvir_config_domain_console_get_type;
+ gvir_config_domain_console_new;
+ gvir_config_domain_console_new_from_xml;
+
gvir_config_domain_device_get_type;
gvir_config_domain_disk_get_type;
--
1.7.7.3
12 years, 11 months
[libvirt] Group for accessing one/all VM graphics and not virsh
by Reeted
Hello libvirt people,
is there a (preferably simple) way in Linux to allow a certain set of
users to be able to do:
virt-viewer --connect qemu+ssh://username@virthost/system vmname
for connecting to virt-viewer BUT without letting them do all the other
things that can be done with virsh?
I know that if I add them to the libvirtd and kvm groups, they will be
able to connect with virt-viewer to any virtual machine AND ALSO do any
virsh command on any virtual machine. This is too much permission.
I can accept the first part (a way to allow a group of user to connect
with virt-viewer to all the virtual machines of the host) since more
restriction can be enforced by using VNC passwords... But if they are
also able to do anything in virsh that's too much.
I am using only qemu and kvm in libvirt.
Thank you
R.
12 years, 11 months
[libvirt] Coverity automatic detection
by Alex Jia
This email is automatically generated.
The test result is based on the following git commit:
d336dbd spec: fix sanlock dependency
Analysis summary report:
------------------------
Files analyzed : 241
Total LoC input to cov-analyze : 328912
Functions analyzed : 7999
Paths analyzed : 923483
Defect occurrences found : 71 Total
7 ATOMICITY
3 CHECKED_RETURN
14 DEADCODE
7 FORWARD_NULL
13 LOCK
2 NEGATIVE_RETURNS
1 NULL_RETURNS
6 RESOURCE_LEAK
1 RETURN_LOCAL
12 REVERSE_INULL
3 UNINIT
2 UNUSED_VALUE
Exceeded path limit of 5000 paths in 0.49% of functions (normally up to 5% of functions encounter this limitation)
For details, please see attachment.
Regards,
Alex
12 years, 11 months
[libvirt] [PATCH v4] Implement DNS SRV record into the bridge driver
by Michal Novotny
Hi,
this is the fourth version of my SRV record for DNSMasq patch rebased
for the current codebase to the bridge driver and libvirt XML file to
include support for the SRV records in the DNS. The syntax is based on
DNSMasq man page and tests for both xml2xml and xml2argv were added as
well. This is basically un-reviewed version 3 of this patch rebased to
the current codebase with changed version information to 0.9.9 as it's
supposed to go in 0.9.9 or later because of current 0.9.8 features
freeze.
Also, the second part of this patch is fixing the networkxml2argv test
to pass both checks, i.e. both unit tests and also syntax check.
Please review,
Michal
Signed-off-by: Michal Novotny <minovotn(a)redhat.com>
---
docs/formatnetwork.html.in | 12 ++
docs/schemas/network.rng | 26 ++++
src/conf/network_conf.c | 130 +++++++++++++++++++-
src/conf/network_conf.h | 16 +++
src/network/bridge_driver.c | 43 +++++++
tests/networkxml2argvdata/isolated-network.argv | 14 ++-
.../networkxml2argvdata/nat-network-dns-hosts.argv | 12 ++-
.../nat-network-dns-srv-record-minimal.argv | 16 +++
.../nat-network-dns-srv-record-minimal.xml | 26 ++++
.../nat-network-dns-srv-record.argv | 16 +++
.../nat-network-dns-srv-record.xml | 26 ++++
.../nat-network-dns-txt-record.argv | 19 ++-
tests/networkxml2argvdata/nat-network.argv | 19 ++-
tests/networkxml2argvdata/netboot-network.argv | 17 ++-
.../networkxml2argvdata/netboot-proxy-network.argv | 15 ++-
tests/networkxml2argvdata/routed-network.argv | 8 +-
tests/networkxml2argvtest.c | 14 ++-
.../nat-network-dns-srv-record-minimal.xml | 26 ++++
.../nat-network-dns-srv-record.xml | 26 ++++
.../nat-network-dns-srv-record-minimal.xml | 26 ++++
.../nat-network-dns-srv-record.xml | 26 ++++
21 files changed, 501 insertions(+), 32 deletions(-)
create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record.argv
create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record.xml
create mode 100644 tests/networkxml2xmlin/nat-network-dns-srv-record-minimal.xml
create mode 100644 tests/networkxml2xmlin/nat-network-dns-srv-record.xml
create mode 100644 tests/networkxml2xmlout/nat-network-dns-srv-record-minimal.xml
create mode 100644 tests/networkxml2xmlout/nat-network-dns-srv-record.xml
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 02302fa..79cb4ce 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -345,6 +345,7 @@
<domain name="example.com"/>
<dns>
<txt name="example" value="example value" />
+ <srv service="name" protocol="tcp" domain="test-domain-name" target="." port="1024" priority="10" weight="10"/>
<host ip='192.168.122.2'>
<hostname>myhost</hostname>
<hostname>myhostalias</hostname>
@@ -396,6 +397,17 @@
<span class="since">Since 0.9.3</span>
</dd>
</dl>
+ <dl>
+ <dt><code>srv</code></dt>
+ <dd>The <code>dns</code> element can have also 0 or more <code>srv</code>
+ record elements. Each <code>srv</code> record element defines a DNS SRV record
+ and has 2 mandatory and 5 optional attributes. The mandatory attributes
+ are service name and protocol (tcp, udp) and the optional attributes are
+ target, port, priority, weight and domain as defined in DNS server SRV
+ RFC (RFC 2782).
+ <span class="since">Since 0.9.9</span>
+ </dd>
+ </dl>
</dd>
<dt><code>ip</code></dt>
<dd>The <code>address</code> attribute defines an IPv4 address in
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 937e180..fac0eda 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -138,6 +138,19 @@
</element>
</zeroOrMore>
<zeroOrMore>
+ <element name="srv">
+ <attribute name="service"><text/></attribute>
+ <attribute name="protocol"><ref name="protocol"/></attribute>
+ <optional>
+ <attribute name="domain"><ref name="dnsName"/></attribute>
+ <attribute name="target"><text/></attribute>
+ <attribute name="port"><ref name="unsignedShort"/></attribute>
+ <attribute name="priority"><ref name="unsignedShort"/></attribute>
+ <attribute name="weight"><ref name="unsignedShort"/></attribute>
+ </optional>
+ </element>
+ </zeroOrMore>
+ <zeroOrMore>
<element name="host">
<attribute name="ip"><ref name="ipv4Addr"/></attribute>
<oneOrMore>
@@ -217,6 +230,19 @@
</element>
</define>
+ <define name='unsignedShort'>
+ <data type='integer'>
+ <param name="minInclusive">0</param>
+ <param name="maxInclusive">65535</param>
+ </data>
+ </define>
+
+ <define name='protocol'>
+ <data type='string'>
+ <param name='pattern'>(tcp)|(udp)</param>
+ </data>
+ </define>
+
<define name='addr-family'>
<data type='string'>
<param name="pattern">(ipv4)|(ipv6)</param>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 1058b07..5b293f9 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -138,6 +138,15 @@ static void virNetworkDNSDefFree(virNetworkDNSDefPtr def)
}
}
VIR_FREE(def->hosts);
+ if (def->nsrvrecords) {
+ while (def->nsrvrecords--) {
+ VIR_FREE(def->srvrecords[def->nsrvrecords].domain);
+ VIR_FREE(def->srvrecords[def->nsrvrecords].service);
+ VIR_FREE(def->srvrecords[def->nsrvrecords].protocol);
+ VIR_FREE(def->srvrecords[def->nsrvrecords].target);
+ }
+ }
+ VIR_FREE(def->srvrecords);
VIR_FREE(def);
}
}
@@ -553,8 +562,99 @@ error:
}
static int
+virNetworkDNSSrvDefParseXML(virNetworkDNSDefPtr def,
+ xmlNodePtr cur,
+ xmlXPathContextPtr ctxt)
+{
+ char *domain;
+ char *service;
+ char *protocol;
+ char *target;
+ int port;
+ int priority;
+ int weight;
+ int ret = 0;
+ char xpath[1024] = { 0 };
+
+ if (!(service = virXMLPropString(cur, "service"))) {
+ virNetworkReportError(VIR_ERR_XML_DETAIL,
+ "%s", _("Missing required service attribute in dns srv record"));
+ goto error;
+ }
+
+ if (strlen(service) > DNS_RECORD_LENGTH_SRV) {
+ virNetworkReportError(VIR_ERR_XML_DETAIL,
+ "%s", _("Service name is too long, limit is %d bytes"), DNS_RECORD_LENGTH_SRV);
+ goto error;
+ }
+
+ if (!(protocol = virXMLPropString(cur, "protocol"))) {
+ virNetworkReportError(VIR_ERR_XML_DETAIL,
+ _("Missing required protocol attribute in dns srv record '%s'"), service);
+ goto error;
+ }
+
+ /* Check whether protocol value is the supported one */
+ if (STRNEQ(protocol, "tcp") && (STRNEQ(protocol, "udp"))) {
+ virNetworkReportError(VIR_ERR_XML_DETAIL,
+ _("Invalid protocol attribute value '%s'"), protocol);
+ goto error;
+ }
+
+ if (VIR_REALLOC_N(def->srvrecords, def->nsrvrecords + 1) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ def->srvrecords[def->nsrvrecords].service = service;
+ def->srvrecords[def->nsrvrecords].protocol = protocol;
+ def->srvrecords[def->nsrvrecords].domain = NULL;
+ def->srvrecords[def->nsrvrecords].target = NULL;
+ def->srvrecords[def->nsrvrecords].port = 0;
+ def->srvrecords[def->nsrvrecords].priority = 0;
+ def->srvrecords[def->nsrvrecords].weight = 0;
+
+ /* Following attributes are optional but we had to make sure their NULL above */
+ if ((target = virXMLPropString(cur, "target")) && (domain = virXMLPropString(cur, "domain"))) {
+ snprintf(xpath, sizeof(xpath), "string(//network/dns/srv[@service='%s']/@port)", service);
+ if (virXPathInt(xpath, ctxt, &port))
+ def->srvrecords[def->nsrvrecords].port = port;
+
+ snprintf(xpath, sizeof(xpath), "string(//network/dns/srv[@service='%s']/@priority)", service);
+ if (virXPathInt(xpath, ctxt, &priority))
+ def->srvrecords[def->nsrvrecords].priority = priority;
+
+ snprintf(xpath, sizeof(xpath), "string(//network/dns/srv[@service='%s']/@weight)", service);
+ if (virXPathInt(xpath, ctxt, &weight))
+ def->srvrecords[def->nsrvrecords].weight = weight;
+
+ def->srvrecords[def->nsrvrecords].domain = domain;
+ def->srvrecords[def->nsrvrecords].target = target;
+ def->srvrecords[def->nsrvrecords].port = port;
+ def->srvrecords[def->nsrvrecords].priority = priority;
+ def->srvrecords[def->nsrvrecords].weight = weight;
+ }
+
+ def->nsrvrecords++;
+
+ goto cleanup;
+
+error:
+ VIR_FREE(domain);
+ VIR_FREE(service);
+ VIR_FREE(protocol);
+ VIR_FREE(target);
+
+ ret = 1;
+
+cleanup:
+ return ret;
+}
+
+static int
virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
- xmlNodePtr node)
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt)
{
xmlNodePtr cur;
int ret = -1;
@@ -599,6 +699,11 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
name = NULL;
value = NULL;
} else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "srv")) {
+ ret = virNetworkDNSSrvDefParseXML(def, cur, ctxt);
+ if (ret < 0)
+ goto error;
+ } else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "host")) {
ret = virNetworkDNSHostsDefParseXML(def, cur);
if (ret < 0)
@@ -887,7 +992,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
dnsNode = virXPathNode("./dns", ctxt);
if (dnsNode != NULL) {
- if (virNetworkDNSDefParseXML(&def->dns, dnsNode) < 0)
+ if (virNetworkDNSDefParseXML(&def->dns, dnsNode, ctxt) < 0)
goto error;
}
@@ -1146,6 +1251,27 @@ virNetworkDNSDefFormat(virBufferPtr buf,
def->txtrecords[i].value);
}
+ for (i = 0 ; i < def->nsrvrecords ; i++) {
+ if (def->srvrecords[i].service && def->srvrecords[i].protocol) {
+ virBufferAsprintf(buf, " <srv service='%s' protocol='%s' ",
+ def->srvrecords[i].service,
+ def->srvrecords[i].protocol);
+
+ if (def->srvrecords[i].domain)
+ virBufferAsprintf(buf, "domain='%s' ", def->srvrecords[i].domain);
+ if (def->srvrecords[i].target)
+ virBufferAsprintf(buf, "target='%s' ", def->srvrecords[i].target);
+ if (def->srvrecords[i].port)
+ virBufferAsprintf(buf, "port='%d' ", def->srvrecords[i].port);
+ if (def->srvrecords[i].priority)
+ virBufferAsprintf(buf, "priority='%d' ", def->srvrecords[i].priority);
+ if (def->srvrecords[i].weight)
+ virBufferAsprintf(buf, "weight='%d' ", def->srvrecords[i].weight);
+
+ virBufferAsprintf(buf, "/>\n");
+ }
+ }
+
if (def->nhosts) {
int ii, j;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 1be20f8..5ef4878 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -24,6 +24,8 @@
#ifndef __NETWORK_CONF_H__
# define __NETWORK_CONF_H__
+#define DNS_RECORD_LENGTH_SRV (512 - 30) /* Limit minus overhead as mentioned in RFC-2782 */
+
# include <libxml/parser.h>
# include <libxml/tree.h>
# include <libxml/xpath.h>
@@ -69,6 +71,18 @@ struct _virNetworkDNSTxtRecordsDef {
char *value;
};
+typedef struct _virNetworkDNSSrvRecordsDef virNetworkDNSSrvRecordsDef;
+typedef virNetworkDNSSrvRecordsDef *virNetworkDNSSrvRecordsDefPtr;
+struct _virNetworkDNSSrvRecordsDef {
+ char *domain;
+ char *service;
+ char *protocol;
+ char *target;
+ int port;
+ int priority;
+ int weight;
+};
+
struct _virNetworkDNSHostsDef {
virSocketAddr ip;
int nnames;
@@ -82,6 +96,8 @@ struct _virNetworkDNSDef {
virNetworkDNSTxtRecordsDefPtr txtrecords;
unsigned int nhosts;
virNetworkDNSHostsDefPtr hosts;
+ unsigned int nsrvrecords;
+ virNetworkDNSSrvRecordsDefPtr srvrecords;
};
typedef struct _virNetworkDNSDef *virNetworkDNSDefPtr;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 63338a2..0c0e7a7 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -527,6 +527,49 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
virCommandAddArgPair(cmd, "--txt-record", record);
VIR_FREE(record);
}
+
+ for (i = 0; i < dns->nsrvrecords; i++) {
+ char *record = NULL;
+ char *recordPort = NULL;
+ char *recordPriority = NULL;
+ char *recordWeight = NULL;
+
+ if (dns->srvrecords[i].service && dns->srvrecords[i].protocol) {
+ if (dns->srvrecords[i].port) {
+ if (virAsprintf(&recordPort, "%d", dns->srvrecords[i].port) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ if (dns->srvrecords[i].priority) {
+ if (virAsprintf(&recordPriority, "%d", dns->srvrecords[i].priority) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ if (dns->srvrecords[i].weight) {
+ if (virAsprintf(&recordWeight, "%d", dns->srvrecords[i].weight) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ if (virAsprintf(&record, "%s.%s.%s,%s,%s,%s,%s",
+ dns->srvrecords[i].service,
+ dns->srvrecords[i].protocol,
+ dns->srvrecords[i].domain ? dns->srvrecords[i].domain : "",
+ dns->srvrecords[i].target ? dns->srvrecords[i].target : "",
+ recordPort ? recordPort : "",
+ recordPriority ? recordPriority : "",
+ recordWeight ? recordWeight : "") < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ virCommandAddArgPair(cmd, "--srv-host", record);
+ VIR_FREE(record);
+ }
+ }
}
/*
diff --git a/tests/networkxml2argvdata/isolated-network.argv b/tests/networkxml2argvdata/isolated-network.argv
index 7ea2e94..4936d1b 100644
--- a/tests/networkxml2argvdata/isolated-network.argv
+++ b/tests/networkxml2argvdata/isolated-network.argv
@@ -1,6 +1,12 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \
---except-interface lo --dhcp-option=3 --no-resolv \
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--dhcp-option=3 \
+--no-resolv \
--listen-address 192.168.152.1 \
--dhcp-range 192.168.152.2,192.168.152.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases --dhcp-lease-max=253 \
---dhcp-no-override\
+--dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases \
+--dhcp-lease-max=253 \
+--dhcp-no-override
diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
index 2158df8..bdf8376 100644
--- a/tests/networkxml2argvdata/nat-network-dns-hosts.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
@@ -1,3 +1,9 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --domain example.com \
---conf-file= --except-interface lo --listen-address 192.168.122.1 \
---expand-hosts --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--domain example.com \
+--conf-file= \
+--except-interface lo \
+--listen-address 192.168.122.1 \
+--expand-hosts \
+--addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
new file mode 100644
index 0000000..7005078
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
@@ -0,0 +1,16 @@
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--srv-host=name.tcp.,,,, \
+--listen-address 192.168.122.1 \
+--listen-address 192.168.123.1 \
+--listen-address 2001:db8:ac10:fe01::1 \
+--listen-address 2001:db8:ac10:fd01::1 \
+--listen-address 10.24.10.1 \
+--dhcp-range 192.168.122.2,192.168.122.254 \
+--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
new file mode 100644
index 0000000..e9b7680
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
new file mode 100644
index 0000000..ebb3942
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
@@ -0,0 +1,16 @@
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--srv-host=name.tcp.test-domain-name,.,1024,10,10 \
+--listen-address 192.168.122.1 \
+--listen-address 192.168.123.1 \
+--listen-address 2001:db8:ac10:fe01::1 \
+--listen-address 2001:db8:ac10:fd01::1 \
+--listen-address 10.24.10.1 \
+--dhcp-range 192.168.122.2,192.168.122.254 \
+--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.xml b/tests/networkxml2argvdata/nat-network-dns-srv-record.xml
new file mode 100644
index 0000000..4be85b5
--- /dev/null
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
index be6ba4b..5c35aae 100644
--- a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
@@ -1,9 +1,16 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \
---except-interface lo --txt-record=example,example value \
---listen-address 192.168.122.1 --listen-address 192.168.123.1 \
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--txt-record=example,example value \
+--listen-address 192.168.122.1 \
+--listen-address 192.168.123.1 \
--listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
+--listen-address 2001:db8:ac10:fd01::1 \
+--listen-address 10.24.10.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 --dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile\
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
diff --git a/tests/networkxml2argvdata/nat-network.argv b/tests/networkxml2argvdata/nat-network.argv
index d7faee2..e22de4c 100644
--- a/tests/networkxml2argvdata/nat-network.argv
+++ b/tests/networkxml2argvdata/nat-network.argv
@@ -1,8 +1,15 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---listen-address 192.168.123.1 --listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--listen-address 192.168.122.1 \
+--listen-address 192.168.123.1 \
+--listen-address 2001:db8:ac10:fe01::1 \
+--listen-address 2001:db8:ac10:fd01::1 \
+--listen-address 10.24.10.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 --dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile\
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
diff --git a/tests/networkxml2argvdata/netboot-network.argv b/tests/networkxml2argvdata/netboot-network.argv
index 78e873c..bf8ff5e 100644
--- a/tests/networkxml2argvdata/netboot-network.argv
+++ b/tests/networkxml2argvdata/netboot-network.argv
@@ -1,6 +1,15 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --domain example.com \
---conf-file= --except-interface lo --listen-address 192.168.122.1 \
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--domain example.com \
+--conf-file= \
+--except-interface lo \
+--listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
---dhcp-lease-max=253 --dhcp-no-override --expand-hosts --enable-tftp \
---tftp-root /var/lib/tftproot --dhcp-boot pxeboot.img\
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--expand-hosts \
+--enable-tftp \
+--tftp-root /var/lib/tftproot \
+--dhcp-boot pxeboot.img
diff --git a/tests/networkxml2argvdata/netboot-proxy-network.argv b/tests/networkxml2argvdata/netboot-proxy-network.argv
index 5fe1b8e..29935ea 100644
--- a/tests/networkxml2argvdata/netboot-proxy-network.argv
+++ b/tests/networkxml2argvdata/netboot-proxy-network.argv
@@ -1,6 +1,13 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --domain example.com \
---conf-file= --except-interface lo --listen-address 192.168.122.1 \
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--domain example.com \
+--conf-file= \
+--except-interface lo \
+--listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
---dhcp-lease-max=253 --dhcp-no-override --expand-hosts \
---dhcp-boot pxeboot.img,,10.20.30.40\
+--dhcp-lease-max=253 \
+--dhcp-no-override \
+--expand-hosts \
+--dhcp-boot pxeboot.img,,10.20.30.40
diff --git a/tests/networkxml2argvdata/routed-network.argv b/tests/networkxml2argvdata/routed-network.argv
index d059630..79c319b 100644
--- a/tests/networkxml2argvdata/routed-network.argv
+++ b/tests/networkxml2argvdata/routed-network.argv
@@ -1,2 +1,6 @@
-/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= \
---except-interface lo --listen-address 192.168.122.1\
+/usr/sbin/dnsmasq \
+--strict-order \
+--bind-interfaces \
+--conf-file= \
+--except-interface lo \
+--listen-address 192.168.122.1
diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c
index 4a11d6f..4223cb7 100644
--- a/tests/networkxml2argvtest.c
+++ b/tests/networkxml2argvtest.c
@@ -18,6 +18,7 @@
static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
char *inXmlData = NULL;
char *outArgvData = NULL;
+ char *actual_tmp = NULL;
char *actual = NULL;
int ret = -1;
virNetworkDefPtr dev = NULL;
@@ -47,9 +48,17 @@ static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
if (networkBuildDhcpDaemonCommandLine(obj, &cmd, pidfile, dctx) < 0)
goto fail;
- if (!(actual = virCommandToString(cmd)))
+ if (!(actual_tmp = virCommandToString(cmd)))
goto fail;
+ if (VIR_ALLOC_N( actual, (strlen(actual_tmp) + 3) * sizeof(char) ) < 0)
+ goto fail;
+
+ /* A little hack to make it working for both check and syntax-check */
+ memcpy(actual, actual_tmp, strlen(actual_tmp));
+ actual[ strlen(actual_tmp) ] = '\n';
+ actual[ strlen(actual_tmp) + 1 ] = 0;
+
if (STRNEQ(outArgvData, actual)) {
virtTestDifference(stderr, outArgvData, actual);
goto fail;
@@ -61,6 +70,7 @@ static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
free(inXmlData);
free(outArgvData);
free(actual);
+ free(actual_tmp);
VIR_FREE(pidfile);
virCommandFree(cmd);
virNetworkObjFree(obj);
@@ -120,6 +130,8 @@ mymain(void)
DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network");
DO_TEST("nat-network-dns-txt-record");
+ DO_TEST("nat-network-dns-srv-record");
+ DO_TEST("nat-network-dns-srv-record-minimal");
DO_TEST("nat-network-dns-hosts");
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
diff --git a/tests/networkxml2xmlin/nat-network-dns-srv-record-minimal.xml b/tests/networkxml2xmlin/nat-network-dns-srv-record-minimal.xml
new file mode 100644
index 0000000..e9b7680
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-srv-record-minimal.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlin/nat-network-dns-srv-record.xml b/tests/networkxml2xmlin/nat-network-dns-srv-record.xml
new file mode 100644
index 0000000..4be85b5
--- /dev/null
+++ b/tests/networkxml2xmlin/nat-network-dns-srv-record.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-dns-srv-record-minimal.xml b/tests/networkxml2xmlout/nat-network-dns-srv-record-minimal.xml
new file mode 100644
index 0000000..e9b7680
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-srv-record-minimal.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlout/nat-network-dns-srv-record.xml b/tests/networkxml2xmlout/nat-network-dns-srv-record.xml
new file mode 100644
index 0000000..4be85b5
--- /dev/null
+++ b/tests/networkxml2xmlout/nat-network-dns-srv-record.xml
@@ -0,0 +1,26 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254' />
+ <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
+ <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+ </dhcp>
+ </ip>
+ <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ </ip>
+ <ip family='ipv4' address='10.24.10.1'>
+ </ip>
+</network>
--
1.7.7.3
12 years, 11 months
[libvirt] [PATCH 00/14] Add a virtlockd lock manager daemon
by Daniel P. Berrange
The lock manager infrastructure we recently added to QEMU only has
two possible drivers at this time, 'nop' and 'sanlock'. The former
does absolutely nothing, while the latter requires a 3rd party
package installed and is a little heavy on disk I/O and storage
requirements.
This series adds a new daemon 'virtlockd' which is intended to be
enabled by default on all hosts running 'libvirtd'. This daemon
provides a service for disk locking based on the traditional
fcntl() lock primitives. There is a new libvirt manager plugin
which talks to this daemon over RPC. The reason for doing the
locks in a separate process is that we want the locks to remain
active, even if libvirtd crashes, or is restarted. The virtlockd
daemon has this one single job so should be pretty reliable and
selfcontained. This patch series really benefits from the new RPC
APIs, requiring minimal code for the new daemon / client
At this time, virtlockd does not lock the actual disk files, but
instead creates a lockspace & leases under /var/lib/libvirt/lockd.
The lockspace we use for disks is named org.libvirt.lockd.files,
and lease names are based on a SHA256 checksum of the fully
qualified disk name. eg
/var/lib/libvirt/lockd/org.libvirt.lockd.files/adf94fc33a24da1abff7dd7374a9919bb51efee646da8c3ac464c10cd59750bd
These leases are all zero-bytes long and no I/O is ever performed
on them, only fcntl() is used. So there is material overhead.
Whenever creating or deleting leases, we first acquire a lock on
/var/lib/libvirt/lockd/org.libvirt.lockd.files/org.libvirt.lockd.index
A non-root virtlockd will instead use $HOME/.libvirt/lockd
By default we gain protection out of the box against
- Starting two guests on the same host with the same disk image
not marked with <shareable/>
- libvirtd getting confused and forgetting a guest, allowing it
to be started for a 2nd time
If the admin mounts a shared filesytem (eg NFS) on /var/lib/libvirt/lockd
then this protection is extended across all hosts sharing that
mount volume.
As part of this series, I also introduce support for systemd
services for libvirtd and libvir-guests.
12 years, 11 months
[libvirt] [PATCH] examples: Update event tests for shutdown event
by Jiri Denemark
---
examples/domain-events/events-c/event-test.c | 22 ++++++++++++++-----
examples/domain-events/events-python/event-test.py | 6 +++-
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index 648e6ea..f4938c4 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -40,7 +40,7 @@ void usage(const char *pname);
const char *eventToString(int event) {
const char *ret = "";
- switch(event) {
+ switch ((virDomainEventType) event) {
case VIR_DOMAIN_EVENT_DEFINED:
ret ="Defined";
break;
@@ -59,13 +59,16 @@ const char *eventToString(int event) {
case VIR_DOMAIN_EVENT_STOPPED:
ret ="Stopped";
break;
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ ret = "Shutdown";
+ break;
}
return ret;
}
static const char *eventDetailToString(int event, int detail) {
const char *ret = "";
- switch(event) {
+ switch ((virDomainEventType) event) {
case VIR_DOMAIN_EVENT_DEFINED:
if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED)
ret = "Added";
@@ -77,7 +80,7 @@ static const char *eventDetailToString(int event, int detail) {
ret = "Removed";
break;
case VIR_DOMAIN_EVENT_STARTED:
- switch (detail) {
+ switch ((virDomainEventStartedDetailType) detail) {
case VIR_DOMAIN_EVENT_STARTED_BOOTED:
ret = "Booted";
break;
@@ -93,7 +96,7 @@ static const char *eventDetailToString(int event, int detail) {
}
break;
case VIR_DOMAIN_EVENT_SUSPENDED:
- switch (detail) {
+ switch ((virDomainEventSuspendedDetailType) detail) {
case VIR_DOMAIN_EVENT_SUSPENDED_PAUSED:
ret = "Paused";
break;
@@ -115,7 +118,7 @@ static const char *eventDetailToString(int event, int detail) {
}
break;
case VIR_DOMAIN_EVENT_RESUMED:
- switch (detail) {
+ switch ((virDomainEventResumedDetailType) detail) {
case VIR_DOMAIN_EVENT_RESUMED_UNPAUSED:
ret = "Unpaused";
break;
@@ -128,7 +131,7 @@ static const char *eventDetailToString(int event, int detail) {
}
break;
case VIR_DOMAIN_EVENT_STOPPED:
- switch (detail) {
+ switch ((virDomainEventStoppedDetailType) detail) {
case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN:
ret = "Shutdown";
break;
@@ -152,6 +155,13 @@ static const char *eventDetailToString(int event, int detail) {
break;
}
break;
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ switch ((virDomainEventShutdownDetailType) detail) {
+ case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED:
+ ret = "Finished";
+ break;
+ }
+ break;
}
return ret;
}
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 60a9c34..0c75091 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -430,7 +430,8 @@ def eventToString(event):
"Started",
"Suspended",
"Resumed",
- "Stopped" );
+ "Stopped",
+ "Shutdown" );
return eventStrings[event];
def detailToString(event, detail):
@@ -440,7 +441,8 @@ def detailToString(event, detail):
( "Booted", "Migrated", "Restored", "Snapshot" ),
( "Paused", "Migrated", "IOError", "Watchdog" ),
( "Unpaused", "Migrated"),
- ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot")
+ ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
+ ( "Finished" )
)
return eventStrings[event][detail]
--
1.7.8
12 years, 11 months
[libvirt] [libvirt-glib] Use gvir_error_set_literal in more places
by Christophe Fergeau
GVirConnection has some gvir_set_error uses that can be replaced
by gvir_set_error_set_literal. When passing a single string, this is
safer since we are guaranteed that unwanted printf-format sequences
in the string won't cause issues.
---
libvirt-gobject/libvirt-gobject-connection.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index 50cd860..f478948 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -421,9 +421,9 @@ gboolean gvir_connection_open(GVirConnection *conn,
if (!priv->uri) {
char *uri = virConnectGetURI(priv->conn);
if (!uri) {
- gvir_set_error(err, GVIR_CONNECTION_ERROR,
+ gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
0,
- "%s", "Unable to get connection URI");
+ "Unable to get connection URI");
virConnectClose(priv->conn);
priv->conn = NULL;
g_mutex_unlock(priv->lock);
@@ -618,9 +618,9 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
g_mutex_lock(priv->lock);
if (!priv->conn) {
- g_set_error(err, GVIR_CONNECTION_ERROR,
- 0,
- "Connection is not open");
+ g_set_error_literal(err, GVIR_CONNECTION_ERROR,
+ 0,
+ "Connection is not open");
g_mutex_unlock(priv->lock);
goto cleanup;
}
@@ -633,9 +633,9 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
goto cleanup;
if ((nactive = virConnectNumOfDomains(vconn)) < 0) {
- gvir_set_error(err, GVIR_CONNECTION_ERROR,
- 0,
- "Unable to count domains");
+ gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to count domains");
goto cleanup;
}
if (nactive) {
@@ -644,9 +644,9 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
active = g_new(gint, nactive);
if ((nactive = virConnectListDomains(vconn, active, nactive)) < 0) {
- gvir_set_error(err, GVIR_CONNECTION_ERROR,
- 0,
- "Unable to list domains");
+ gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to list domains");
goto cleanup;
}
}
--
1.7.7.3
12 years, 11 months
[libvirt] Add <console> support
by Christophe Fergeau
Hi,
This patch series adds support for setting <console> nodes as has been
discussed in the "[PATCH libvirt-glib 02/15] Add objects for dealing with
<console> devices" thread.
It introduces a GVirConfigDomainChardev which derives from
GVirConfigDomainDevice. The actual classes to create <console>, <serial>,
<parallel> nodes will inherit from this parent class.
Then we have GVirConfigDomainChardevSource which derives from
GVirConfigObject (with a dummy root node name) and from which derives
GVirConfigDomainChardevSourcePty.
A GVirConfigDomainChardevSourcePty is associated to a
GVirConfigDomainConsole object through GVirConfigDomainChardev::add_source.
Maybe it should be ::set_source, I'm unsure... The code from ::add_source
directly messes with the xml nodes so a careful review won't hurt :)
At this point I consider this to be at least 50% RFC so we can still
redesign the whole thing.
Christophe
12 years, 11 months
[libvirt] [PATCH 00/10] Console coruption with two or more clients series
by Peter Krempa
This series fixes anoying console corruption if two clients try to connect
at same time to the console. The current state of this is, that two/more
of libvirt iohelpers are spawned on the same time that compete for data
from the pty. This causes that each of the consoles get scrambled and
unusable.
Patches
fdstream: Emit stream abort callback even if poll() doesnt.
virnetclientstream: Propagate stream error messages to callback
daemon: Subscribe the stream event callback for error events.
add the ability to abort a stream from the daemon side.
fdstream: Add internal function to check if a fdstream is open
This patch adds a helper function that checks internally if a fdstream
is open and working.
virsh: fix console stream error reporting
Add flags for virDomainOpenConsole
virsh: add support for VIR_DOMAIN_CONSOLE_FORCE flag
This patches add instrumentation to virsh that supports the new ability to
abort streams from the daemon side and adapts the console callback to handle
this. These patches also add a new flag set for virDomainOpenConsole API
call that allow users to control the if the existing console connection should
be left in place or killed in favor of the new one
qemu: Add ability to abort existing console while creating new one
lxc: Add ability to abort existing console when creating a new one
uml: Add ability to abort existing console when creating a new one
These patches modify the hypervisor drivers so that they are aware of existing
console connections and refuse to create a new one (or kill the old).
The xen driver also supports console in a similar way like the previously
mentioned drivers, but lacks the means to store a stream reference
permanently. I'll look in if it's possible to modify this driver to support
this new functionality.
For convinience, to review these patches:
git checkout -b console_corruption 33b55fd85ae5435bda53c3cfcbe1385074befd01
git pull git://aeon.pipo.sk/libvirt.git console_corruption
Peter
Peter Krempa (10):
fdstream: Emit stream abort callback even if poll() doesnt.
virnetclientstream: Propagate stream error messages to callback
daemon: Subscribe the stream event callback for error events.
fdstream: Add internal function to check if a fdstream is open
virsh: fix console stream error reporting
Add flags for virDomainOpenConsole
virsh: add support for VIR_DOMAIN_CONSOLE_FORCE flag
qemu: Add ability to abort existing console while creating new one
lxc: Add ability to abort existing console when creating a new one
uml: Add ability to abort existing console when creating a new one
daemon/stream.c | 2 +-
include/libvirt/libvirt.h.in | 12 +++++++-
src/fdstream.c | 61 ++++++++++++++++++++++++++++++++++++++---
src/fdstream.h | 2 +
src/libvirt_private.syms | 1 +
src/lxc/lxc_driver.c | 28 ++++++++++++++++++-
src/qemu/qemu_domain.c | 3 ++
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 23 +++++++++++++++-
src/rpc/virnetclientstream.c | 12 +++++---
src/uml/uml_driver.c | 28 ++++++++++++++++++-
tools/console.c | 27 ++++++++++++------
tools/console.h | 2 +-
tools/virsh.c | 18 +++++++++---
14 files changed, 192 insertions(+), 29 deletions(-)
--
1.7.3.4
12 years, 11 months
[libvirt] KVM call agenda for 12/6 (Tuesday) @ 10am US/Eastern
by Juan Quintela
Hi
Please send in any agenda items you are interested in covering.
Proposal (from Anthony):
> 1. A short introduction to each of the guest agents, what guests they
> support, and what verbs they support.
> 2. A short description of key requirements from each party (oVirt,
> libvirt, QEMU) for a guest agent
> 3. An open discussion about possible ways to collaborate/converge.
Notice that guest integration will take more than one week (Anthony
estimation also).
For libvirt and ovirt folks, please contact me or Chris for details of
the call.
Thanks, Juan.
12 years, 11 months