summaryrefslogtreecommitdiffstats
path: root/scripts/runqemu
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2016-11-28 22:02:05 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-01-23 12:05:22 +0000
commit9dd223bf1853187488ce550502a003933e41ee2a (patch)
treed870058d6bcc7485f842599b57b4a583a8af1d33 /scripts/runqemu
parent5ea3627dbb61ab065be8737c46007d7d8d7f3501 (diff)
downloadpoky-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/runqemu')
-rwxr-xr-xscripts/runqemu62
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):
84Examples: 84Examples:
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
150def 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
150class BaseConfig(object): 163class 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: