Доступ к многоадресным сетям qemu (из контейнеров Docker)

grep -Zlr "\<THE_WORD\>" * | xargs -0 wc -l

Опции для grep:

  • -Z - завершать напечатанные имена файлов нулевым/нулевым байтом для их разделения (помогает при странных именах или именах с пробелами)
  • -l - перечислять имена файлов, а не строки, которые соответствуют
  • -r - рекурсивно
  • -i - игнорировать регистр (необязательно, но возможно полезно для поиска ВСЕХ вариантов)

А в кавычках, вокруг THE_WORD, я использовал "разделители слов" (\< и \>), которые предотвращают нахождение "HI" в "WHICH". Полезно, это.

Передайте список имен файлов, содержащих "THE_WORD" с нулевым разделителем в xargs, сообщив ему, что он ожидает разделители нулевых байт (-0), выполните wc (word-count), показывая количество строк (-l)


EDIT:

Чтобы ответить на ваш вопрос в комментариях, попробуйте этот вариант: (Я провел исследование!)

grep -oi "\<THE_WORD\>" /dev/null * | sort | uniq -c 

И объяснение:

  • -o говорит выводить КАЖДОЕ вхождение в строку, так что если у вас есть "blah blah blah THE_WORD blah THE_WORD blah blah blah blah", он выведет ДВА раза для этой строки, без этого флага grep вывел бы только ОДИН раз для этой строки.
  • -i совпадают варианты верхнего и нижнего регистра (т.е. The_Word, the_word, etc)
  • \< должно быть началом слова, таким образом 'HI' НЕ найдено в 'WHICH'.
  • `>' должен заканчиваться на конце слова, что опять же предотвращает нахождение 'HI' в 'WHICH'
  • /dev/null фиктивное имя файла, чтобы заставить grep ВСЕГДА выводить имена файлов, даже если вы ищете только один файл. Это можно заставить, используя опцию -H для grep, но я нахожу этот способ таким же простым и более описательным, поскольку -H можно оценить как "малоизвестную магию"

  • передайте все это в sort (который, uh.... сортирует...)

  • передайте отсортированный список в uniq, с -c для подсчета каждого вхождения в отсортированный список

И таадаа!!!

Пример:

File example.c contains:

(*H)->segments=realloc((*H)->segments,sizeof(segment_t*)*((*H)->segment_count+1));

xenon-lornix:~/projects/emma> grep -oi "\<H\>" /dev/null *.c | sort | uniq -c
  3 example.c:H

Таким образом возвращается список из count (3), where (example.c), и what (H)!!! Вуаля!!! Урааааа!!!

Еще один, с тем же содержимым файла:

xenon-lornix:~/projects/emma> grep -oi "\<segments\>" /dev/null example.c | sort | uniq -c
  2 aa.c:segments

Здесь видно, что он нашел оба сегмента, но не засчитал сегмент. Ключи \< и \> заставляют сопоставлять только целые слова. THE_WORD123 не НЕ соответствует _THE_WORD_, разрыв слова происходит на неалфавитно-цифровых символах. К СВЕДЕНИЮ.

0
17.03.2018, 07:23
1 ответ

Предполагая, что вы используете виртуальные машины на одном хосте, а не на нескольких хостах, самый простой способ создать сеть между виртуальными машинами 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 и т. д., если хотите и считаете, что это более эффективно.

0
28.01.2020, 04:28

Теги

Похожие вопросы