Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 49 participants
- 40230 discussions
Hi,
Recent development in KVM for 64-bit Power ISA Book3S machines, allows
users to run multiple KVM guest instances on POWER7 and PPC970
processor based systems. Also qemu-system-ppc64 has been enhanced to
support a new machine type "pseries" suitable for Power Book3S machines.
This addition effectively brings the KVM+qemu combination to run
multiple guest instances on a Power Book3S machine.
Libvirt continues to be the key interface to configure and manage the
KVM guest instances on x86. This patch set is an effort to enable
libvirt to support KVM guest configuration and management on Power Book3S
machines.
Based on community discussion around the earlier version, this patch
series augments the present 'kvm' driver to support PowerPC-KVM based
guests. Since some of the supported devices vary between architectures,
the code is now reworked to dynamically choose the correct handler
function based on guest domain architecture at runtime (def->os.arch).
This patch series consists of 4 patches :
Patch 1/4 : Use sysfs to gather host topology. Presently libvirt
depends on /proc/cpuinfo gather CPU, cores, threads, etc
This is highly architecture dependent. A alternative is
to use sysfs, which provides a platform-neutral interface
to parse CPU topology.
Patch 2/4 : Add PowerPC CPU Driver
Patch 3/4 : Add support for qemu-system-ppc64
Patch 4/4 : Refactor qemu commmand-line generation to separate out arch-
specific options from generic command line.
Changelog from v1:
* Patches 1,2,3 unchanged ; The hacks in Patch 4 of v1 have been
replaced by a new patch to neatly select arch-specific features.
Awaiting comments and feedback,
--
Prerna Saxena
Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India
4
9
22 Nov '11
One of the top questions by libvirt users is how to create a host
bridge device so that guests can be directly on the physical
network. There are several example documents that explain how to do
this manually, but following them often results in confusion and
failure. virt-manager does a good job of creating a bridge based on an
existing network device, but not everyone wants to use virt-manager.
This patch adds a new command, iface-bridge that makes it just about
as simple as possible to create a new bridge device based on an
existing ethernet/vlan/bond device (including associating IP
configuration with the bridge rather than the now-attached device),
and start that new bridge up ready for action, eg:
virsh iface-bridge eth0 br0
For symmetry's sake, it also adds a command to remove a device from a
bridge, restoring the IP config to the now-unattached device:
virsh iface-unbridge br0
(I had a short debate about whether to do "iface-unbridge eth0"
instead, but that would involve searching through all bridge devices
for the one that contained eth0, which seems like a bit too much
trouble).
NOTE: These two commands require that the netcf library be available
on the host. Hopefully this will provide some extra incentive for
people using suse, debian, ubuntu, and other similar systems to polish
up (and push downstream) the ports to those distros recently pushed to
the upstream netcf repo by Dan Berrange. Anyone interested in helping
with that effort in any way should join the netcf-devel mailing list
(subscription info at
https://fedorahosted.org/mailman/listinfo/netcf-devel)
During creation of the bridge, it's possible to specify whether or not
the STP protocol should be started up on the bridge and, if so, how
many seconds the bridge should squelch traffic from newly added
devices while learning new topology (defaults are stp='on' and
delay='0', which seems to usually work best for bridges used in the
context of libvirt guests).
There is also an option to not immediately start the bridge (and a
similar option to not immediately start the un-attached device after
dfestroying the bridge. Default is to start the new device, because in
the case of iface-unbridge not starting is strongly discouraged as it
will leave the system with no network connectivity on that interface
(because it's necessary to destroy/undefine the bridge device before
the unattached device can be defined), and it seemed better to make
the option for iface-bridge behave consistently.
Aside from adding the code for these two functions, and the two
entries into the command table, the only other change to virsh.c was
to add the option name to vshCommandOptInterfaceBy(), because the
iface-unbridge command names its interface option as "bridge".
After being hounded by Eric to always put documentation in with any
new code changes, this patch seems a bit naked without some html bits
describing it :-), but it looks like docs/virshcmdref.html.in has been
deprecated in favor of the version in the separate repo at
http://libvirt.org/git/?p=libvirt-virshcmdref.git.
---
tools/virsh.c | 430 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 425 insertions(+), 5 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index af80e4b..ddfd341 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -330,12 +330,14 @@ static virNWFilterPtr vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd
VSH_BYUUID|VSH_BYNAME)
static virInterfacePtr vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
+ const char *optname,
+
const char **name, int flag);
/* default is lookup by Name and MAC */
#define vshCommandOptInterface(_ctl, _cmd, _name) \
- vshCommandOptInterfaceBy(_ctl, _cmd, _name, \
- VSH_BYMAC|VSH_BYNAME)
+ vshCommandOptInterfaceBy(_ctl, _cmd, NULL, _name, \
+ VSH_BYMAC|VSH_BYNAME)
static virStoragePoolPtr vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd,
const char *optname, const char **name, int flag);
@@ -6807,7 +6809,7 @@ cmdInterfaceName(vshControl *ctl, const vshCmd *cmd)
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
- if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL,
+ if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL, NULL,
VSH_BYMAC)))
return false;
@@ -6837,7 +6839,7 @@ cmdInterfaceMAC(vshControl *ctl, const vshCmd *cmd)
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
- if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL,
+ if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL, NULL,
VSH_BYNAME)))
return false;
@@ -7137,6 +7139,417 @@ cmdInterfaceRollback(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
}
/*
+ * "iface-bridge" command
+ */
+static const vshCmdInfo info_interface_bridge[] = {
+ {"help", N_("create a bridge device and attach an existing network device to it")},
+ {"desc", N_("bridge an existing network device")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_bridge[] = {
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, N_("existing interface name")},
+ {"bridge", VSH_OT_DATA, VSH_OFLAG_REQ, N_("new bridge device name")},
+ {"no-stp", VSH_OT_BOOL, 0, N_("do not enable STP for this bridge")},
+ {"delay", VSH_OT_INT, 0, N_("number of seconds to squelch traffic on newly connected ports")},
+ {"no-start", VSH_OT_BOOL, 0, N_("don't start the bridge immediately")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdInterfaceBridge(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+ bool ret = false;
+ virInterfacePtr if_handle = NULL, br_handle = NULL;
+ const char *if_name, *br_name;
+ char *if_type = NULL, *if2_name = NULL, *delay_str = NULL;
+ bool stp = false, nostart = false;
+ unsigned int delay = 0;
+ char *if_xml = NULL;
+ xmlChar *br_xml = NULL;
+ int br_xml_size;
+ xmlDocPtr xml_doc = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr top_node, br_node, if_node, cur;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ goto cleanup;
+
+ /* Get a handle to the original device */
+ if (!(if_handle = vshCommandOptInterfaceBy(ctl, cmd, "interface",
+ &if_name, VSH_BYNAME))) {
+ goto cleanup;
+ }
+
+ /* Name for new bridge device */
+ if (vshCommandOptString(cmd, "bridge", &br_name) <= 0) {
+ vshError(ctl, "%s", _("Missing bridge device name in command"));
+ goto cleanup;
+ }
+
+ /* make sure "new" device doesn't already exist */
+ if ((br_handle = virInterfaceLookupByName(ctl->conn, br_name))) {
+ vshError(ctl, _("Network device %s already exists"), br_name);
+ goto cleanup;
+ }
+
+ /* use "no-stp" because we want "stp" to default true */
+ stp = !vshCommandOptBool(cmd, "no-stp");
+
+ if (vshCommandOptUInt(cmd, "delay", &delay) < 0) {
+ vshError(ctl, "%s", _("Unable to parse delay parameter"));
+ goto cleanup;
+ }
+
+ nostart = vshCommandOptBool(cmd, "no-start");
+
+ /* Get the original interface into an xmlDoc */
+ if (!(if_xml = virInterfaceGetXMLDesc(if_handle, VIR_INTERFACE_XML_INACTIVE)))
+ goto cleanup;
+ if (!(xml_doc = virXMLParseStringCtxt(if_xml,
+ _("(interface definition)"), &ctxt))) {
+ vshError(ctl, _("Failed to parse configuration of %s"), if_name);
+ goto cleanup;
+ }
+ top_node = ctxt->node;
+
+ /* Verify that the original device isn't already a bridge. */
+ if (!(if_type = virXMLPropString(top_node, "type"))) {
+ vshError(ctl, _("Existing device %s has no type"), if_name);
+ goto cleanup;
+ }
+
+ if (STREQ(if_type, "bridge")) {
+ vshError(ctl, _("Existing device %s is already a bridge"), if_name);
+ goto cleanup;
+ }
+
+ /* verify the name in the XML matches the device name */
+ if (!(if2_name = virXMLPropString(top_node, "name")) ||
+ STRNEQ(if2_name, if_name)) {
+ vshError(ctl, _("Interface name from config %s doesn't match given supplied name %s"),
+ if2_name, if_name);
+ goto cleanup;
+ }
+
+ /* Create a <bridge> node under <interface>. */
+ if (!(br_node = xmlNewChild(top_node, NULL, BAD_CAST "bridge", NULL))) {
+ vshError(ctl, "%s", _("Failed to create bridge node in xml document"));
+ goto cleanup;
+ }
+
+ /* Set stp and delay attributes in <bridge> according to the
+ * commandline options.
+ */
+ if (!xmlSetProp(br_node, BAD_CAST "stp", BAD_CAST (stp ? "on" : "off"))) {
+ vshError(ctl, "%s", _("Failed to set stp attribute in xml document"));
+ goto cleanup;
+ }
+
+ if ((delay || stp) &&
+ ((virAsprintf(&delay_str, "%d", delay) < 0) ||
+ !xmlSetProp(br_node, BAD_CAST "delay", BAD_CAST delay_str))) {
+ vshError(ctl, _("Failed to set bridge delay %d in xml document"), delay);
+ goto cleanup;
+ }
+
+ /* Change the type of the outer/master interface to "bridge" and the
+ * name to the provided bridge name.
+ */
+ if (!xmlSetProp(top_node, BAD_CAST "type", BAD_CAST "bridge")) {
+ vshError(ctl, "%s", _("Failed to set bridge interface type to 'bridge' in xml document"));
+ goto cleanup;
+ }
+
+ if (!xmlSetProp(top_node, BAD_CAST "name", BAD_CAST br_name)) {
+ vshError(ctl, _("Failed to set master bridge interface name to '%s' in xml document"),
+ br_name);
+ goto cleanup;
+ }
+
+ /* Create an <interface> node under <bridge> that uses the
+ * original interface's type and name.
+ */
+ if (!(if_node = xmlNewChild(br_node, NULL, BAD_CAST "interface", NULL))) {
+ vshError(ctl, "%s", _("Failed to create interface node under bridge node in xml document"));
+ goto cleanup;
+ }
+
+ /* set the type of the inner/slave interface to the original
+ * if_type, and the name to the original if_name.
+ */
+ if (!xmlSetProp(if_node, BAD_CAST "type", BAD_CAST if_type)) {
+ vshError(ctl, _("Failed to set new slave interface type to '%s' in xml document"),
+ if_name);
+ goto cleanup;
+ }
+
+ if (!xmlSetProp(if_node, BAD_CAST "name", BAD_CAST if_name)) {
+ vshError(ctl, _("Failed to set new slave interface name to '%s' in xml document"),
+ br_name);
+ goto cleanup;
+ }
+
+ /* Cycle through all the nodes under the original <interface>,
+ * moving all <mac>, <bond> and <vlan> nodes down into the new
+ * lower level <interface>.
+ */
+ cur = top_node->children;
+ while (cur) {
+ xmlNodePtr old = cur;
+
+ cur = cur->next;
+ if ((old->type == XML_ELEMENT_NODE) &&
+ (xmlStrEqual(old->name, BAD_CAST "mac") || /* ethernet stuff to move down */
+ xmlStrEqual(old->name, BAD_CAST "bond") || /* bond stuff to move down */
+ xmlStrEqual(old->name, BAD_CAST "vlan"))) { /* vlan stuff to move down */
+ xmlUnlinkNode(old);
+ if (!xmlAddChild(if_node, old)) {
+ vshError(ctl, _("Failed to move '%s' element in xml document"), old->name);
+ xmlFreeNode(old);
+ goto cleanup;
+ }
+ }
+ }
+
+ /* The document should now be fully converted; write it out to a string. */
+ xmlDocDumpMemory(xml_doc, &br_xml, &br_xml_size);
+
+ if (!br_xml || br_xml_size <= 0) {
+ vshError(ctl, _("Failed to format new xml document for bridge %s"), br_name);
+ goto cleanup;
+ }
+
+
+ /* br_xml is the new interface to define. It will automatically undefine the
+ * independent original interface.
+ */
+ if (!(br_handle = virInterfaceDefineXML(ctl->conn, (char *) br_xml, 0))) {
+ vshError(ctl, _("Failed to define new bridge interface %s"),
+ br_name);
+ goto cleanup;
+ }
+
+ vshPrint(ctl, _("Created bridge %s with attached device %s\n"),
+ if_name, br_name);
+
+ /* start it up unless requested not to */
+ if (!nostart) {
+ if (virInterfaceCreate(br_handle, 0) < 0) {
+ vshError(ctl, _("Failed to start bridge interface %s"), br_name);
+ goto cleanup;
+ }
+ vshPrint(ctl, _("Bridge interface %s started\n"), br_name);
+ }
+
+ ret = true;
+ cleanup:
+ if (if_handle)
+ virInterfaceFree(if_handle);
+ if (br_handle)
+ virInterfaceFree(br_handle);
+ VIR_FREE(if_xml);
+ VIR_FREE(br_xml);
+ VIR_FREE(if_type);
+ VIR_FREE(if2_name);
+ VIR_FREE(delay_str);
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml_doc);
+ return ret;
+}
+
+/*
+ * "iface-unbridge" command
+ */
+static const vshCmdInfo info_interface_unbridge[] = {
+ {"help", N_("undefine a bridge device after detaching its slave device")},
+ {"desc", N_("unbridge a network device")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_interface_unbridge[] = {
+ {"bridge", VSH_OT_DATA, VSH_OFLAG_REQ, N_("current bridge device name")},
+ {"no-start", VSH_OT_BOOL, 0, N_("don't start the un-slaved interface immediately (not recommended)")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdInterfaceUnbridge(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+ bool ret = false;
+ virInterfacePtr if_handle = NULL, br_handle = NULL;
+ const char *br_name;
+ char *if_type = NULL, *if_name = NULL;
+ bool nostart = false;
+ char *br_xml = NULL;
+ xmlChar *if_xml = NULL;
+ int if_xml_size;
+ xmlDocPtr xml_doc = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr top_node, br_node, if_node, cur;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ goto cleanup;
+
+ /* Get a handle to the original device */
+ if (!(br_handle = vshCommandOptInterfaceBy(ctl, cmd, "bridge",
+ &br_name, VSH_BYNAME))) {
+ goto cleanup;
+ }
+
+ nostart = vshCommandOptBool(cmd, "no-start");
+
+ /* Get the bridge xml into an xmlDoc */
+ if (!(br_xml = virInterfaceGetXMLDesc(br_handle, VIR_INTERFACE_XML_INACTIVE)))
+ goto cleanup;
+ if (!(xml_doc = virXMLParseStringCtxt(br_xml,
+ _("(bridge interface definition)"),
+ &ctxt))) {
+ vshError(ctl, _("Failed to parse configuration of %s"), br_name);
+ goto cleanup;
+ }
+ top_node = ctxt->node;
+
+ /* Verify that the device really is a bridge. */
+ if (!(if_type = virXMLPropString(top_node, "type"))) {
+ vshError(ctl, _("Existing device %s has no type"), br_name);
+ goto cleanup;
+ }
+
+ if (STRNEQ(if_type, "bridge")) {
+ vshError(ctl, _("Device %s is not a bridge"), br_name);
+ goto cleanup;
+ }
+ VIR_FREE(if_type);
+
+ /* verify the name in the XML matches the device name */
+ if (!(if_name = virXMLPropString(top_node, "name")) ||
+ STRNEQ(if_name, br_name)) {
+ vshError(ctl, _("Interface name from config %s doesn't match given supplied name %s"),
+ if_name, br_name);
+ goto cleanup;
+ }
+ VIR_FREE(if_name);
+
+ /* Find the <bridge> node under <interface>. */
+ if (!(br_node = virXPathNode("./bridge", ctxt))) {
+ vshError(ctl, "%s", _("No bridge node in xml document"));
+ goto cleanup;
+ }
+
+ if ((if_node = virXPathNode("./bridge/interface[2]", ctxt))) {
+ vshError(ctl, "%s", _("Multiple interfaecs attached to bridge"));
+ goto cleanup;
+ }
+
+ if (!(if_node = virXPathNode("./bridge/interface", ctxt))) {
+ vshError(ctl, "%s", _("No interface attached to bridge"));
+ goto cleanup;
+ }
+
+ /* Change the type and name of the outer/master interface to
+ * the type/name of the attached slave interface.
+ */
+ if (!(if_name = virXMLPropString(if_node, "name"))) {
+ vshError(ctl, _("Device attached to bridge %s has no name"), br_name);
+ goto cleanup;
+ }
+
+ if (!(if_type = virXMLPropString(if_node, "type"))) {
+ vshError(ctl, _("Attached device %s has no type"), if_name);
+ goto cleanup;
+ }
+
+ if (!xmlSetProp(top_node, BAD_CAST "type", BAD_CAST if_type)) {
+ vshError(ctl, _("Failed to set interface type to '%s' in xml document"),
+ if_type);
+ goto cleanup;
+ }
+
+ if (!xmlSetProp(top_node, BAD_CAST "name", BAD_CAST if_name)) {
+ vshError(ctl, _("Failed to set interface name to '%s' in xml document"),
+ if_name);
+ goto cleanup;
+ }
+
+ /* Cycle through all the nodes under the attached <interface>,
+ * moving all <mac>, <bond> and <vlan> nodes up into the toplevel
+ * <interface>.
+ */
+ cur = if_node->children;
+ while (cur) {
+ xmlNodePtr old = cur;
+
+ cur = cur->next;
+ if ((old->type == XML_ELEMENT_NODE) &&
+ (xmlStrEqual(old->name, BAD_CAST "mac") || /* ethernet stuff to move down */
+ xmlStrEqual(old->name, BAD_CAST "bond") || /* bond stuff to move down */
+ xmlStrEqual(old->name, BAD_CAST "vlan"))) { /* vlan stuff to move down */
+ xmlUnlinkNode(old);
+ if (!xmlAddChild(top_node, old)) {
+ vshError(ctl, _("Failed to move '%s' element in xml document"), old->name);
+ xmlFreeNode(old);
+ goto cleanup;
+ }
+ }
+ }
+
+ /* The document should now be fully converted; write it out to a string. */
+ xmlDocDumpMemory(xml_doc, &if_xml, &if_xml_size);
+
+ if (!if_xml || if_xml_size <= 0) {
+ vshError(ctl, _("Failed to format new xml document for un-enslaved interface %s"),
+ if_name);
+ goto cleanup;
+ }
+
+ /* Destroy and Undefine the bridge device, since we otherwise
+ * can't safely define the unattached device.
+ */
+ if (virInterfaceDestroy(br_handle, 0) < 0) {
+ vshError(ctl, _("Failed to destroy bridge interface %s"), br_name);
+ goto cleanup;
+ }
+ if (virInterfaceUndefine(br_handle) < 0) {
+ vshError(ctl, _("Failed to undefine bridge interface %s"), br_name);
+ goto cleanup;
+ }
+
+ /* if_xml is the new interface to define.
+ */
+ if (!(if_handle = virInterfaceDefineXML(ctl->conn, (char *) if_xml, 0))) {
+ vshError(ctl, _("Failed to define new interface %s"), if_name);
+ goto cleanup;
+ }
+
+ vshPrint(ctl, _("Device %s un-attached from bridge %s\n"),
+ if_name, br_name);
+
+ /* unless requested otherwise, undefine the bridge device */
+ if (!nostart) {
+ if (virInterfaceCreate(if_handle, 0) < 0) {
+ vshError(ctl, _("Failed to start interface %s"), if_name);
+ goto cleanup;
+ }
+ vshPrint(ctl, _("Interface %s started\n"), if_name);
+ }
+
+ ret = true;
+ cleanup:
+ if (if_handle)
+ virInterfaceFree(if_handle);
+ if (br_handle)
+ virInterfaceFree(br_handle);
+ VIR_FREE(if_xml);
+ VIR_FREE(br_xml);
+ VIR_FREE(if_type);
+ VIR_FREE(if_name);
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml_doc);
+ return ret;
+}
+
+/*
* "nwfilter-define" command
*/
static const vshCmdInfo info_nwfilter_define[] = {
@@ -14199,6 +14612,10 @@ static const vshCmdDef nodedevCmds[] = {
static const vshCmdDef ifaceCmds[] = {
{"iface-begin", cmdInterfaceBegin, opts_interface_begin,
info_interface_begin, 0},
+ {"iface-bridge", cmdInterfaceBridge, opts_interface_bridge,
+ info_interface_bridge, 0},
+ {"iface-unbridge", cmdInterfaceUnbridge, opts_interface_unbridge,
+ info_interface_unbridge, 0},
{"iface-commit", cmdInterfaceCommit, opts_interface_commit,
info_interface_commit, 0},
{"iface-define", cmdInterfaceDefine, opts_interface_define,
@@ -15101,11 +15518,14 @@ vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
static virInterfacePtr
vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
+ const char *optname,
const char **name, int flag)
{
virInterfacePtr iface = NULL;
const char *n = NULL;
- const char *optname = "interface";
+
+ if (!optname)
+ optname = "interface";
if (!cmd_has_option (ctl, cmd, optname))
return NULL;
--
1.7.7.1
3
4
[libvirt] Bug 754974 - connection with xen+ssh vm's are missing with list (virsh)
by Robin van Leeuwen 21 Nov '11
by Robin van Leeuwen 21 Nov '11
21 Nov '11
Hi
I posted the above mentioned bug to Bugzilla and one reply said to mention
it on libvir-list(a)redhat.com as well. So here it is:
https://bugzilla.redhat.com/show_bug.cgi?id=754974
Is mentioning it in this list too, (when it involves libvirt
offcourse) after filing
a bug on Bugzilla, the appropiate action to take?
Kind regards,
Robin
2
1
21 Nov '11
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
libvirt-gobject/libvirt-gobject-domain.c | 68 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 3 +
libvirt-gobject/libvirt-gobject.sym | 1 +
3 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 1fa27bd..7ff820b 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -449,6 +449,74 @@ GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
return conf;
}
+/**
+ * gvir_domain_set_config:
+ * @domain: the domain
+ * @conf: the new configuration for the domain
+ * @err: (allow-none): Place-holder for error or NULL
+ *
+ * Resets configuration of an existing domain.
+ *
+ * Note: If domain is already running, the new configuration will not take
+ * affect until domain reboots.
+ *
+ * Returns: TRUE on success, FALSE if an error occurred.
+ */
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err)
+{
+ gchar *xml;
+ virConnectPtr conn;
+ virDomainPtr handle;
+ gchar uuid[VIR_UUID_STRING_BUFLEN];
+ GVirDomainPrivate *priv = domain->priv;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN (domain), FALSE);
+ g_return_val_if_fail(GVIR_IS_CONFIG_DOMAIN (conf), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
+
+ g_return_val_if_fail(xml != NULL, FALSE);
+
+ if ((conn = virDomainGetConnect(priv->handle)) == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to get domain connection");
+ g_free (xml);
+
+ return FALSE;
+ }
+
+ handle = virDomainDefineXML(conn, xml);
+ g_free (xml);
+
+ if (handle == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+ return FALSE;
+ }
+
+ virDomainGetUUIDString(handle, uuid);
+ virDomainFree(handle);
+
+ if (g_strcmp0 (uuid, priv->uuid) != 0) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
/**
* gvir_domain_get_info:
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 94bd53e..0479de8 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -123,6 +123,9 @@ GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
guint64 flags,
GError **err);
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err);
gchar *gvir_domain_screenshot(GVirDomain *dom,
GVirStream *stream,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 164b6b8..46c53f9 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -53,6 +53,7 @@ LIBVIRT_GOBJECT_0.0.1 {
gvir_domain_shutdown;
gvir_domain_reboot;
gvir_domain_get_config;
+ gvir_domain_set_config;
gvir_domain_get_info;
gvir_domain_screenshot;
--
1.7.7.1
2
1
This series does mainly two things:
1. use cgroup cpuset to manage numa parameters
2. add a virsh command numatune to allow user to change numa parameters
from command line
Current numa parameters include nodeset and mode, but these cgroup cpuset
provides don't completely match with them, details:
params cpuset
------------------------------------------------------
nodeset cpuset provides cpuset.mems
mode strict cpuset provides cpuset.mem_hardwall
mode interleave cpuset provices cpuset.memory_spread_*
mode preferred no equivalent. !spread to preferred?
Besides, only one of the mode can be set currently at a time, but
for cpuset, the parameters are independent. From the perspective
of cpuset, we can set all the modes values independently, but it
seems not be consistent with the current numatune definition in xml.
Maybe we can improve the xml definition to fit cpuset better?(there
are more cpuset parameters than listed above)
Hu Tao (11):
don't modify CPU set string in virDomainCpuSetParse
enable cgroup cpuset by default
Add functions to set/get cgroup cpuset parameters
introduce numa backend
use cpuset to manage numa
add VIR_DOMAIN_NUMATUNE_MEM_NONE
add new API virDomain{G,S}etNumaParameters
Implement main entries of virDomain{G,S}etNumaParameters
Add virDomain{G,S}etNumaParameters support to the remote driver
Implement virDomain{G,S}etNumaParameters for the qemu driver
add new command numatune to virsh
daemon/remote.c | 64 +++++++
include/libvirt/libvirt.h.in | 23 +++
python/generator.py | 2 +
src/conf/domain_conf.c | 2 +-
src/conf/domain_conf.h | 9 +
src/driver.h | 15 ++
src/libvirt.c | 113 ++++++++++++
src/libvirt_private.syms | 10 +
src/libvirt_public.syms | 6 +
src/qemu/qemu.conf | 5 +-
src/qemu/qemu_cgroup.c | 73 ++++++++
src/qemu/qemu_conf.c | 3 +-
src/qemu/qemu_driver.c | 399 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_process.c | 11 +-
src/remote/remote_driver.c | 50 ++++++
src/remote/remote_protocol.x | 25 +++-
src/remote_protocol-structs | 16 ++
src/util/cgroup.c | 112 ++++++++++++
src/util/cgroup.h | 11 ++
tools/virsh.c | 180 +++++++++++++++++++
20 files changed, 1121 insertions(+), 8 deletions(-)
--
1.7.3.1
5
27
[libvirt] [PATCH] Bug Fix: Do not release network actual device in qemuBuildCommandLine on error
by Roopa Prabhu 21 Nov '11
by Roopa Prabhu 21 Nov '11
21 Nov '11
From: Roopa Prabhu <roprabhu(a)cisco.com>
For direct attach devices, in qemuBuildCommandLine, we seem to be freeing
actual device on error path (with networkReleaseActualDevice). But the actual
device is not deleted.
qemuProcessStop eventually deletes the direct attach device and releases actual device. But by the time qemuProcessStop is called qemuBuildCommandLine
has already freed actual device. Leaving stray macvtap devices behind on error.
So the simplest fix is to remove the networkReleaseActualDevice in
qemuBuildCommandLine. This patch does just that.
Does this look right ?. I have only verified this with direct and bridge mode.
The other option is to do both delMacvtap and networkReleaseActualDevice in
qemuBuildCommandLine instead of doing only networkReleaseActualDevice.
I do have a patch for this too.
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
---
src/qemu/qemu_command.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bb12016..ba33a4a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5378,8 +5378,6 @@ qemuBuildCommandLine(virConnectPtr conn,
virReportOOMError();
error:
/* free up any resources in the network driver */
- for (i = 0 ; i < def->nnets ; i++)
- networkReleaseActualDevice(def->nets[i]);
for (i = 0; i <= last_good_net; i++)
virDomainConfNWFilterTeardown(def->nets[i]);
virCommandFree(cmd);
3
2
21 Nov '11
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
libvirt-gobject/libvirt-gobject-domain.c | 63 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 3 +
libvirt-gobject/libvirt-gobject.sym | 1 +
3 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 1fa27bd..a198715 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -449,6 +449,69 @@ GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
return conf;
}
+/**
+ * gvir_domain_set_config:
+ * @domain: the domain
+ * @conf: the new configuration for the domain
+ * @err: (allow-none): Place-holder for error or NULL
+ *
+ * Resets configuration of an existing domain.
+ *
+ * Note: If domain is already running, the new configuration will not take
+ * affect until domain reboots.
+ *
+ * Returns: TRUE on success, FALSE if an error occurred.
+ */
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err)
+{
+ const gchar *xml;
+ virConnectPtr conn;
+ virDomainPtr handle;
+ gchar uuid[VIR_UUID_STRING_BUFLEN];
+ GVirDomainPrivate *priv = domain->priv;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN (domain), FALSE);
+ g_return_val_if_fail(GVIR_IS_CONFIG_DOMAIN (conf), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
+
+ g_return_val_if_fail(xml != NULL, FALSE);
+
+ if ((conn = virDomainGetConnect(priv->handle)) == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to get domain connection");
+ return FALSE;
+ }
+
+ handle = virDomainDefineXML(conn, xml);
+
+ if (handle == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+ return FALSE;
+ }
+
+ virDomainGetUUIDString(priv->handle, uuid);
+
+ if (strcmp (uuid, priv->uuid) != 0) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+ return FALSE;
+ }
+
+ return TRUE;
+}
/**
* gvir_domain_get_info:
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 94bd53e..0479de8 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -123,6 +123,9 @@ GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
guint64 flags,
GError **err);
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err);
gchar *gvir_domain_screenshot(GVirDomain *dom,
GVirStream *stream,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 164b6b8..46c53f9 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -53,6 +53,7 @@ LIBVIRT_GOBJECT_0.0.1 {
gvir_domain_shutdown;
gvir_domain_reboot;
gvir_domain_get_config;
+ gvir_domain_set_config;
gvir_domain_get_info;
gvir_domain_screenshot;
--
1.7.7.1
2
3
[libvirt] [PATCH 2/2] nwfilter: use shell variable to invoke 'ip(6)tables' command
by Stefan Berger 21 Nov '11
by Stefan Berger 21 Nov '11
21 Nov '11
Introduce a shell variable 'IBT' to invoke the ip(6)tables command.
Tested with libvirt-tck.
---
src/nwfilter/nwfilter_ebiptables_driver.c | 313 ++++++++++++++----------------
1 file changed, 155 insertions(+), 158 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -146,6 +146,10 @@ static const char ebiptables_script_set_
#define NWFILTER_SET_EBTABLES_SHELLVAR(BUFPTR) \
virBufferAsprintf(BUFPTR, "EBT=%s\n", ebtables_cmd_path);
+#define NWFILTER_SET_IPTABLES_SHELLVAR(BUFPTR) \
+ virBufferAsprintf(BUFPTR, "IPT=%s\n", iptables_cmd_path);
+#define NWFILTER_SET_IP6TABLES_SHELLVAR(BUFPTR) \
+ virBufferAsprintf(BUFPTR, "IPT=%s\n", ip6tables_cmd_path);
#define VIRT_IN_CHAIN "libvirt-in"
#define VIRT_OUT_CHAIN "libvirt-out"
@@ -493,66 +497,60 @@ ebtablesHandleEthHdr(virBufferPtr buf,
/************************ iptables support ************************/
-static int iptablesLinkIPTablesBaseChain(const char *iptables_cmd,
- virBufferPtr buf,
+static int iptablesLinkIPTablesBaseChain(virBufferPtr buf,
const char *udchain,
const char *syschain,
unsigned int pos,
int stopOnError)
{
virBufferAsprintf(buf,
- "res=$(%s -L %s -n --line-number | "
+ "res=$($IPT -L %s -n --line-number | "
"%s \" %s \")\n"
"if [ $? -ne 0 ]; then\n"
- " %s -I %s %d -j %s\n"
+ " $IPT -I %s %d -j %s\n"
"else\n"
" r=$(echo $res | %s '{print $1}')\n"
" if [ \"${r}\" != \"%d\" ]; then\n"
- " " CMD_DEF("%s -I %s %d -j %s") CMD_SEPARATOR
+ " " CMD_DEF("$IPT -I %s %d -j %s") CMD_SEPARATOR
" " CMD_EXEC
" %s"
" r=$(( $r + 1 ))\n"
- " " CMD_DEF("%s -D %s ${r}") CMD_SEPARATOR
+ " " CMD_DEF("$IPT -D %s ${r}") CMD_SEPARATOR
" " CMD_EXEC
" %s"
" fi\n"
"fi\n",
- iptables_cmd, syschain,
+ syschain,
grep_cmd_path, udchain,
- iptables_cmd, syschain, pos, udchain,
+ syschain, pos, udchain,
gawk_cmd_path,
pos,
- iptables_cmd, syschain, pos, udchain,
+ syschain, pos, udchain,
CMD_STOPONERR(stopOnError),
- iptables_cmd, syschain,
+ syschain,
CMD_STOPONERR(stopOnError));
return 0;
}
-static int iptablesCreateBaseChains(const char *iptables_cmd,
- virBufferPtr buf)
+static int iptablesCreateBaseChains(virBufferPtr buf)
{
- virBufferAsprintf(buf,"%s -N " VIRT_IN_CHAIN CMD_SEPARATOR
- "%s -N " VIRT_OUT_CHAIN CMD_SEPARATOR
- "%s -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR
- "%s -N " HOST_IN_CHAIN CMD_SEPARATOR,
- iptables_cmd,
- iptables_cmd,
- iptables_cmd,
- iptables_cmd);
- iptablesLinkIPTablesBaseChain(iptables_cmd, buf,
+ virBufferAddLit(buf, "$IPT -N " VIRT_IN_CHAIN CMD_SEPARATOR
+ "$IPT -N " VIRT_OUT_CHAIN CMD_SEPARATOR
+ "$IPT -N " VIRT_IN_POST_CHAIN CMD_SEPARATOR
+ "$IPT -N " HOST_IN_CHAIN CMD_SEPARATOR);
+ iptablesLinkIPTablesBaseChain(buf,
VIRT_IN_CHAIN , "FORWARD", 1, 1);
- iptablesLinkIPTablesBaseChain(iptables_cmd, buf,
+ iptablesLinkIPTablesBaseChain(buf,
VIRT_OUT_CHAIN , "FORWARD", 2, 1);
- iptablesLinkIPTablesBaseChain(iptables_cmd, buf,
+ iptablesLinkIPTablesBaseChain(buf,
VIRT_IN_POST_CHAIN, "FORWARD", 3, 1);
- iptablesLinkIPTablesBaseChain(iptables_cmd, buf,
+ iptablesLinkIPTablesBaseChain(buf,
HOST_IN_CHAIN , "INPUT" , 1, 1);
return 0;
@@ -560,8 +558,7 @@ static int iptablesCreateBaseChains(cons
static int
-iptablesCreateTmpRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesCreateTmpRootChain(virBufferPtr buf,
char prefix,
int incoming, const char *ifname,
int stopOnError)
@@ -576,10 +573,9 @@ iptablesCreateTmpRootChain(const char *i
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- CMD_DEF("%s -N %s") CMD_SEPARATOR
+ CMD_DEF("$IPT -N %s") CMD_SEPARATOR
CMD_EXEC
"%s",
- iptables_cmd,
chain,
CMD_STOPONERR(stopOnError));
@@ -588,20 +584,18 @@ iptablesCreateTmpRootChain(const char *i
static int
-iptablesCreateTmpRootChains(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesCreateTmpRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesCreateTmpRootChain(iptables_cmd, buf, 'F', 0, ifname, 1);
- iptablesCreateTmpRootChain(iptables_cmd, buf, 'F', 1, ifname, 1);
- iptablesCreateTmpRootChain(iptables_cmd, buf, 'H', 1, ifname, 1);
+ iptablesCreateTmpRootChain(buf, 'F', 0, ifname, 1);
+ iptablesCreateTmpRootChain(buf, 'F', 1, ifname, 1);
+ iptablesCreateTmpRootChain(buf, 'H', 1, ifname, 1);
return 0;
}
static int
-_iptablesRemoveRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+_iptablesRemoveRootChain(virBufferPtr buf,
char prefix,
int incoming, const char *ifname,
int isTempChain)
@@ -621,66 +615,60 @@ _iptablesRemoveRootChain(const char *ipt
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- "%s -F %s" CMD_SEPARATOR
- "%s -X %s" CMD_SEPARATOR,
- iptables_cmd, chain,
- iptables_cmd, chain);
+ "$IPT -F %s" CMD_SEPARATOR
+ "$IPT -X %s" CMD_SEPARATOR,
+ chain,
+ chain);
return 0;
}
static int
-iptablesRemoveRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRemoveRootChain(virBufferPtr buf,
char prefix,
int incoming,
const char *ifname)
{
- return _iptablesRemoveRootChain(iptables_cmd,
- buf, prefix, incoming, ifname, 0);
+ return _iptablesRemoveRootChain(buf, prefix, incoming, ifname, 0);
}
static int
-iptablesRemoveTmpRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRemoveTmpRootChain(virBufferPtr buf,
char prefix,
int incoming,
const char *ifname)
{
- return _iptablesRemoveRootChain(iptables_cmd, buf, prefix,
+ return _iptablesRemoveRootChain(buf, prefix,
incoming, ifname, 1);
}
static int
-iptablesRemoveTmpRootChains(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRemoveTmpRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesRemoveTmpRootChain(iptables_cmd, buf, 'F', 0, ifname);
- iptablesRemoveTmpRootChain(iptables_cmd, buf, 'F', 1, ifname);
- iptablesRemoveTmpRootChain(iptables_cmd, buf, 'H', 1, ifname);
+ iptablesRemoveTmpRootChain(buf, 'F', 0, ifname);
+ iptablesRemoveTmpRootChain(buf, 'F', 1, ifname);
+ iptablesRemoveTmpRootChain(buf, 'H', 1, ifname);
return 0;
}
static int
-iptablesRemoveRootChains(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRemoveRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesRemoveRootChain(iptables_cmd, buf, 'F', 0, ifname);
- iptablesRemoveRootChain(iptables_cmd, buf, 'F', 1, ifname);
- iptablesRemoveRootChain(iptables_cmd, buf, 'H', 1, ifname);
+ iptablesRemoveRootChain(buf, 'F', 0, ifname);
+ iptablesRemoveRootChain(buf, 'F', 1, ifname);
+ iptablesRemoveRootChain(buf, 'H', 1, ifname);
return 0;
}
static int
-iptablesLinkTmpRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesLinkTmpRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
int incoming, const char *ifname,
@@ -698,11 +686,10 @@ iptablesLinkTmpRootChain(const char *ipt
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- CMD_DEF("%s -A %s "
+ CMD_DEF("$IPT -A %s "
"%s %s -g %s") CMD_SEPARATOR
CMD_EXEC
"%s",
- iptables_cmd,
basechain,
match, ifname, chain,
@@ -713,37 +700,33 @@ iptablesLinkTmpRootChain(const char *ipt
static int
-iptablesLinkTmpRootChains(const char *cmd,
- virBufferPtr buf,
+iptablesLinkTmpRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesLinkTmpRootChain(cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1);
- iptablesLinkTmpRootChain(cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1);
- iptablesLinkTmpRootChain(cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname, 1);
+ iptablesLinkTmpRootChain(buf, VIRT_OUT_CHAIN, 'F', 0, ifname, 1);
+ iptablesLinkTmpRootChain(buf, VIRT_IN_CHAIN , 'F', 1, ifname, 1);
+ iptablesLinkTmpRootChain(buf, HOST_IN_CHAIN , 'H', 1, ifname, 1);
return 0;
}
static int
-iptablesSetupVirtInPost(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesSetupVirtInPost(virBufferPtr buf,
const char *ifname)
{
const char *match = MATCH_PHYSDEV_IN;
virBufferAsprintf(buf,
- "res=$(%s -n -L " VIRT_IN_POST_CHAIN
+ "res=$($IPT -n -L " VIRT_IN_POST_CHAIN
" | grep \"\\%s %s\")\n"
"if [ \"${res}\" = \"\" ]; then "
- CMD_DEF("%s"
+ CMD_DEF("$IPT"
" -A " VIRT_IN_POST_CHAIN
" %s %s -j ACCEPT") CMD_SEPARATOR
CMD_EXEC
"%s"
"fi\n",
- iptables_cmd,
PHYSDEV_IN, ifname,
- iptables_cmd,
match, ifname,
CMD_STOPONERR(1));
return 0;
@@ -751,22 +734,19 @@ iptablesSetupVirtInPost(const char *ipta
static int
-iptablesClearVirtInPost(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesClearVirtInPost(virBufferPtr buf,
const char *ifname)
{
const char *match = MATCH_PHYSDEV_IN;
virBufferAsprintf(buf,
- "%s -D " VIRT_IN_POST_CHAIN
+ "$IPT -D " VIRT_IN_POST_CHAIN
" %s %s -j ACCEPT" CMD_SEPARATOR,
- iptables_cmd,
match, ifname);
return 0;
}
static int
-_iptablesUnlinkRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+_iptablesUnlinkRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
int incoming, const char *ifname,
@@ -788,9 +768,8 @@ _iptablesUnlinkRootChain(const char *ipt
PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- "%s -D %s "
+ "$IPT -D %s "
"%s %s -g %s" CMD_SEPARATOR,
- iptables_cmd,
basechain,
match, ifname, chain);
@@ -799,57 +778,52 @@ _iptablesUnlinkRootChain(const char *ipt
static int
-iptablesUnlinkRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesUnlinkRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
int incoming, const char *ifname)
{
- return _iptablesUnlinkRootChain(iptables_cmd, buf,
+ return _iptablesUnlinkRootChain(buf,
basechain, prefix, incoming, ifname, 0);
}
static int
-iptablesUnlinkTmpRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesUnlinkTmpRootChain(virBufferPtr buf,
const char *basechain,
char prefix,
int incoming, const char *ifname)
{
- return _iptablesUnlinkRootChain(iptables_cmd, buf,
+ return _iptablesUnlinkRootChain(buf,
basechain, prefix, incoming, ifname, 1);
}
static int
-iptablesUnlinkRootChains(const char *cmd,
- virBufferPtr buf,
+iptablesUnlinkRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesUnlinkRootChain(cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
- iptablesUnlinkRootChain(cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname);
- iptablesUnlinkRootChain(cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname);
+ iptablesUnlinkRootChain(buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
+ iptablesUnlinkRootChain(buf, VIRT_IN_CHAIN , 'F', 1, ifname);
+ iptablesUnlinkRootChain(buf, HOST_IN_CHAIN , 'H', 1, ifname);
return 0;
}
static int
-iptablesUnlinkTmpRootChains(const char *cmd,
- virBufferPtr buf,
+iptablesUnlinkTmpRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesUnlinkTmpRootChain(cmd, buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
- iptablesUnlinkTmpRootChain(cmd, buf, VIRT_IN_CHAIN , 'F', 1, ifname);
- iptablesUnlinkTmpRootChain(cmd, buf, HOST_IN_CHAIN , 'H', 1, ifname);
+ iptablesUnlinkTmpRootChain(buf, VIRT_OUT_CHAIN, 'F', 0, ifname);
+ iptablesUnlinkTmpRootChain(buf, VIRT_IN_CHAIN , 'F', 1, ifname);
+ iptablesUnlinkTmpRootChain(buf, HOST_IN_CHAIN , 'H', 1, ifname);
return 0;
}
static int
-iptablesRenameTmpRootChain(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRenameTmpRootChain(virBufferPtr buf,
char prefix,
int incoming,
const char *ifname)
@@ -870,8 +844,7 @@ iptablesRenameTmpRootChain(const char *i
PRINT_IPT_ROOT_CHAIN( chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- "%s -E %s %s" CMD_SEPARATOR,
- iptables_cmd,
+ "$IPT -E %s %s" CMD_SEPARATOR,
tmpchain,
chain);
return 0;
@@ -879,13 +852,12 @@ iptablesRenameTmpRootChain(const char *i
static int
-iptablesRenameTmpRootChains(const char *iptables_cmd,
- virBufferPtr buf,
+iptablesRenameTmpRootChains(virBufferPtr buf,
const char *ifname)
{
- iptablesRenameTmpRootChain(iptables_cmd, buf, 'F', 0, ifname);
- iptablesRenameTmpRootChain(iptables_cmd, buf, 'F', 1, ifname);
- iptablesRenameTmpRootChain(iptables_cmd, buf, 'H', 1, ifname);
+ iptablesRenameTmpRootChain(buf, 'F', 0, ifname);
+ iptablesRenameTmpRootChain(buf, 'F', 1, ifname);
+ iptablesRenameTmpRootChain(buf, 'H', 1, ifname);
return 0;
}
@@ -1259,8 +1231,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_TCP:
case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p tcp");
@@ -1315,8 +1286,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_UDP:
case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p udp");
@@ -1349,8 +1319,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p udplite");
@@ -1378,8 +1347,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_ESP:
case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p esp");
@@ -1407,8 +1375,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_AH:
case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p ah");
@@ -1436,8 +1403,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p sctp");
@@ -1470,8 +1436,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
if (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ICMP)
@@ -1536,8 +1501,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_IGMP:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p igmp");
@@ -1565,8 +1529,7 @@ _iptablesCreateRuleInstance(int directio
case VIR_NWFILTER_RULE_PROTOCOL_ALL:
case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -%%c %s %%s",
- iptables_cmd,
+ CMD_DEF_PRE "$IPT -%%c %s %%s",
chain);
virBufferAddLit(&buf, " -p all");
@@ -3681,24 +3644,32 @@ ebiptablesApplyNewRules(virConnectPtr co
goto tear_down_tmpebchains;
if (haveIptables) {
- iptablesUnlinkTmpRootChains(iptables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
- iptablesCreateBaseChains(iptables_cmd_path, &buf);
+ iptablesCreateBaseChains(&buf);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpebchains;
- iptablesCreateTmpRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesCreateTmpRootChains(&buf, ifname);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpiptchains;
- iptablesLinkTmpRootChains(iptables_cmd_path, &buf, ifname);
- iptablesSetupVirtInPost(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesLinkTmpRootChains(&buf, ifname);
+ iptablesSetupVirtInPost(&buf, ifname);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpiptchains;
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
for (i = 0; i < nruleInstances; i++) {
sa_assert (inst);
if (inst[i]->ruleType == RT_IPTABLES)
@@ -3714,24 +3685,32 @@ ebiptablesApplyNewRules(virConnectPtr co
}
if (haveIp6tables) {
- iptablesUnlinkTmpRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
- iptablesCreateBaseChains(ip6tables_cmd_path, &buf);
+ iptablesCreateBaseChains(&buf);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpiptchains;
- iptablesCreateTmpRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesCreateTmpRootChains(&buf, ifname);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpip6tchains;
- iptablesLinkTmpRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesSetupVirtInPost(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesLinkTmpRootChains(&buf, ifname);
+ iptablesSetupVirtInPost(&buf, ifname);
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpip6tchains;
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
for (i = 0; i < nruleInstances; i++) {
if (inst[i]->ruleType == RT_IP6TABLES)
iptablesInstCommand(&buf,
@@ -3776,14 +3755,18 @@ tear_down_ebsubchains_and_unlink:
tear_down_tmpip6tchains:
if (haveIp6tables) {
- iptablesUnlinkTmpRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
}
tear_down_tmpiptchains:
if (haveIptables) {
- iptablesUnlinkTmpRootChains(iptables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
}
tear_down_tmpebchains:
@@ -3825,13 +3808,17 @@ ebiptablesTearNewRules(virConnectPtr con
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (iptables_cmd_path) {
- iptablesUnlinkTmpRootChains(iptables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
}
if (ip6tables_cmd_path) {
- iptablesUnlinkTmpRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesRemoveTmpRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkTmpRootChains(&buf, ifname);
+ iptablesRemoveTmpRootChains(&buf, ifname);
}
if (ebtables_cmd_path) {
@@ -3860,18 +3847,22 @@ ebiptablesTearOldRules(virConnectPtr con
/* switch to new iptables user defined chains */
if (iptables_cmd_path) {
- iptablesUnlinkRootChains(iptables_cmd_path, &buf, ifname);
- iptablesRemoveRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkRootChains(&buf, ifname);
+ iptablesRemoveRootChains(&buf, ifname);
- iptablesRenameTmpRootChains(iptables_cmd_path, &buf, ifname);
+ iptablesRenameTmpRootChains(&buf, ifname);
ebiptablesExecCLI(&buf, &cli_status, NULL);
}
if (ip6tables_cmd_path) {
- iptablesUnlinkRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesRemoveRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
- iptablesRenameTmpRootChains(ip6tables_cmd_path, &buf, ifname);
+ iptablesUnlinkRootChains(&buf, ifname);
+ iptablesRemoveRootChains(&buf, ifname);
+
+ iptablesRenameTmpRootChains(&buf, ifname);
ebiptablesExecCLI(&buf, &cli_status, NULL);
}
@@ -3958,15 +3949,19 @@ ebiptablesAllTeardown(const char *ifname
int cli_status;
if (iptables_cmd_path) {
- iptablesUnlinkRootChains(iptables_cmd_path, &buf, ifname);
- iptablesClearVirtInPost (iptables_cmd_path, &buf, ifname);
- iptablesRemoveRootChains(iptables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkRootChains(&buf, ifname);
+ iptablesClearVirtInPost (&buf, ifname);
+ iptablesRemoveRootChains(&buf, ifname);
}
if (ip6tables_cmd_path) {
- iptablesUnlinkRootChains(ip6tables_cmd_path, &buf, ifname);
- iptablesClearVirtInPost (ip6tables_cmd_path, &buf, ifname);
- iptablesRemoveRootChains(ip6tables_cmd_path, &buf, ifname);
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
+ iptablesUnlinkRootChains(&buf, ifname);
+ iptablesClearVirtInPost (&buf, ifname);
+ iptablesRemoveRootChains(&buf, ifname);
}
if (ebtables_cmd_path) {
@@ -4041,11 +4036,12 @@ ebiptablesDriverInit(bool privileged)
iptables_cmd_path = virFindFileInPath("iptables");
if (iptables_cmd_path) {
+ NWFILTER_SET_IPTABLES_SHELLVAR(&buf);
+
virBufferAsprintf(&buf,
- CMD_DEF("%s -n -L FORWARD") CMD_SEPARATOR
+ CMD_DEF("$IPT -n -L FORWARD") CMD_SEPARATOR
CMD_EXEC
"%s",
- iptables_cmd_path,
CMD_STOPONERR(1));
if (ebiptablesExecCLI(&buf, &cli_status, NULL) || cli_status)
@@ -4054,11 +4050,12 @@ ebiptablesDriverInit(bool privileged)
ip6tables_cmd_path = virFindFileInPath("ip6tables");
if (ip6tables_cmd_path) {
+ NWFILTER_SET_IP6TABLES_SHELLVAR(&buf);
+
virBufferAsprintf(&buf,
- CMD_DEF("%s -n -L FORWARD") CMD_SEPARATOR
+ CMD_DEF("$IPT -n -L FORWARD") CMD_SEPARATOR
CMD_EXEC
"%s",
- ip6tables_cmd_path,
CMD_STOPONERR(1));
if (ebiptablesExecCLI(&buf, &cli_status, NULL) || cli_status)
2
1
[libvirt] [PATCH 1/2] nwfilter: use shell variable to invoke 'ebtables' command
by Stefan Berger 21 Nov '11
by Stefan Berger 21 Nov '11
21 Nov '11
Introduce a shell variable 'EBT' to invoke the ebtables command.
Hard-code the used ebtables table to '-t nat'.
Tested with libvirt-tck.
---
src/nwfilter/nwfilter_ebiptables_driver.c | 170 +++++++++++++++++-------------
1 file changed, 97 insertions(+), 73 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -46,7 +46,6 @@
#define VIR_FROM_THIS VIR_FROM_NWFILTER
-#define EBTABLES_DEFAULT_TABLE "nat"
#define EBTABLES_CHAIN_INCOMING "PREROUTING"
#define EBTABLES_CHAIN_OUTGOING "POSTROUTING"
@@ -86,7 +85,6 @@ static char *ip6tables_cmd_path;
static char *grep_cmd_path;
static char *gawk_cmd_path;
-
#define PRINT_ROOT_CHAIN(buf, prefix, ifname) \
snprintf(buf, sizeof(buf), "libvirt-%c-%s", prefix, ifname)
#define PRINT_CHAIN(buf, prefix, ifname, suffix) \
@@ -110,7 +108,7 @@ static const char ebtables_script_func_c
"collect_chains()\n"
"{\n"
" for tmp2 in $*; do\n"
- " for tmp in $(%s -t %s -L $tmp2 | \\\n"
+ " for tmp in $($EBT -t nat -L $tmp2 | \\\n"
" sed -n \"/Bridge chain/,\\$ s/.*-j \\\\([%s]-.*\\\\)/\\\\1/p\");\n"
" do\n"
" echo $tmp\n"
@@ -122,8 +120,8 @@ static const char ebtables_script_func_c
static const char ebiptables_script_func_rm_chains[] =
"rm_chains()\n"
"{\n"
- " for tmp in $*; do %s -t %s -F $tmp; done\n"
- " for tmp in $*; do %s -t %s -X $tmp; done\n"
+ " for tmp in $*; do $EBT -t nat -F $tmp; done\n"
+ " for tmp in $*; do $EBT -t nat -X $tmp; done\n"
"}\n";
static const char ebiptables_script_func_rename_chains[] =
@@ -131,8 +129,8 @@ static const char ebiptables_script_func
"{\n"
" for tmp in $*; do\n"
" case $tmp in\n"
- " %c*) %s -t %s -E $tmp %c${tmp#?} ;;\n"
- " %c*) %s -t %s -E $tmp %c${tmp#?} ;;\n"
+ " %c*) $EBT -t nat -E $tmp %c${tmp#?} ;;\n"
+ " %c*) $EBT -t nat -E $tmp %c${tmp#?} ;;\n"
" esac\n"
" done\n"
"}\n";
@@ -146,6 +144,9 @@ static const char ebiptables_script_set_
#define NWFILTER_FUNC_RENAME_CHAINS ebiptables_script_func_rename_chains
#define NWFILTER_FUNC_SET_IFS ebiptables_script_set_ifs
+#define NWFILTER_SET_EBTABLES_SHELLVAR(BUFPTR) \
+ virBufferAsprintf(BUFPTR, "EBT=%s\n", ebtables_cmd_path);
+
#define VIRT_IN_CHAIN "libvirt-in"
#define VIRT_OUT_CHAIN "libvirt-out"
#define VIRT_IN_POST_CHAIN "libvirt-in-post"
@@ -1990,9 +1991,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
-
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
vars,
@@ -2015,8 +2015,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_VLAN:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
@@ -2082,8 +2082,8 @@ ebtablesCreateRuleInstance(char chainPre
}
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
@@ -2120,8 +2120,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_RARP:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
vars,
@@ -2229,8 +2229,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_IP:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
vars,
@@ -2365,8 +2365,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
if (ebtablesHandleEthHdr(&buf,
vars,
@@ -2489,8 +2489,8 @@ ebtablesCreateRuleInstance(char chainPre
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
virBufferAsprintf(&buf,
- CMD_DEF_PRE "%s -t %s -%%c %s %%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ CMD_DEF_PRE "$EBT -t nat -%%c %s %%s",
+ chain);
break;
default:
@@ -2757,10 +2757,10 @@ ebtablesCreateTmpRootChain(virBufferPtr
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -N %s") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
+ chain,
CMD_STOPONERR(stopOnError));
return 0;
@@ -2780,10 +2780,9 @@ ebtablesLinkTmpRootChain(virBufferPtr bu
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- CMD_DEF("%s -t %s -A %s -%c %s -j %s") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -%c %s -j %s") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
(incoming) ? EBTABLES_CHAIN_INCOMING
: EBTABLES_CHAIN_OUTGOING,
iodev, ifname, chain,
@@ -2811,10 +2810,10 @@ _ebtablesRemoveRootChain(virBufferPtr bu
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- "%s -t %s -F %s" CMD_SEPARATOR
- "%s -t %s -X %s" CMD_SEPARATOR,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain);
+ "$EBT -t nat -F %s" CMD_SEPARATOR
+ "$EBT -t nat -X %s" CMD_SEPARATOR,
+ chain,
+ chain);
return 0;
}
@@ -2856,8 +2855,7 @@ _ebtablesUnlinkRootChain(virBufferPtr bu
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(buf,
- "%s -t %s -D %s -%c %s -j %s" CMD_SEPARATOR,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
+ "$EBT -t nat -D %s -%c %s -j %s" CMD_SEPARATOR,
(incoming) ? EBTABLES_CHAIN_INCOMING
: EBTABLES_CHAIN_OUTGOING,
iodev, ifname, chain);
@@ -2917,25 +2915,24 @@ ebtablesCreateTmpSubChain(ebiptablesRule
}
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -F %s") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -F %s") CMD_SEPARATOR
CMD_EXEC
- CMD_DEF("%s -t %s -X %s") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -X %s") CMD_SEPARATOR
CMD_EXEC
- CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -N %s") CMD_SEPARATOR
CMD_EXEC
"%s"
- CMD_DEF("%s -t %s -%%c %s %%s %s -j %s")
+ CMD_DEF("$EBT -t nat -%%c %s %%s %s -j %s")
CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
+ chain,
+ chain,
+ chain,
CMD_STOPONERR(stopOnError),
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
rootchain, protostr, chain,
CMD_STOPONERR(stopOnError));
@@ -2967,11 +2964,11 @@ _ebtablesRemoveSubChains(virBufferPtr bu
char rootchain[MAX_CHAINNAME_LENGTH];
unsigned i;
+ NWFILTER_SET_EBTABLES_SHELLVAR(buf);
+
virBufferAsprintf(buf, NWFILTER_FUNC_COLLECT_CHAINS,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chains);
- virBufferAsprintf(buf, NWFILTER_FUNC_RM_CHAINS,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE);
+ chains);
+ virBufferAdd(buf, NWFILTER_FUNC_RM_CHAINS, -1);
virBufferAsprintf(buf, NWFILTER_FUNC_SET_IFS);
virBufferAddLit(buf, "chains=\"$(collect_chains");
@@ -2984,8 +2981,7 @@ _ebtablesRemoveSubChains(virBufferPtr bu
for (i = 0; chains[i] != 0; i++) {
PRINT_ROOT_CHAIN(rootchain, chains[i], ifname);
virBufferAsprintf(buf,
- "%s -t %s -F %s\n",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
+ "$EBT -t nat -F %s\n",
rootchain);
}
virBufferAddLit(buf, "rm_chains $chains\n");
@@ -3040,8 +3036,8 @@ ebtablesRenameTmpSubChain(virBufferPtr b
}
virBufferAsprintf(buf,
- "%s -t %s -E %s %s" CMD_SEPARATOR,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, tmpchain, chain);
+ "$EBT -t nat -E %s %s" CMD_SEPARATOR,
+ tmpchain, chain);
return 0;
}
@@ -3064,14 +3060,14 @@ ebtablesRenameTmpSubAndRootChains(virBuf
CHAINPREFIX_HOST_OUT_TEMP,
0};
+ NWFILTER_SET_EBTABLES_SHELLVAR(buf);
+
virBufferAsprintf(buf, NWFILTER_FUNC_COLLECT_CHAINS,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chains);
+ chains);
virBufferAsprintf(buf, NWFILTER_FUNC_RENAME_CHAINS,
CHAINPREFIX_HOST_IN_TEMP,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
CHAINPREFIX_HOST_IN,
CHAINPREFIX_HOST_OUT_TEMP,
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
CHAINPREFIX_HOST_OUT);
virBufferAsprintf(buf, NWFILTER_FUNC_SET_IFS);
@@ -3151,40 +3147,41 @@ ebtablesApplyBasicRules(const char *ifna
ebiptablesAllTeardown(ifname);
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
PRINT_ROOT_CHAIN(chain, chainPrefix, ifname);
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -s ! %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -s ! %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
chain, macaddr_str,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -p IPv4 -j ACCEPT") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
+ chain,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -p ARP -j ACCEPT") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -p ARP -j ACCEPT") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
+ chain,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
+ chain,
CMD_STOPONERR(1));
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
@@ -3250,6 +3247,8 @@ ebtablesApplyDHCPOnlyRules(const char *i
ebiptablesAllTeardown(ifname);
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
@@ -3257,7 +3256,7 @@ ebtablesApplyDHCPOnlyRules(const char *i
PRINT_ROOT_CHAIN(chain_out, CHAINPREFIX_HOST_OUT_TEMP, ifname);
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s"
+ CMD_DEF("$EBT -t nat -A %s"
" -s %s -d Broadcast "
" -p ipv4 --ip-protocol udp"
" --ip-src 0.0.0.0 --ip-dst 255.255.255.255"
@@ -3266,20 +3265,20 @@ ebtablesApplyDHCPOnlyRules(const char *i
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_in,
+ chain_in,
macaddr_str,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_in,
+ chain_in,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s"
+ CMD_DEF("$EBT -t nat -A %s"
" -d %s"
" -p ipv4 --ip-protocol udp"
" %s"
@@ -3288,17 +3287,17 @@ ebtablesApplyDHCPOnlyRules(const char *i
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_out,
+ chain_out,
macaddr_str,
srcIPParam != NULL ? srcIPParam : "",
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_out,
+ chain_out,
CMD_STOPONERR(1));
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
@@ -3352,6 +3351,8 @@ ebtablesApplyDropAllRules(const char *if
ebiptablesAllTeardown(ifname);
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
@@ -3359,19 +3360,19 @@ ebtablesApplyDropAllRules(const char *if
PRINT_ROOT_CHAIN(chain_out, CHAINPREFIX_HOST_OUT_TEMP, ifname);
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_in,
+ chain_in,
CMD_STOPONERR(1));
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -A %s -j DROP") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_out,
+ chain_out,
CMD_STOPONERR(1));
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
@@ -3410,6 +3411,8 @@ static int ebtablesCleanAll(const char *
if (!ebtables_cmd_path)
return 0;
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkRootChain(&buf, 1, ifname);
ebtablesUnlinkRootChain(&buf, 0, ifname);
ebtablesRemoveSubChains(&buf, ifname);
@@ -3611,8 +3614,11 @@ ebiptablesApplyNewRules(virConnectPtr co
}
}
+
/* cleanup whatever may exist */
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
ebtablesRemoveTmpSubChains(&buf, ifname);
@@ -3621,6 +3627,8 @@ ebiptablesApplyNewRules(virConnectPtr co
ebiptablesExecCLI(&buf, &cli_status, NULL);
}
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
/* create needed chains */
if (ebtablesCreateTmpRootAndSubChains(&buf, ifname, chains_in_set , 1,
&ebtChains, &nEbtChains) ||
@@ -3636,6 +3644,8 @@ ebiptablesApplyNewRules(virConnectPtr co
if (ebiptablesExecCLI(&buf, &cli_status, &errmsg) || cli_status != 0)
goto tear_down_tmpebchains;
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
/* process ebtables commands; interleave commands from filters with
commands for creating and connecting ebtables chains */
j = 0;
@@ -3735,6 +3745,8 @@ ebiptablesApplyNewRules(virConnectPtr co
iptablesCheckBridgeNFCallEnabled(true);
}
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
if (virHashSize(chains_in_set) != 0)
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
if (virHashSize(chains_out_set) != 0)
@@ -3756,6 +3768,8 @@ ebiptablesApplyNewRules(virConnectPtr co
tear_down_ebsubchains_and_unlink:
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
}
@@ -3774,6 +3788,8 @@ tear_down_tmpiptchains:
tear_down_tmpebchains:
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesRemoveTmpSubChains(&buf, ifname);
ebtablesRemoveTmpRootChain(&buf, 1, ifname);
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
@@ -3819,6 +3835,8 @@ ebiptablesTearNewRules(virConnectPtr con
}
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
@@ -3858,6 +3876,8 @@ ebiptablesTearOldRules(virConnectPtr con
}
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkRootChain(&buf, 1, ifname);
ebtablesUnlinkRootChain(&buf, 0, ifname);
@@ -3899,6 +3919,8 @@ ebiptablesRemoveRules(virConnectPtr conn
virBuffer buf = VIR_BUFFER_INITIALIZER;
ebiptablesRuleInstPtr *inst = (ebiptablesRuleInstPtr *)_inst;
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
for (i = 0; i < nruleInstances; i++)
ebiptablesInstCommand(&buf,
inst[i]->commandTemplate,
@@ -3948,6 +3970,8 @@ ebiptablesAllTeardown(const char *ifname
}
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
+
ebtablesUnlinkRootChain(&buf, 1, ifname);
ebtablesUnlinkRootChain(&buf, 0, ifname);
@@ -4003,12 +4027,12 @@ ebiptablesDriverInit(bool privileged)
ebtables_cmd_path = virFindFileInPath("ebtables");
if (ebtables_cmd_path) {
+ NWFILTER_SET_EBTABLES_SHELLVAR(&buf);
/* basic probing */
virBufferAsprintf(&buf,
- CMD_DEF("%s -t %s -L") CMD_SEPARATOR
+ CMD_DEF("$EBT -t nat -L") CMD_SEPARATOR
CMD_EXEC
"%s",
- ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
CMD_STOPONERR(1));
if (ebiptablesExecCLI(&buf, &cli_status, NULL) || cli_status)
2
1
21 Nov '11
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
libvirt-gobject/libvirt-gobject-domain.c | 65 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 3 +
libvirt-gobject/libvirt-gobject.sym | 1 +
3 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 1fa27bd..7121a21 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -449,6 +449,71 @@ GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
return conf;
}
+/**
+ * gvir_domain_set_config:
+ * @domain: the domain
+ * @conf: the new configuration for the domain
+ * @err: (allow-none): Place-holder for error or NULL
+ *
+ * Resets configuration of an existing domain.
+ *
+ * Note: If domain is already running, the new configuration will not take
+ * affect until domain reboots.
+ *
+ * Returns: TRUE on success, FALSE if an error occurred.
+ */
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err)
+{
+ const gchar *xml;
+ virConnectPtr conn;
+ virDomainPtr handle;
+ gchar uuid[VIR_UUID_STRING_BUFLEN];
+ GVirDomainPrivate *priv = domain->priv;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN (domain), FALSE);
+ g_return_val_if_fail(GVIR_IS_CONFIG_DOMAIN (conf), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
+
+ g_return_val_if_fail(xml != NULL, FALSE);
+
+ if ((conn = virDomainGetConnect(priv->handle)) == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to get domain connection");
+ return FALSE;
+ }
+
+ handle = virDomainDefineXML(conn, xml);
+
+ if (handle == NULL) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+ return FALSE;
+ }
+
+ virDomainGetUUIDString(handle, uuid);
+ virDomainFree(handle);
+
+ if (g_strcmp0 (uuid, priv->uuid) != 0) {
+ if (err != NULL)
+ *err = gvir_error_new_literal(GVIR_DOMAIN_ERROR,
+ 0,
+ "Failed to set "
+ "domain configuration");
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
/**
* gvir_domain_get_info:
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 94bd53e..0479de8 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -123,6 +123,9 @@ GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
guint64 flags,
GError **err);
+gboolean gvir_domain_set_config(GVirDomain *domain,
+ GVirConfigDomain *conf,
+ GError **err);
gchar *gvir_domain_screenshot(GVirDomain *dom,
GVirStream *stream,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 164b6b8..46c53f9 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -53,6 +53,7 @@ LIBVIRT_GOBJECT_0.0.1 {
gvir_domain_shutdown;
gvir_domain_reboot;
gvir_domain_get_config;
+ gvir_domain_set_config;
gvir_domain_get_info;
gvir_domain_screenshot;
--
1.7.7.1
1
0