diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | configure | 144 | ||||
-rw-r--r-- | disas/meson.build | 2 | ||||
-rw-r--r-- | docs/system/deprecated.rst | 11 | ||||
-rw-r--r-- | docs/system/removed-features.rst | 11 | ||||
-rw-r--r-- | fsdev/meson.build | 1 | ||||
-rw-r--r-- | hmp-commands.hx | 6 | ||||
-rw-r--r-- | hw/ide/atapi.c | 30 | ||||
-rw-r--r-- | include/ui/console.h | 2 | ||||
-rw-r--r-- | meson.build | 346 | ||||
-rw-r--r-- | meson_options.txt | 4 | ||||
-rw-r--r-- | monitor/hmp-cmds.c | 7 | ||||
-rw-r--r-- | monitor/qmp-cmds.c | 51 | ||||
-rw-r--r-- | pc-bios/descriptors/meson.build | 30 | ||||
-rw-r--r-- | pc-bios/meson.build | 6 | ||||
-rw-r--r-- | qapi/misc.json | 49 | ||||
-rw-r--r-- | qapi/run-state.json | 10 | ||||
-rw-r--r-- | qemu-options.hx | 8 | ||||
-rw-r--r-- | qemu.nsi | 42 | ||||
-rw-r--r-- | qga/meson.build | 55 | ||||
-rw-r--r-- | softmmu/physmem.c | 2 | ||||
-rw-r--r-- | softmmu/runstate-action.c | 4 | ||||
-rw-r--r-- | softmmu/runstate.c | 7 | ||||
-rw-r--r-- | softmmu/vl.c | 8 | ||||
-rw-r--r-- | subprojects/libvhost-user/meson.build | 3 | ||||
-rw-r--r-- | target/i386/cpu.c | 1 | ||||
-rw-r--r-- | tests/acceptance/vnc.py | 18 | ||||
-rw-r--r-- | tests/test-qemu-opts.c | 2 | ||||
-rw-r--r-- | ui/vnc-stubs.c | 7 | ||||
-rw-r--r-- | ui/vnc.c | 8 | ||||
-rw-r--r-- | util/cacheflush.c | 8 | ||||
-rw-r--r-- | util/qemu-option.c | 86 |
32 files changed, 433 insertions, 538 deletions
@@ -335,9 +335,7 @@ endif ifdef CONFIG_WIN32 @echo 'Windows targets:' $(call print-help,installer,Build NSIS-based installer for QEMU) -ifdef CONFIG_QGA_MSI $(call print-help,msi,Build MSI-based installer for qemu-ga) -endif @echo '' endif $(call print-help,$(MAKE) [targets],(quiet build, default)) @@ -359,7 +359,7 @@ sanitizers="no" tsan="no" fortify_source="$default_feature" strip_opt="yes" -tcg_interpreter="no" +tcg_interpreter="false" bigendian="no" mingw32="no" gcov="no" @@ -404,7 +404,7 @@ zstd="auto" guest_agent="$default_feature" guest_agent_with_vss="no" guest_agent_ntddscsi="no" -guest_agent_msi="$default_feature" +guest_agent_msi="auto" vss_win32_sdk="$default_feature" win_sdk="no" want_tools="$default_feature" @@ -1119,9 +1119,9 @@ for opt do ;; --enable-whpx) whpx="enabled" ;; - --disable-tcg-interpreter) tcg_interpreter="no" + --disable-tcg-interpreter) tcg_interpreter="true" ;; - --enable-tcg-interpreter) tcg_interpreter="yes" + --enable-tcg-interpreter) tcg_interpreter="false" ;; --disable-cap-ng) cap_ng="disabled" ;; @@ -1334,9 +1334,9 @@ for opt do ;; --disable-guest-agent) guest_agent="no" ;; - --enable-guest-agent-msi) guest_agent_msi="yes" + --enable-guest-agent-msi) guest_agent_msi="enabled" ;; - --disable-guest-agent-msi) guest_agent_msi="no" + --disable-guest-agent-msi) guest_agent_msi="disabled" ;; --with-vss-sdk) vss_win32_sdk="" ;; @@ -1571,20 +1571,15 @@ libexecdir="${libexecdir:-$prefix/libexec}" includedir="${includedir:-$prefix/include}" if test "$mingw32" = "yes" ; then - mandir="$prefix" - datadir="$prefix" - docdir="$prefix" - bindir="$prefix" - sysconfdir="$prefix" - local_statedir="$prefix" + bindir="${bindir:-$prefix}" else - mandir="${mandir:-$prefix/share/man}" - datadir="${datadir:-$prefix/share}" - docdir="${docdir:-$prefix/share/doc}" bindir="${bindir:-$prefix/bin}" - sysconfdir="${sysconfdir:-$prefix/etc}" - local_statedir="${local_statedir:-$prefix/var}" fi +mandir="${mandir:-$prefix/share/man}" +datadir="${datadir:-$prefix/share}" +docdir="${docdir:-$prefix/share/doc}" +sysconfdir="${sysconfdir:-$prefix/etc}" +local_statedir="${local_statedir:-$prefix/var}" firmwarepath="${firmwarepath:-$datadir/qemu-firmware}" localedir="${localedir:-$datadir/locale}" @@ -3390,16 +3385,6 @@ else for pthread_lib in $PTHREADLIBS_LIST; do if compile_prog "" "$pthread_lib" ; then pthread=yes - found=no - for lib_entry in $LIBS; do - if test "$lib_entry" = "$pthread_lib"; then - found=yes - break - fi - done - if test "$found" = "no"; then - LIBS="$pthread_lib $LIBS" - fi break fi done @@ -4088,28 +4073,6 @@ if compile_prog "" "" ; then bswap_h=yes fi -########################################## -# Do we need librt -# uClibc provides 2 versions of clock_gettime(), one with realtime -# support and one without. This means that the clock_gettime() don't -# need -lrt. We still need it for timer_create() so we check for this -# function in addition. -cat > $TMPC <<EOF -#include <signal.h> -#include <time.h> -int main(void) { - timer_create(CLOCK_REALTIME, NULL, NULL); - return clock_gettime(CLOCK_REALTIME, NULL); -} -EOF - -if compile_prog "" "" ; then - : -# we need pthread for static linking. use previous pthread test result -elif compile_prog "" "$pthread_lib -lrt" ; then - LIBS="$LIBS -lrt" -fi - # Check whether we have openpty() in either libc or libutil cat > $TMPC << EOF extern int openpty(int *am, int *as, char *name, void *termp, void *winp); @@ -5378,62 +5341,19 @@ if [ "$guest_agent" != "no" ]; then fi fi -# Guest agent Window MSI package +# Guest agent Windows MSI package -if test "$guest_agent" != yes; then - if test "$guest_agent_msi" = yes; then - error_exit "MSI guest agent package requires guest agent enabled" - fi - guest_agent_msi=no -elif test "$mingw32" != "yes"; then - if test "$guest_agent_msi" = "yes"; then - error_exit "MSI guest agent package is available only for MinGW Windows cross-compilation" - fi - guest_agent_msi=no -elif ! has wixl; then - if test "$guest_agent_msi" = "yes"; then - error_exit "MSI guest agent package requires wixl tool installed ( usually from msitools package )" - fi - guest_agent_msi=no -else - # we support qemu-ga, mingw32, and wixl: default to MSI enabled if it wasn't - # disabled explicitly - if test "$guest_agent_msi" != "no"; then - guest_agent_msi=yes - fi +if test "$QEMU_GA_MANUFACTURER" = ""; then + QEMU_GA_MANUFACTURER=QEMU fi - -if test "$guest_agent_msi" = "yes"; then - if test "$guest_agent_with_vss" = "yes"; then - QEMU_GA_MSI_WITH_VSS="-D InstallVss" - fi - - if test "$QEMU_GA_MANUFACTURER" = ""; then - QEMU_GA_MANUFACTURER=QEMU - fi - - if test "$QEMU_GA_DISTRO" = ""; then - QEMU_GA_DISTRO=Linux - fi - - if test "$QEMU_GA_VERSION" = ""; then - QEMU_GA_VERSION=$(cat $source_path/VERSION) - fi - - QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=$($pkg_config --variable=prefix glib-2.0)/bin" - - case "$cpu" in - x86_64) - QEMU_GA_MSI_ARCH="-a x64 -D Arch=64" - ;; - i386) - QEMU_GA_MSI_ARCH="-D Arch=32" - ;; - *) - error_exit "CPU $cpu not supported for building installation package" - ;; - esac +if test "$QEMU_GA_DISTRO" = ""; then + QEMU_GA_DISTRO=Linux fi +if test "$QEMU_GA_VERSION" = ""; then + QEMU_GA_VERSION=$(cat $source_path/VERSION) +fi + +QEMU_GA_MSI_MINGW_DLL_PATH="$($pkg_config --variable=prefix glib-2.0)/bin" # Mac OS X ships with a broken assembler roms= @@ -5532,15 +5452,10 @@ if test "$mingw32" = "yes" ; then if test "$guest_agent_ntddscsi" = "yes" ; then echo "CONFIG_QGA_NTDDSCSI=y" >> $config_host_mak fi - if test "$guest_agent_msi" = "yes"; then - echo "CONFIG_QGA_MSI=y" >> $config_host_mak - echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak - echo "QEMU_GA_MSI_WITH_VSS=${QEMU_GA_MSI_WITH_VSS}" >> $config_host_mak - echo "QEMU_GA_MSI_ARCH=${QEMU_GA_MSI_ARCH}" >> $config_host_mak - echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}" >> $config_host_mak - echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO}" >> $config_host_mak - echo "QEMU_GA_VERSION=${QEMU_GA_VERSION}" >> $config_host_mak - fi + echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak + echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}" >> $config_host_mak + echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO}" >> $config_host_mak + echo "QEMU_GA_VERSION=${QEMU_GA_VERSION}" >> $config_host_mak else echo "CONFIG_POSIX=y" >> $config_host_mak fi @@ -5839,11 +5754,6 @@ fi if test "$optreset" = "yes" ; then echo "HAVE_OPTRESET=y" >> $config_host_mak fi -if test "$tcg" = "enabled"; then - if test "$tcg_interpreter" = "yes" ; then - echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak - fi -fi if test "$fdatasync" = "yes" ; then echo "CONFIG_FDATASYNC=y" >> $config_host_mak fi @@ -6462,7 +6372,7 @@ NINJA=$ninja $meson setup \ -Dattr=$attr -Ddefault_devices=$default_devices \ -Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \ -Dvhost_user_blk_server=$vhost_user_blk_server \ - -Dfuse=$fuse -Dfuse_lseek=$fuse_lseek \ + -Dfuse=$fuse -Dfuse_lseek=$fuse_lseek -Dguest_agent_msi=$guest_agent_msi \ $(if test "$default_features" = no; then echo "-Dauto_features=disabled"; fi) \ $cross_arg \ "$PWD" "$source_path" diff --git a/disas/meson.build b/disas/meson.build index 09a852742e..da341a511e 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -22,5 +22,3 @@ common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c')) common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c')) common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c')) common_ss.add(when: capstone, if_true: files('capstone.c')) - -specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c')) diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst index e20bfcb17a..9de663526a 100644 --- a/docs/system/deprecated.rst +++ b/docs/system/deprecated.rst @@ -127,15 +127,16 @@ Drives with interface types other than ``if=none`` are for onboard devices. It is possible to use drives the board doesn't pick up with -device. This usage is now deprecated. Use ``if=none`` instead. +Short-form boolean options (since 6.0) +'''''''''''''''''''''''''''''''''''''' + +Boolean options such as ``share=on``/``share=off`` could be written +in short form as ``share`` and ``noshare``. This is now deprecated +and will cause a warning. QEMU Machine Protocol (QMP) commands ------------------------------------ -``change`` (since 2.5.0) -'''''''''''''''''''''''' - -Use ``blockdev-change-medium`` or ``change-vnc-password`` instead. - ``blockdev-open-tray``, ``blockdev-close-tray`` argument ``device`` (since 2.8.0) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/system/removed-features.rst b/docs/system/removed-features.rst index 430fc33ca1..88b81a6156 100644 --- a/docs/system/removed-features.rst +++ b/docs/system/removed-features.rst @@ -53,6 +53,11 @@ are automatically loaded from qcow2 images. Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See documentation of ``query-hotpluggable-cpus`` for additional details. +``change`` (removed in 6.0) +''''''''''''''''''''''''''' + +Use ``blockdev-change-medium`` or ``change-vnc-password`` instead. + Human Monitor Protocol (HMP) commands ------------------------------------- @@ -68,6 +73,12 @@ The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See documentation of ``query-hotpluggable-cpus`` for additional details. +``change vnc TARGET`` (removed in 6.0) +'''''''''''''''''''''''''''''''''''''' + +No replacement. The ``change vnc password`` and ``change DEVICE MEDIUM`` +commands are not affected. + Guest Emulator ISAs ------------------- diff --git a/fsdev/meson.build b/fsdev/meson.build index 65455a179e..adf57cc43e 100644 --- a/fsdev/meson.build +++ b/fsdev/meson.build @@ -8,7 +8,6 @@ fsdev_ss.add(when: ['CONFIG_FSDEV_9P'], if_true: files( ), if_false: files('qemu-fsdev-dummy.c')) softmmu_ss.add_all(when: 'CONFIG_LINUX', if_true: fsdev_ss) -have_virtfs_proxy_helper = have_tools and libattr.found() and libcap_ng.found() and have_virtfs if have_virtfs_proxy_helper executable('virtfs-proxy-helper', files('virtfs-proxy-helper.c', '9p-marshal.c', '9p-iov-marshal.c'), diff --git a/hmp-commands.hx b/hmp-commands.hx index 73e0832ea1..d4001f9c5d 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -231,12 +231,6 @@ SRST read-write Makes the device writable. - ``change vnc`` *display*,\ *options* - Change the configuration of the VNC server. The valid syntax for *display* - and *options* are described at :ref:`sec_005finvocation`. eg:: - - (qemu) change vnc localhost:1 - ``change vnc password`` [*password*] Change the password associated with the VNC server. If the new password diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index e79157863f..b626199e3d 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -322,6 +322,8 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors, int sector_size) { + assert(0 <= lba && lba < (s->nb_sectors >> 2)); + s->lba = lba; s->packet_transfer_size = nb_sectors * sector_size; s->elementary_transfer_size = 0; @@ -420,6 +422,8 @@ eot: static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, int sector_size) { + assert(0 <= lba && lba < (s->nb_sectors >> 2)); + s->lba = lba; s->packet_transfer_size = nb_sectors * sector_size; s->io_buffer_size = 0; @@ -973,35 +977,49 @@ static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf) static void cmd_read(IDEState *s, uint8_t* buf) { - int nb_sectors, lba; + unsigned int nb_sectors, lba; + + /* Total logical sectors of ATAPI_SECTOR_SIZE(=2048) bytes */ + uint64_t total_sectors = s->nb_sectors >> 2; if (buf[0] == GPCMD_READ_10) { nb_sectors = lduw_be_p(buf + 7); } else { nb_sectors = ldl_be_p(buf + 6); } - - lba = ldl_be_p(buf + 2); if (nb_sectors == 0) { ide_atapi_cmd_ok(s); return; } + lba = ldl_be_p(buf + 2); + if (lba >= total_sectors || lba + nb_sectors - 1 >= total_sectors) { + ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); + return; + } + ide_atapi_cmd_read(s, lba, nb_sectors, 2048); } static void cmd_read_cd(IDEState *s, uint8_t* buf) { - int nb_sectors, lba, transfer_request; + unsigned int nb_sectors, lba, transfer_request; - nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8]; - lba = ldl_be_p(buf + 2); + /* Total logical sectors of ATAPI_SECTOR_SIZE(=2048) bytes */ + uint64_t total_sectors = s->nb_sectors >> 2; + nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8]; if (nb_sectors == 0) { ide_atapi_cmd_ok(s); return; } + lba = ldl_be_p(buf + 2); + if (lba >= total_sectors || lba + nb_sectors - 1 >= total_sectors) { + ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR); + return; + } + transfer_request = buf[9] & 0xf8; if (transfer_request == 0x00) { /* nothing */ diff --git a/include/ui/console.h b/include/ui/console.h index 5dd21976a3..7a3fc11abf 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -439,7 +439,7 @@ void vnc_display_open(const char *id, Error **errp); void vnc_display_add_client(const char *id, int csock, bool skipauth); int vnc_display_password(const char *id, const char *password); int vnc_display_pw_expire(const char *id, time_t expires); -QemuOpts *vnc_parse(const char *str, Error **errp); +void vnc_parse(const char *str); int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp); /* input.c */ diff --git a/meson.build b/meson.build index af2bc89741..35a9eddf5c 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,16 @@ if cpu in ['x86', 'x86_64'] } endif +edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ] +install_edk2_blobs = false +if get_option('install_blobs') + foreach target : target_dirs + install_edk2_blobs = install_edk2_blobs or target in edk2_targets + endforeach +endif + +bzip2 = find_program('bzip2', required: install_edk2_blobs) + ################## # Compiler flags # ################## @@ -100,12 +110,12 @@ if 'CONFIG_FUZZ' in config_host native: false, language: ['c', 'cpp', 'objc']) endif -add_project_arguments(config_host['QEMU_CFLAGS'].split(), - native: false, language: ['c', 'objc']) -add_project_arguments(config_host['QEMU_CXXFLAGS'].split(), - native: false, language: 'cpp') -add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(), - native: false, language: ['c', 'cpp', 'objc']) +add_global_arguments(config_host['QEMU_CFLAGS'].split(), + native: false, language: ['c', 'objc']) +add_global_arguments(config_host['QEMU_CXXFLAGS'].split(), + native: false, language: 'cpp') +add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(), + native: false, language: ['c', 'cpp', 'objc']) if targetos == 'linux' add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers', @@ -113,25 +123,8 @@ if targetos == 'linux' language: ['c', 'cpp']) endif -if 'CONFIG_TCG_INTERPRETER' in config_host - tcg_arch = 'tci' -elif config_host['ARCH'] == 'sparc64' - tcg_arch = 'sparc' -elif config_host['ARCH'] == 's390x' - tcg_arch = 's390' -elif config_host['ARCH'] in ['x86_64', 'x32'] - tcg_arch = 'i386' -elif config_host['ARCH'] == 'ppc64' - tcg_arch = 'ppc' -elif config_host['ARCH'] in ['riscv32', 'riscv64'] - tcg_arch = 'riscv' -else - tcg_arch = config_host['ARCH'] -endif -add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, - '-iquote', '.', +add_project_arguments('-iquote', '.', '-iquote', meson.current_source_dir(), - '-iquote', meson.current_source_dir() / 'accel/tcg', '-iquote', meson.current_source_dir() / 'include', '-iquote', meson.current_source_dir() / 'disas/libvixl', language: ['c', 'cpp', 'objc']) @@ -226,14 +219,33 @@ if not get_option('hax').disabled() accelerators += 'CONFIG_HAX' endif endif + +tcg_arch = config_host['ARCH'] if not get_option('tcg').disabled() if cpu not in supported_cpus - if 'CONFIG_TCG_INTERPRETER' in config_host + if get_option('tcg_interpreter') warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu)) else error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu)) endif endif + if get_option('tcg_interpreter') + tcg_arch = 'tci' + elif config_host['ARCH'] == 'sparc64' + tcg_arch = 'sparc' + elif config_host['ARCH'] == 's390x' + tcg_arch = 's390' + elif config_host['ARCH'] in ['x86_64', 'x32'] + tcg_arch = 'i386' + elif config_host['ARCH'] == 'ppc64' + tcg_arch = 'ppc' + elif config_host['ARCH'] in ['riscv32', 'riscv64'] + tcg_arch = 'riscv' + endif + add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, + '-iquote', meson.current_source_dir() / 'accel/tcg', + language: ['c', 'cpp', 'objc']) + accelerators += 'CONFIG_TCG' config_host += { 'CONFIG_TCG': 'y' } endif @@ -1019,8 +1031,8 @@ if get_option('cfi') error('-fno-sanitize-trap=cfi-icall is not supported by the compiler') endif endif - add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) - add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) + add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) + add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) endif ################# @@ -1032,6 +1044,8 @@ have_virtfs = (targetos == 'linux' and libattr.found() and libcap_ng.found()) +have_virtfs_proxy_helper = have_virtfs and have_tools + if get_option('virtfs').enabled() if not have_virtfs if targetos != 'linux' @@ -1234,7 +1248,9 @@ foreach target : target_dirs if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) config_target += { sym: 'y' } config_all += { sym: 'y' } - if sym == 'CONFIG_XEN' and have_xen_pci_passthrough + if sym == 'CONFIG_TCG' and tcg_arch == 'tci' + config_target += { 'CONFIG_TCG_INTERPRETER': 'y' } + elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } endif accel_kconfig += [ sym + '=y' ] @@ -2190,6 +2206,8 @@ endif if 'CONFIG_GUEST_AGENT' in config_host subdir('qga') +elif get_option('guest_agent_msi').enabled() + error('Guest agent MSI requested, but the guest agent is not being built') endif # Don't build qemu-keymap if xkbcommon is not explicitly enabled @@ -2279,6 +2297,7 @@ endif # Configuration summary # ######################### +# Directories summary_info = {} summary_info += {'Install prefix': get_option('prefix')} summary_info += {'BIOS directory': qemu_datadir} @@ -2298,8 +2317,64 @@ endif summary_info += {'Doc directory': get_option('docdir')} summary_info += {'Build directory': meson.current_build_dir()} summary_info += {'Source path': meson.current_source_dir()} -summary_info += {'GIT binary': config_host['GIT']} summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} +summary(summary_info, bool_yn: true, section: 'Directories') + +# Host binaries +summary_info = {} +summary_info += {'git': config_host['GIT']} +summary_info += {'make': config_host['MAKE']} +summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} +summary_info += {'sphinx-build': sphinx_build.found()} +if config_host.has_key('HAVE_GDB_BIN') + summary_info += {'gdb': config_host['HAVE_GDB_BIN']} +endif +summary_info += {'genisoimage': config_host['GENISOIMAGE']} +if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT') + summary_info += {'wixl': wixl.found() ? wixl.full_path() : false} +endif +if slirp_opt != 'disabled' + summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} +endif +summary(summary_info, bool_yn: true, section: 'Host binaries') + +# Configurable features +summary_info = {} +summary_info += {'Documentation': build_docs} +summary_info += {'system-mode emulation': have_system} +summary_info += {'user-mode emulation': have_user} +summary_info += {'block layer': have_block} +summary_info += {'Install blobs': get_option('install_blobs')} +summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} +if config_host.has_key('CONFIG_MODULES') + summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')} +endif +summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')} +summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')} +if have_system + summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']} +endif +summary_info += {'Trace backends': config_host['TRACE_BACKENDS']} +if config_host['TRACE_BACKENDS'].split().contains('simple') + summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'} +endif +summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')} +summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')} +summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} +summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} +summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')} +summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')} +summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')} +summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} +summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')} +summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')} +summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')} +summary(summary_info, bool_yn: true, section: 'Configurable features') + +# Compilation information +summary_info = {} +summary_info += {'host CPU': cpu} +summary_info += {'host endianness': build_machine.endian()} summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]} summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]} if link_language == 'cpp' @@ -2310,6 +2385,11 @@ endif if targetos == 'darwin' summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]} endif +if targetos == 'windows' + if 'WIN_SDK' in config_host + summary_info += {'Windows SDK': config_host['WIN_SDK']} + endif +endif summary_info += {'ARFLAGS': config_host['ARFLAGS']} summary_info += {'CFLAGS': ' '.join(get_option('c_args') + ['-O' + get_option('optimization')] @@ -2325,39 +2405,83 @@ if link_args.length() > 0 endif summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']} summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']} -summary_info += {'make': config_host['MAKE']} -summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} -summary_info += {'sphinx-build': sphinx_build.found()} -summary_info += {'genisoimage': config_host['GENISOIMAGE']} -# TODO: add back version -summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt} -if slirp_opt != 'disabled' - summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} -endif -summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} -if config_host.has_key('CONFIG_MODULES') - summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')} -endif -summary_info += {'host CPU': cpu} -summary_info += {'host endianness': build_machine.endian()} -summary_info += {'target list': ' '.join(target_dirs)} -summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} -summary_info += {'sparse enabled': sparse.found()} -summary_info += {'strip binaries': get_option('strip')} summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')} summary_info += {'link-time optimization (LTO)': get_option('b_lto')} +summary_info += {'PIE': get_option('b_pie')} summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} -if targetos == 'darwin' - summary_info += {'Cocoa support': cocoa.found()} +summary_info += {'malloc trim support': has_malloc_trim} +summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')} +summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')} +summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')} +summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')} +summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')} +summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')} +summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')} +summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')} +summary_info += {'memory allocator': get_option('malloc')} +summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')} +summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')} +summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} +summary_info += {'gcov': get_option('b_coverage')} +summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} +summary_info += {'CFI support': get_option('cfi')} +if get_option('cfi') + summary_info += {'CFI debug support': get_option('cfi_debug')} endif -# TODO: add back version -summary_info += {'SDL support': sdl.found()} -summary_info += {'SDL image support': sdl_image.found()} -# TODO: add back version -summary_info += {'GTK support': gtk.found()} -summary_info += {'pixman': pixman.found()} -# TODO: add back version -summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')} +summary_info += {'strip binaries': get_option('strip')} +summary_info += {'sparse': sparse.found() ? sparse.full_path() : false} +summary_info += {'mingw32 support': targetos == 'windows'} +summary(summary_info, bool_yn: true, section: 'Compilation') + +# Targets and accelerators +summary_info = {} +if have_system + summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} + summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} + summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} + summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} + summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')} + if config_host.has_key('CONFIG_XEN_BACKEND') + summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} + endif +endif +summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} +if config_all.has_key('CONFIG_TCG') + summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} + summary_info += {'TCG interpreter': tcg_arch == 'tci'} +endif +summary_info += {'target list': ' '.join(target_dirs)} +if have_system + summary_info += {'default devices': get_option('default_devices')} +endif +summary(summary_info, bool_yn: true, section: 'Targets and accelerators') + +# Block layer +summary_info = {} +summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} +summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'} +if have_block + summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} + summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} + summary_info += {'VirtFS support': have_virtfs} + summary_info += {'build virtiofs daemon': have_virtiofsd} + summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')} + summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')} + summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')} + summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')} + summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')} + summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')} + summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')} + summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')} + summary_info += {'qed support': config_host.has_key('CONFIG_QED')} + summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')} + summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')} + summary_info += {'FUSE exports': fuse.found()} +endif +summary(summary_info, bool_yn: true, section: 'Block layer support') + +# Crypto +summary_info = {} summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']} summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')} # TODO: add back version @@ -2371,6 +2495,26 @@ summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')} if config_host.has_key('CONFIG_NETTLE') summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')} endif +summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')} +summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')} +summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')} +summary(summary_info, bool_yn: true, section: 'Crypto') + +# Libraries +summary_info = {} +if targetos == 'darwin' + summary_info += {'Cocoa support': cocoa.found()} +endif +# TODO: add back version +summary_info += {'SDL support': sdl.found()} +summary_info += {'SDL image support': sdl_image.found()} +# TODO: add back version +summary_info += {'GTK support': gtk.found()} +summary_info += {'pixman': pixman.found()} +# TODO: add back version +summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')} +# TODO: add back version +summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt} summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')} summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')} summary_info += {'iconv support': iconv.found()} @@ -2378,12 +2522,6 @@ summary_info += {'curses support': curses.found()} # TODO: add back version summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')} summary_info += {'curl support': curl.found()} -summary_info += {'mingw32 support': targetos == 'windows'} -summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']} -summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} -summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} -summary_info += {'VirtFS support': have_virtfs} -summary_info += {'build virtiofs daemon': have_virtiofsd} summary_info += {'Multipath support': mpathpersist.found()} summary_info += {'VNC support': vnc.found()} if vnc.found() @@ -2391,52 +2529,16 @@ if vnc.found() summary_info += {'VNC JPEG support': jpeg.found()} summary_info += {'VNC PNG support': png.found()} endif -summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')} -if config_host.has_key('CONFIG_XEN_BACKEND') - summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} -endif summary_info += {'brlapi support': brlapi.found()} -summary_info += {'Documentation': build_docs} -summary_info += {'PIE': get_option('b_pie')} summary_info += {'vde support': config_host.has_key('CONFIG_VDE')} summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')} summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')} summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')} summary_info += {'ATTR/XATTR support': libattr.found()} -summary_info += {'Install blobs': get_option('install_blobs')} -summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} -summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} -summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} -summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} -summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} -if config_all.has_key('CONFIG_TCG') - summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} - summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')} -endif -summary_info += {'malloc trim support': has_malloc_trim} summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')} summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')} summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} -summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')} -summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')} -summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')} -summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')} -summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')} -summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')} summary_info += {'libcap-ng support': libcap_ng.found()} -summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')} -summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} -summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} -summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')} -summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')} -summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')} -summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} -summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')} -summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')} -summary_info += {'Trace backends': config_host['TRACE_BACKENDS']} -if config_host['TRACE_BACKENDS'].split().contains('simple') - summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'} -endif # TODO: add back protocol and server version summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')} summary_info += {'rbd support': rbd.found()} @@ -2449,29 +2551,16 @@ summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')} summary_info += {'libiscsi support': libiscsi.found()} summary_info += {'libnfs support': libnfs.found()} -summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')} if targetos == 'windows' - if 'WIN_SDK' in config_host - summary_info += {'Windows SDK': config_host['WIN_SDK']} + if config_host.has_key('CONFIG_GUEST_AGENT') + summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')} + summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')} endif - summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')} - summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')} - summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')} endif summary_info += {'seccomp support': seccomp.found()} -summary_info += {'CFI support': get_option('cfi')} -summary_info += {'CFI debug support': get_option('cfi_debug')} -summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} -summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'} -summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')} -summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')} -summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')} summary_info += {'GlusterFS support': glusterfs.found()} -summary_info += {'gcov': get_option('b_coverage')} summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')} summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')} -summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')} -summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')} summary_info += {'lzo support': lzo.found()} summary_info += {'snappy support': snappy.found()} summary_info += {'bzip2 support': libbzip2.found()} @@ -2479,35 +2568,12 @@ summary_info += {'lzfse support': liblzfse.found()} summary_info += {'zstd support': zstd.found()} summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')} summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')} -summary_info += {'memory allocator': get_option('malloc')} -summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')} -summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')} -summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')} -summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')} -summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')} -summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')} -summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')} -summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')} -summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')} -summary_info += {'qed support': config_host.has_key('CONFIG_QED')} -summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')} -summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')} summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt} summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')} summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')} summary_info += {'libudev': libudev.found()} -summary_info += {'default devices': get_option('default_devices')} -summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')} -summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')} -if config_host.has_key('HAVE_GDB_BIN') - summary_info += {'gdb': config_host['HAVE_GDB_BIN']} -endif -summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} -summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')} -summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')} -summary_info += {'FUSE exports': fuse.found()} summary_info += {'FUSE lseek': fuse_lseek.found()} -summary(summary_info, bool_yn: true) +summary(summary_info, bool_yn: true, section: 'Dependencies') if not supported_cpus.contains(cpu) message() diff --git a/meson_options.txt b/meson_options.txt index 72a3ca22d6..95f1079829 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,6 +17,8 @@ option('install_blobs', type : 'boolean', value : true, description: 'install provided firmware blobs') option('sparse', type : 'feature', value : 'auto', description: 'sparse checker') +option('guest_agent_msi', type : 'feature', value : 'auto', + description: 'Build MSI package for the QEMU Guest Agent') option('malloc_trim', type : 'feature', value : 'auto', description: 'enable libc malloc_trim() for memory optimization') @@ -37,6 +39,8 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto', description: 'Xen PCI passthrough support') option('tcg', type: 'feature', value: 'auto', description: 'TCG support') +option('tcg_interpreter', type: 'boolean', value: false, + description: 'TCG bytecode interpreter (TCI)') option('cfi', type: 'boolean', value: 'false', description: 'Control-Flow Integrity (CFI)') option('cfi_debug', type: 'boolean', value: 'false', diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index fd4d77e246..499647a578 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1521,13 +1521,16 @@ void hmp_change(Monitor *mon, const QDict *qdict) } if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) { - if (!arg) { + if (arg) { MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common); monitor_read_password(hmp_mon, hmp_change_read_arg, NULL); return; + } else { + qmp_change_vnc_password(arg, &err); } + } else { + monitor_printf(mon, "Expected 'password' after 'vnc'\n"); } - qmp_change("vnc", target, !!arg, arg, &err); } else #endif { diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 34f7e75b7b..990936136c 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -251,58 +251,7 @@ void qmp_change_vnc_password(const char *password, Error **errp) error_setg(errp, "Could not set password"); } } - -static void qmp_change_vnc_listen(const char *target, Error **errp) -{ - QemuOptsList *olist = qemu_find_opts("vnc"); - QemuOpts *opts; - - if (strstr(target, "id=")) { - error_setg(errp, "id not supported"); - return; - } - - opts = qemu_opts_find(olist, "default"); - if (opts) { - qemu_opts_del(opts); - } - opts = vnc_parse(target, errp); - if (!opts) { - return; - } - - vnc_display_open("default", errp); -} - -static void qmp_change_vnc(const char *target, bool has_arg, const char *arg, - Error **errp) -{ - if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) { - if (!has_arg) { - error_setg(errp, QERR_MISSING_PARAMETER, "password"); - } else { - qmp_change_vnc_password(arg, errp); - } - } else { - qmp_change_vnc_listen(target, errp); - } -} -#endif /* !CONFIG_VNC */ - -void qmp_change(const char *device, const char *target, - bool has_arg, const char *arg, Error **errp) -{ - if (strcmp(device, "vnc") == 0) { -#ifdef CONFIG_VNC - qmp_change_vnc(target, has_arg, arg, errp); -#else - error_setg(errp, QERR_FEATURE_DISABLED, "vnc"); #endif - } else { - qmp_blockdev_change_medium(true, device, false, NULL, target, - has_arg, arg, false, 0, errp); - } -} void qmp_add_client(const char *protocol, const char *fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, diff --git a/pc-bios/descriptors/meson.build b/pc-bios/descriptors/meson.build index 7040834573..ac6ec66b00 100644 --- a/pc-bios/descriptors/meson.build +++ b/pc-bios/descriptors/meson.build @@ -1,14 +1,16 @@ -foreach f: [ - '50-edk2-i386-secure.json', - '50-edk2-x86_64-secure.json', - '60-edk2-aarch64.json', - '60-edk2-arm.json', - '60-edk2-i386.json', - '60-edk2-x86_64.json' -] - configure_file(input: files(f), - output: f, - configuration: {'DATADIR': qemu_datadir}, - install: get_option('install_blobs'), - install_dir: qemu_datadir / 'firmware') -endforeach +if install_edk2_blobs + foreach f: [ + '50-edk2-i386-secure.json', + '50-edk2-x86_64-secure.json', + '60-edk2-aarch64.json', + '60-edk2-arm.json', + '60-edk2-i386.json', + '60-edk2-x86_64.json' + ] + configure_file(input: files(f), + output: f, + configuration: {'DATADIR': qemu_datadir}, + install: get_option('install_blobs'), + install_dir: qemu_datadir / 'firmware') + endforeach +endif diff --git a/pc-bios/meson.build b/pc-bios/meson.build index fab323af84..af95c5d1f1 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -1,8 +1,4 @@ -if 'arm-softmmu' in target_dirs or \ - 'aarch64-softmmu' in target_dirs or \ - 'i386-softmmu' in target_dirs or \ - 'x86_64-softmmu' in target_dirs - bzip2 = find_program('bzip2', required: true) +if install_edk2_blobs fds = [ 'edk2-aarch64-code.fd', 'edk2-arm-code.fd', diff --git a/qapi/misc.json b/qapi/misc.json index 27ccd7385f..156f98203e 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -239,55 +239,6 @@ 'features': [ 'savevm-monitor-nodes' ] } ## -# @change: -# -# This command is multiple commands multiplexed together. -# -# @device: This is normally the name of a block device but it may also be 'vnc'. -# when it's 'vnc', then sub command depends on @target -# -# @target: If @device is a block device, then this is the new filename. -# If @device is 'vnc', then if the value 'password' selects the vnc -# change password command. Otherwise, this specifies a new server URI -# address to listen to for VNC connections. -# -# @arg: If @device is a block device, then this is an optional format to open -# the device with. -# If @device is 'vnc' and @target is 'password', this is the new VNC -# password to set. See change-vnc-password for additional notes. -# -# Features: -# @deprecated: This command is deprecated. For changing block -# devices, use 'blockdev-change-medium' instead; for changing VNC -# parameters, use 'change-vnc-password' instead. -# -# Returns: - Nothing on success. -# - If @device is not a valid block device, DeviceNotFound -# -# Since: 0.14 -# -# Example: -# -# 1. Change a removable medium -# -# -> { "execute": "change", -# "arguments": { "device": "ide1-cd0", -# "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } } -# <- { "return": {} } -# -# 2. Change VNC password -# -# -> { "execute": "change", -# "arguments": { "device": "vnc", "target": "password", -# "arg": "foobar1" } } -# <- { "return": {} } -# -## -{ 'command': 'change', - 'data': {'device': 'str', 'target': 'str', '*arg': 'str'}, - 'features': [ 'deprecated' ] } - -## # @getfd: # # Receive a file descriptor via SCM rights and assign it a name diff --git a/qapi/run-state.json b/qapi/run-state.json index 1f3b329f05..43d66d700f 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -330,14 +330,14 @@ # # Possible QEMU actions upon guest reboot # -# @none: Reset the VM +# @reset: Reset the VM # -# @shutdown: Shutdown the VM and exit +# @shutdown: Shutdown the VM and exit, according to the shutdown action # # Since: 6.0 ## { 'enum': 'RebootAction', - 'data': [ 'none', 'shutdown' ] } + 'data': [ 'reset', 'shutdown' ] } ## # @ShutdownAction: @@ -360,10 +360,12 @@ # # @pause: Pause the VM # +# @shutdown: Shutdown the VM and exit, according to the shutdown action +# # Since: 6.0 ## { 'enum': 'PanicAction', - 'data': [ 'poweroff', 'pause', 'none' ] } + 'data': [ 'pause', 'shutdown', 'none' ] } ## # @watchdog-set-action: diff --git a/qemu-options.hx b/qemu-options.hx index 62791f56d8..9172d51659 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3900,12 +3900,12 @@ SRST ERST DEF("action", HAS_ARG, QEMU_OPTION_action, - "-action reboot=none|shutdown\n" - " action when guest reboots [default=none]\n" + "-action reboot=reset|shutdown\n" + " action when guest reboots [default=reset]\n" "-action shutdown=poweroff|pause\n" " action when guest shuts down [default=poweroff]\n" - "-action panic=poweroff|pause|none\n" - " action when guest panics [default=poweroff]\n" + "-action panic=pause|shutdown|none\n" + " action when guest panics [default=shutdown]\n" "-action watchdog=reset|shutdown|poweroff|inject-nmi|pause|debug|none\n" " action when watchdog fires [default=reset]\n", QEMU_ARCH_ALL) @@ -35,11 +35,6 @@ !define OUTFILE "qemu-setup.exe" !endif -; Optionally install documentation. -!ifndef CONFIG_DOCUMENTATION -!define CONFIG_DOCUMENTATION -!endif - ; Use maximum compression. SetCompressor /SOLID lzma @@ -116,26 +111,13 @@ Section "${PRODUCT} (required)" ; Set output path to the installation directory. SetOutPath "$INSTDIR" - File "${SRCDIR}\Changelog" File "${SRCDIR}\COPYING" File "${SRCDIR}\COPYING.LIB" File "${SRCDIR}\README.rst" File "${SRCDIR}\VERSION" - File "${BINDIR}\*.bmp" - File "${BINDIR}\*.bin" - File "${BINDIR}\*.dtb" - File "${BINDIR}\*.fd" - File "${BINDIR}\*.img" - File "${BINDIR}\*.lid" - File "${BINDIR}\*.ndrv" - File "${BINDIR}\*.rom" - File "${BINDIR}\openbios-*" - File /r "${BINDIR}\keymaps" -!ifdef CONFIG_GTK File /r "${BINDIR}\share" -!endif !ifdef W64 SetRegView 64 @@ -176,21 +158,11 @@ SectionEnd !ifdef CONFIG_DOCUMENTATION Section "Documentation" SectionDoc - SetOutPath "$INSTDIR" - File "${BINDIR}\index.html" - SetOutPath "$INSTDIR\interop" - FILE /r "${BINDIR}\interop\*.*" - SetOutPath "$INSTDIR\specs" - FILE /r "${BINDIR}\specs\*.*" - SetOutPath "$INSTDIR\system" - FILE /r "${BINDIR}\system\*.*" - SetOutPath "$INSTDIR\tools" - FILE /r "${BINDIR}\tools\*.*" - SetOutPath "$INSTDIR\user" - FILE /r "${BINDIR}\user\*.*" + SetOutPath "$INSTDIR\doc" + File /r "${BINDIR}\doc" SetOutPath "$INSTDIR" CreateDirectory "$SMPROGRAMS\${PRODUCT}" - CreateShortCut "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" "$INSTDIR\index.html" "" "$INSTDIR\index.html" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT}\User Documentation.lnk" "$INSTDIR\doc\index.html" "" "$INSTDIR\doc\index.html" 0 SectionEnd !endif @@ -238,13 +210,7 @@ Section "Uninstall" Delete "$INSTDIR\qemu-io.exe" Delete "$INSTDIR\qemu.exe" Delete "$INSTDIR\qemu-system-*.exe" - Delete "$INSTDIR\index.html" - RMDir /r "$INSTDIR\interop" - RMDir /r "$INSTDIR\specs" - RMDir /r "$INSTDIR\system" - RMDir /r "$INSTDIR\tools" - RMDir /r "$INSTDIR\user" - RMDir /r "$INSTDIR\keymaps" + RMDir /r "$INSTDIR\doc" RMDir /r "$INSTDIR\share" ; Remove generated files Delete "$INSTDIR\stderr.txt" diff --git a/qga/meson.build b/qga/meson.build index 520af6ce9b..cfb1fbc085 100644 --- a/qga/meson.build +++ b/qga/meson.build @@ -55,33 +55,46 @@ if targetos == 'windows' gen_tlb = [] endif - wixl = find_program('wixl', required: false) + qemu_ga_msi_arch = { + 'x86': ['-D', 'Arch=32'], + 'x86_64': ['-a', 'x64', '-D', 'Arch=64'] + } + wixl = not_found + if cpu in qemu_ga_msi_arch + wixl = find_program('wixl', required: get_option('guest_agent_msi')) + elif get_option('guest_agent_msi').enabled() + error('CPU not supported for building guest agent installation package') + endif + if wixl.found() deps = [gen_tlb, qga] - if 'CONFIG_QGA_VSS' in config_host and 'QEMU_GA_MSI_WITH_VSS' in config_host + qemu_ga_msi_vss = [] + if 'CONFIG_QGA_VSS' in config_host + qemu_ga_msi_vss = ['-D', 'InstallVss'] deps += qga_vss endif - if 'CONFIG_QGA_MSI' in config_host - qga_msi = custom_target('QGA MSI', - input: files('installer/qemu-ga.wxs'), - output: 'qemu-ga-@0@.msi'.format(config_host['ARCH']), - depends: deps, - command: [ - find_program('env'), - 'QEMU_GA_VERSION=' + config_host['QEMU_GA_VERSION'], - 'QEMU_GA_MANUFACTURER=' + config_host['QEMU_GA_MANUFACTURER'], - 'QEMU_GA_DISTRO=' + config_host['QEMU_GA_DISTRO'], - 'BUILD_DIR=' + meson.build_root(), - wixl, '-o', '@OUTPUT0@', '@INPUT0@', - config_host['QEMU_GA_MSI_ARCH'].split(), - config_host['QEMU_GA_MSI_WITH_VSS'].split(), - config_host['QEMU_GA_MSI_MINGW_DLL_PATH'].split(), - ]) - all_qga += [qga_msi] - alias_target('msi', qga_msi) - endif + qga_msi = custom_target('QGA MSI', + input: files('installer/qemu-ga.wxs'), + output: 'qemu-ga-@0@.msi'.format(config_host['ARCH']), + depends: deps, + command: [ + find_program('env'), + 'QEMU_GA_VERSION=' + config_host['QEMU_GA_VERSION'], + 'QEMU_GA_MANUFACTURER=' + config_host['QEMU_GA_MANUFACTURER'], + 'QEMU_GA_DISTRO=' + config_host['QEMU_GA_DISTRO'], + 'BUILD_DIR=' + meson.build_root(), + wixl, '-o', '@OUTPUT0@', '@INPUT0@', + qemu_ga_msi_arch[cpu], + qemu_ga_msi_vss, + '-D', 'Mingw_dlls=' + config_host['QEMU_GA_MSI_MINGW_DLL_PATH'], + ]) + all_qga += [qga_msi] + alias_target('msi', qga_msi) endif else + if get_option('guest_agent_msi').enabled() + error('MSI guest agent package is available only for MinGW Windows cross-compilation') + endif install_subdir('run', install_dir: get_option('localstatedir')) endif diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 6301f4f0a5..cdcd197656 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -605,7 +605,7 @@ static void tcg_register_iommu_notifier(CPUState *cpu, * when the IOMMU tells us the mappings we've cached have changed. */ MemoryRegion *mr = MEMORY_REGION(iommu_mr); - TCGIOMMUNotifier *notifier; + TCGIOMMUNotifier *notifier = NULL; int i; for (i = 0; i < cpu->iommu_notifiers->len; i++) { diff --git a/softmmu/runstate-action.c b/softmmu/runstate-action.c index 99ce880886..ae0761a9c3 100644 --- a/softmmu/runstate-action.c +++ b/softmmu/runstate-action.c @@ -13,9 +13,9 @@ #include "qapi/error.h" #include "qemu/option_int.h" -RebootAction reboot_action = REBOOT_ACTION_NONE; +RebootAction reboot_action = REBOOT_ACTION_RESET; ShutdownAction shutdown_action = SHUTDOWN_ACTION_POWEROFF; -PanicAction panic_action = PANIC_ACTION_POWEROFF; +PanicAction panic_action = PANIC_ACTION_SHUTDOWN; /* * Receives actions to be applied for specific guest events diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 6177693a30..beee050815 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -471,14 +471,15 @@ void qemu_system_guest_panicked(GuestPanicInformation *info) } /* * TODO: Currently the available panic actions are: none, pause, and - * poweroff, but in principle debug and reset could be supported as well. + * shutdown, but in principle debug and reset could be supported as well. * Investigate any potential use cases for the unimplemented actions. */ - if (panic_action == PANIC_ACTION_PAUSE) { + if (panic_action == PANIC_ACTION_PAUSE + || (panic_action == PANIC_ACTION_SHUTDOWN && shutdown_action == SHUTDOWN_ACTION_PAUSE)) { qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, !!info, info); vm_stop(RUN_STATE_GUEST_PANICKED); - } else if (panic_action == PANIC_ACTION_POWEROFF) { + } else if (panic_action == PANIC_ACTION_SHUTDOWN) { qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, !!info, info); vm_stop(RUN_STATE_GUEST_PANICKED); diff --git a/softmmu/vl.c b/softmmu/vl.c index 7ddf405d76..a8876b8965 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1113,7 +1113,7 @@ static void parse_display(const char *p) * display access. */ if (*opts == '=') { - vnc_parse(opts + 1, &error_fatal); + vnc_parse(opts + 1); } else { error_report("VNC requires a display argument vnc=<display>"); exit(1); @@ -1402,7 +1402,7 @@ static void qemu_create_default_devices(void) if (!qemu_display_find_default(&dpy)) { dpy.type = DISPLAY_TYPE_NONE; #if defined(CONFIG_VNC) - vnc_parse("localhost:0,to=99,id=default", &error_abort); + vnc_parse("localhost:0,to=99,id=default"); #endif } } @@ -3186,7 +3186,7 @@ void qemu_init(int argc, char **argv, char **envp) } break; case QEMU_OPTION_vnc: - vnc_parse(optarg, &error_fatal); + vnc_parse(optarg); break; case QEMU_OPTION_no_acpi: olist = qemu_find_opts("machine"); @@ -3202,7 +3202,7 @@ void qemu_init(int argc, char **argv, char **envp) break; case QEMU_OPTION_no_shutdown: olist = qemu_find_opts("action"); - qemu_opts_parse_noisily(olist, "panic=pause,shutdown=pause", false); + qemu_opts_parse_noisily(olist, "shutdown=pause", false); break; case QEMU_OPTION_uuid: if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) { diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build index c5d85c11d7..b03446e7cd 100644 --- a/subprojects/libvhost-user/meson.build +++ b/subprojects/libvhost-user/meson.build @@ -2,12 +2,14 @@ project('libvhost-user', 'c', license: 'GPL-2.0-or-later', default_options: ['c_std=gnu99']) +threads = dependency('threads') glib = dependency('glib-2.0') inc = include_directories('../../include', '../../linux-headers') vhost_user = static_library('vhost-user', files('libvhost-user.c'), include_directories: inc, + dependencies: threads, c_args: '-D_GNU_SOURCE') executable('link-test', files('link-test.c'), @@ -21,4 +23,5 @@ vhost_user_glib = static_library('vhost-user-glib', dependencies: glib) vhost_user_dep = declare_dependency(link_with: vhost_user_glib, + dependencies: glib, include_directories: include_directories('.')) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 35459a38bb..72a79e6019 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4319,6 +4319,7 @@ static void max_x86_cpu_initfn(Object *obj) if (lmce_supported()) { object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abort); } + object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &error_abort); } else { object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, &error_abort); diff --git a/tests/acceptance/vnc.py b/tests/acceptance/vnc.py index 3f40bc2be1..22656bbcc2 100644 --- a/tests/acceptance/vnc.py +++ b/tests/acceptance/vnc.py @@ -24,10 +24,8 @@ class Vnc(Test): self.vm.add_args('-nodefaults', '-S') self.vm.launch() self.assertFalse(self.vm.qmp('query-vnc')['return']['enabled']) - set_password_response = self.vm.qmp('change', - device='vnc', - target='password', - arg='new_password') + set_password_response = self.vm.qmp('change-vnc-password', + password='new_password') self.assertIn('error', set_password_response) self.assertEqual(set_password_response['error']['class'], 'GenericError') @@ -38,10 +36,8 @@ class Vnc(Test): self.vm.add_args('-nodefaults', '-S', '-vnc', ':0') self.vm.launch() self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled']) - set_password_response = self.vm.qmp('change', - device='vnc', - target='password', - arg='new_password') + set_password_response = self.vm.qmp('change-vnc-password', + password='new_password') self.assertIn('error', set_password_response) self.assertEqual(set_password_response['error']['class'], 'GenericError') @@ -52,8 +48,6 @@ class Vnc(Test): self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password') self.vm.launch() self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled']) - set_password_response = self.vm.qmp('change', - device='vnc', - target='password', - arg='new_password') + set_password_response = self.vm.qmp('change-vnc-password', + password='new_password') self.assertEqual(set_password_response['return'], {}) diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 2aab831d10..8bbb17b1c7 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -515,7 +515,7 @@ static void test_opts_parse(void) error_free_or_abort(&err); g_assert(!opts); - /* Implied value */ + /* Implied value (qemu_opts_parse warns but accepts it) */ opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 3); diff --git a/ui/vnc-stubs.c b/ui/vnc-stubs.c index c6b737dcec..b4eb3ce718 100644 --- a/ui/vnc-stubs.c +++ b/ui/vnc-stubs.c @@ -10,13 +10,12 @@ int vnc_display_pw_expire(const char *id, time_t expires) { return -ENODEV; }; -QemuOpts *vnc_parse(const char *str, Error **errp) +void vnc_parse(const char *str) { if (strcmp(str, "none") == 0) { - return NULL; + return; } - error_setg(errp, "VNC support is disabled"); - return NULL; + error_setg(&error_fatal, "VNC support is disabled"); } int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp) { @@ -50,6 +50,7 @@ #include "crypto/random.h" #include "qom/object_interfaces.h" #include "qemu/cutils.h" +#include "qemu/help_option.h" #include "io/dns-resolver.h" #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT @@ -4211,14 +4212,14 @@ static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts) qemu_opts_set_id(opts, id); } -QemuOpts *vnc_parse(const char *str, Error **errp) +void vnc_parse(const char *str) { QemuOptsList *olist = qemu_find_opts("vnc"); - QemuOpts *opts = qemu_opts_parse(olist, str, true, errp); + QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str)); const char *id; if (!opts) { - return NULL; + exit(1); } id = qemu_opts_id(opts); @@ -4226,7 +4227,6 @@ QemuOpts *vnc_parse(const char *str, Error **errp) /* auto-assign id if not present */ vnc_auto_assign_id(olist, opts); } - return opts; } int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp) diff --git a/util/cacheflush.c b/util/cacheflush.c index 6a20723902..933355b0c9 100644 --- a/util/cacheflush.c +++ b/util/cacheflush.c @@ -32,7 +32,7 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) * We want to save the whole contents of CTR_EL0, so that we * have more than the linesize, but also IDC and DIC. */ -static unsigned int save_ctr_el0; +static uint64_t save_ctr_el0; static void __attribute__((constructor)) init_ctr_el0(void) { asm volatile("mrs\t%0, ctr_el0" : "=r"(save_ctr_el0)); @@ -46,9 +46,9 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { const unsigned CTR_IDC = 1u << 28; const unsigned CTR_DIC = 1u << 29; - const unsigned int ctr_el0 = save_ctr_el0; - const uintptr_t icache_lsize = 4 << extract32(ctr_el0, 0, 4); - const uintptr_t dcache_lsize = 4 << extract32(ctr_el0, 16, 4); + const uint64_t ctr_el0 = save_ctr_el0; + const uintptr_t icache_lsize = 4 << extract64(ctr_el0, 0, 4); + const uintptr_t dcache_lsize = 4 << extract64(ctr_el0, 16, 4); uintptr_t p; /* diff --git a/util/qemu-option.c b/util/qemu-option.c index c88e159f18..40564a12eb 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -496,8 +496,7 @@ static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value, return opt; } -static bool opt_validate(QemuOpt *opt, bool *help_wanted, - Error **errp) +static bool opt_validate(QemuOpt *opt, Error **errp) { const QemuOptDesc *desc; const QemuOptsList *list = opt->opts->list; @@ -505,9 +504,6 @@ static bool opt_validate(QemuOpt *opt, bool *help_wanted, desc = find_desc_by_name(list->desc, opt->name); if (!desc && !opts_accepts_any(list)) { error_setg(errp, QERR_INVALID_PARAMETER, opt->name); - if (help_wanted && is_help_option(opt->name)) { - *help_wanted = true; - } return false; } @@ -524,7 +520,7 @@ bool qemu_opt_set(QemuOpts *opts, const char *name, const char *value, { QemuOpt *opt = opt_create(opts, name, g_strdup(value), false); - if (!opt_validate(opt, NULL, errp)) { + if (!opt_validate(opt, errp)) { qemu_opt_del(opt); return false; } @@ -619,7 +615,17 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, { QemuOpts *opts = NULL; - if (id) { + if (list->merge_lists) { + if (id) { + error_setg(errp, QERR_INVALID_PARAMETER, "id"); + return NULL; + } + opts = qemu_opts_find(list, NULL); + if (opts) { + return opts; + } + } else if (id) { + assert(fail_if_exists); if (!id_wellformed(id)) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier"); @@ -629,17 +635,8 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, } opts = qemu_opts_find(list, id); if (opts != NULL) { - if (fail_if_exists && !list->merge_lists) { - error_setg(errp, "Duplicate ID '%s' for %s", id, list->name); - return NULL; - } else { - return opts; - } - } - } else if (list->merge_lists) { - opts = qemu_opts_find(list, NULL); - if (opts) { - return opts; + error_setg(errp, "Duplicate ID '%s' for %s", id, list->name); + return NULL; } } opts = g_malloc0(sizeof(*opts)); @@ -759,10 +756,14 @@ void qemu_opts_print(QemuOpts *opts, const char *separator) static const char *get_opt_name_value(const char *params, const char *firstname, + bool warn_on_flag, + bool *help_wanted, char **name, char **value) { const char *p; + const char *prefix = ""; size_t len; + bool is_help = false; len = strcspn(params, "=,"); if (params[len] != '=') { @@ -777,8 +778,14 @@ static const char *get_opt_name_value(const char *params, if (strncmp(*name, "no", 2) == 0) { memmove(*name, *name + 2, strlen(*name + 2) + 1); *value = g_strdup("off"); + prefix = "no"; } else { *value = g_strdup("on"); + is_help = is_help_option(*name); + } + if (!is_help && warn_on_flag) { + warn_report("short-form boolean option '%s%s' deprecated", prefix, *name); + error_printf("Please use %s=%s instead\n", *name, *value); } } } else { @@ -790,6 +797,9 @@ static const char *get_opt_name_value(const char *params, } assert(!*p || *p == ','); + if (help_wanted && is_help) { + *help_wanted = true; + } if (*p == ',') { p++; } @@ -798,14 +808,19 @@ static const char *get_opt_name_value(const char *params, static bool opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, bool prepend, - bool *help_wanted, Error **errp) + bool warn_on_flag, bool *help_wanted, Error **errp) { char *option, *value; const char *p; QemuOpt *opt; for (p = params; *p;) { - p = get_opt_name_value(p, firstname, &option, &value); + p = get_opt_name_value(p, firstname, warn_on_flag, help_wanted, &option, &value); + if (help_wanted && *help_wanted) { + g_free(option); + g_free(value); + return false; + } firstname = NULL; if (!strcmp(option, "id")) { @@ -816,7 +831,7 @@ static bool opts_do_parse(QemuOpts *opts, const char *params, opt = opt_create(opts, option, value, prepend); g_free(option); - if (!opt_validate(opt, help_wanted, errp)) { + if (!opt_validate(opt, errp)) { qemu_opt_del(opt); return false; } @@ -831,7 +846,7 @@ static char *opts_parse_id(const char *params) char *name, *value; for (p = params; *p;) { - p = get_opt_name_value(p, NULL, &name, &value); + p = get_opt_name_value(p, NULL, false, NULL, &name, &value); if (!strcmp(name, "id")) { g_free(name); return value; @@ -847,11 +862,10 @@ bool has_help_option(const char *params) { const char *p; char *name, *value; - bool ret; + bool ret = false; for (p = params; *p;) { - p = get_opt_name_value(p, NULL, &name, &value); - ret = is_help_option(name); + p = get_opt_name_value(p, NULL, false, &ret, &name, &value); g_free(name); g_free(value); if (ret) { @@ -871,12 +885,12 @@ bool has_help_option(const char *params) bool qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, Error **errp) { - return opts_do_parse(opts, params, firstname, false, NULL, errp); + return opts_do_parse(opts, params, firstname, false, false, NULL, errp); } static QemuOpts *opts_parse(QemuOptsList *list, const char *params, bool permit_abbrev, bool defaults, - bool *help_wanted, Error **errp) + bool warn_on_flag, bool *help_wanted, Error **errp) { const char *firstname; char *id = opts_parse_id(params); @@ -893,14 +907,14 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params, * (if unlikely) future misuse: */ assert(!defaults || list->merge_lists); - opts = qemu_opts_create(list, id, !defaults, errp); + opts = qemu_opts_create(list, id, !list->merge_lists, errp); g_free(id); if (opts == NULL) { return NULL; } - if (!opts_do_parse(opts, params, firstname, defaults, help_wanted, - errp)) { + if (!opts_do_parse(opts, params, firstname, defaults, + warn_on_flag, help_wanted, errp)) { qemu_opts_del(opts); return NULL; } @@ -918,7 +932,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params, QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, bool permit_abbrev, Error **errp) { - return opts_parse(list, params, permit_abbrev, false, NULL, errp); + return opts_parse(list, params, permit_abbrev, false, false, NULL, errp); } /** @@ -936,11 +950,13 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params, QemuOpts *opts; bool help_wanted = false; - opts = opts_parse(list, params, permit_abbrev, false, &help_wanted, &err); - if (err) { + opts = opts_parse(list, params, permit_abbrev, false, true, + opts_accepts_any(list) ? NULL : &help_wanted, + &err); + if (!opts) { + assert(!!err + !!help_wanted == 1); if (help_wanted) { qemu_opts_print_help(list, true); - error_free(err); } else { error_report_err(err); } @@ -953,7 +969,7 @@ void qemu_opts_set_defaults(QemuOptsList *list, const char *params, { QemuOpts *opts; - opts = opts_parse(list, params, permit_abbrev, true, NULL, NULL); + opts = opts_parse(list, params, permit_abbrev, true, false, NULL, NULL); assert(opts); } |