qemu系統的trace使用

                                                       

首席安全官+是一個聚焦“雲計算、大數據、人工智能”等高技術領域,致力網絡空間安全發展與戰略研究,發佈網絡安全創新理念、先進架構、前沿技術、產業趨勢和資本動態的平臺,努力打造“有特色、高水平、國際化”的網絡安全思想高地。

                                                                                          微信二維碼

                                       

目錄

1. 重新編譯qemu

2. 日誌記錄方式

2.1. 默認效果

2.2. 分析代碼

2.3.查看到日誌文件中打印

2.4.對接libvirt

3. 添加自定義trace-event


1. 重新編譯qemu

[root@localhost qemu-2.8.0]# ./configure  --target-list=x86_64-softmmu --enable-kvm --prefix=/usr --enable-debug --enable-numa --enable-trace-backends=simple

[root@localhost qemu-2.8.0]#  make

編譯參數–enable-trace-backends可以指定trace系統使用的後端系統(backend),如果指定爲log,這樣trace函數如下:

                           

                                                                                                 圖1-1
如果後端爲simple(默認值),則trace函數爲:

                                

                               

                                                                                                   圖1-2
各種不同的trace方式的詳細解釋可以參考qemu文檔:./qemu-5.0.0/docs/devel/tracing.txt
 

2. 日誌記錄方式

2.1. 默認效果

打開某個event的開關,然後進行操作,默認可以打印在qemu monitor上:

(qemu) trace-event migration_thread_setup_complete on
(qemu) migrate -d tcp:0:4444
(qemu)
(qemu)
(qemu)
(qemu) [email protected]:migration_thread_setup_complete

2.2. 分析代碼

qemu_logfile
$1 = 0x7fddf6411450 "%d@%zd.%06zd:migration_thread_setup_complete \n"
(gdb) p qemu_logfile
$2 = (FILE *) 0x7fddeff521c0 <_IO_2_1_stderr_>

可以看到默認打印在標準輸出stderr上.

qemu_logfile = fopen(logfilename, log_append ? “a” : “w”);

                               

                                                                                      圖2-1 設置logfile
這裏沒有設置logfilename,因此qemu_logfile = stderr,所以
#全局搜索logfilename,得到,但是打斷點之後發現並沒有走這裏,因此繼續跟蹤該函數調用情況。

                               

                                                                                      圖2-2
全局搜索qemu_set_log_filename

                                

                                                                                                      圖2-3

trace_init_file函數會被調用,並且file爲空,因此qemu_set_log_filename纔沒有執行,繼續跟蹤調用棧
vl.c:4129 trace_init_file(trace_file);

                               

                                                                                              圖2-4

然後發現不是這裏,這裏是backend爲其他選項的時候的處理,log應該是另外一個地方也調用了qemu_set_log_filename,是下面vl.c:4134處

if (log_file) {
        qemu_set_log_filename(log_file, &error_fatal);
    }

                                  

                                                                                          圖2-5
搜索QEMU_OPTION_D

