Merge lp:~tamura-yoshiaki/nova/bug-805312 into lp:~hudson-openstack/nova/trunk

Proposed by Yoshiaki Tamura
Status: Merged
Approved by: Vish Ishaya
Approved revision: 1246
Merged at revision: 1317
Proposed branch: lp:~tamura-yoshiaki/nova/bug-805312
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 76 lines (+23/-7)
2 files modified
nova/virt/libvirt.xml.template (+5/-1)
nova/virt/libvirt/connection.py (+18/-6)
To merge this branch: bzr merge lp:~tamura-yoshiaki/nova/bug-805312
Reviewer Review Type Date Requested Status
Christopher MacGown (community) Approve
Devin Carlen (community) Approve
Review via email: mp+66744@code.launchpad.net

Commit message

Fix boot from volume failure for network block devices.

This patch looks up the device_path and swithes between 'block' and 'network' when creating libvirt.xml.

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

This looks good but it looks like there is some logic is being duplicated:

35 + if vol['device_path'].startswith('/dev/'):
36 + vol['type'] = 'block'
37 + elif ':' in vol['device_path']:
38 + (protocol, name) = vol['device_path'].split(':')
39 + vol['type'] = 'network'
40 + vol['protocol'] = protocol
41 + vol['device_path'] = name
42 + else:
43 + raise exception.InvalidDevicePath(path=vol['device_path'])

There is very similar logic in the attach_volume method. I recommend fixing this so that there is no repetition. Maybe something like:

def _get_volume_device_type(self, device_path):
    if device_path.startswith('/dev/'):
        return 'block'
    elif ':' in device_path:
        return 'network'
    else:
        raise exception.InvalidDevicePath(path=device_path)

And then re-use that.

review: Needs Fixing
Revision history for this message
Yoshiaki Tamura (tamura-yoshiaki) wrote :

> This looks good but it looks like there is some logic is being duplicated:
>
> 35 + if vol['device_path'].startswith('/dev/'):
> 36 + vol['type'] = 'block'
> 37 + elif ':' in vol['device_path']:
> 38 + (protocol, name) = vol['device_path'].split(':')
> 39 + vol['type'] = 'network'
> 40 + vol['protocol'] = protocol
> 41 + vol['device_path'] = name
> 42 + else:
> 43 + raise
> exception.InvalidDevicePath(path=vol['device_path'])
>
> There is very similar logic in the attach_volume method. I recommend fixing
> this so that there is no repetition. Maybe something like:
>
> def _get_volume_device_type(self, device_path):
> if device_path.startswith('/dev/'):
> return 'block'
> elif ':' in device_path:
> return 'network'
> else:
> raise exception.InvalidDevicePath(path=device_path)
>
> And then re-use that.

Sorry for my slow response. Applied your comments.

Revision history for this message
Devin Carlen (devcamcar) wrote :

great, thanks!

review: Approve
Revision history for this message
Devin Carlen (devcamcar) wrote :

Don't forget to set it to "Ready for review" again.

Revision history for this message
Christopher MacGown (0x44) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/virt/libvirt.xml.template'
2--- nova/virt/libvirt.xml.template 2011-06-24 12:01:51 +0000
3+++ nova/virt/libvirt.xml.template 2011-07-20 07:23:37 +0000
4@@ -82,9 +82,13 @@
5 </disk>
6 #end if
7 #for $vol in $volumes
8- <disk type='block'>
9+ <disk type='${vol.type}'>
10 <driver type='raw'/>
11+ #if $vol.type == 'network'
12+ <source protocol='${vol.protocol}' name='${vol.name}'/>
13+ #else
14 <source dev='${vol.device_path}'/>
15+ #end if
16 <target dev='${vol.mount_device}' bus='${disk_bus}'/>
17 </disk>
18 #end for
19
20=== modified file 'nova/virt/libvirt/connection.py'
21--- nova/virt/libvirt/connection.py 2011-07-13 18:19:32 +0000
22+++ nova/virt/libvirt/connection.py 2011-07-20 07:23:37 +0000
23@@ -335,21 +335,20 @@
24 def attach_volume(self, instance_name, device_path, mountpoint):
25 virt_dom = self._lookup_by_name(instance_name)
26 mount_device = mountpoint.rpartition("/")[2]
27- if device_path.startswith('/dev/'):
28+ (type, protocol, name) = \
29+ self._get_volume_device_info(vol['device_path'])
30+ if type == 'block':
31 xml = """<disk type='block'>
32 <driver name='qemu' type='raw'/>
33 <source dev='%s'/>
34 <target dev='%s' bus='virtio'/>
35 </disk>""" % (device_path, mount_device)
36- elif ':' in device_path:
37- (protocol, name) = device_path.split(':')
38+ elif type == 'network':
39 xml = """<disk type='network'>
40 <driver name='qemu' type='raw'/>
41 <source protocol='%s' name='%s'/>
42 <target dev='%s' bus='virtio'/>
43- </disk>""" % (protocol,
44- name,
45- mount_device)
46+ </disk>""" % (protocol, name, mount_device)
47 else:
48 raise exception.InvalidDevicePath(path=device_path)
49
50@@ -971,6 +970,16 @@
51 return True
52 return False
53
54+ @exception.wrap_exception
55+ def _get_volume_device_info(self, device_path):
56+ if device_path.startswith('/dev/'):
57+ return ('block', None, None)
58+ elif ':' in device_path:
59+ (protocol, name) = device_path.split(':')
60+ return ('network', protocol, name)
61+ else:
62+ raise exception.InvalidDevicePath(path=device_path)
63+
64 def _prepare_xml_info(self, instance, rescue=False, network_info=None,
65 block_device_mapping=None):
66 block_device_mapping = block_device_mapping or []
67@@ -993,6 +1002,9 @@
68
69 for vol in block_device_mapping:
70 vol['mount_device'] = _strip_dev(vol['mount_device'])
71+ (vol['type'], vol['protocol'], vol['name']) = \
72+ self._get_volume_device_info(vol['device_path'])
73+
74 ebs_root = self._volume_in_mapping(self.root_mount_device,
75 block_device_mapping)
76 if self._volume_in_mapping(self.local_mount_device,