[openstack-nova] Updated patches from master-patches

Pádraig Brady pbrady at fedoraproject.org
Fri Mar 2 15:40:26 UTC 2012


commit 80cbbe245c38e1bd6f9d5fbb4c8548c69bfe3800
Author: Pádraig Brady <P at draigBrady.com>
Date:   Fri Mar 2 15:37:58 2012 +0000

    Updated patches from master-patches

 ...e-don-t-access-the-net-when-building-docs.patch |    2 +-
 ...-interface-drivers-for-the-Linux-Bridge-p.patch |  195 ++++++++++++++++++++
 0003-Adds-soft-reboot-support-to-libvirt.patch     |  171 +++++++++++++++++
 openstack-nova.spec                                |    4 +
 4 files changed, 371 insertions(+), 1 deletions(-)
---
diff --git a/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch b/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
index 4d6dd3e..71f6bca 100644
--- a/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
+++ b/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
@@ -1,4 +1,4 @@
-From 001a6b44c152b2594b79ea005c2afba41be4054a Mon Sep 17 00:00:00 2001
+From 8a88224a8f00d264fd92548d4fe444906b24b47c Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <pbrady at redhat.com>
 Date: Fri, 6 Jan 2012 12:16:34 +0000
 Subject: [PATCH] Ensure we don't access the net when building docs
