Komunikace přes sokety

From DCEwiki
Jump to navigation Jump to search

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"
...