For QEMU's startup parameters, QEMU uses some basic framework functions to complete the relevant parsing, which makes it easier for subsequent developers to add functionality.
This part of the code is still a bit complicated, so let me summarize.
An example of a QEMU-KVM startup parameter is a virtual machine created using Libvirt.
/usr/libexec/qemu-kvm
-name rhel6.5
-S
-M pc-0.15
-enable-kvm
-M 1024
-realtime Mlock=off
-SMP 1,sockets=1,cores=1,threads=1
-uuid 8f338d83-41c1-9df6-d42f-851f13949359
-no-user-config
-nodefaults
-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/rhel6.5.monitor,server,nowait
-mon Chardev=charmonitor,id=monitor,mode=control
-RTC BASE=UTC
-no-shutdown
-boot C
-drive File=/var/lib/libvirt/images/rhel6.5.img,if=none,id=drive-virtio-disk0,format=raw,cache=none
-device Virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0
-drive If=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw
-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
-netdev tap,fd=23,id=hostnet0
-device e1000,netdev=hostnet0,id=net0,mac=52:54:00:61:00:e7,bus=pci.0,addr=0x3
-chardev pty,id=charserial0
-device isa-serial,chardev=charserial0,id=serial0
-usb-device usb-tablet,id=input0
-vnc 127.0.0.1:0
-VGA Cirrus
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
QEMU parameter Code analysis, realtime this parameter as an example to illustrate:
Modify Point one:
Qemu_add_opts (&qemu_realtime_opts);
Modify Point two:
Static Qemuoptslist qemu_realtime_opts = {
. Name = "Realtime",
. Head = Qtailq_head_initializer (Qemu_realtime_opts.head),
. desc = {
{
. Name = "Mlock",
. Type = Qemu_opt_bool,
},
{/* End of List */}
},
};
Modify Point three:
Case Qemu_option_realtime:
opts = Qemu_opts_parse (qemu_find_opts ("Realtime"), Optarg, 0);
if (!opts) {
Exit (1);
}
Configure_realtime (opts);
Break
Modify Point four:
static void Configure_realtime (Qemuopts *opts)
{
BOOL Enable_mlock;
Enable_mlock = Qemu_opt_get_bool (opts, "Mlock", true);
if (Enable_mlock) {
if (Os_mlock () < 0) {
fprintf (stderr, "qemu:locking memory failed\n");
Exit (1);
}
}
}
Modify Point Five:
Increase in QEMU-OPTION.HX
DEF ("Realtime", Has_arg, Qemu_option_realtime,
"-realtime [mlock=on|off]\n"
"Run Qemu with realtime features\n"
"Mlock=on|off Controls Mlock Support (Default:on) \ n",
Qemu_arch_all)
Stexi
@item-realtime Mlock=on|off
@findex-realtime
Run Qemu with realtime features.
Mlocking Qemu and guest memory can be enabled via @option {mlock=on}
(enabled by default).
Etexi
The following is an analysis of the processing flow of these functions:
1.qemu_add_opts (&qemu_realtime_opts);
The Qemu_add_opts function is declared in include/qemu/config-file.h and defined in UTIL/QEMU-CONFIG.C.
Defining static variables in UTIL/QEMU-CONFIG.C
Static Qemuoptslist *vm_config_groups[32];
Static Qemuoptslist *drive_config_groups[4];
An array is defined and added to the vm_config_groups array by qemu_add_opts. Qemu_realtime_opts is defined as follows:
Static Qemuoptslist qemu_realtime_opts = {
. Name = "Realtime",
. Head = Qtailq_head_initializer (Qemu_realtime_opts.head),
. desc = {
{
. Name = "Mlock",
. Type = Qemu_opt_bool,
},
{/* End of List */}
},
};
2. In the main function of VL.C, call Lookup_opt, which finds the qemu_options variable and returns the corresponding pointer based on the parameters argv currently executing.
Returns the Optarg and Optind parameters meaning: Optarg executes the corresponding parameter after the corresponding content, such as-realtime after the Mlock=off.
The type of the return value is Qemuoption, which corresponds to a variable pointer in the same name as QEMU-OPTION.HX, and the qemu_options variable is defined in LV.C.
static const Qemuoption qemu_options[] = {
{"H", 0, Qemu_option_h, qemu_arch_all},
#define Qemu_options_generate_options
#include "Qemu-options-wrapper.h"
{NULL},
};
typedef struct QEMUOPTION {
const char *name;
int flags;
int index;
uint32_t Arch_mask;
} qemuoption;
#define HAS_ARG 0x0001
#include "qemu-options-wrapper.h" by macro processing Qemu_options_generate_enum, QEMU_OPTIONS_GENERATE_HELP, Qemu_options_ Generate_options.
Specific content in # include "Qemu-options.def"
After the macro is processed, the qemu_options content is populated.
The qemu_options_generate_help is used in the following scenarios.
static void Help (int exitcode)
{
Version ();
printf ("Usage:%s [options] [disk_image]\n\n"
"' Disk_image ' is a raw hard disk image for the IDE hard disk 0\n\n",
Error_get_progname ());
#define Qemu_options_generate_help
#include "Qemu-options-wrapper.h"
printf ("\nduring emulation, the following keys are useful:\n"
"Ctrl-alt-f Toggle Full screen\n"
"Ctrl-alt-n switch to Virtual Console ' n ' \ nthe"
"Ctrl-alt Toggle Mouse and keyboard grab\n"
"\ n"
"When using-nographic, press ' ctrl-a h ' to get some help.\n");
Exit (ExitCode);
}
The definition of an enumeration macro is defined in Qemu-options.h
#ifndef _qemu_options_h_
#define _qemu_options_h_
enum {
#define Qemu_options_generate_enum
#include "Qemu-options-wrapper.h"
};
#endif
3.qemu_find_opts the code flow, returning the qemuoptslist variable of the corresponding name.
Qemuoptslist *qemu_find_opts (const char *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);
}
return ret;
}
Call the Qemu_opts_parse function, generate the qemuopts variable according to the data format defined in Qemuoptslist, and define the format of the qemuopts variable as follows:
In Include/qemu/option_int.h
struct Qemuopt {
const char *name;
const char *STR;
Const QEMUOPTDESC *DESC;
Union {
BOOL Boolean;
uint64_t UINT;
} value;
Qemuopts *opts;
Qtailq_entry (qemuopt) next;
};
struct Qemuopts {
Char *id;
Qemuoptslist *list;
Location Loc;
Qtailq_head (Qemuopthead, qemuopt) HEAD;
Qtailq_entry (qemuopts) next;
};
Finally, you can call Qemu_opt_get_bool to get the specific value of the parameter. The QEMU parameter framework has been parsed according to the defined format.