KVM-QEMU vdagent實現機制分析(二)

1.       虛擬串口模塊的初始化註冊

QEMU中與虛擬串口(virtio-serial)通信相關的文件主要有以下幾個:

Virtio-pci.c

virtio-serial-bus.c(h)            //從名字上看也像

virtio-console.c

vl.c                         //qemumain函數在這裏

Virtio-pci.c的最後一行是這樣的:

type_init(virtio_pci_register_types)

virtio-serial-bus.c最後一行是這樣的:

type_init(virtio_serial_register_types)

Type_init是一個宏定義,它的定義在module.h裏面,它調了module_init這個宏

Module_init的定義如下:

#define  module_init(function, type)                                         \

static void  __attribute__((constructor)) do_qemu_init_ ## function(void) {  \

    register_module_init(function, type);                                   \

}

因爲__attribute__((constructor))類似全局變量類的構造函數,會在qemumain()之前被執行。因此可以看成是virtio-serial-bus這個模塊會在qemu進程運行的最初就被初始化註冊(實際是將真正的模塊初始化函數virtio_serial_register_types設置好,並將該模塊加入到全局模塊鏈表中)。同理,virtio-pcivirtio-console和其他設備模塊都是這樣的。

2.       虛擬串口模塊的初始化

真正的模塊構造是在vl.cmain()函數中調用到:module_call_init(MODULE_INIT_QOM);開始的,該函數遍歷全局模塊鏈表逐一做初始化。就virtio-serial-bus virtio-serial port的初始化流程如下:

 

上圖只是一些主要API的調用流程,大致介紹一下:

1)        Virtio-pci模塊註冊的時候註冊了virtio-serial-bus這個虛擬串口設備,因此在模塊初始化的過程中virtio-serial-busvirtio_serial_init初始化函數會被調用;

2)        virtio-serial-busvirtio_serial_init裏面除了做了最common的初始化之外,主要做了兩件事:

a)建立了與虛擬機vdagent通信的數據輸入輸出隊列;

b)建立了與虛擬機vdagent通信的控制消息的輸入輸出隊列;

3)        在控制接收隊列中有vdagent發送過來的消息的時候,handle_control_message被觸發;

4)        Virtio-console.c裏面也在模塊初始化中已經註冊了virtio-serial-port這個設備模塊,並註冊了VirtIOSerialPortClass類的回調函數guest_open

5)        因此當virtio-serial-bushandle_control_message裏判斷是VIRTIO_CONSOLE_PORT_OPEN消息的時候,virtio-console.cguest_open消息被調用;

6)        Guest_open的下一步處理在Spice-qemu-char.cspice_chr_guest_open函數中,接下來qemu將這個事件傳遞給了spice server去處理了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章