qemu启动参数修改.docx
《qemu启动参数修改.docx》由会员分享,可在线阅读,更多相关《qemu启动参数修改.docx(6页珍藏版)》请在冰豆网上搜索。
qemu启动参数修改
对于qemu的启动参数,qemu使用了一些基本的框架函数完成相关的解析,方便后续开发人员增加功能。
这部分的代码还是有点复杂,所以自己总结一下。
qemu-kvm启动参数的一个例子,使用libvirt创建的一个虚拟机。
/usr/libexec/qemu-kvm
-namerhel6.5
-S
-Mpc-0.15
-enable-kvm
-m1024
-realtimemlock=off
-smp1,sockets=1,cores=1,threads=1
-uuid8f338d83-41c1-9df6-d42f-851f13949359
-no-user-config
-nodefaults
-chardevsocket,id=charmonitor,path=/var/lib/libvirt/qemu/rhel6.5.monitor,server,nowait
-monchardev=charmonitor,id=monitor,mode=control
-rtcbase=utc
-no-shutdown
-bootc
-drivefile=/var/lib/libvirt/images/rhel6.5.img,if=none,id=drive-virtio-disk0,format=raw,cache=none
-devicevirtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0
-driveif=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw
-deviceide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
-netdevtap,fd=23,id=hostnet0
-devicee1000,netdev=hostnet0,id=net0,mac=52:
54:
00:
61:
00:
e7,bus=pci.0,addr=0x3
-chardevpty,id=charserial0
-deviceisa-serial,chardev=charserial0,id=serial0
-usb-deviceusb-tablet,id=input0
-vnc127.0.0.1:
0
-vgacirrus
-devicevirtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
qemu参数代码分析,以realtime这个参数为例进行说明:
修改点一:
qemu_add_opts(&qemu_realtime_opts);
修改点二:
staticQemuOptsListqemu_realtime_opts={
.name="realtime",
.head=QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
.desc={
{
.name="mlock",
.type=QEMU_OPT_BOOL,
},
{/*endoflist*/}
},
};
修改点三:
caseQEMU_OPTION_realtime:
opts=qemu_opts_parse(qemu_find_opts("realtime"),optarg,0);
if(!
opts){
exit
(1);
}
configure_realtime(opts);
break;
修改点四:
staticvoidconfigure_realtime(QemuOpts*opts)
{
boolenable_mlock;
enable_mlock=qemu_opt_get_bool(opts,"mlock",true);
if(enable_mlock){
if(os_mlock()<0){
fprintf(stderr,"qemu:
lockingmemoryfailed\n");
exit
(1);
}
}
}
修改点五:
qemu-option.hx中增加
DEF("realtime",HAS_ARG,QEMU_OPTION_realtime,
"-realtime[mlock=on|off]\n"
" runqemuwithrealtimefeatures\n"
" mlock=on|offcontrolsmlocksupport(default:
on)\n",
QEMU_ARCH_ALL)
STEXI
@item-realtimemlock=on|off
@findex-realtime
Runqemuwithrealtimefeatures.
mlockingqemuandguestmemorycanbeenabledvia@option{mlock=on}
(enabledbydefault).
ETEXI
下面分析一下这些函数的处理流程:
1.qemu_add_opts(&qemu_realtime_opts);
qemu_add_opts函数在include/qemu/config-file.h中声明,在util/qemu-config.c中定义。
在util/qemu-config.c中定义静态变量
staticQemuOptsList*vm_config_groups[32];
staticQemuOptsList*drive_config_groups[4];
定义了数组,通过qemu_add_opts增加到vm_config_groups数组中。
qemu_realtime_opts定义如下:
staticQemuOptsListqemu_realtime_opts={
.name="realtime",
.head=QTAILQ_HEAD_INITIALIZER(qemu_realtime_opts.head),
.desc={
{
.name="mlock",
.type=QEMU_OPT_BOOL,
},
{/*endoflist*/}
},
};
2.在vl.c的main函数中,调用lookup_opt,该函数根据argv当前执行的参数,查找qemu_options变量,返回对应的指针。
返回的optarg和optind参数含义:
optarg执行对应参数后对应的内容,比如-realtime后的mlock=off.
返回值的类型是QemuOption,对应的是和qemu-option.hx中名称一致的变量指针,qemu_options变量在lv.c中定义。
staticconstQEMUOptionqemu_options[]={
{"h",0,QEMU_OPTION_h,QEMU_ARCH_ALL},
#defineQEMU_OPTIONS_GENERATE_OPTIONS
#include"qemu-options-wrapper.h"
{NULL},
};
typedefstructQEMUOption{
constchar*name;
intflags;
intindex;
uint32_tarch_mask;
}QEMUOption;
#defineHAS_ARG0x0001
#include"qemu-options-wrapper.h"中通过宏分别处理QEMU_OPTIONS_GENERATE_ENUM、QEMU_OPTIONS_GENERATE_HELP、QEMU_OPTIONS_GENERATE_OPTIONS。
具体的内容在#include"qemu-options.def"
通过宏处理后,qemu_options内容被填充。
QEMU_OPTIONS_GENERATE_HELP在如下场景下使用。
staticvoidhelp(intexitcode)
{
version();
printf("usage:
%s[options][disk_image]\n\n"
"'disk_image'isarawharddiskimageforIDEharddisk0\n\n",
error_get_progname());
#defineQEMU_OPTIONS_GENERATE_HELP
#include"qemu-options-wrapper.h"
printf("\nDuringemulation,thefollowingkeysareuseful:
\n"
"ctrl-alt-f togglefullscreen\n"
"ctrl-alt-n switchtovirtualconsole'n'\n"
"ctrl-alt togglemouseandkeyboardgrab\n"
"\n"
"Whenusing-nographic,press'ctrl-ah'togetsomehelp.\n");
exit(exitcode);
}
枚举宏的定义在qemu-options.h中定义
#ifndef_QEMU_OPTIONS_H_
#define_QEMU_OPTIONS_H_
enum{
#defineQEMU_OPTIONS_GENERATE_ENUM
#include"qemu-options-wrapper.h"
};
#endif
3.qemu_find_opts代码流程,返回对应名称的QemuOptsList变量。
QemuOptsList*qemu_find_opts(constchar*group)
{
QemuOptsList*ret;
Error*local_err=NULL;
ret=find_list(vm_config_groups,group,&local_err);
if(error_is_set(&local_err)){
error_report("%s",error_get_pretty(local_err));
error_free(local_err);
}
returnret;
}
调用qemu_opts_parse函数,根据QemuOptsList中定义的数据格式,生成QemuOpts变量,QemuOpts变量的格式定义如下:
在include/qemu/option_int.h
structQemuOpt{
constchar *name;
constchar *str;
constQemuOptDesc*desc;
union{
boolboolean;
uint64_tuint;
}value;
QemuOpts *opts;
QTAILQ_ENTRY(QemuOpt)next;
};
structQemuOpts{
char*id;
QemuOptsList*list;
Locationloc;
QTAILQ_HEAD(QemuOptHead,QemuOpt)head;
QTAILQ_ENTRY(QemuOpts)next;
};
最终可以调用qemu_opt_get_bool来获取参数的具体值。
qemu参数框架已经根据定义的格式完成了解析。