diff --git a/0002-Add-VIF-and-interface-drivers-for-the-Linux-Bridge-p.patch b/0002-Add-VIF-and-interface-drivers-for-the-Linux-Bridge-p.patch
new file mode 100644
index 0000000..0c14492
--- /dev/null
+++ b/0002-Add-VIF-and-interface-drivers-for-the-Linux-Bridge-p.patch
@@ -0,0 +1,195 @@
+From 7fb880b4db992f28a27cc18ea478338174fda93a Mon Sep 17 00:00:00 2001
+From: Sumit Naiksatam <snaiksat at cisco.com>
+Date: Mon, 27 Feb 2012 00:26:14 -0800
+Subject: [PATCH] Add VIF and interface drivers for the Linux Bridge plugin
+
+Fixes bug #941794
+Drivers have been reviewed earlier by Quantum reviewers and are being
+moved here on their request.
+
+Change-Id: If04807c473542e2f0259faa6d243c3e6e9539f64
+---
+ Authors                        |    1 +
+ nova/network/linux_net.py      |   82 ++++++++++++++++++++++++++++++++++++++++
+ nova/tests/test_libvirt_vif.py |   22 ++++++++++-
+ nova/virt/libvirt/vif.py       |   29 ++++++++++++++
+ 4 files changed, 133 insertions(+), 1 deletions(-)
+
+diff --git a/Authors b/Authors
+index 06416bf..f435fe1 100644
+--- a/Authors
++++ b/Authors
+@@ -162,6 +162,7 @@ Scott Moser <smoser at ubuntu.com>
+ Soren Hansen <soren.hansen at rackspace.com>
+ Stanislaw Pitucha <stanislaw.pitucha at hp.com>
+ Stephanie Reese <reese.sm at gmail.com>
++Sumit Naiksatam <snaiksat at cisco.com>
+ Thierry Carrez <thierry at openstack.org>
+ Tim Simpson <tim.simpson at rackspace.com>
+ Todd Willey <todd at ansolabs.com>
+diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
+index 46d2aad..4a8328a 100755
+--- a/nova/network/linux_net.py
++++ b/nova/network/linux_net.py
+@@ -1124,5 +1124,87 @@ class LinuxOVSInterfaceDriver(LinuxNetInterfaceDriver):
+         dev = "gw-" + str(network['uuid'][0:11])
+         return dev
+ 
++
++# plugs interfaces using Linux Bridge when using QuantumManager
++class QuantumLinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
++
++    BRIDGE_NAME_PREFIX = "brq"
++    GATEWAY_INTERFACE_PREFIX = "gw-"
++
++    def plug(self, network, mac_address, gateway=True):
++        dev = self.get_dev(network)
++        bridge = self.get_bridge(network)
++        if not gateway:
++            # If we weren't instructed to act as a gateway then add the
++            # appropriate flows to block all non-dhcp traffic.
++            # .. and make sure iptbles won't forward it as well.
++            iptables_manager.ipv4['filter'].add_rule('FORWARD',
++                    '--in-interface %s -j DROP' % bridge)
++            iptables_manager.ipv4['filter'].add_rule('FORWARD',
++                    '--out-interface %s -j DROP' % bridge)
++            return bridge
++        else:
++            iptables_manager.ipv4['filter'].add_rule('FORWARD',
++                    '--in-interface %s -j ACCEPT' % bridge)
++            iptables_manager.ipv4['filter'].add_rule('FORWARD',
++                    '--out-interface %s -j ACCEPT' % bridge)
++
++        QuantumLinuxBridgeInterfaceDriver.create_tap_dev(dev, mac_address)
++
++        if not _device_exists(bridge):
++            LOG.debug(_("Starting bridge %s "), bridge)
++            utils.execute('brctl', 'addbr', bridge, run_as_root=True)
++            utils.execute('brctl', 'setfd', bridge, str(0), run_as_root=True)
++            utils.execute('brctl', 'stp', bridge, 'off', run_as_root=True)
++            utils.execute('ip', 'link', 'set', bridge, "address", mac_address,
++                          run_as_root=True)
++            utils.execute('ip', 'link', 'set', bridge, 'up', run_as_root=True)
++            LOG.debug(_("Done starting bridge %s"), bridge)
++
++        full_ip = '%s/%s' % (network['dhcp_server'],
++                             network['cidr'].rpartition('/')[2])
++        utils.execute('ip', 'address', 'add', full_ip, 'dev', bridge,
++                run_as_root=True)
++
++        return dev
++
++    def unplug(self, network):
++        dev = self.get_dev(network)
++
++        if not _device_exists(dev):
++            return None
++        else:
++            try:
++                utils.execute('ip', 'link', 'delete', dev, run_as_root=True)
++            except exception.ProcessExecutionError:
++                LOG.warning(_("Failed unplugging gateway interface '%s'"),
++                            dev)
++                raise
++            LOG.debug(_("Unplugged gateway interface '%s'"), dev)
++            return dev
++
++    @classmethod
++    def create_tap_dev(_self, dev, mac_address=None):
++        if not _device_exists(dev):
++            try:
++                # First, try with 'ip'
++                utils.execute('ip', 'tuntap', 'add', dev, 'mode', 'tap',
++                          run_as_root=True)
++            except exception.ProcessExecutionError:
++                # Second option: tunctl
++                utils.execute('tunctl', '-b', '-t', dev, run_as_root=True)
++            if mac_address:
++                utils.execute('ip', 'link', 'set', dev, "address", mac_address,
++                              run_as_root=True)
++            utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True)
++
++    def get_dev(self, network):
++        dev = self.GATEWAY_INTERFACE_PREFIX + str(network['uuid'][0:11])
++        return dev
++
++    def get_bridge(self, network):
++        bridge = self.BRIDGE_NAME_PREFIX + str(network['uuid'][0:11])
++        return bridge
++
+ iptables_manager = IptablesManager()
+ interface_driver = utils.import_object(FLAGS.linuxnet_interface_driver)
+diff --git a/nova/tests/test_libvirt_vif.py b/nova/tests/test_libvirt_vif.py
+index 3f9b8e1..8e0d662 100644
+--- a/nova/tests/test_libvirt_vif.py
++++ b/nova/tests/test_libvirt_vif.py
+@@ -23,7 +23,9 @@ from nova.virt import firewall
+ from nova.virt import vif
+ from nova.virt.libvirt import connection
+ from nova.virt.libvirt.vif import LibvirtBridgeDriver, \
+-                LibvirtOpenVswitchDriver, LibvirtOpenVswitchVirtualPortDriver
++                LibvirtOpenVswitchDriver, \
++                LibvirtOpenVswitchVirtualPortDriver, \
++                QuantumLinuxBridgeVIFDriver
+ 
+ FLAGS = flags.FLAGS
+ 
+@@ -157,3 +159,21 @@ class LibvirtVifTestCase(test.TestCase):
+ 
+         self.assertTrue(iface_id_found)
+         d.unplug(None, self.net, self.mapping)
++
++    def test_quantum_bridge_ethernet_driver(self):
++        d = QuantumLinuxBridgeVIFDriver()
++        xml = self._get_instance_xml(d, 'ethernet')
++
++        doc = ElementTree.fromstring(xml)
++        ret = doc.findall('./devices/interface')
++        self.assertEqual(len(ret), 1)
++        node = ret[0]
++        self.assertEqual(node.get("type"), "ethernet")
++        dev_name = node.find("target").get("dev")
++        self.assertTrue(dev_name.startswith("tap"))
++        mac = node.find("mac").get("address")
++        self.assertEqual(mac, self.mapping['mac'])
++        script = node.find("script").get("path")
++        self.assertEquals(script, "")
++
++        d.unplug(None, self.net, self.mapping)
+diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py
+index 886eea7..a2c946b 100644
+--- a/nova/virt/libvirt/vif.py
++++ b/nova/virt/libvirt/vif.py
+@@ -172,3 +172,32 @@ class LibvirtOpenVswitchVirtualPortDriver(VIFDriver):
+     def unplug(self, instance, network, mapping):
+         """No action needed.  Libvirt takes care of cleanup"""
+         pass
++
++
++class QuantumLinuxBridgeVIFDriver(VIFDriver):
++    """VIF driver for Linux Bridge when running Quantum."""
++
++    def get_dev_name(self, iface_id):
++        return "tap" + iface_id[0:11]
++
++    def plug(self, instance, network, mapping):
++        iface_id = mapping['vif_uuid']
++        dev = self.get_dev_name(iface_id)
++        linux_net.QuantumLinuxBridgeInterfaceDriver.create_tap_dev(dev)
++
++        result = {
++            'script': '',
++            'name': dev,
++            'mac_address': mapping['mac']}
++        return result
++
++    def unplug(self, instance, network, mapping):
++        """Unplug the VIF from the network by deleting the port from
++        the bridge."""
++        dev = self.get_dev_name(mapping['vif_uuid'])
++        try:
++            utils.execute('ip', 'link', 'delete', dev, run_as_root=True)
++        except exception.ProcessExecutionError:
++            LOG.warning(_("Failed while unplugging vif of instance '%s'"),
++                        instance['name'])
++            raise
diff --git a/0003-Adds-soft-reboot-support-to-libvirt.patch b/0003-Adds-soft-reboot-support-to-libvirt.patch
new file mode 100644
index 0000000..a800b62
--- /dev/null
+++ b/0003-Adds-soft-reboot-support-to-libvirt.patch
@@ -0,0 +1,171 @@
+From dd7dd9f3e29670591d2cfd01c22b740f433b1ba1 Mon Sep 17 00:00:00 2001
+From: Vishvananda Ishaya <vishvananda at gmail.com>
+Date: Wed, 29 Feb 2012 17:29:02 -0800
+Subject: [PATCH] Adds soft-reboot support to libvirt
+
+ * Falls back to hard reboot if guest doesn't respond
+ * Cleans up reboot/rescue/unrescue interaction
+ * Fixed fake for tests
+ * Added a force hard reboot test to verify fallback works
+ * Fixes bug 939557
+
+Change-Id: I8d0c9a35725de5e5bfb8f13a2d869c6122ba44ef
+---
+ nova/tests/fakelibvirt.py       |    6 +++-
+ nova/tests/test_virt_drivers.py |    4 ++
+ nova/virt/libvirt/connection.py |   63 ++++++++++++++++++++++++++++++++------
+ 3 files changed, 62 insertions(+), 11 deletions(-)
+
+diff --git a/nova/tests/fakelibvirt.py b/nova/tests/fakelibvirt.py
+index 309a6f1..81f946f 100644
+--- a/nova/tests/fakelibvirt.py
++++ b/nova/tests/fakelibvirt.py
+@@ -288,8 +288,12 @@ class Domain(object):
+     def suspend(self):
+         self._state = VIR_DOMAIN_PAUSED
+ 
++    def shutdown(self):
++        self._state = VIR_DOMAIN_SHUTDOWN
++        self._connection._mark_not_running(self)
++
+     def info(self):
+-        return [VIR_DOMAIN_RUNNING,
++        return [self._state,
+                 long(self._def['memory']),
+                 long(self._def['memory']),
+                 self._def['vcpu'],
+diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py
+index 5b5b7d4..8018008 100644
+--- a/nova/tests/test_virt_drivers.py
++++ b/nova/tests/test_virt_drivers.py
+@@ -476,6 +476,10 @@ class LibvirtConnTestCase(_VirtDriverTestCase):
+             nova.virt.libvirt.firewall.libvirt = self.saved_libvirt
+         super(LibvirtConnTestCase, self).tearDown()
+ 
++    def test_force_hard_reboot(self):
++        self.flags(libvirt_wait_soft_reboot_seconds=0)
++        self.test_reboot()
++
+     @test.skip_test("Test nothing, but this method "
+                     "needed to override superclass.")
+     def test_migrate_disk_and_power_off(self):
+diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
+index 356bcda..d8f1465 100644
+--- a/nova/virt/libvirt/connection.py
++++ b/nova/virt/libvirt/connection.py
+@@ -151,6 +151,11 @@ libvirt_opts = [
+                help='Override the default disk prefix for the devices attached'
+                     ' to a server, which is dependent on libvirt_type. '
+                     '(valid options are: sd, xvd, uvd, vd)'),
++    cfg.IntOpt('libvirt_wait_soft_reboot_seconds',
++               default=120,
++               help='Number of seconds to wait for instance to shut down after'
++                    ' soft reboot request is made. We fall back to hard reboot'
++                    ' if instance does not shutdown within this window.'),
+     ]
+ 
+ FLAGS = flags.FLAGS
+@@ -649,14 +654,55 @@ class LibvirtConnection(driver.ComputeDriver):
+                 snapshot_ptr.delete(0)
+ 
+     @exception.wrap_exception()
+-    def reboot(self, instance, network_info, reboot_type=None, xml=None):
++    def reboot(self, instance, network_info, reboot_type='SOFT'):
++        """Reboot a virtual machine, given an instance reference."""
++        if reboot_type == 'SOFT':
++            # NOTE(vish): This will attempt to do a graceful shutdown/restart.
++            if self._soft_reboot(instance):
++                LOG.info(_("Instance soft rebooted successfully."),
++                         instance=instance)
++                return
++            else:
++                LOG.info(_("Failed to soft reboot instance."),
++                         instance=instance)
++        return self._hard_reboot(instance, network_info)
++
++    def _soft_reboot(self, instance):
++        """Attempt to shutdown and restart the instance gracefully.
++
++        We use shutdown and create here so we can return if the guest
++        responded and actually rebooted. Note that this method only
++        succeeds if the guest responds to acpi. Therefore we return
++        success or failure so we can fall back to a hard reboot if
++        necessary.
++
++        :returns: True if the reboot succeeded
++        """
++        dom = self._lookup_by_name(instance.name)
++        dom.shutdown()
++        # NOTE(vish): This actually could take slighty longer than the
++        #             FLAG defines depending on how long the get_info
++        #             call takes to return.
++        for x in xrange(FLAGS.libvirt_wait_soft_reboot_seconds):
++            state = self.get_info(instance)['state']
++            if state == power_state.SHUTDOWN:
++                LOG.info(_("Instance shutdown successfully."),
++                         instance=instance)
++                dom.create()
++                timer = utils.LoopingCall(self._wait_for_running, instance)
++                return timer.start(interval=0.5, now=True)
++            greenthread.sleep(1)
++        return False
++
++    def _hard_reboot(self, instance, network_info, xml=None):
+         """Reboot a virtual machine, given an instance reference.
+ 
+         This method actually destroys and re-creates the domain to ensure the
+         reboot happens, as the guest OS cannot ignore this action.
+ 
++        If xml is set, it uses the passed in xml in place of the xml from the
++        existing domain.
+         """
+-
+         virt_dom = self._conn.lookupByName(instance['name'])
+         # NOTE(itoumsn): Use XML delived from the running instance
+         # instead of using to_xml(instance, network_info). This is almost
+@@ -664,9 +710,6 @@ class LibvirtConnection(driver.ComputeDriver):
+         if not xml:
+             xml = virt_dom.XMLDesc(0)
+ 
+-        # NOTE(itoumsn): self.shutdown() and wait instead of self.destroy() is
+-        # better because we cannot ensure flushing dirty buffers
+-        # in the guest OS. But, in case of KVM, shutdown() does not work...
+         self._destroy(instance, network_info, cleanup=False)
+         self.unplug_vifs(instance, network_info)
+         self.plug_vifs(instance, network_info)
+@@ -742,7 +785,7 @@ class LibvirtConnection(driver.ComputeDriver):
+         }
+         self._create_image(context, instance, xml, '.rescue', rescue_images,
+                            network_info=network_info)
+-        self.reboot(instance, network_info, xml=xml)
++        self._hard_reboot(instance, network_info, xml=xml)
+ 
+     @exception.wrap_exception()
+     def unrescue(self, instance, network_info):
+@@ -755,9 +798,9 @@ class LibvirtConnection(driver.ComputeDriver):
+         unrescue_xml_path = os.path.join(FLAGS.instances_path,
+                                          instance['name'],
+                                          'unrescue.xml')
+-        unrescue_xml = libvirt_utils.load_file(unrescue_xml_path)
++        xml = libvirt_utils.load_file(unrescue_xml_path)
+         libvirt_utils.file_delete(unrescue_xml_path)
+-        self.reboot(instance, network_info, xml=unrescue_xml)
++        self._hard_reboot(instance, network_info, xml=xml)
+         rescue_files = os.path.join(FLAGS.instances_path, instance['name'],
+                                     "*.rescue")
+         for rescue_file in glob.iglob(rescue_files):
+@@ -2196,12 +2239,12 @@ class LibvirtConnection(driver.ComputeDriver):
+         except exception.NotFound:
+             LOG.error(_("During wait running, instance disappeared."),
+                       instance=instance)
+-            raise utils.LoopingCallDone
++            raise utils.LoopingCallDone(False)
+ 
+         if state == power_state.RUNNING:
+             LOG.info(_("Instance running successfully."),
+                      instance=instance)
+-            raise utils.LoopingCallDone
++            raise utils.LoopingCallDone(True)
+ 
+     @exception.wrap_exception()
+     def finish_migration(self, context, migration, instance, disk_info,
diff --git a/openstack-nova.spec b/openstack-nova.spec
index d896f83..61019c8 100644
--- a/openstack-nova.spec
+++ b/openstack-nova.spec
@@ -35,6 +35,8 @@ Source23:         openstack-nova-db-setup
 # patches_base=essex-4
 #
 Patch0001: 0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
+Patch0002: 0002-Add-VIF-and-interface-drivers-for-the-Linux-Bridge-p.patch
+Patch0003: 0003-Adds-soft-reboot-support-to-libvirt.patch
 
 BuildArch:        noarch
 BuildRequires:    intltool
@@ -170,6 +172,8 @@ This package contains documentation files for nova.
 %setup -q -n nova-%{version}
 
 %patch0001 -p1
+%patch0002 -p1
+%patch0003 -p1
 
 find . \( -name .gitignore -o -name .placeholder \) -delete
 


More information about the scm-commits mailing list