Merge lp:~racb/nova/868349 into lp:~ubuntu-server-dev/nova/diablo

Proposed by Robie Basak
Status: Merged
Merge reported by: James Page
Merged at revision: not available
Proposed branch: lp:~racb/nova/868349
Merge into: lp:~ubuntu-server-dev/nova/diablo
Diff against target: 250 lines (+49/-46)
2 files modified
debian/changelog (+7/-0)
debian/patches/backport-libvirt-console-pipe.patch (+42/-46)
To merge this branch: bzr merge lp:~racb/nova/868349
Reviewer Review Type Date Requested Status
James Page Approve
Review via email: mp+78284@code.launchpad.net

Description of the change

  * debian/patches/backport-libvirt-console-pipe.patch:
    - Patch updated to fix race on instance termination (LP: #868349)

To post a comment you must log in.
Revision history for this message
James Page (james-page) wrote :

LGTM - tested on local all-in-one deployment and resolves the original bug report.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2011-10-04 09:50:31 +0000
+++ debian/changelog 2011-10-05 16:48:18 +0000
@@ -1,3 +1,10 @@
1nova (2011.3-0ubuntu6) oneiric; urgency=low
2
3 * debian/patches/backport-libvirt-console-pipe.patch:
4 - Patch updated to fix race on instance termination (LP: #868349)
5
6 -- Robie Basak <robie.basak@ubuntu.com> Wed, 05 Oct 2011 17:37:49 +0100
7
1nova (2011.3-0ubuntu5) oneiric; urgency=low8nova (2011.3-0ubuntu5) oneiric; urgency=low
29
3 * debian/nova-common.postinst:10 * debian/nova-common.postinst:
411
=== modified file 'debian/patches/backport-libvirt-console-pipe.patch'
--- debian/patches/backport-libvirt-console-pipe.patch 2011-09-30 14:22:57 +0000
+++ debian/patches/backport-libvirt-console-pipe.patch 2011-10-05 16:48:18 +0000
@@ -1,10 +1,9 @@
1Description: Move console.log to a ringbuffer1Description: Move console.log to a ringbuffer
2Author: Robie Basak <robie.basak@canonical.com>2Author: Robie Basak <robie.basak@canonical.com>
3Status: https://review.openstack.org/#change,7063Status: https://review.openstack.org/#change,706
4diff -Naupr nova-2011.3.orig//Authors nova-2011.3//Authors4--- a/Authors
5--- nova-2011.3.orig//Authors 2011-09-22 08:02:23.000000000 -04005+++ b/Authors
6+++ nova-2011.3//Authors 2011-09-30 10:14:45.375607481 -04006@@ -95,6 +95,7 @@
7@@ -95,6 +95,7 @@ Ricardo Carrillo Cruz <emaildericky@gmai
8 Rick Clark <rick@openstack.org>7 Rick Clark <rick@openstack.org>
9 Rick Harris <rconradharris@gmail.com>8 Rick Harris <rconradharris@gmail.com>
10 Rob Kost <kost@isi.edu>9 Rob Kost <kost@isi.edu>
@@ -12,10 +11,9 @@
12 Ryan Lane <rlane@wikimedia.org>11 Ryan Lane <rlane@wikimedia.org>
13 Ryan Lucio <rlucio@internap.com>12 Ryan Lucio <rlucio@internap.com>
14 Ryu Ishimoto <ryu@midokura.jp>13 Ryu Ishimoto <ryu@midokura.jp>
15diff -Naupr nova-2011.3.orig//nova/tests/test_libvirt.py nova-2011.3//nova/tests/test_libvirt.py14--- a/nova/tests/test_libvirt.py
16--- nova-2011.3.orig//nova/tests/test_libvirt.py 2011-09-22 08:02:23.000000000 -040015+++ b/nova/tests/test_libvirt.py
17+++ nova-2011.3//nova/tests/test_libvirt.py 2011-09-30 10:14:45.379607485 -040016@@ -565,7 +565,7 @@
18@@ -565,7 +565,7 @@ class LibvirtConnTestCase(test.TestCase)
19 (lambda t: t.findall(parameter)[1].get('name'), 'DHCPSERVER'),17 (lambda t: t.findall(parameter)[1].get('name'), 'DHCPSERVER'),
20 (lambda t: t.findall(parameter)[1].get('value'), '10.0.0.1'),18 (lambda t: t.findall(parameter)[1].get('value'), '10.0.0.1'),
21 (lambda t: t.find('./devices/serial/source').get(19 (lambda t: t.find('./devices/serial/source').get(
@@ -24,7 +22,7 @@
24 (lambda t: t.find('./memory').text, '2097152')]22 (lambda t: t.find('./memory').text, '2097152')]
25 if rescue:23 if rescue:
26 common_checks += [24 common_checks += [
27@@ -1494,3 +1494,54 @@ class NWFilterTestCase(test.TestCase):25@@ -1501,3 +1501,54 @@
28 self.assertEqual(original_filter_count - len(fakefilter.filters), 2)26 self.assertEqual(original_filter_count - len(fakefilter.filters), 2)
29 27
30 db.instance_destroy(admin_ctxt, instance_ref['id'])28 db.instance_destroy(admin_ctxt, instance_ref['id'])
@@ -79,9 +77,8 @@
79+ os.unlink(self.ringbuffer_path)77+ os.unlink(self.ringbuffer_path)
80+ os.unlink(self.fifo_path)78+ os.unlink(self.fifo_path)
81+ os.rmdir(self.directory_path)79+ os.rmdir(self.directory_path)
82diff -Naupr nova-2011.3.orig//nova/tests/test_utils.py nova-2011.3//nova/tests/test_utils.py80--- a/nova/tests/test_utils.py
83--- nova-2011.3.orig//nova/tests/test_utils.py 2011-09-22 08:02:23.000000000 -040081+++ b/nova/tests/test_utils.py
84+++ nova-2011.3//nova/tests/test_utils.py 2011-09-30 10:14:45.379607485 -0400
85@@ -15,9 +15,12 @@82@@ -15,9 +15,12 @@
86 # under the License.83 # under the License.
87 84
@@ -95,7 +92,7 @@
95 import nova92 import nova
96 from nova import exception93 from nova import exception
97 from nova import test94 from nova import test
98@@ -439,3 +442,55 @@ class MonkeyPatchTestCase(test.TestCase)95@@ -439,3 +442,55 @@
99 in nova.tests.monkey_patch_example.CALLED_FUNCTION)96 in nova.tests.monkey_patch_example.CALLED_FUNCTION)
100 self.assertFalse(package_b + 'ExampleClassB.example_method_add'97 self.assertFalse(package_b + 'ExampleClassB.example_method_add'
101 in nova.tests.monkey_patch_example.CALLED_FUNCTION)98 in nova.tests.monkey_patch_example.CALLED_FUNCTION)
@@ -151,10 +148,9 @@
151+ yield check_buffer, r, expected148+ yield check_buffer, r, expected
152+ r.close()149+ r.close()
153+ f.close()150+ f.close()
154diff -Naupr nova-2011.3.orig//nova/utils.py nova-2011.3//nova/utils.py151--- a/nova/utils.py
155--- nova-2011.3.orig//nova/utils.py 2011-09-22 08:02:23.000000000 -0400152+++ b/nova/utils.py
156+++ nova-2011.3//nova/utils.py 2011-09-30 10:20:37.823615836 -0400153@@ -26,10 +26,12 @@
157@@ -26,10 +26,12 @@ import json
158 import lockfile154 import lockfile
159 import netaddr155 import netaddr
160 import os156 import os
@@ -167,7 +163,7 @@
167 import struct163 import struct
168 import sys164 import sys
169 import time165 import time
170@@ -49,6 +51,7 @@ from nova import log as logging166@@ -49,6 +51,7 @@
171 from nova import version167 from nova import version
172 168
173 169
@@ -175,7 +171,7 @@
175 LOG = logging.getLogger("nova.utils")171 LOG = logging.getLogger("nova.utils")
176 ISO_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"172 ISO_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
177 PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"173 PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
178@@ -910,3 +913,132 @@ def convert_to_list_dict(lst, label):174@@ -910,3 +913,132 @@
179 if not isinstance(lst, list):175 if not isinstance(lst, list):
180 lst = [lst]176 lst = [lst]
181 return [{label: x} for x in lst]177 return [{label: x} for x in lst]
@@ -308,10 +304,22 @@
308+304+
309+ def close(self):305+ def close(self):
310+ self.f.close()306+ self.f.close()
311diff -Naupr nova-2011.3.orig//nova/virt/libvirt/connection.py nova-2011.3//nova/virt/libvirt/connection.py307--- a/nova/virt/libvirt.xml.template
312--- nova-2011.3.orig//nova/virt/libvirt/connection.py 2011-09-22 08:02:23.000000000 -0400308+++ b/nova/virt/libvirt.xml.template
313+++ nova-2011.3//nova/virt/libvirt/connection.py 2011-09-30 10:14:45.387607449 -0400309@@ -153,8 +153,8 @@
314@@ -37,6 +37,7 @@ Supports KVM, LXC, QEMU, UML, and XEN.310
311 #end for
312 <!-- The order is significant here. File must be defined first -->
313- <serial type="file">
314- <source path='${basepath}/console.log'/>
315+ <serial type="pipe">
316+ <source path='${basepath}/console.fifo'/>
317 <target port='1'/>
318 </serial>
319
320--- a/nova/virt/libvirt/connection.py
321+++ b/nova/virt/libvirt/connection.py
322@@ -37,6 +37,7 @@
315 323
316 """324 """
317 325
@@ -319,7 +327,7 @@
319 import hashlib327 import hashlib
320 import functools328 import functools
321 import multiprocessing329 import multiprocessing
322@@ -44,7 +45,9 @@ import netaddr330@@ -44,7 +45,9 @@
323 import os331 import os
324 import random332 import random
325 import re333 import re
@@ -329,7 +337,7 @@
329 import sys337 import sys
330 import tempfile338 import tempfile
331 import time339 import time
332@@ -52,6 +55,7 @@ import uuid340@@ -52,6 +55,7 @@
333 from xml.dom import minidom341 from xml.dom import minidom
334 from xml.etree import ElementTree342 from xml.etree import ElementTree
335 343
@@ -337,7 +345,7 @@
337 from eventlet import greenthread345 from eventlet import greenthread
338 from eventlet import tpool346 from eventlet import tpool
339 347
340@@ -141,6 +145,8 @@ flags.DEFINE_string('default_local_forma348@@ -141,6 +145,8 @@
341 flags.DEFINE_bool('libvirt_use_virtio_for_bridges',349 flags.DEFINE_bool('libvirt_use_virtio_for_bridges',
342 False,350 False,
343 'Use virtio for bridge interfaces')351 'Use virtio for bridge interfaces')
@@ -346,7 +354,7 @@
346 354
347 355
348 def get_connection(read_only):356 def get_connection(read_only):
349@@ -170,6 +176,55 @@ def _get_eph_disk(ephemeral):357@@ -170,6 +176,57 @@
350 return 'disk.eph' + str(ephemeral['num'])358 return 'disk.eph' + str(ephemeral['num'])
351 359
352 360
@@ -364,6 +372,7 @@
364+ def _reopen(self):372+ def _reopen(self):
365+ if self.fd is not None:373+ if self.fd is not None:
366+ os.close(self.fd)374+ os.close(self.fd)
375+ self.fd = None
367+ self.fd = os.open(self.fifo_path, os.O_RDONLY | os.O_NONBLOCK)376+ self.fd = os.open(self.fifo_path, os.O_RDONLY | os.O_NONBLOCK)
368+377+
369+ def _reader_thread_func(self):378+ def _reader_thread_func(self):
@@ -394,6 +403,7 @@
394+ pass403+ pass
395+ if self.fd is not None:404+ if self.fd is not None:
396+ os.close(self.fd)405+ os.close(self.fd)
406+ self.fd = None
397+407+
398+ def peek(self):408+ def peek(self):
399+ return self.ringbuffer.peek()409+ return self.ringbuffer.peek()
@@ -402,7 +412,7 @@
402 class LibvirtConnection(driver.ComputeDriver):412 class LibvirtConnection(driver.ComputeDriver):
403 413
404 def __init__(self, read_only):414 def __init__(self, read_only):
405@@ -185,9 +240,15 @@ class LibvirtConnection(driver.ComputeDr415@@ -185,9 +242,15 @@
406 self.firewall_driver = fw_class(get_connection=self._get_connection)416 self.firewall_driver = fw_class(get_connection=self._get_connection)
407 self.vif_driver = utils.import_object(FLAGS.libvirt_vif_driver)417 self.vif_driver = utils.import_object(FLAGS.libvirt_vif_driver)
408 418
@@ -419,7 +429,7 @@
419 429
420 def _get_connection(self):430 def _get_connection(self):
421 if not self._wrapped_conn or not self._test_connection():431 if not self._wrapped_conn or not self._test_connection():
422@@ -229,6 +290,15 @@ class LibvirtConnection(driver.ComputeDr432@@ -229,6 +292,15 @@
423 else:433 else:
424 return libvirt.openAuth(uri, auth, 0)434 return libvirt.openAuth(uri, auth, 0)
425 435
@@ -435,7 +445,7 @@
435 def list_instances(self):445 def list_instances(self):
436 return [self._conn.lookupByID(x).name()446 return [self._conn.lookupByID(x).name()
437 for x in self._conn.listDomainsID()]447 for x in self._conn.listDomainsID()]
438@@ -333,6 +403,7 @@ class LibvirtConnection(driver.ComputeDr448@@ -333,6 +405,7 @@
439 def _cleanup(self, instance):449 def _cleanup(self, instance):
440 target = os.path.join(FLAGS.instances_path, instance['name'])450 target = os.path.join(FLAGS.instances_path, instance['name'])
441 instance_name = instance['name']451 instance_name = instance['name']
@@ -443,7 +453,7 @@
443 LOG.info(_('instance %(instance_name)s: deleting instance files'453 LOG.info(_('instance %(instance_name)s: deleting instance files'
444 ' %(target)s') % locals())454 ' %(target)s') % locals())
445 if FLAGS.libvirt_type == 'lxc':455 if FLAGS.libvirt_type == 'lxc':
446@@ -652,24 +723,22 @@ class LibvirtConnection(driver.ComputeDr456@@ -652,24 +725,22 @@
447 457
448 @exception.wrap_exception()458 @exception.wrap_exception()
449 def get_console_output(self, instance):459 def get_console_output(self, instance):
@@ -473,7 +483,7 @@
473 483
474 @exception.wrap_exception()484 @exception.wrap_exception()
475 def get_ajax_console(self, instance):485 def get_ajax_console(self, instance):
476@@ -816,11 +885,25 @@ class LibvirtConnection(driver.ComputeDr486@@ -816,11 +887,25 @@
477 container_dir = '%s/rootfs' % basepath(suffix='')487 container_dir = '%s/rootfs' % basepath(suffix='')
478 utils.execute('mkdir', '-p', container_dir)488 utils.execute('mkdir', '-p', container_dir)
479 489
@@ -504,17 +514,3 @@
504 514
505 if not disk_images:515 if not disk_images:
506 disk_images = {'image_id': inst['image_ref'],516 disk_images = {'image_id': inst['image_ref'],
507diff -Naupr nova-2011.3.orig//nova/virt/libvirt.xml.template nova-2011.3//nova/virt/libvirt.xml.template
508--- nova-2011.3.orig//nova/virt/libvirt.xml.template 2011-09-22 08:02:23.000000000 -0400
509+++ nova-2011.3//nova/virt/libvirt.xml.template 2011-09-30 10:14:45.383607472 -0400
510@@ -153,8 +153,8 @@
511
512 #end for
513 <!-- The order is significant here. File must be defined first -->
514- <serial type="file">
515- <source path='${basepath}/console.log'/>
516+ <serial type="pipe">
517+ <source path='${basepath}/console.fifo'/>
518 <target port='1'/>
519 </serial>
520

Subscribers

People subscribed via source and target branches