DEF("D", HAS_ARG, QEMU_OPTION_D, \
"-D logfile      output log to logfile (default stderr)\n",

使用方式應該是-D /var/log/qemu/qemu.log

2.3.查看到日誌文件中打印

[root@localhost ~]# cat /var/log/qemu/qemu.log
[email protected]:migration_thread_setup_complete

2.4.對接libvirt

xml中使用qemu:commandline配置log文件路徑

[root@localhost mydisk1]# cat vm1.xml
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>vm1</name>
  <memory unit='M'>2048</memory>
  <metadata>
    <app1:foo xmlns:app1="http://app1.org/app1/">..</app1:foo>
    <app2:bar xmlns:app2="http://app1.org/app2/">..</app2:bar>
  </metadata>
  <qemu:commandline>
                <qemu:arg value='-D'/>
                <qemu:arg value='/var/log/qemu/qemu.log'/>
  </qemu:commandline>
.....
</domain>
[root@localhost mydisk1]# virsh start vm1
error: Failed to start domain vm1
error: internal error: process exited while connecting to monitor: /var/log/qemu/qemu.log: Permission denied

解決方法:關閉selinux

查看進程

[root@localhost mydisk1]# ps -ef|grep qemu
root       899     1  0 Jan03 ?        00:00:00 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio-ports/org.qemu.guest_agent.0 --blacklist=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status -F/etc/qemu-ga/fsfreeze-hook
root     21360     1 28 16:31 ?        00:00:01 /usr/bin/qemu-system-x86_64 -name guest=vm1,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-7-vm1/master-key.aes -machine pc-i440fx-2.6,accel=kvm,usb=off -cpu Broadwell,+vme,+ss,+ht,+vmx,+osxsave,+f16c,+rdrand,+hypervisor,+arat,+tsc_adjust,+xsaveopt,+pdpe1gb,+abm -m 2048 -realtime mlock=off -smp 2,sockets=1,cores=2,threads=1 -uuid 36a5008d-2da8-4790-955b-57fc1f32c376 -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-7-vm1/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime -no-shutdown -boot order=c,menu=on,strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 -drive file=/home/mydisk1/ubuntu-14.04-server.qcow2,format=qcow2,if=none,id=drive-ide0-0-0 -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -netdev tap,fd=24,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=00:02:02:00:a0:04,bus=pci.0,addr=0x3 -chardev socket,id=charserial0,host=0.0.0.0,port=4003,telnet,server,nowait -device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,path=/var/lib/libvirt/qemu/test.agent,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 -vnc 0.0.0.0:0 -k en-us -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -D /var/log/qemu/qemu.log -msg timestamp=on
root     21388 20174  0 16:32 pts/1    00:00:00 grep --color=auto qemu

通過virsh打開trace-event

[root@localhost ~]# virsh qemu-monitor-command  vm1 --hmp "trace-event migration_thread_setup_complete on"

#列出已經打開的trace-event

[root@localhost ~]# virsh qemu-monitor-command  vm1 --hmp "info trace-events"

3. 添加自定義trace-event

qemu目錄下每個子系統都有一個trace-events文件,裏面申明瞭很多靜態的trace events

[root@localhost qemu-2.8.0]# ll */trace-events
-rw-r--r--. 1 user user   822 Dec 21  2016 audio/trace-events
-rw-r--r--. 1 user user  8024 Dec 21  2016 block/trace-events
-rw-r--r--. 1 user user  1655 Dec 21  2016 crypto/trace-events
-rw-r--r--. 1 user user  4083 Dec 21  2016 io/trace-events
-rw-r--r--. 1 user user   834 Dec 21  2016 linux-user/trace-events
-rw-r--r--. 1 user user 13764 Dec 21  2016 migration/trace-events
-rw-r--r--. 1 user user  1323 Dec 21  2016 net/trace-events
-rw-r--r--. 1 user user  2032 Dec 21  2016 qapi/trace-events
-rw-r--r--. 1 user user   333 Dec 21  2016 qom/trace-events
-rw-r--r--. 1 user user   693 Dec 21  2016 target-arm/trace-events
-rw-r--r--. 1 user user   352 Dec 21  2016 target-i386/trace-events
-rw-r--r--. 1 user user   252 Dec 21  2016 target-ppc/trace-events
-rw-r--r--. 1 user user  1133 Dec 21  2016 target-s390x/trace-events
-rw-r--r--. 1 user user  2079 Dec 21  2016 target-sparc/trace-events
-rw-r--r--. 1 user user  3004 Dec 21  2016 ui/trace-events
-rw-r--r--. 1 user user  1697 Dec 21  2016 util/trace-events

這裏用migration/trace-events做實驗

[root@localhost qemu-2.8.0]# cat migration/trace-events |grep migration_thread_
migration_thread_after_loop(void) ""
migration_thread_file_err(void) ""
migration_thread_setup_complete(void) ""
migration_thread_huangxun(void) ""
migration_thread_low_pending(uint64_t pending) "%" PRIu64

仿照migration_thread_setup_complete寫一個migration_thread_huangxun,
括號裏面是參數,“”是格式,可以參考qemu源碼主目錄下的trace-events文件的講解,添加完成後,重新編譯qemu
查看新生成的代碼

[root@localhost qemu-2.8.0]# grep -l -r 'huangxun'
qemu-img
trace/generated-tracers.o
trace/generated-tracers.h
trace/generated-tracers.h-timestamp
trace/generated-tracers.c
trace/generated-tracers.c-timestamp
qemu-io
migration/trace-events
i386-softmmu/qemu-system-i386
ivshmem-server
qemu-nbd
libqemuutil.a
trace-events-all
qemu-ga
x86_64-softmmu/qemu-system-x86_64
fsdev/virtfs-proxy-helper

#[root@localhost qemu-2.8.0]# cat trace/generated-tracers.h|less
static inline void trace_migration_thread_huangxun(void)
{
    if (true) {
        if (trace_event_get_state(TRACE_MIGRATION_THREAD_HUANGXUN)) {
            struct timeval _now;
            gettimeofday(&_now, NULL);
            qemu_log_mask(LOG_TRACE, "%d@%zd.%06zd:migration_thread_huangxun " "" "\n",
                          getpid(),
                          (size_t)_now.tv_sec, (size_t)_now.tv_usec
                          );
        }
    }
}
#[root@localhost qemu-2.8.0]# cat trace/generated-tracers.c|less
TraceEvent _TRACE_MIGRATION_THREAD_HUANGXUN_EVENT = {
    .id = 0,
    .vcpu_id = TRACE_VCPU_EVENT_NONE,
    .name = "migration_thread_huangxun",
    .sstate = TRACE_MIGRATION_THREAD_HUANGXUN_ENABLED,
    .dstate = &_TRACE_MIGRATION_THREAD_HUANGXUN_DSTATE
};
[root@localhost qemu-2.8.0]# cat trace-events-all|less
migration_thread_after_loop(void) ""
migration_thread_file_err(void) ""
migration_thread_setup_complete(void) ""
migration_thread_huangxun(void) ""

使用新增加的event

[root@localhost qemu-2.8.0]# vim migration/migration.c

                                   

                                                                                           圖3-1

進行熱遷移測試

源端啓動參數

/usr/bin/qemu-system-x86_64 -m 256 -cpu host -drive file=/home/mydisk1/ubuntu-14.04-server.qcow2 -smp 2  -enable-kvm  -net nic,model=virtio,macaddr=00:00:00:00:00:01 -net tap,ifname=tap0,script=no,downscript=no -serial telnet:0.0.0.0:4000,server,nowait -nographic  -vnc 0:0 -D /var/log/qemu/qemu.log

目的端啓動參數

/usr/bin/qemu-system-x86_64 -m 256 -cpu host -drive file=/home/mydisk1/ubuntu-14.04-server.qcow2 -smp 2  -enable-kvm  -net nic,model=virtio,macaddr=00:00:00:00:00:01 -net tap,ifname=tap1,script=no,downscript=no -serial telnet:0.0.0.0:4001,server,nowait -nographic -incoming tcp:0:4444 -vnc 0:1 -D /var/log/qemu/qemu2.log

打開event開關,並進行遷移操作

(qemu) trace-event migration_thread_huangxun on
(qemu) migrate -d tcp:0:4444

查看log,成功打印event信息

[root@localhost ~]# cat /var/log/qemu/qemu.log
[email protected]:migration_thread_huangxun

Reference

[1]QEMU 與塊設備
http://docs.ceph.org.cn/rbd/qemu-rbd/
[2]qemu monitor protocol簡介
https://blog.csdn.net/fulaidai/article/details/23714561
錯誤處理

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