Merge lp:~racb/nova/868349 into lp:~ubuntu-server-dev/nova/diablo
- 868349
- Merge into 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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Approve | ||
Review via email: mp+78284@code.launchpad.net |
Commit message
Description of the change
* debian/
- Patch updated to fix race on instance termination (LP: #868349)
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2011-10-04 09:50:31 +0000 | |||
3 | +++ debian/changelog 2011-10-05 16:48:18 +0000 | |||
4 | @@ -1,3 +1,10 @@ | |||
5 | 1 | nova (2011.3-0ubuntu6) oneiric; urgency=low | ||
6 | 2 | |||
7 | 3 | * debian/patches/backport-libvirt-console-pipe.patch: | ||
8 | 4 | - Patch updated to fix race on instance termination (LP: #868349) | ||
9 | 5 | |||
10 | 6 | -- Robie Basak <robie.basak@ubuntu.com> Wed, 05 Oct 2011 17:37:49 +0100 | ||
11 | 7 | |||
12 | 1 | nova (2011.3-0ubuntu5) oneiric; urgency=low | 8 | nova (2011.3-0ubuntu5) oneiric; urgency=low |
13 | 2 | 9 | ||
14 | 3 | * debian/nova-common.postinst: | 10 | * debian/nova-common.postinst: |
15 | 4 | 11 | ||
16 | === modified file 'debian/patches/backport-libvirt-console-pipe.patch' | |||
17 | --- debian/patches/backport-libvirt-console-pipe.patch 2011-09-30 14:22:57 +0000 | |||
18 | +++ debian/patches/backport-libvirt-console-pipe.patch 2011-10-05 16:48:18 +0000 | |||
19 | @@ -1,10 +1,9 @@ | |||
20 | 1 | Description: Move console.log to a ringbuffer | 1 | Description: Move console.log to a ringbuffer |
21 | 2 | Author: Robie Basak <robie.basak@canonical.com> | 2 | Author: Robie Basak <robie.basak@canonical.com> |
22 | 3 | Status: https://review.openstack.org/#change,706 | 3 | Status: https://review.openstack.org/#change,706 |
27 | 4 | diff -Naupr nova-2011.3.orig//Authors nova-2011.3//Authors | 4 | --- a/Authors |
28 | 5 | --- nova-2011.3.orig//Authors 2011-09-22 08:02:23.000000000 -0400 | 5 | +++ b/Authors |
29 | 6 | +++ nova-2011.3//Authors 2011-09-30 10:14:45.375607481 -0400 | 6 | @@ -95,6 +95,7 @@ |
26 | 7 | @@ -95,6 +95,7 @@ Ricardo Carrillo Cruz <emaildericky@gmai | ||
30 | 8 | Rick Clark <rick@openstack.org> | 7 | Rick Clark <rick@openstack.org> |
31 | 9 | Rick Harris <rconradharris@gmail.com> | 8 | Rick Harris <rconradharris@gmail.com> |
32 | 10 | Rob Kost <kost@isi.edu> | 9 | Rob Kost <kost@isi.edu> |
33 | @@ -12,10 +11,9 @@ | |||
34 | 12 | Ryan Lane <rlane@wikimedia.org> | 11 | Ryan Lane <rlane@wikimedia.org> |
35 | 13 | Ryan Lucio <rlucio@internap.com> | 12 | Ryan Lucio <rlucio@internap.com> |
36 | 14 | Ryu Ishimoto <ryu@midokura.jp> | 13 | Ryu Ishimoto <ryu@midokura.jp> |
41 | 15 | diff -Naupr nova-2011.3.orig//nova/tests/test_libvirt.py nova-2011.3//nova/tests/test_libvirt.py | 14 | --- a/nova/tests/test_libvirt.py |
42 | 16 | --- nova-2011.3.orig//nova/tests/test_libvirt.py 2011-09-22 08:02:23.000000000 -0400 | 15 | +++ b/nova/tests/test_libvirt.py |
43 | 17 | +++ nova-2011.3//nova/tests/test_libvirt.py 2011-09-30 10:14:45.379607485 -0400 | 16 | @@ -565,7 +565,7 @@ |
40 | 18 | @@ -565,7 +565,7 @@ class LibvirtConnTestCase(test.TestCase) | ||
44 | 19 | (lambda t: t.findall(parameter)[1].get('name'), 'DHCPSERVER'), | 17 | (lambda t: t.findall(parameter)[1].get('name'), 'DHCPSERVER'), |
45 | 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'), |
46 | 21 | (lambda t: t.find('./devices/serial/source').get( | 19 | (lambda t: t.find('./devices/serial/source').get( |
47 | @@ -24,7 +22,7 @@ | |||
48 | 24 | (lambda t: t.find('./memory').text, '2097152')] | 22 | (lambda t: t.find('./memory').text, '2097152')] |
49 | 25 | if rescue: | 23 | if rescue: |
50 | 26 | common_checks += [ | 24 | common_checks += [ |
52 | 27 | @@ -1494,3 +1494,54 @@ class NWFilterTestCase(test.TestCase): | 25 | @@ -1501,3 +1501,54 @@ |
53 | 28 | self.assertEqual(original_filter_count - len(fakefilter.filters), 2) | 26 | self.assertEqual(original_filter_count - len(fakefilter.filters), 2) |
54 | 29 | 27 | ||
55 | 30 | db.instance_destroy(admin_ctxt, instance_ref['id']) | 28 | db.instance_destroy(admin_ctxt, instance_ref['id']) |
56 | @@ -79,9 +77,8 @@ | |||
57 | 79 | + os.unlink(self.ringbuffer_path) | 77 | + os.unlink(self.ringbuffer_path) |
58 | 80 | + os.unlink(self.fifo_path) | 78 | + os.unlink(self.fifo_path) |
59 | 81 | + os.rmdir(self.directory_path) | 79 | + os.rmdir(self.directory_path) |
63 | 82 | diff -Naupr nova-2011.3.orig//nova/tests/test_utils.py nova-2011.3//nova/tests/test_utils.py | 80 | --- a/nova/tests/test_utils.py |
64 | 83 | --- nova-2011.3.orig//nova/tests/test_utils.py 2011-09-22 08:02:23.000000000 -0400 | 81 | +++ b/nova/tests/test_utils.py |
62 | 84 | +++ nova-2011.3//nova/tests/test_utils.py 2011-09-30 10:14:45.379607485 -0400 | ||
65 | 85 | @@ -15,9 +15,12 @@ | 82 | @@ -15,9 +15,12 @@ |
66 | 86 | # under the License. | 83 | # under the License. |
67 | 87 | 84 | ||
68 | @@ -95,7 +92,7 @@ | |||
69 | 95 | import nova | 92 | import nova |
70 | 96 | from nova import exception | 93 | from nova import exception |
71 | 97 | from nova import test | 94 | from nova import test |
73 | 98 | @@ -439,3 +442,55 @@ class MonkeyPatchTestCase(test.TestCase) | 95 | @@ -439,3 +442,55 @@ |
74 | 99 | in nova.tests.monkey_patch_example.CALLED_FUNCTION) | 96 | in nova.tests.monkey_patch_example.CALLED_FUNCTION) |
75 | 100 | self.assertFalse(package_b + 'ExampleClassB.example_method_add' | 97 | self.assertFalse(package_b + 'ExampleClassB.example_method_add' |
76 | 101 | in nova.tests.monkey_patch_example.CALLED_FUNCTION) | 98 | in nova.tests.monkey_patch_example.CALLED_FUNCTION) |
77 | @@ -151,10 +148,9 @@ | |||
78 | 151 | + yield check_buffer, r, expected | 148 | + yield check_buffer, r, expected |
79 | 152 | + r.close() | 149 | + r.close() |
80 | 153 | + f.close() | 150 | + f.close() |
85 | 154 | diff -Naupr nova-2011.3.orig//nova/utils.py nova-2011.3//nova/utils.py | 151 | --- a/nova/utils.py |
86 | 155 | --- nova-2011.3.orig//nova/utils.py 2011-09-22 08:02:23.000000000 -0400 | 152 | +++ b/nova/utils.py |
87 | 156 | +++ nova-2011.3//nova/utils.py 2011-09-30 10:20:37.823615836 -0400 | 153 | @@ -26,10 +26,12 @@ |
84 | 157 | @@ -26,10 +26,12 @@ import json | ||
88 | 158 | import lockfile | 154 | import lockfile |
89 | 159 | import netaddr | 155 | import netaddr |
90 | 160 | import os | 156 | import os |
91 | @@ -167,7 +163,7 @@ | |||
92 | 167 | import struct | 163 | import struct |
93 | 168 | import sys | 164 | import sys |
94 | 169 | import time | 165 | import time |
96 | 170 | @@ -49,6 +51,7 @@ from nova import log as logging | 166 | @@ -49,6 +51,7 @@ |
97 | 171 | from nova import version | 167 | from nova import version |
98 | 172 | 168 | ||
99 | 173 | 169 | ||
100 | @@ -175,7 +171,7 @@ | |||
101 | 175 | LOG = logging.getLogger("nova.utils") | 171 | LOG = logging.getLogger("nova.utils") |
102 | 176 | ISO_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" | 172 | ISO_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" |
103 | 177 | PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f" | 173 | PERFECT_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%f" |
105 | 178 | @@ -910,3 +913,132 @@ def convert_to_list_dict(lst, label): | 174 | @@ -910,3 +913,132 @@ |
106 | 179 | if not isinstance(lst, list): | 175 | if not isinstance(lst, list): |
107 | 180 | lst = [lst] | 176 | lst = [lst] |
108 | 181 | return [{label: x} for x in lst] | 177 | return [{label: x} for x in lst] |
109 | @@ -308,10 +304,22 @@ | |||
110 | 308 | + | 304 | + |
111 | 309 | + def close(self): | 305 | + def close(self): |
112 | 310 | + self.f.close() | 306 | + self.f.close() |
117 | 311 | diff -Naupr nova-2011.3.orig//nova/virt/libvirt/connection.py nova-2011.3//nova/virt/libvirt/connection.py | 307 | --- a/nova/virt/libvirt.xml.template |
118 | 312 | --- nova-2011.3.orig//nova/virt/libvirt/connection.py 2011-09-22 08:02:23.000000000 -0400 | 308 | +++ b/nova/virt/libvirt.xml.template |
119 | 313 | +++ nova-2011.3//nova/virt/libvirt/connection.py 2011-09-30 10:14:45.387607449 -0400 | 309 | @@ -153,8 +153,8 @@ |
120 | 314 | @@ -37,6 +37,7 @@ Supports KVM, LXC, QEMU, UML, and XEN. | 310 | |
121 | 311 | #end for | ||
122 | 312 | <!-- The order is significant here. File must be defined first --> | ||
123 | 313 | - <serial type="file"> | ||
124 | 314 | - <source path='${basepath}/console.log'/> | ||
125 | 315 | + <serial type="pipe"> | ||
126 | 316 | + <source path='${basepath}/console.fifo'/> | ||
127 | 317 | <target port='1'/> | ||
128 | 318 | </serial> | ||
129 | 319 | |||
130 | 320 | --- a/nova/virt/libvirt/connection.py | ||
131 | 321 | +++ b/nova/virt/libvirt/connection.py | ||
132 | 322 | @@ -37,6 +37,7 @@ | ||
133 | 315 | 323 | ||
134 | 316 | """ | 324 | """ |
135 | 317 | 325 | ||
136 | @@ -319,7 +327,7 @@ | |||
137 | 319 | import hashlib | 327 | import hashlib |
138 | 320 | import functools | 328 | import functools |
139 | 321 | import multiprocessing | 329 | import multiprocessing |
141 | 322 | @@ -44,7 +45,9 @@ import netaddr | 330 | @@ -44,7 +45,9 @@ |
142 | 323 | import os | 331 | import os |
143 | 324 | import random | 332 | import random |
144 | 325 | import re | 333 | import re |
145 | @@ -329,7 +337,7 @@ | |||
146 | 329 | import sys | 337 | import sys |
147 | 330 | import tempfile | 338 | import tempfile |
148 | 331 | import time | 339 | import time |
150 | 332 | @@ -52,6 +55,7 @@ import uuid | 340 | @@ -52,6 +55,7 @@ |
151 | 333 | from xml.dom import minidom | 341 | from xml.dom import minidom |
152 | 334 | from xml.etree import ElementTree | 342 | from xml.etree import ElementTree |
153 | 335 | 343 | ||
154 | @@ -337,7 +345,7 @@ | |||
155 | 337 | from eventlet import greenthread | 345 | from eventlet import greenthread |
156 | 338 | from eventlet import tpool | 346 | from eventlet import tpool |
157 | 339 | 347 | ||
159 | 340 | @@ -141,6 +145,8 @@ flags.DEFINE_string('default_local_forma | 348 | @@ -141,6 +145,8 @@ |
160 | 341 | flags.DEFINE_bool('libvirt_use_virtio_for_bridges', | 349 | flags.DEFINE_bool('libvirt_use_virtio_for_bridges', |
161 | 342 | False, | 350 | False, |
162 | 343 | 'Use virtio for bridge interfaces') | 351 | 'Use virtio for bridge interfaces') |
163 | @@ -346,7 +354,7 @@ | |||
164 | 346 | 354 | ||
165 | 347 | 355 | ||
166 | 348 | def get_connection(read_only): | 356 | def get_connection(read_only): |
168 | 349 | @@ -170,6 +176,55 @@ def _get_eph_disk(ephemeral): | 357 | @@ -170,6 +176,57 @@ |
169 | 350 | return 'disk.eph' + str(ephemeral['num']) | 358 | return 'disk.eph' + str(ephemeral['num']) |
170 | 351 | 359 | ||
171 | 352 | 360 | ||
172 | @@ -364,6 +372,7 @@ | |||
173 | 364 | + def _reopen(self): | 372 | + def _reopen(self): |
174 | 365 | + if self.fd is not None: | 373 | + if self.fd is not None: |
175 | 366 | + os.close(self.fd) | 374 | + os.close(self.fd) |
176 | 375 | + self.fd = None | ||
177 | 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) |
178 | 368 | + | 377 | + |
179 | 369 | + def _reader_thread_func(self): | 378 | + def _reader_thread_func(self): |
180 | @@ -394,6 +403,7 @@ | |||
181 | 394 | + pass | 403 | + pass |
182 | 395 | + if self.fd is not None: | 404 | + if self.fd is not None: |
183 | 396 | + os.close(self.fd) | 405 | + os.close(self.fd) |
184 | 406 | + self.fd = None | ||
185 | 397 | + | 407 | + |
186 | 398 | + def peek(self): | 408 | + def peek(self): |
187 | 399 | + return self.ringbuffer.peek() | 409 | + return self.ringbuffer.peek() |
188 | @@ -402,7 +412,7 @@ | |||
189 | 402 | class LibvirtConnection(driver.ComputeDriver): | 412 | class LibvirtConnection(driver.ComputeDriver): |
190 | 403 | 413 | ||
191 | 404 | def __init__(self, read_only): | 414 | def __init__(self, read_only): |
193 | 405 | @@ -185,9 +240,15 @@ class LibvirtConnection(driver.ComputeDr | 415 | @@ -185,9 +242,15 @@ |
194 | 406 | self.firewall_driver = fw_class(get_connection=self._get_connection) | 416 | self.firewall_driver = fw_class(get_connection=self._get_connection) |
195 | 407 | self.vif_driver = utils.import_object(FLAGS.libvirt_vif_driver) | 417 | self.vif_driver = utils.import_object(FLAGS.libvirt_vif_driver) |
196 | 408 | 418 | ||
197 | @@ -419,7 +429,7 @@ | |||
198 | 419 | 429 | ||
199 | 420 | def _get_connection(self): | 430 | def _get_connection(self): |
200 | 421 | if not self._wrapped_conn or not self._test_connection(): | 431 | if not self._wrapped_conn or not self._test_connection(): |
202 | 422 | @@ -229,6 +290,15 @@ class LibvirtConnection(driver.ComputeDr | 432 | @@ -229,6 +292,15 @@ |
203 | 423 | else: | 433 | else: |
204 | 424 | return libvirt.openAuth(uri, auth, 0) | 434 | return libvirt.openAuth(uri, auth, 0) |
205 | 425 | 435 | ||
206 | @@ -435,7 +445,7 @@ | |||
207 | 435 | def list_instances(self): | 445 | def list_instances(self): |
208 | 436 | return [self._conn.lookupByID(x).name() | 446 | return [self._conn.lookupByID(x).name() |
209 | 437 | for x in self._conn.listDomainsID()] | 447 | for x in self._conn.listDomainsID()] |
211 | 438 | @@ -333,6 +403,7 @@ class LibvirtConnection(driver.ComputeDr | 448 | @@ -333,6 +405,7 @@ |
212 | 439 | def _cleanup(self, instance): | 449 | def _cleanup(self, instance): |
213 | 440 | target = os.path.join(FLAGS.instances_path, instance['name']) | 450 | target = os.path.join(FLAGS.instances_path, instance['name']) |
214 | 441 | instance_name = instance['name'] | 451 | instance_name = instance['name'] |
215 | @@ -443,7 +453,7 @@ | |||
216 | 443 | LOG.info(_('instance %(instance_name)s: deleting instance files' | 453 | LOG.info(_('instance %(instance_name)s: deleting instance files' |
217 | 444 | ' %(target)s') % locals()) | 454 | ' %(target)s') % locals()) |
218 | 445 | if FLAGS.libvirt_type == 'lxc': | 455 | if FLAGS.libvirt_type == 'lxc': |
220 | 446 | @@ -652,24 +723,22 @@ class LibvirtConnection(driver.ComputeDr | 456 | @@ -652,24 +725,22 @@ |
221 | 447 | 457 | ||
222 | 448 | @exception.wrap_exception() | 458 | @exception.wrap_exception() |
223 | 449 | def get_console_output(self, instance): | 459 | def get_console_output(self, instance): |
224 | @@ -473,7 +483,7 @@ | |||
225 | 473 | 483 | ||
226 | 474 | @exception.wrap_exception() | 484 | @exception.wrap_exception() |
227 | 475 | def get_ajax_console(self, instance): | 485 | def get_ajax_console(self, instance): |
229 | 476 | @@ -816,11 +885,25 @@ class LibvirtConnection(driver.ComputeDr | 486 | @@ -816,11 +887,25 @@ |
230 | 477 | container_dir = '%s/rootfs' % basepath(suffix='') | 487 | container_dir = '%s/rootfs' % basepath(suffix='') |
231 | 478 | utils.execute('mkdir', '-p', container_dir) | 488 | utils.execute('mkdir', '-p', container_dir) |
232 | 479 | 489 | ||
233 | @@ -504,17 +514,3 @@ | |||
234 | 504 | 514 | ||
235 | 505 | if not disk_images: | 515 | if not disk_images: |
236 | 506 | disk_images = {'image_id': inst['image_ref'], | 516 | disk_images = {'image_id': inst['image_ref'], |
237 | 507 | diff -Naupr nova-2011.3.orig//nova/virt/libvirt.xml.template nova-2011.3//nova/virt/libvirt.xml.template | ||
238 | 508 | --- nova-2011.3.orig//nova/virt/libvirt.xml.template 2011-09-22 08:02:23.000000000 -0400 | ||
239 | 509 | +++ nova-2011.3//nova/virt/libvirt.xml.template 2011-09-30 10:14:45.383607472 -0400 | ||
240 | 510 | @@ -153,8 +153,8 @@ | ||
241 | 511 | |||
242 | 512 | #end for | ||
243 | 513 | <!-- The order is significant here. File must be defined first --> | ||
244 | 514 | - <serial type="file"> | ||
245 | 515 | - <source path='${basepath}/console.log'/> | ||
246 | 516 | + <serial type="pipe"> | ||
247 | 517 | + <source path='${basepath}/console.fifo'/> | ||
248 | 518 | <target port='1'/> | ||
249 | 519 | </serial> | ||
250 | 520 |
LGTM - tested on local all-in-one deployment and resolves the original bug report.