Дата и время публикации:
Проблемы и решение
1. Суть проблем
1.1 Несколько слов об наследование опции -net и -nic
Qemu ранее использовал опцию -net nic вместо -device DEVNAME и -net TYPE взамен -netdev TYPE. Хотя, использование опций -net nic и -net TYPE считается устаревшим, начиная с версии Qemu 0.12 [3.1], поэтому для реализации поддержки мультисетевых устройств в Qemu/KVM, реализуемых согласно схеме, показанной на рисунке 1.1, используются их более современные аналоги -device DEVNAME и -netdev TYPE
Рисунок 1.1
1.2 Проблема "IP-Config: Auto-configuration of network failed"
Показана в дампе 1.2.1
Дамп 1.2.1
... [ 7.215993] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/amba/amba:fpga/10007000.kmi/serio1/input/input2 [ 7.380255] usb 1-2: new full-speed USB device number 3 using ohci-pci [ 7.656654] ftdi_sio 1-2:1.0: FTDI USB Serial Device converter detected [ 7.663882] usb 1-2: Detected FT232BM [ 7.674369] usb 1-2: FTDI USB Serial Device converter now attached to ttyUSB0 [ 9.439977] ..... timed out! [ 90.298166] IP-Config: Reopening network devices... [ 90.330664] Sending DHCP and RARP requests ...... timed out! [ 177.651921] IP-Config: Auto-configuration of network failed ...
Которая заключалась в указанных неверно и переданных в опции ядра ip= статического IP-адреса (Static IP Address) , который изначально рассчитан на использование с одним сетевым устройством.
1.3 Переменные QB_TAP_OPT и QB_NETWORK_DEVICE
Определяемые в описании, файла конфигурации -conf/machine/qemuarm5te.conf , к реализуемой эмулируемой виртуальной платформы "qemuarm5te" в сборочной машине Yocto/poky, интерисующий фрагмент показаны в дампе 1.3.1
Дамп 1.3.1
#@TYPE: Machine #@NAME: QEMU ARM9 machine #@DESCRIPTION: Machine configuration for running an ARMv5te system on QEMU require conf/machine/include/qemu.inc require conf/machine/include/tune-arm926ejs.inc ... # network device to be access from host machine QB_NETWORK_DEVICE = "-device virtio-net-pci,netdev=net0,mac=@MAC@" QB_NETWORK_DEVICE += " -device virtio-net-pci,netdev=net1" # network option for 'tap' mode QB_TAP_OPT = "-netdev tap,id=net0,ifname=tap0,script=no,downscript=no" QB_TAP_OPT += " -netdev tap,id=net1,ifname=tap1,script=no,downscript=no" ... KMACHINE_qemuarmv5 = "qemuarm5te"
Далее, переменные будут использованы в скрипте runqemu, который нужно модифицировать, потому что значения сетевого устройства tap0 прописаны жестко и не учитывают возможность одновременного использования с другими запущенными копиями Qemu/KVM , например в проекте gnome-boxes
2. Решение
2.1 Реализация схемы мультисетевых устройств
Как показано на рисунке 1.1, главной проблемой реализации поддержки мультисетевых устройств является идентификация -device DEVNAME и -netdev TYPE, потому что отсутствие явного сопоставления этих функций приводит к появлению поперечной связи внутри пар сетевых интерфейсов tap0 / eth0 и tap1 / eth0
Для устранения этой связи в обоих опциях вводится параметр id=, который устанавливает данное сопоставление внутри пар tap0 / eth0 и tap1 / eth0, как показано в дампе 2.1.1
Дамп 2.1.1
... QB_NETWORK_DEVICE = "-device virtio-net-pci,netdev=net0,mac=@MAC@" QB_NETWORK_DEVICE += "-device virtio-net-pci,netdev=net1" QB_TAP_OPT = "-netdev tap,id=net0,ifname=tap0,script=no,downscript=no" QB_TAP_OPT = "-netdev tap,id=net1,ifname=tap1,script=no,downscript=no" ...
Таким образом, -netdev tap,id=net0,ifname=tap0 будет связан -device virtio-net-pci,netdev=net0 , а -netdev tap,id=net1,ifname=tap1 с -device virtio-net-pci,netdev=net1
В результате чего, как показано на рисунке 1.1, поперечная связь исчезнет, а вертикальные связи пар tap0 / eth0, tap1 / eth0 будут обрамлены соответствующими цветами — красным и зеленым.
2.2 Устранение проблемы "IP-Config: Auto-configuration of network failed"
Как было показано ранее в дампе 1.2.1, вывод данного сообщения сопровождался с внушительной задержкой, примерно равной 1.5 минуты, между выдаваемыми диагностическими сообщениями ядра Linux на консоль "..... timed out!" и "IP-Config: Reopening network devices..."
Как показал ручной статический анализ в редакторе исходного кода скрипта runqemu сборочной машине Yocto/poky, в основе данной ошибки лежала таже проблема, что и с сопоставлением интерфейсов вычислительного узла эмулятора Qemu/KVM (host) и виртуального узла в режиме роутер (Route-VM), а именно установка статической конфигурации IP адресов и таблицы IP-маршрутизации в ядре Linux[3.2], которая показана в листинге 2.2.1
Листинг 2.2.1
... 129 class BaseConfig(object): 130 def __init__(self): … 220 self.cmdline_ip_tap = "ip=192.168.7.@CLIENT@::192.168.7.@GATEWAY@:255.255.255.0" … 1099 def setup_tap(self,tapdev,subnet): … 1168 self.tap = tap 1169 tapnum = int(tap[3:]) 1170 gateway = tapnum * 2 + 1 1171 client = gateway + 1 1172 if self.fstype == 'nfs': 1173 self.setup_nfs() 1174 netconf = " " + self.cmdline_ip_tap 1175 netconf = netconf.replace('@CLIENT@', str(client)) 1176 netconf = netconf.replace('@GATEWAY@', str(gateway)) 1177 logger.info("Network configuration:%s", netconf) ...
Как показано в строках 220,1174-1177 листинга 2.2.2, статическая конфигурация IP адресов и инициализация таблицы IP-маршрутизации в ядре Linux устанавливается путем передачи ему параметра "ip=", полный формат значения которого показан в листинге 2.2.2
Листинг 2.2.2
ip=<client-ip>:<srv-ip>:<gw-ip>:<netmask>:<host>:<device>:<autoconf>
Как показано в листинге 2.2.2, в первой, во второй и в третьей позиции передаются IP-адреса клиента, NFS-сервера и шлюза, т.е. в client-ip — IP-адрес сетевого узла и gw-ip — щлюза через который будет осуществляться доступ к NFS серверу, указанному в srv-ip
Кроме того, в значениях параметра <netmask> — маска подсети, в <host> — имя узла, <device> — сетевое устройство с которым идентифицируется данная подсеть, а также какой протокол rarp или bootp будет указан в настройках автоконфигурации – <autoconf> . Также в <autoconf> может быть указано both (автоопределение включено) , off (автоопределение выключено), последний, как мне показалось, предпочтителен.
Результат использования параметра ip= показан в листинге 2.2.3
Листинг 2.2.3
... 1099 def setup_tap(self,tapdev,subnet): ... 1168 self.tap = tap 1169 tapnum = int(tap[3:]) 1170 gateway = tapnum * 2 + 1 1171 client = gateway + 1 1172 if self.fstype == 'nfs': 1173 self.setup_nfs() 1174 if subnet = "192.168.7" : 1175 netconf = "192.168.7.%s::192.168.2.%s:255.255.255.0::tap%d:off" % (client, gateway,tapnum) 1176 logger.info("Network configuration:%s", netconf) ... 1191 def setup_network(self): ... 1204 self.setup_tap("tap0", "192.168.7") 1205 self.setup_tap("tap1", "192.168.8")
Как показано в строках 1174-1176 листинга 2.2.3, при двойной настройке в setup_tap() нужно обязательно указывать адрес подсети "192.168.7", значения для которой указываются в параметре ip= : в первой, и третьей позиции передаются IP-адреса клиента и шлюза, в четвертой маска подсети (mask). И самое главное устраняющее ошибку "IP-Config: Auto-configuration of network failed" имя сетевого устройство (device), в данном случае это будет значение tap0 в шестой позиции, и отключающее автоконфигурацию (autoconf) значение off в седьмой позиции. При этом имя узла в пятой позиции (host) не указывается, т.е. остается пустым.
2.3 Использование переменных QB_TAP_OPT и QB_NETWORK_DEVICE
Осуществляется чтением их значений в скрипте runqemu сборочной машины Yocto/poky, как показано в листинге 2.3.1
Листинг 2.3.1
1099 def setup_tap(self): ... 1180 qb_tap_opt = self.get('QB_TAP_OPT') ... 1189 self.set('NETWORK_CMD', '%s %s' % (self.network_device.replace('@MAC@', mac), qemu_tap_opt)) ... 1191 def setup_network(self): ... 1196 self.network_device = self.get('QB_NETWORK_DEVICE') or self.network_device ...
Как показано в листинге 2.3.1, фрагменте скрипта runqemu сборочной машинеYocto/poky чтение переменных QB_TAP_OPT и QB_NETWORK_DEVICE происходит до запуска эмулятора Qemu/KVM при получении соответствующих значений опций -device DEVNAME и -netdev TYPE
3. Библиография
3.1 Qemu.Documentation/Networking.The legacy -net option
3.2 Setting a Static IP Address Using the Kernel Command Line