web-dev-qa-db-ja.com

libvirtドメインのシリアルポート情報を取得しますか?

Libvirtドメインのシリアルポート情報(別名Source Path)を取得しようとしています(qemu/KVMマシンを使用):

Serial Device 1 (Primary Console)
  Device type: pty
  Source path: /dev/pts/2

しかし、 ここのAPIリファレンス を確認しましたが、Source Pathをサポートしていないようです。

そのような情報を直接リストできるVBoxManageのようなコマンドはありますか?


奇妙なことに、私はlibvirtグループに属しており、KVMマシンとvirt-managervirshを制御(開始、停止など)できます) virsh #プロンプトも表示されます。

しかし、virsh list --allコマンドでは何も表示されません。それでも、root権限で実行する必要があります。

5
daisy

KVMは、仮想化用のカーネルAPIです。 シリアルポートは扱いません。 qemuは、仮想化のパフォーマンスを向上させるためにkvmを使用できるマシン(PCおよびその他)のエミュレーターです。標準の8250 UARTシリアルポート(isa-serial)または準仮想化シリアルポート(virtio-serial)をエミュレートできます。

Qemuでは、マシンに追加するデバイスと、それらのデバイスがマップするバックエンドを指定するコマンドライン引数を使用してマシンを定義します(たとえば、ハードディスクをイメージファイルにエミュレートします)。 、tapデバイスへのネットワークアダプタ...)。

シリアルポートの場合、通常、qemuが呼び出すものchardevsにマップします。

考えられるさまざまなものがたくさんあります。通常、パイプ、ソケット、ファイル記述子、疑似端末など、バイトを送受信できるものなら何でもかまいません。

たとえば、qemuを次のように実行する場合:

qemu ... -device isa-serial,chardev=c,id=s -chardev pty,id=c 

qemuは疑似端末を割り当て、起動時のstdoutで次のことを報告します。

char device redirected to /dev/pts/18 (label c)

そして、それをVMに追加された新しいisaシリアルポートにマップします。 Linux VMを起動すると、カーネルログに次のように表示されます。

[    3.636092] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[    3.658666] 00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A

また、ゲストの/dev/ttyS0に何かを書き込むと、ホストの/dev/pts/18で読み取ることができます。

Qemu VMが開始された後、qemuが呼び出すmonitorインターフェイスで制御できます。には2つのタイプがあります。 )モニターインターフェース:

  • 人間のモニター:シェルのようなCLI
  • マシンモニター:qemuマシンプロトコル(QMP)と呼ばれるテキスト(json)プロトコルを実装するよりマシンフレンドリーなインターフェース。

何も指定せずにデフォルトのSDLコンソールを使用する場合は、を押してSDLコンソールにヒューマンモニターを表示します。 Ctrl+Alt+2

ただし、そのために任意のchardevバックエンド(pty、socket、stdio ...)を指定することもできます。通常、私はそこでstdioを使用します。

qemu ... -monitor stdio

ターミナルでmonitorを取得するには、テスト用にqemuを実行しているときにqemuを起動します。

そのmonitorインターフェイスで、info qtreeコマンドを実行して、マシンのデバイスに関する情報を取得できます。

(qemu) info qtree
bus: main-system-bus
[...]
  dev: i440FX-pcihost, id ""
[...]
bus: pci.0
[...]
  dev: PIIX3, id ""
    class ISA bridge, addr 00:01.0, pci id 8086:7000 (sub 1af4:1100)
    bus: isa.0
      type ISA
      dev: isa-serial, id "s"
    index = 0 (0)
    iobase = 1016 (0x3f8)
    irq = 4 (0x4)
    chardev = "c"

上に、前に作成したisa-serialデバイスがあり、それが"c"chardevにマップされていることがわかります。

info chardevを使用して、そのchardevから情報を取得できます。

(qemu) info chardev
parallel0: filename=vc
c: filename=pty:/dev/pts/18
compat_monitor0: filename=stdio

c/dev/pts/18ptyにマップされているのがわかります。

QMPモニターを使用して、プログラムで同じ情報を取得できます。 VMを-qmp stdioで開始すると、次のコマンドを渡すことができます。

{"execute":"qmp_capabilities"} # enable commands
{"return": {}}   # return value

{"execute":"qom-list","arguments":{"path":"/machine/peripheral/s"}}
{"return": [{"name": "parent_bus", "type": "link<bus>"}, {"name": "wakeup", "type": "uint32"}, {"name": "chardev", "type": "str"}, {"name": "irq", "type": "uint32"}, {"name": "iobase", "type": "uint32"}, {"name": "index", "type": "uint32"}, {"name": "hotpluggable", "type": "bool"}, {"name": "realized", "type": "bool"}, {"name": "type", "type": "string"}]}

# query chardev for "s":
{"execute":"qom-get","arguments":{"path":"/machine/peripheral/s","property":"chardev"}}
{"return": "c"}

# query chardevs:
{"execute":"query-chardev"}
{"return": [{"filename": "vc", "label": "parallel0"}, {"filename": "pty:/dev/pts/18", "label": "c"}, {"filename": "stdio", "label": "compat_monitor0"}]}

(これらのqom-listおよびqom-get(qomはqemuオブジェクトモデルを表す)が、Linuxマシンの/syslsおよびcatを実行することを彷彿とさせる方法を参照してください) 。

今、あなたの質問は、qemuを手動で直接呼び出すのではなく、代わりにlibvirtを使用していることを示唆しています。 libvirtは、多くの仮想化管理インフラストラクチャの1つです。 qemu(kvmの有無にかかわらず)、xen、またはvirtualbox(少なくとも)VMを管理できます。

Qemu VMの場合、libvirtでVM(virt-managerまたはその他を使用)を定義すると、qemuコマンドに渡される引数に変換され、libvirtは通常qmpモニターを使用します開始後にVM)を制御します。

libvirtドメインの場合、次のコマンドでドメインの現在の構成を取得できます。

virsh dumpxml the-domain

構成をXMLとしてダンプします。 xmllintまたはxmlstarlet、または任意のXML解析ソリューションを使用して、そこから情報を抽出できます。

$ virsh dumpxml domain | xmllint --xpath '//serial' -
<serial type="pty">
  <source path="/dev/pts/4"/>
  <target port="0"/>
  <alias name="serial0"/>
</serial><serial type="pty">
  <source path="/dev/pts/5"/>
  <target port="1"/>
  <alias name="serial1"/>
</serial><serial type="pty">
  <source path="/dev/pts/6"/>
  <target port="2"/>
  <alias name="serial2"/>
</serial>
$ virsh dumpxml domain |
  xmllint --xpath 'string(//serial[target/@port=0]/source/@path)' -
/dev/pts/4

xmlstarletと同等のもの:

Sudo virsh dumpxml domain | xmlstarlet sel -t -c '//serial'
Sudo virsh dumpxml domain |
  xmlstarlet sel -t -v '//serial[target/@port=0]/source/@path'

virsh qemu-monitor-commandコマンドを使用してQMPモニターにコマンドを渡すこともできることに注意してください。

例えば:

$ virsh qemu-monitor-command domain '{"execute":"qom-get","arguments":
{"path":"/machine/peripheral/serial0","property":"chardev"}}'
{"return":"charserial0","id":"libvirt-84"}
9