QEMU的參數解析
QEMU中定義了QEMUOption結構體來表示執行qemu-system-i386等命令時用到的選項。
並且在vl.c中定義了QEMUOption數組qemu_options來存儲所有可用的選項,並且利用qemu-options-wrapper.h來給這個數組賦值。如上圖
,#define QEMU_OPTIONS_GENERATE_OPTIONS選擇qemu-options-wrapper.h的操作,在qemu-options-wrapper.h中有一些宏
QEMU_OPTIONS_GENERATE_ENUM: 生成一個枚舉值列表,對應與上圖中QEMUOption結構的index值,例如QEMU_OPTION_h
QEMU_OPTIONS_GENERATE_HELP: 生成幫助信息輸出到標准輸出
QEMU_OPTIONS_GENERATE_OPTIONS: 生成一組選項列表
在qemu-options.hx中可以看到調用,例如object選項
給qemu_options數組賦值之后,在vl.c的main函數中根據這個數組來解析命令。
參數解析第一步,遍歷參數數組,通過lookup_opt函數來得到一個QEMUOption,判斷這個QEMUOption是否在原來生成的QEMUOption數組中,主要作用是排錯。第二步才是真正的解析
lookup_opt中通過參數名來在qemu_options這個全局數組中根據參數尋找對應的option,然后將option后邊的參數保存到optarg
第二步也是遍歷參數數組,通過lookup_opt函數找到對應的QEMUOption,然后將option后邊的參數保存到optarg通過index成員來判斷是哪個option,然后執行不同的分支。
解析參數用到的四個結構:QemuOpts, QemuOpt, QemuOptsList, QemuOptDesc
QemuOpts和QemuOpt定義在option_int.h中,QemuOpt存儲子選項,每個QemuOpt都有一個QemuOptDesc來描述子選項的名字,類型以及幫助信息。QemuOpts表示同一個id下的所有子選項,QEMU可能會多次使用同一個大選項來指定多個相同的設備,這個就是用id來區分。
子選項的類型如下:
QemuOptDesc和QemuOptsList定義在option.h中,一個QemuOptsList代表一個qemu option,子選項就存在QemuOpt中。
整個QEMU選項結構體之間的關系圖如下:
以object選項為例,具體解析
首先在vl.c的main函數中解析參數,解析參數用到的函數時qemu_opts_parse_noisily和qemu_find_opts
![
1.qemu_find_opts函數
qemu_find_opts聲明在qemu\config-file.h中,定義在qemu-config.c中,內部調用了find_list函數,find_list函數里面通過比較vm_config_groups(是一個QemuOptsList結構數組)的name與group的值,來返回一個QemuOptsList
vm_config_groups這個結構的填充,實在vl.c的main函數中通過調用qemu_add_opts這個函數把定義好的不同的選項QemuOptsList結構添加到這個數組中。
2.qemu_opts_parse_noisily函數
qemu_opts_parse_noisily聲明在qemu\option.h中,定義在util\qemu-option.c中,調用了opts_parse
在opts_parse函數中首先獲取id的值,然后調用qemu_opts_create返回一個opts,調用opts_do_parse解析。firstname是list->implied_opt_name值。
在qemu_opts_create中,判斷如果id存在或list->merge_lists存在,則直接調用qemu_opts_find來返回一個QEMUOpts結構。否則新建一個QemuOpts節點,插入list。
在qemu_opts_find中,調用宏QTAILQ_FOREACH,遍歷list中的每個QemuOpts節點,判斷id是否同時存在或同事不存在,
opts_do_parse函數中,具體的解析操作
得到一個子選項后,調用opt_set函數,首先得到這個子選項的描述信息desc,然后新建一個子選項節點QemuOpt,填充信息,將這個QemuOpt節點加入到QemuOpts這個結構中。opt->str先保存子選項的值,然后調用qemu_opt_parse函數,根據子選項的類型來給value重新賦值。
在qemu_opt_parse中根據子選項的類型,重新對value賦值。