Предполагая, что вы используете виртуальные машины на одном хосте, а не на нескольких хостах, самый простой способ создать сеть между виртуальными машинами QEMU и другими виртуальными машинами (или реальными хостами )— использовать ответвительные устройства вместо многоадресной рассылки., затем соедините крановые устройства и добавьте к мосту свои интерфейсы контейнера Docker (или что угодно ).
Кстати, синтаксис и описание сети в приведенной вами ссылке устарели и на каком-то этапе исчезнут. В частности, исчезнет концепция вланов QEMU. В текущем синтаксисе используйте что-то вроде
-netdev tap,ifname=qemu0
, а затем (как root)
ip link add br_qemu type bridge
ip link set br_qemu up
ip link set qemu0 master br_qemu
ip link set qemu1 master br_qemu
и т. д. Если вы создаете мост перед запуском виртуальных машин, вы также можете использовать -netdev bridge,br=br_qemu
, чтобы заставить QEMU добавить к мосту интерфейсы ответвлений.
Если вам особенно нужна многоадресная рассылка, потому что ваши виртуальные машины работают на разных физических хостах, это будет сложнее. Первым шагом было бы выяснить формат, в котором QEMU отправляет пакеты (это не необработанный пакет, но я не смотрел дальше ), а вторым — написать прокси, который присоединяется к группе многоадресной рассылки, и пересылает между этой группой и интерфейсом крана.
В качестве альтернативы (, но менее эффективно ), вы можете запустить выделенную виртуальную машину QEMU с двумя сетевыми картами, одной многоадресной рассылкой и одной ответвительной, которая настроена только на пересылку между ними.
Еще лучшей альтернативой было бы реализовать связь между различными физическими хостами по-другому (туннель, VLAN через физическую LAN (настоящие VLAN 801.q, а не QEMU )), и придерживаться крановые интерфейсы.
Редактировать
Чтобы добавить VLAN в вашу локальную сеть, скажем eth0
на хосте, просто выполните
ip link add link eth0 name eth0.5 type vlan id 5
, где 5
— выбранный вами тег VLAN. Далее добавляем этот интерфейс в мост
ip link set eth0.5 master br_qemu
и вы можете идти. Вы можете поместить эти две команды в сценарий, который вы используете для запуска виртуальных машин. В качестве альтернативы, поместите эквивалент этого в/etc/network/interfaces
(google или прочитайте справочную страницу для деталей ). Да, это требует небольшой настройки хоста.
Редактировать
Хорошо, я посмотрел формат многоадресных пакетов, отправляемых QEMU, и это всего лишь кадр Ethernet. Таким образом, вы можете сделать что-то вроде
socat UDP4-DATAGRAM:230.0.0.1:1234,sourceport=1234,ip-add-membership=230.0.0.1:10.0.0.2 TUN:10.2.3.1/24,tun-type=tap,iff-no-pi,iff-up
на хосте с контейнером докеров, где 10.0.0.2
— допустимый IP-адрес хоста по отношению к группе многоадресной рассылки, например. IP-адрес eth0
. Это даст вам интерфейсtap
(уровня 2 ), где вы сможете отправлять пакеты Ethernet и получать их от группы многоадресной рассылки. Теперь вам нужно только соединить/направить их в контейнер Docker.
Вместо socat
вы также можете написать собственную короткую программу на C и т. д., если хотите и считаете, что это более эффективно.
Вы можете использовать цикл while
вокруг документа здесь -:
while IFS= read -r x; do
cat << EOF > "${x}_M0.ctl"
seqfile = ${x}_p.phy
treefile = Sametree.txt
outfile = ${x}_M0_mlc
getSE = 0
RateAncestor = 1
Small_Diff = 5e-7
cleandata = 1
fix_blength = 2
method = 0
EOF
done < list.txt
Если строки в вашем list.txt
имеют начальные или конечные символы SPC или TAB, которые должны не интерпретироваться как часть имени файла (, и вы не изменили иным образом переменную IFS
), затем опустите назначение IFS=
перед командой read
:
while read -r x; do
Или явно установите SPC и TAB:
while IFS=$' \t' read -r x; do
(обратите внимание, что расширение его на другие пробельные символы, такие как CR
, FF
, NBSP
... не будет работать, поскольку они не получают специальной обработки пробелов IFS, только SPC, TAB и NL ).
#!/bin/bash
tr -d '[:blank:]' < list.txt > outputFile.tmp
for i in $(cat outputFile.tmp)
do
echo "seqfile = ${i}_p.phy" >> ${i}_M0.ctl
echo "treefile = Sametree.txt" >> ${i}_M0.ctl
echo "outfile = ${i}_M0_mlc" >> ${i}_M0.ctl
echo "" >> ${i}_M0.ctl
echo "getSE = 0" >> ${i}_M0.ctl
echo "RateAncestor = 1" >> ${i}_M0.ctl
echo "Small_Diff = 5e-7" >> ${i}_M0.ctl
echo "cleandata = 1" >> ${i}_M0.ctl
echo "fix_blength = 2" >> ${i}_M0.ctl
echo "method = 0" >> ${i}_M0.ctl
done
exit 0