Komunikace přes sokety

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání

Interaktivní práce se sokety

Pro interaktivní přístup ke konzolím přes sokety, lze použít buď socat nebo jednoduchou utilitu unixterm, která je součástí nástrojů k vde2. Ovšem socat má mnohem větší možnosti, jak se ukáže posléze..

Otevření monitorovací konzole přes unixterm

Poznámka
stroj:~# unixterm /tmp/monitor.soket
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) ^Cstroj:~#

.. a stejná konzole přes socat

Poznámka
stroj:~# socat STDIO "/tmp/monitor.soket,crnl"
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) ^Cstroj:~#

Jak vidno, výstup vypadá, i funguje v obou případech stejně, ovšem nadále již budu popisovat práci pouze s aplikací socat, jelikož unixterm nelze používat pro neinteraktivní přístup.

Otevření QMP konzole přes socat..

Poznámka
patty:~# socat STDIO "/tmp/qmp.soket,crnl"
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 14, "major": 0}, "package": ""}, "capabilities": []}}
^Cstroj:~#
Poznámka Užitečný wrapper - rlwrap

Při interaktivní práci se sokety se hodí wrapper rlwrap. Aplikace unixterm, ani socat totiž nemají historii příkazů, která se však při interaktivní práci s konzolí hodí. A to je právě funkcionalita, kterou tato utilita zajistí.

Komunikace se sokety ve skriptu

Pro komunikaci se sokety ve skriptech je ideální socat, protože umožňuje (mimo jiné) přesměrovávat vstupy a výstupy i mezi sokety vzájemně.

Při neiteraktivní práci s konzolemi QEMU však narazíte na určité rozdíly. Při komunikaci přes QMP je totiž nutné nejprve odeslat příkaz, kterým se QMP komunikace zinicializuje a teprve potom vlastní příkaz. Viz níže..

Výstup příkazu odeslaného na monitorovací konzoli...

Poznámka
stroj:~# echo 'info pci' | socat - GOPEN:"/tmp/monitor.soket,crnl"
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) 
(qemu) 
(qemu) info pci
  Bus  0, device   0, function 0:
    Host bridge: PCI device 8086:1237
      id ""
  Bus  0, device   1, function 0:
    ISA bridge: PCI device 8086:7000
      id ""
  Bus  0, device   1, function 1:
    IDE controller: PCI device 8086:7010
      BAR4: I/O at 0xc000 [0xc00f].
      id ""
  Bus  0, device   1, function 3:
    Bridge: PCI device 8086:7113
      IRQ 9.
      id ""
  Bus  0, device   2, function 0:
    VGA controller: PCI device 1013:00b8
      BAR0: 32 bit prefetchable memory at 0xf0000000 [0xf1ffffff].
      BAR1: 32 bit memory at 0xf2000000 [0xf2000fff].
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0000fffe].
      id ""
  Bus  0, device   3, function 0:
    Ethernet controller: PCI device 8086:100e
      IRQ 11.
      BAR0: 32 bit memory at 0xf2020000 [0xf203ffff].
      BAR1: I/O at 0xc040 [0xc07f].
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0001fffe].
      id ""
  Bus  0, device   4, function 0:
    RAM controller: PCI device 1af4:1002
      IRQ 11.
      BAR0: I/O at 0xc080 [0xc09f].
      id ""
(qemu) 
(qemu) stroj:~#

Výstup příkazu odeslaného na QMP konzoli...

Poznámka
patty:~# echo -e '{ "execute": "qmp_capabilities" }\n{ "execute": "query-pci" }' \
 | socat - GOPEN:"/tmp/qmp.soket,crnl"
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 14, "major": 0}, "package": ""}, "capabilities": []}}
{"return": {}}
{"return": [{"bus": 0, "devices": [{"bus": 0, "qdev_id": "", "slot": 0, "class_info": 
{"class": 1536, "desc": "Host bridge"}, 
"id": {"device": 32902, "vendor": 4663}, "function": 0, "regions": []}, 
{"bus": 0, "qdev_id": "", "slot": 1, "class_info": {"class": 1537, "desc": "ISA bridge"}, 
"id": {"device": 32902, "vendor": 28672}, "function": 0, "regions": []}, 
{"bus": 0, "qdev_id": "", "slot": 1, "class_info": {"class": 257, "desc": "IDE controller"}, 
"id": {"device": 32902, "vendor": 28688}, "function": 1, "regions": [{"bar": 4, "size": 16, 
"address": 49152, "type": "io"}]}, {"bus": 0, "qdev_id": "", "irq": 9, "slot": 1, 
"class_info": {"class": 1664, "desc": "Bridge"}, "id": {"device": 32902, "vendor": 28947}, 
"function": 3, "regions": []}, {"bus": 0, "qdev_id": "", "slot": 2, "class_info": 
{"class": 768, "desc": "VGA controller"}, "id": {"device": 4115, "vendor": 184}, 
"function": 0, "regions": [{"prefetch": true, "mem_type_64": false, "bar": 0, "size": 33554432, 
"address": 4026531840, "type": "memory"}, {"prefetch": false, "mem_type_64": false, 
"bar": 1, "size": 4096, "address": 4060086272, "type": "memory"}, {"prefetch": false, 
"mem_type_64": false, "bar": 6, "size": 65536, "address": -1, "type": "memory"}]}, {"bus": 0, 
"qdev_id": "", "irq": 11, "slot": 3, "class_info": {"class": 512, "desc": 
"Ethernet controller"}, "id": {"device": 32902, "vendor": 4110}, "function": 0, 
"regions": [{"prefetch": false, "mem_type_64": false, "bar": 0, "size": 131072, 
"address": 4060217344, "type": "memory"}, {"bar": 1, "size": 64, "address": 49216, "type": "io"}, 
{"prefetch": false, "mem_type_64": false, "bar": 6, "size": 131072, 
"address": -1, "type": "memory"}]}, {"bus": 0, "qdev_id": "", "irq": 11, "slot": 4, 
"class_info": {"class": 1280, "desc": "RAM controller"}, "id": {"device": 6900, "vendor": 4098}, 
"function": 0, "regions": [{"bar": 0, "size": 32, "address": 49280, "type": "io"}]}]}]}
stroj:~#

Jak je vidno z příkladů, příkazy, které se zadávají přes monitorovací konzoli lze zadávat i přes QMP, ovšem jejich názvy nejsou zcela identické. Jaké příkazy lze přes JSON aktuálně použít, lze zjistit zavoláním příkazu query-commands..

Poznámka
stroj:~# echo -e '{ "execute": "qmp_capabilities" }\n{ "execute": "query-commands" }' \
 | socat - GOPEN:"/tmp/qmp.soket,crnl"
...