diff options
author | Robert Yang <liezhi.yang@windriver.com> | 2016-11-28 22:02:05 -0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-01-23 12:05:22 +0000 |
commit | 9dd223bf1853187488ce550502a003933e41ee2a (patch) | |
tree | d870058d6bcc7485f842599b57b4a583a8af1d33 /scripts | |
parent | 5ea3627dbb61ab065be8737c46007d7d8d7f3501 (diff) | |
download | poky-9dd223bf1853187488ce550502a003933e41ee2a.tar.gz |
runqemu: fixes for slirp, network device and hostfwd
Fixed:
- Add QB_NETWORK_DEVICE to set network device, it will be used by both
slirp and tap.
- Set QB_NETWORK_DEVICE to "-device virtio-net-pci" in qemuboot.bbclass
but runqemu will default to "-device e1000" when QB_NETWORK_DEVICE is
not set, this is because oe-core's qemu targets support
virtio-net-pci, but the one outside of oe-core may not,
"-device e1000" is more common.
- Set hostfwd by default: 2222 -> 22, 2323 -> 23, and it will choose a
usable port when the one like 222 is being used. This can avoid
conflicts when multilib slirp qemus are running. We can forward more
ports by default if needed, and bsp.conf can custom it.
- Use different mac sections for slirp and tap to fix conflicts when
running both of them on the same host.
[YOCTO #7887]
CC: Nathan Rossi <nathan@nathanrossi.com>
CC: Randy Witt <randy.e.witt@linux.intel.com>
(From OE-Core rev: 7dddd090806914a62d977730440d803e48f44763)
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/runqemu | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/scripts/runqemu b/scripts/runqemu index b176e20845..30e5346356 100755 --- a/scripts/runqemu +++ b/scripts/runqemu | |||
@@ -84,7 +84,7 @@ of the following environment variables (in any order): | |||
84 | Examples: | 84 | Examples: |
85 | runqemu qemuarm | 85 | runqemu qemuarm |
86 | runqemu tmp/deploy/images/qemuarm | 86 | runqemu tmp/deploy/images/qemuarm |
87 | runqemu tmp/deploy/images/qemux86/.qemuboot.conf | 87 | runqemu tmp/deploy/images/qemux86/<qemuboot.conf> |
88 | runqemu qemux86-64 core-image-sato ext4 | 88 | runqemu qemux86-64 core-image-sato ext4 |
89 | runqemu qemux86-64 wic-image-minimal wic | 89 | runqemu qemux86-64 wic-image-minimal wic |
90 | runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial | 90 | runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial |
@@ -147,6 +147,19 @@ def get_first_file(cmds): | |||
147 | return f | 147 | return f |
148 | return '' | 148 | return '' |
149 | 149 | ||
150 | def check_free_port(host, port): | ||
151 | """ Check whether the port is free or not """ | ||
152 | import socket | ||
153 | from contextlib import closing | ||
154 | |||
155 | with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: | ||
156 | if sock.connect_ex((host, port)) == 0: | ||
157 | # Port is open, so not free | ||
158 | return False | ||
159 | else: | ||
160 | # Port is not open, so free | ||
161 | return True | ||
162 | |||
150 | class BaseConfig(object): | 163 | class BaseConfig(object): |
151 | def __init__(self): | 164 | def __init__(self): |
152 | # Vars can be merged with .qemuboot.conf, use a dict to manage them. | 165 | # Vars can be merged with .qemuboot.conf, use a dict to manage them. |
@@ -186,6 +199,15 @@ class BaseConfig(object): | |||
186 | self.snapshot = False | 199 | self.snapshot = False |
187 | self.fstypes = ('ext2', 'ext3', 'ext4', 'jffs2', 'nfs', 'btrfs', 'cpio.gz', 'cpio', 'ramfs') | 200 | self.fstypes = ('ext2', 'ext3', 'ext4', 'jffs2', 'nfs', 'btrfs', 'cpio.gz', 'cpio', 'ramfs') |
188 | self.vmtypes = ('hddimg', 'hdddirect', 'wic', 'vmdk', 'qcow2', 'vdi', 'iso') | 201 | self.vmtypes = ('hddimg', 'hdddirect', 'wic', 'vmdk', 'qcow2', 'vdi', 'iso') |
202 | self.network_device = "-device e1000,netdev=net0,mac=@MAC@" | ||
203 | # Use different mac section for tap and slirp to avoid | ||
204 | # conflicts, e.g., when one is running with tap, the other is | ||
205 | # running with slirp. | ||
206 | # The last section is dynamic, which is for avoiding conflicts, | ||
207 | # when multiple qemus are running, e.g., when multiple tap or | ||
208 | # slirp qemus are running. | ||
209 | self.mac_tap = "52:54:00:12:34:" | ||
210 | self.mac_slirp = "52:54:00:12:35:" | ||
189 | 211 | ||
190 | def acquire_lock(self): | 212 | def acquire_lock(self): |
191 | logger.info("Acquiring lockfile %s..." % self.lock) | 213 | logger.info("Acquiring lockfile %s..." % self.lock) |
@@ -757,14 +779,39 @@ class BaseConfig(object): | |||
757 | 779 | ||
758 | self.nfs_running = True | 780 | self.nfs_running = True |
759 | 781 | ||
760 | |||
761 | def setup_slirp(self): | 782 | def setup_slirp(self): |
762 | """Setup user networking""" | 783 | """Setup user networking""" |
763 | 784 | ||
764 | if self.fstype == 'nfs': | 785 | if self.fstype == 'nfs': |
765 | self.setup_nfs() | 786 | self.setup_nfs() |
766 | self.kernel_cmdline_script += ' ip=dhcp' | 787 | self.kernel_cmdline_script += ' ip=dhcp' |
767 | self.set('NETWORK_CMD', self.get('QB_SLIRP_OPT')) | 788 | # Port mapping |
789 | hostfwd = ",hostfwd=tcp::2222-:22,hostfwd=tcp::2323-:23" | ||
790 | qb_slirp_opt_default = "-netdev user,id=net0%s" % hostfwd | ||
791 | qb_slirp_opt = self.get('QB_SLIRP_OPT') or qb_slirp_opt_default | ||
792 | # Figure out the port | ||
793 | ports = re.findall('hostfwd=[^-]*:([0-9]+)-[^,-]*', qb_slirp_opt) | ||
794 | ports = [int(i) for i in ports] | ||
795 | mac = 2 | ||
796 | # Find a free port to avoid conflicts | ||
797 | for p in ports[:]: | ||
798 | p_new = p | ||
799 | while not check_free_port('localhost', p_new): | ||
800 | p_new += 1 | ||
801 | mac += 1 | ||
802 | while p_new in ports: | ||
803 | p_new += 1 | ||
804 | mac += 1 | ||
805 | if p != p_new: | ||
806 | ports.append(p_new) | ||
807 | qb_slirp_opt = re.sub(':%s-' % p, ':%s-' % p_new, qb_slirp_opt) | ||
808 | logger.info("Port forward changed: %s -> %s" % (p, p_new)) | ||
809 | mac = "%s%02x" % (self.mac_slirp, mac) | ||
810 | self.set('NETWORK_CMD', '%s %s' % (self.network_device.replace('@MAC@', mac), qb_slirp_opt)) | ||
811 | # Print out port foward | ||
812 | hostfwd = re.findall('(hostfwd=[^,]*)', qb_slirp_opt) | ||
813 | if hostfwd: | ||
814 | logger.info('Port forward: %s' % ' '.join(hostfwd)) | ||
768 | 815 | ||
769 | def setup_tap(self): | 816 | def setup_tap(self): |
770 | """Setup tap""" | 817 | """Setup tap""" |
@@ -834,21 +881,22 @@ class BaseConfig(object): | |||
834 | if self.fstype == 'nfs': | 881 | if self.fstype == 'nfs': |
835 | self.setup_nfs() | 882 | self.setup_nfs() |
836 | self.kernel_cmdline_script += " ip=192.168.7.%s::192.168.7.%s:255.255.255.0" % (client, gateway) | 883 | self.kernel_cmdline_script += " ip=192.168.7.%s::192.168.7.%s:255.255.255.0" % (client, gateway) |
837 | mac = "52:54:00:12:34:%02x" % client | 884 | mac = "%s%02x" % (self.mac_tap, client) |
838 | qb_tap_opt = self.get('QB_TAP_OPT') | 885 | qb_tap_opt = self.get('QB_TAP_OPT') |
839 | if qb_tap_opt: | 886 | if qb_tap_opt: |
840 | qemu_tap_opt = qb_tap_opt.replace('@TAP@', tap).replace('@MAC@', mac) | 887 | qemu_tap_opt = qb_tap_opt.replace('@TAP@', tap) |
841 | else: | 888 | else: |
842 | qemu_tap_opt = "-device virtio-net-pci,netdev=net0,mac=%s -netdev tap,id=net0,ifname=%s,script=no,downscript=no" % (mac, self.tap) | 889 | qemu_tap_opt = "-netdev tap,id=net0,ifname=%s,script=no,downscript=no" % (self.tap) |
843 | 890 | ||
844 | if self.vhost_enabled: | 891 | if self.vhost_enabled: |
845 | qemu_tap_opt += ',vhost=on' | 892 | qemu_tap_opt += ',vhost=on' |
846 | 893 | ||
847 | self.set('NETWORK_CMD', qemu_tap_opt) | 894 | self.set('NETWORK_CMD', '%s %s' % (self.network_device.replace('@MAC@', mac), qemu_tap_opt)) |
848 | 895 | ||
849 | def setup_network(self): | 896 | def setup_network(self): |
850 | cmd = "stty -g" | 897 | cmd = "stty -g" |
851 | self.saved_stty = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8') | 898 | self.saved_stty = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8') |
899 | self.network_device = self.get('QB_NETWORK_DEVICE') or self.network_device | ||
852 | if self.slirp_enabled: | 900 | if self.slirp_enabled: |
853 | self.setup_slirp() | 901 | self.setup_slirp() |
854 | else: | 902 | else: |