Merge
This commit is contained in:
commit
322a792ffa
@ -6,6 +6,11 @@
|
||||
# most restrictive to least restrictive
|
||||
#
|
||||
.base_job_template:
|
||||
variables:
|
||||
# Each script line from will be in a collapsible section in the job output
|
||||
# and show the duration of each line.
|
||||
FF_SCRIPT_SECTIONS: 1
|
||||
|
||||
rules:
|
||||
#############################################################
|
||||
# Stage 1: exclude scenarios where we definitely don't
|
||||
|
@ -316,8 +316,7 @@ clang-system:
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++
|
||||
--extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined
|
||||
TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu
|
||||
ppc-softmmu s390x-softmmu
|
||||
TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu s390x-softmmu
|
||||
MAKE_CHECK_ARGS: check-qtest check-tcg
|
||||
|
||||
clang-user:
|
||||
@ -468,27 +467,16 @@ tsan-build:
|
||||
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
||||
MAKE_CHECK_ARGS: bench V=1
|
||||
|
||||
# gprof/gcov are GCC features
|
||||
build-gprof-gcov:
|
||||
# gcov is a GCC features
|
||||
gcov:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
job: amd64-ubuntu2004-container
|
||||
timeout: 80m
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
CONFIGURE_ARGS: --enable-gprof --enable-gcov
|
||||
CONFIGURE_ARGS: --enable-gcov
|
||||
TARGETS: aarch64-softmmu ppc64-softmmu s390x-softmmu x86_64-softmmu
|
||||
artifacts:
|
||||
expire_in: 1 days
|
||||
paths:
|
||||
- build
|
||||
|
||||
check-gprof-gcov:
|
||||
extends: .native_test_job_template
|
||||
needs:
|
||||
- job: build-gprof-gcov
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
MAKE_CHECK_ARGS: check
|
||||
after_script:
|
||||
- cd build
|
||||
@ -511,6 +499,7 @@ build-oss-fuzz:
|
||||
IMAGE: fedora
|
||||
script:
|
||||
- mkdir build-oss-fuzz
|
||||
- export LSAN_OPTIONS=suppressions=scripts/oss-fuzz/lsan_suppressions.txt
|
||||
- CC="clang" CXX="clang++" CFLAGS="-fsanitize=address"
|
||||
./scripts/oss-fuzz/build.sh
|
||||
- export ASAN_OPTIONS="fast_unwind_on_malloc=0"
|
||||
@ -558,29 +547,22 @@ build-coroutine-sigaltstack:
|
||||
MAKE_CHECK_ARGS: check-unit
|
||||
|
||||
# Check our reduced build configurations
|
||||
build-without-default-devices:
|
||||
build-without-defaults:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
job: amd64-centos8-container
|
||||
variables:
|
||||
IMAGE: centos8
|
||||
CONFIGURE_ARGS: --without-default-devices --disable-user
|
||||
|
||||
build-without-default-features:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
job: amd64-fedora-container
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS:
|
||||
--without-default-devices
|
||||
--without-default-features
|
||||
--disable-capstone
|
||||
--disable-fdt
|
||||
--disable-pie
|
||||
--disable-qom-cast-debug
|
||||
--disable-strip
|
||||
TARGETS: avr-softmmu i386-softmmu mips64-softmmu s390x-softmmu sh4-softmmu
|
||||
TARGETS: avr-softmmu mips64-softmmu s390x-softmmu sh4-softmmu
|
||||
sparc64-softmmu hexagon-linux-user i386-linux-user s390x-linux-user
|
||||
MAKE_CHECK_ARGS: check-unit check-qtest SPEED=slow
|
||||
MAKE_CHECK_ARGS: check-unit check-qtest-avr check-qtest-mips64
|
||||
|
||||
build-libvhost-user:
|
||||
extends: .base_job_template
|
||||
|
@ -53,7 +53,7 @@ x64-freebsd-12-build:
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-12-4
|
||||
CIRRUS_VM_CPUS: 8
|
||||
CIRRUS_VM_RAM: 8G
|
||||
UPDATE_COMMAND: pkg update
|
||||
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
||||
INSTALL_COMMAND: pkg install -y
|
||||
TEST_TARGETS: check
|
||||
|
||||
@ -66,7 +66,7 @@ x64-freebsd-13-build:
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-13-1
|
||||
CIRRUS_VM_CPUS: 8
|
||||
CIRRUS_VM_RAM: 8G
|
||||
UPDATE_COMMAND: pkg update
|
||||
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
||||
INSTALL_COMMAND: pkg install -y
|
||||
TEST_TARGETS: check
|
||||
|
||||
|
@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
|
||||
NINJA='/usr/local/bin/ninja'
|
||||
PACKAGING_COMMAND='pkg'
|
||||
PIP3='/usr/local/bin/pip-3.8'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract usbredir virglrenderer vte3 zstd'
|
||||
PYPI_PKGS=''
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
|
@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
|
||||
NINJA='/usr/local/bin/ninja'
|
||||
PACKAGING_COMMAND='pkg'
|
||||
PIP3='/usr/local/bin/pip-3.8'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract usbredir virglrenderer vte3 zstd'
|
||||
PYPI_PKGS=''
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
|
@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
|
||||
NINJA='/opt/homebrew/bin/ninja'
|
||||
PACKAGING_COMMAND='brew'
|
||||
PIP3='/opt/homebrew/bin/pip3'
|
||||
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 zlib zstd'
|
||||
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract usbredir vde vte3 zlib zstd'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
|
||||
PYTHON='/opt/homebrew/bin/python3'
|
||||
|
@ -187,7 +187,9 @@ cross-win64-system:
|
||||
job: win64-fedora-cross-container
|
||||
variables:
|
||||
IMAGE: fedora-win64-cross
|
||||
CROSS_SKIP_TARGETS: or1k-softmmu rx-softmmu sh4eb-softmmu sparc64-softmmu
|
||||
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu
|
||||
m68k-softmmu microblazeel-softmmu nios2-softmmu
|
||||
or1k-softmmu rx-softmmu sh4eb-softmmu sparc64-softmmu
|
||||
tricore-softmmu xtensaeb-softmmu
|
||||
artifacts:
|
||||
paths:
|
||||
|
@ -13,6 +13,17 @@
|
||||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
|
||||
# All custom runners can extend this template to upload the testlog
|
||||
# data as an artifact and also feed the junit report
|
||||
.custom_artifacts_template:
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
|
||||
include:
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-s390x.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml'
|
||||
|
@ -3,6 +3,7 @@
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04/20.04"
|
||||
|
||||
ubuntu-20.04-s390x-all-linux-static:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -19,12 +20,11 @@ ubuntu-20.04-s390x-all-linux-static:
|
||||
- ../configure --enable-debug --static --disable-system --disable-glusterfs --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync check-tcg
|
||||
- make --output-sync -j`nproc` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc` check-tcg
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-all:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -41,9 +41,9 @@ ubuntu-20.04-s390x-all:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-alldbg:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -64,9 +64,9 @@ ubuntu-20.04-s390x-alldbg:
|
||||
- make clean
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-clang:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -86,7 +86,6 @@ ubuntu-20.04-s390x-clang:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-tci:
|
||||
needs: []
|
||||
@ -109,6 +108,7 @@ ubuntu-20.04-s390x-tci:
|
||||
- make --output-sync -j`nproc`
|
||||
|
||||
ubuntu-20.04-s390x-notcg:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -128,4 +128,3 @@ ubuntu-20.04-s390x-notcg:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
@ -3,6 +3,7 @@
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04"
|
||||
|
||||
ubuntu-22.04-aarch32-all:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -22,4 +23,3 @@ ubuntu-22.04-aarch32-all:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
@ -3,6 +3,7 @@
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04"
|
||||
|
||||
ubuntu-22.04-aarch64-all-linux-static:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -19,12 +20,11 @@ ubuntu-22.04-aarch64-all-linux-static:
|
||||
- ../configure --enable-debug --static --disable-system --disable-pie
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make check-tcg
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc --ignore=40` check-tcg
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-22.04-aarch64-all:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -44,9 +44,9 @@ ubuntu-22.04-aarch64-all:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-22.04-aarch64-alldbg:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -63,9 +63,9 @@ ubuntu-22.04-aarch64-alldbg:
|
||||
- make clean
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-22.04-aarch64-clang:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -81,11 +81,10 @@ ubuntu-22.04-aarch64-clang:
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --cc=clang-10 --cxx=clang++-10 --enable-sanitizers
|
||||
- ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-sanitizers
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-22.04-aarch64-tci:
|
||||
needs: []
|
||||
@ -108,6 +107,7 @@ ubuntu-22.04-aarch64-tci:
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
|
||||
ubuntu-22.04-aarch64-notcg:
|
||||
extends: .custom_artifacts_template
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
@ -127,4 +127,3 @@ ubuntu-22.04-aarch64-notcg:
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
@ -71,7 +71,7 @@ msys2-64bit:
|
||||
# for the msys2 64-bit job, due to the build could not complete within
|
||||
# the project timeout.
|
||||
- ..\msys64\usr\bin\bash -lc '../configure --target-list=x86_64-softmmu
|
||||
--without-default-devices --disable-opengl'
|
||||
--without-default-devices'
|
||||
- ..\msys64\usr\bin\bash -lc 'make'
|
||||
# qTests don't run successfully with "--without-default-devices",
|
||||
# so let's exclude the qtests from CI for now.
|
||||
@ -113,8 +113,7 @@ msys2-32bit:
|
||||
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
||||
- mkdir output
|
||||
- cd output
|
||||
- ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu
|
||||
--disable-opengl'
|
||||
- ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu'
|
||||
- ..\msys64\usr\bin\bash -lc 'make'
|
||||
- ..\msys64\usr\bin\bash -lc 'make check MTESTARGS=\"--no-suite qtest\" ||
|
||||
{ cat meson-logs/testlog.txt; exit 1; }'
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -13,9 +13,6 @@
|
||||
[submodule "roms/qemu-palcode"]
|
||||
path = roms/qemu-palcode
|
||||
url = https://gitlab.com/qemu-project/qemu-palcode.git
|
||||
[submodule "roms/sgabios"]
|
||||
path = roms/sgabios
|
||||
url = https://gitlab.com/qemu-project/sgabios.git
|
||||
[submodule "dtc"]
|
||||
path = dtc
|
||||
url = https://gitlab.com/qemu-project/dtc.git
|
||||
|
59
.travis.yml
59
.travis.yml
@ -16,43 +16,6 @@ cache:
|
||||
- $HOME/avocado/data/cache
|
||||
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# Build dependencies
|
||||
- libaio-dev
|
||||
- libattr1-dev
|
||||
- libbrlapi-dev
|
||||
- libcap-ng-dev
|
||||
- libcacard-dev
|
||||
- libgcc-7-dev
|
||||
- libgnutls28-dev
|
||||
- libgtk-3-dev
|
||||
- libiscsi-dev
|
||||
- liblttng-ust-dev
|
||||
- libncurses5-dev
|
||||
- libnfs-dev
|
||||
- libpixman-1-dev
|
||||
- libpng-dev
|
||||
- librados-dev
|
||||
- libsdl2-dev
|
||||
- libsdl2-image-dev
|
||||
- libseccomp-dev
|
||||
- libspice-protocol-dev
|
||||
- libspice-server-dev
|
||||
- libssh-dev
|
||||
- liburcu-dev
|
||||
- libusb-1.0-0-dev
|
||||
- libvdeplug-dev
|
||||
- libvte-2.91-dev
|
||||
- libzstd-dev
|
||||
- ninja-build
|
||||
- sparse
|
||||
- uuid-dev
|
||||
# Tests dependencies
|
||||
- genisoimage
|
||||
|
||||
|
||||
# The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu
|
||||
# to prevent IRC notifications from forks. This was created using:
|
||||
# $ travis encrypt -r "qemu/qemu" "irc.oftc.net#qemu"
|
||||
@ -128,6 +91,7 @@ jobs:
|
||||
- libbrlapi-dev
|
||||
- libcacard-dev
|
||||
- libcap-ng-dev
|
||||
- libfdt-dev
|
||||
- libgcrypt20-dev
|
||||
- libgnutls28-dev
|
||||
- libgtk-3-dev
|
||||
@ -149,7 +113,8 @@ jobs:
|
||||
- genisoimage
|
||||
env:
|
||||
- TEST_CMD="make check check-tcg V=1"
|
||||
- CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS} --cxx=/bin/false"
|
||||
- CONFIG="--disable-containers --enable-fdt=system
|
||||
--target-list=${MAIN_SOFTMMU_TARGETS} --cxx=/bin/false"
|
||||
- UNRELIABLE=true
|
||||
|
||||
- name: "[ppc64] GCC check-tcg"
|
||||
@ -162,6 +127,7 @@ jobs:
|
||||
- libbrlapi-dev
|
||||
- libcacard-dev
|
||||
- libcap-ng-dev
|
||||
- libfdt-dev
|
||||
- libgcrypt20-dev
|
||||
- libgnutls28-dev
|
||||
- libgtk-3-dev
|
||||
@ -183,7 +149,8 @@ jobs:
|
||||
- genisoimage
|
||||
env:
|
||||
- TEST_CMD="make check check-tcg V=1"
|
||||
- CONFIG="--disable-containers --target-list=ppc64-softmmu,ppc64le-linux-user"
|
||||
- CONFIG="--disable-containers --enable-fdt=system
|
||||
--target-list=ppc64-softmmu,ppc64le-linux-user"
|
||||
|
||||
- name: "[s390x] GCC check-tcg"
|
||||
arch: s390x
|
||||
@ -195,6 +162,7 @@ jobs:
|
||||
- libbrlapi-dev
|
||||
- libcacard-dev
|
||||
- libcap-ng-dev
|
||||
- libfdt-dev
|
||||
- libgcrypt20-dev
|
||||
- libgnutls28-dev
|
||||
- libgtk-3-dev
|
||||
@ -216,7 +184,8 @@ jobs:
|
||||
- genisoimage
|
||||
env:
|
||||
- TEST_CMD="make check check-tcg V=1"
|
||||
- CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS},s390x-linux-user"
|
||||
- CONFIG="--disable-containers --enable-fdt=system
|
||||
--target-list=${MAIN_SOFTMMU_TARGETS},s390x-linux-user"
|
||||
- UNRELIABLE=true
|
||||
script:
|
||||
- BUILD_RC=0 && make -j${JOBS} || BUILD_RC=$?
|
||||
@ -237,6 +206,7 @@ jobs:
|
||||
- libattr1-dev
|
||||
- libcacard-dev
|
||||
- libcap-ng-dev
|
||||
- libfdt-dev
|
||||
- libgnutls28-dev
|
||||
- libiscsi-dev
|
||||
- liblttng-ust-dev
|
||||
@ -255,8 +225,8 @@ jobs:
|
||||
# Tests dependencies
|
||||
- genisoimage
|
||||
env:
|
||||
- CONFIG="--disable-containers --audio-drv-list=sdl --disable-user
|
||||
--target-list-exclude=${MAIN_SOFTMMU_TARGETS}"
|
||||
- CONFIG="--disable-containers --enable-fdt=system --audio-drv-list=sdl
|
||||
--disable-user --target-list-exclude=${MAIN_SOFTMMU_TARGETS}"
|
||||
|
||||
- name: "[s390x] GCC (user)"
|
||||
arch: s390x
|
||||
@ -281,6 +251,7 @@ jobs:
|
||||
- libbrlapi-dev
|
||||
- libcacard-dev
|
||||
- libcap-ng-dev
|
||||
- libfdt-dev
|
||||
- libgcrypt20-dev
|
||||
- libgnutls28-dev
|
||||
- libgtk-3-dev
|
||||
@ -300,6 +271,6 @@ jobs:
|
||||
- ninja-build
|
||||
env:
|
||||
- TEST_CMD="make check-unit"
|
||||
- CONFIG="--disable-containers --disable-tcg --enable-kvm
|
||||
--disable-tools --host-cc=clang --cxx=clang++"
|
||||
- CONFIG="--disable-containers --disable-tcg --enable-kvm --disable-tools
|
||||
--enable-fdt=system --host-cc=clang --cxx=clang++"
|
||||
- UNRELIABLE=true
|
||||
|
49
MAINTAINERS
49
MAINTAINERS
@ -240,7 +240,6 @@ F: target/microblaze/
|
||||
F: hw/microblaze/
|
||||
F: disas/microblaze.c
|
||||
F: tests/docker/dockerfiles/debian-microblaze-cross.d/build-toolchain.sh
|
||||
F: tests/tcg/nios2/Makefile.target
|
||||
|
||||
MIPS TCG CPUs
|
||||
M: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
@ -262,6 +261,7 @@ F: hw/nios2/
|
||||
F: disas/nios2.c
|
||||
F: configs/devices/nios2-softmmu/default.mak
|
||||
F: tests/docker/dockerfiles/debian-nios2-cross.d/build-toolchain.sh
|
||||
F: tests/tcg/nios2/
|
||||
|
||||
OpenRISC TCG CPUs
|
||||
M: Stafford Horne <shorne@gmail.com>
|
||||
@ -295,6 +295,14 @@ F: include/hw/riscv/
|
||||
F: linux-user/host/riscv32/
|
||||
F: linux-user/host/riscv64/
|
||||
|
||||
RISC-V XThead* extensions
|
||||
M: Christoph Muellner <christoph.muellner@vrull.eu>
|
||||
M: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
|
||||
L: qemu-riscv@nongnu.org
|
||||
S: Supported
|
||||
F: target/riscv/insn_trans/trans_xthead.c.inc
|
||||
F: target/riscv/xthead*.decode
|
||||
|
||||
RISC-V XVentanaCondOps extension
|
||||
M: Philipp Tomsich <philipp.tomsich@vrull.eu>
|
||||
L: qemu-riscv@nongnu.org
|
||||
@ -437,7 +445,7 @@ M: Richard Henderson <richard.henderson@linaro.org>
|
||||
R: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Maintained
|
||||
F: include/qemu/accel.h
|
||||
F: include/sysemu/accel-ops.h
|
||||
F: include/sysemu/accel-*.h
|
||||
F: include/hw/core/accel-cpu.h
|
||||
F: accel/accel-*.c
|
||||
F: accel/Makefile.objs
|
||||
@ -500,10 +508,7 @@ F: stubs/xen-hw-stub.c
|
||||
Guest CPU Cores (HAXM)
|
||||
---------------------
|
||||
X86 HAXM CPUs
|
||||
M: Wenchao Wang <wenchao.wang@intel.com>
|
||||
L: haxm-team@intel.com
|
||||
W: https://github.com/intel/haxm/issues
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: accel/stubs/hax-stub.c
|
||||
F: include/sysemu/hax.h
|
||||
F: target/i386/hax/
|
||||
@ -511,7 +516,6 @@ F: target/i386/hax/
|
||||
Guest CPU Cores (NVMM)
|
||||
----------------------
|
||||
NetBSD Virtual Machine Monitor (NVMM) CPU support
|
||||
M: Kamil Rytarowski <kamil@netbsd.org>
|
||||
M: Reinoud Zandijk <reinoud@netbsd.org>
|
||||
S: Maintained
|
||||
F: include/sysemu/nvmm.h
|
||||
@ -536,7 +540,6 @@ F: util/*posix*.c
|
||||
F: include/qemu/*posix*.h
|
||||
|
||||
NETBSD
|
||||
M: Kamil Rytarowski <kamil@netbsd.org>
|
||||
M: Reinoud Zandijk <reinoud@netbsd.org>
|
||||
M: Ryo ONODERA <ryoon@netbsd.org>
|
||||
S: Maintained
|
||||
@ -804,13 +807,13 @@ F: include/hw/net/mv88w8618_eth.h
|
||||
F: docs/system/arm/musicpal.rst
|
||||
|
||||
Nuvoton NPCM7xx
|
||||
M: Havard Skinnemoen <hskinnemoen@google.com>
|
||||
M: Tyrone Ting <kfting@nuvoton.com>
|
||||
M: Hao Wu <wuhaotsh@google.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Supported
|
||||
F: hw/*/npcm7xx*
|
||||
F: include/hw/*/npcm7xx*
|
||||
F: tests/qtest/npcm7xx*
|
||||
F: hw/*/npcm*
|
||||
F: include/hw/*/npcm*
|
||||
F: tests/qtest/npcm*
|
||||
F: pc-bios/npcm7xx_bootrom.bin
|
||||
F: roms/vbootrom
|
||||
F: docs/system/arm/nuvoton.rst
|
||||
@ -944,6 +947,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/versatile*
|
||||
F: hw/i2c/arm_sbcon_i2c.c
|
||||
F: include/hw/i2c/arm_sbcon_i2c.h
|
||||
F: hw/misc/arm_sysctl.c
|
||||
F: docs/system/arm/versatile.rst
|
||||
@ -1249,7 +1253,7 @@ S: Odd Fixes
|
||||
F: hw/isa/piix4.c
|
||||
F: hw/acpi/piix4.c
|
||||
F: hw/mips/malta.c
|
||||
F: hw/mips/gt64xxx_pci.c
|
||||
F: hw/pci-host/gt64120.c
|
||||
F: include/hw/southbridge/piix.h
|
||||
F: tests/avocado/linux_ssh_mips_malta.py
|
||||
F: tests/avocado/machine_mips_malta.py
|
||||
@ -1270,6 +1274,7 @@ F: hw/isa/vt82c686.c
|
||||
F: hw/pci-host/bonito.c
|
||||
F: hw/usb/vt82c686-uhci-pci.c
|
||||
F: include/hw/isa/vt82c686.h
|
||||
F: include/hw/pci-host/bonito.h
|
||||
F: tests/avocado/machine_mips_fuloong2e.py
|
||||
|
||||
Loongson-3 virtual platforms
|
||||
@ -1671,7 +1676,6 @@ F: hw/acpi/piix4.c
|
||||
F: hw/acpi/ich9*.c
|
||||
F: include/hw/acpi/ich9*.h
|
||||
F: include/hw/southbridge/piix.h
|
||||
F: hw/misc/sga.c
|
||||
F: hw/isa/apm.c
|
||||
F: include/hw/isa/apm.h
|
||||
F: tests/unit/test-x86-cpuid.c
|
||||
@ -1991,6 +1995,7 @@ F: hw/usb/dev-serial.c
|
||||
|
||||
VFIO
|
||||
M: Alex Williamson <alex.williamson@redhat.com>
|
||||
R: Cédric Le Goater <clg@redhat.com>
|
||||
S: Supported
|
||||
F: hw/vfio/*
|
||||
F: include/hw/vfio/
|
||||
@ -2092,10 +2097,8 @@ virtiofs
|
||||
M: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
S: Supported
|
||||
F: tools/virtiofsd/*
|
||||
F: hw/virtio/vhost-user-fs*
|
||||
F: include/hw/virtio/vhost-user-fs.h
|
||||
F: docs/tools/virtiofsd.rst
|
||||
L: virtio-fs@redhat.com
|
||||
|
||||
virtio-input
|
||||
@ -2804,8 +2807,7 @@ F: softmmu/cpus.c
|
||||
F: softmmu/cpu-throttle.c
|
||||
F: softmmu/cpu-timers.c
|
||||
F: softmmu/icount.c
|
||||
F: softmmu/runstate-action.c
|
||||
F: softmmu/runstate.c
|
||||
F: softmmu/runstate*
|
||||
F: qapi/run-state.json
|
||||
|
||||
Read, Copy, Update (RCU)
|
||||
@ -3039,6 +3041,11 @@ F: net/slirp.c
|
||||
F: include/net/slirp.h
|
||||
T: git https://people.debian.org/~sthibault/qemu.git slirp
|
||||
|
||||
Stats
|
||||
S: Orphan
|
||||
F: include/sysemu/stats.h
|
||||
F: stats/
|
||||
|
||||
Streams
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
S: Maintained
|
||||
@ -3067,7 +3074,7 @@ T: git https://github.com/stefanha/qemu.git tracing
|
||||
TPM
|
||||
M: Stefan Berger <stefanb@linux.ibm.com>
|
||||
S: Maintained
|
||||
F: tpm.c
|
||||
F: softmmu/tpm*
|
||||
F: hw/tpm/*
|
||||
F: include/hw/acpi/tpm.h
|
||||
F: include/sysemu/tpm*
|
||||
@ -3088,6 +3095,7 @@ S: Maintained
|
||||
F: hw/core/vmstate-if.c
|
||||
F: include/hw/vmstate-if.h
|
||||
F: include/migration/
|
||||
F: include/qemu/userfaultfd.h
|
||||
F: migration/
|
||||
F: scripts/vmstate-static-checker.py
|
||||
F: tests/vmstate-static-checker-data/
|
||||
@ -3095,6 +3103,7 @@ F: tests/qtest/migration-test.c
|
||||
F: docs/devel/migration.rst
|
||||
F: qapi/migration.json
|
||||
F: tests/migration/
|
||||
F: util/userfaultfd.c
|
||||
|
||||
D-Bus
|
||||
M: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
@ -3569,13 +3578,11 @@ F: block/dmg.c
|
||||
parallels
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
M: Denis V. Lunev <den@openvz.org>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/parallels.c
|
||||
F: block/parallels-ext.c
|
||||
F: docs/interop/parallels.txt
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
|
||||
qed
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
|
2
Makefile
2
Makefile
@ -150,7 +150,7 @@ NINJAFLAGS = $(if $V,-v) $(if $(MAKE.n), -n) $(if $(MAKE.k), -k0) \
|
||||
ninja-cmd-goals = $(or $(MAKECMDGOALS), all)
|
||||
ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g))
|
||||
|
||||
makefile-targets := build.ninja ctags TAGS cscope dist clean uninstall
|
||||
makefile-targets := build.ninja ctags TAGS cscope dist clean
|
||||
# "ninja -t targets" also lists all prerequisites. If build system
|
||||
# files are marked as PHONY, however, Make will always try to execute
|
||||
# "ninja build.ninja".
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include "qemu/range.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
#include "monitor/stats.h"
|
||||
#include "sysemu/stats.h"
|
||||
|
||||
/* This check must be after config-host.h is included */
|
||||
#ifdef CONFIG_EVENTFD
|
||||
|
@ -55,8 +55,53 @@ CMPXCHG_HELPER(cmpxchgq_be, uint64_t)
|
||||
CMPXCHG_HELPER(cmpxchgq_le, uint64_t)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMPXCHG128
|
||||
CMPXCHG_HELPER(cmpxchgo_be, Int128)
|
||||
CMPXCHG_HELPER(cmpxchgo_le, Int128)
|
||||
#endif
|
||||
|
||||
#undef CMPXCHG_HELPER
|
||||
|
||||
Int128 HELPER(nonatomic_cmpxchgo_be)(CPUArchState *env, target_ulong addr,
|
||||
Int128 cmpv, Int128 newv, uint32_t oi)
|
||||
{
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
uintptr_t ra = GETPC();
|
||||
Int128 oldv;
|
||||
|
||||
oldv = cpu_ld16_be_mmu(env, addr, oi, ra);
|
||||
if (int128_eq(oldv, cmpv)) {
|
||||
cpu_st16_be_mmu(env, addr, newv, oi, ra);
|
||||
} else {
|
||||
/* Even with comparison failure, still need a write cycle. */
|
||||
probe_write(env, addr, 16, get_mmuidx(oi), ra);
|
||||
}
|
||||
return oldv;
|
||||
#else
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
Int128 HELPER(nonatomic_cmpxchgo_le)(CPUArchState *env, target_ulong addr,
|
||||
Int128 cmpv, Int128 newv, uint32_t oi)
|
||||
{
|
||||
#if TCG_TARGET_REG_BITS == 32
|
||||
uintptr_t ra = GETPC();
|
||||
Int128 oldv;
|
||||
|
||||
oldv = cpu_ld16_le_mmu(env, addr, oi, ra);
|
||||
if (int128_eq(oldv, cmpv)) {
|
||||
cpu_st16_le_mmu(env, addr, newv, oi, ra);
|
||||
} else {
|
||||
/* Even with comparison failure, still need a write cycle. */
|
||||
probe_write(env, addr, 16, get_mmuidx(oi), ra);
|
||||
}
|
||||
return oldv;
|
||||
#else
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ATOMIC_HELPER(OP, TYPE) \
|
||||
TYPE HELPER(glue(atomic_,OP))(CPUArchState *env, target_ulong addr, \
|
||||
TYPE val, uint32_t oi) \
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "exec/exec-all.h"
|
||||
#include "tcg/tcg.h"
|
||||
#include "qemu/atomic.h"
|
||||
#include "qemu/compiler.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/rcu.h"
|
||||
#include "exec/log.h"
|
||||
@ -504,6 +503,7 @@ static void cpu_exec_exit(CPUState *cpu)
|
||||
if (cc->tcg_ops->cpu_exec_exit) {
|
||||
cc->tcg_ops->cpu_exec_exit(cpu);
|
||||
}
|
||||
QEMU_PLUGIN_ASSERT(cpu->plugin_mem_cbs == NULL);
|
||||
}
|
||||
|
||||
void cpu_exec_step_atomic(CPUState *cpu)
|
||||
@ -572,15 +572,18 @@ void cpu_exec_step_atomic(CPUState *cpu)
|
||||
|
||||
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
|
||||
{
|
||||
if (TCG_TARGET_HAS_direct_jump) {
|
||||
uintptr_t offset = tb->jmp_target_arg[n];
|
||||
uintptr_t tc_ptr = (uintptr_t)tb->tc.ptr;
|
||||
uintptr_t jmp_rx = tc_ptr + offset;
|
||||
uintptr_t jmp_rw = jmp_rx - tcg_splitwx_diff;
|
||||
tb_target_set_jmp_target(tc_ptr, jmp_rx, jmp_rw, addr);
|
||||
} else {
|
||||
tb->jmp_target_arg[n] = addr;
|
||||
}
|
||||
/*
|
||||
* Get the rx view of the structure, from which we find the
|
||||
* executable code address, and tb_target_set_jmp_target can
|
||||
* produce a pc-relative displacement to jmp_target_addr[n].
|
||||
*/
|
||||
const TranslationBlock *c_tb = tcg_splitwx_to_rx(tb);
|
||||
uintptr_t offset = tb->jmp_insn_offset[n];
|
||||
uintptr_t jmp_rx = (uintptr_t)tb->tc.ptr + offset;
|
||||
uintptr_t jmp_rw = jmp_rx - tcg_splitwx_diff;
|
||||
|
||||
tb->jmp_target_addr[n] = addr;
|
||||
tb_target_set_jmp_target(c_tb, n, jmp_rx, jmp_rw);
|
||||
}
|
||||
|
||||
static inline void tb_add_jump(TranslationBlock *tb, int n,
|
||||
@ -939,70 +942,10 @@ extern __thread int libafl_valid_current_cpu;
|
||||
|
||||
/* main execution loop */
|
||||
|
||||
int cpu_exec(CPUState *cpu)
|
||||
static int __attribute__((noinline))
|
||||
cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
|
||||
{
|
||||
int ret;
|
||||
SyncClocks sc = { 0 };
|
||||
|
||||
/* replay_interrupt may need current_cpu */
|
||||
current_cpu = cpu;
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
libafl_valid_current_cpu = 1;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
if (cpu_handle_halt(cpu)) {
|
||||
return EXCP_HALTED;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
cpu_exec_enter(cpu);
|
||||
|
||||
/* Calculate difference between guest clock and host clock.
|
||||
* This delay includes the delay of the last cycle, so
|
||||
* what we have to do is sleep until it is 0. As for the
|
||||
* advance/delay we gain here, we try to fix it next time.
|
||||
*/
|
||||
init_delay_params(&sc, cpu);
|
||||
|
||||
/* prepare setjmp context for exception handling */
|
||||
if (sigsetjmp(cpu->jmp_env, 0) != 0) {
|
||||
#if defined(__clang__)
|
||||
/*
|
||||
* Some compilers wrongly smash all local variables after
|
||||
* siglongjmp (the spec requires that only non-volatile locals
|
||||
* which are changed between the sigsetjmp and siglongjmp are
|
||||
* permitted to be trashed). There were bug reports for gcc
|
||||
* 4.5.0 and clang. The bug is fixed in all versions of gcc
|
||||
* that we support, but is still unfixed in clang:
|
||||
* https://bugs.llvm.org/show_bug.cgi?id=21183
|
||||
*
|
||||
* Reload an essential local variable here for those compilers.
|
||||
* Newer versions of gcc would complain about this code (-Wclobbered),
|
||||
* so we only perform the workaround for clang.
|
||||
*/
|
||||
cpu = current_cpu;
|
||||
#else
|
||||
/* Non-buggy compilers preserve this; assert the correct value. */
|
||||
g_assert(cpu == current_cpu);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SOFTMMU
|
||||
clear_helper_retaddr();
|
||||
if (have_mmap_lock()) {
|
||||
mmap_unlock();
|
||||
}
|
||||
#endif
|
||||
if (qemu_mutex_iothread_locked()) {
|
||||
qemu_mutex_unlock_iothread();
|
||||
}
|
||||
qemu_plugin_disable_mem_helpers(cpu);
|
||||
|
||||
assert_no_pages_locked();
|
||||
}
|
||||
|
||||
/* if an exception is pending, we execute it here */
|
||||
while (!cpu_handle_exception(cpu, &ret)) {
|
||||
@ -1092,11 +1035,69 @@ int cpu_exec(CPUState *cpu)
|
||||
|
||||
cpu_loop_exec_tb(cpu, tb, pc, &last_tb, &tb_exit);
|
||||
|
||||
QEMU_PLUGIN_ASSERT(cpu->plugin_mem_cbs == NULL);
|
||||
/* Try to align the host and virtual clocks
|
||||
if the guest is in advance */
|
||||
align_clocks(&sc, cpu);
|
||||
align_clocks(sc, cpu);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpu_exec_setjmp(CPUState *cpu, SyncClocks *sc)
|
||||
{
|
||||
/* Prepare setjmp context for exception handling. */
|
||||
if (unlikely(sigsetjmp(cpu->jmp_env, 0) != 0)) {
|
||||
/* Non-buggy compilers preserve this; assert the correct value. */
|
||||
g_assert(cpu == current_cpu);
|
||||
|
||||
#ifndef CONFIG_SOFTMMU
|
||||
clear_helper_retaddr();
|
||||
if (have_mmap_lock()) {
|
||||
mmap_unlock();
|
||||
}
|
||||
#endif
|
||||
if (qemu_mutex_iothread_locked()) {
|
||||
qemu_mutex_unlock_iothread();
|
||||
}
|
||||
qemu_plugin_disable_mem_helpers(cpu);
|
||||
|
||||
assert_no_pages_locked();
|
||||
}
|
||||
|
||||
return cpu_exec_loop(cpu, sc);
|
||||
}
|
||||
|
||||
int cpu_exec(CPUState *cpu)
|
||||
{
|
||||
int ret;
|
||||
SyncClocks sc = { 0 };
|
||||
|
||||
/* replay_interrupt may need current_cpu */
|
||||
current_cpu = cpu;
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
libafl_valid_current_cpu = 1;
|
||||
|
||||
//// --- End LibAFL code ---
|
||||
|
||||
if (cpu_handle_halt(cpu)) {
|
||||
return EXCP_HALTED;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
cpu_exec_enter(cpu);
|
||||
|
||||
/*
|
||||
* Calculate difference between guest clock and host clock.
|
||||
* This delay includes the delay of the last cycle, so
|
||||
* what we have to do is sleep until it is 0. As for the
|
||||
* advance/delay we gain here, we try to fix it next time.
|
||||
*/
|
||||
init_delay_params(&sc, cpu);
|
||||
|
||||
ret = cpu_exec_setjmp(cpu, &sc);
|
||||
|
||||
cpu_exec_exit(cpu);
|
||||
rcu_read_unlock();
|
||||
@ -1125,13 +1126,12 @@ void tcg_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
/* undo the initializations in reverse order */
|
||||
void tcg_exec_unrealizefn(CPUState *cpu)
|
||||
{
|
||||
qemu_plugin_vcpu_exit_hook(cpu);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
tcg_iommu_free_notifier_list(cpu);
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
tlb_destroy(cpu);
|
||||
g_free(cpu->tb_jmp_cache);
|
||||
g_free_rcu(cpu->tb_jmp_cache, rcu);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
@ -100,9 +100,14 @@ static void tlb_window_reset(CPUTLBDesc *desc, int64_t ns,
|
||||
|
||||
static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
|
||||
{
|
||||
int i, i0 = tb_jmp_cache_hash_page(page_addr);
|
||||
CPUJumpCache *jc = cpu->tb_jmp_cache;
|
||||
int i, i0;
|
||||
|
||||
if (unlikely(!jc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
i0 = tb_jmp_cache_hash_page(page_addr);
|
||||
for (i = 0; i < TB_JMP_PAGE_SIZE; i++) {
|
||||
qatomic_set(&jc->array[i0 + i].tb, NULL);
|
||||
}
|
||||
@ -1142,7 +1147,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
|
||||
&xlat, &sz, full->attrs, &prot);
|
||||
assert(sz >= TARGET_PAGE_SIZE);
|
||||
|
||||
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
|
||||
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" HWADDR_FMT_plx
|
||||
" prot=%x idx=%d\n",
|
||||
vaddr, full->phys_addr, prot, mmu_idx);
|
||||
|
||||
@ -2187,6 +2192,64 @@ uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
return cpu_load_helper(env, addr, oi, ra, helper_le_ldq_mmu);
|
||||
}
|
||||
|
||||
Int128 cpu_ld16_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
MemOp mop = get_memop(oi);
|
||||
int mmu_idx = get_mmuidx(oi);
|
||||
MemOpIdx new_oi;
|
||||
unsigned a_bits;
|
||||
uint64_t h, l;
|
||||
|
||||
tcg_debug_assert((mop & (MO_BSWAP|MO_SSIZE)) == (MO_BE|MO_128));
|
||||
a_bits = get_alignment_bits(mop);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_LOAD,
|
||||
mmu_idx, ra);
|
||||
}
|
||||
|
||||
/* Construct an unaligned 64-bit replacement MemOpIdx. */
|
||||
mop = (mop & ~(MO_SIZE | MO_AMASK)) | MO_64 | MO_UNALN;
|
||||
new_oi = make_memop_idx(mop, mmu_idx);
|
||||
|
||||
h = helper_be_ldq_mmu(env, addr, new_oi, ra);
|
||||
l = helper_be_ldq_mmu(env, addr + 8, new_oi, ra);
|
||||
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
return int128_make128(l, h);
|
||||
}
|
||||
|
||||
Int128 cpu_ld16_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
MemOp mop = get_memop(oi);
|
||||
int mmu_idx = get_mmuidx(oi);
|
||||
MemOpIdx new_oi;
|
||||
unsigned a_bits;
|
||||
uint64_t h, l;
|
||||
|
||||
tcg_debug_assert((mop & (MO_BSWAP|MO_SSIZE)) == (MO_LE|MO_128));
|
||||
a_bits = get_alignment_bits(mop);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_LOAD,
|
||||
mmu_idx, ra);
|
||||
}
|
||||
|
||||
/* Construct an unaligned 64-bit replacement MemOpIdx. */
|
||||
mop = (mop & ~(MO_SIZE | MO_AMASK)) | MO_64 | MO_UNALN;
|
||||
new_oi = make_memop_idx(mop, mmu_idx);
|
||||
|
||||
l = helper_le_ldq_mmu(env, addr, new_oi, ra);
|
||||
h = helper_le_ldq_mmu(env, addr + 8, new_oi, ra);
|
||||
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
return int128_make128(l, h);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store Helpers
|
||||
*/
|
||||
@ -2560,6 +2623,60 @@ void cpu_stq_le_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
cpu_store_helper(env, addr, val, oi, retaddr, helper_le_stq_mmu);
|
||||
}
|
||||
|
||||
void cpu_st16_be_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
MemOp mop = get_memop(oi);
|
||||
int mmu_idx = get_mmuidx(oi);
|
||||
MemOpIdx new_oi;
|
||||
unsigned a_bits;
|
||||
|
||||
tcg_debug_assert((mop & (MO_BSWAP|MO_SSIZE)) == (MO_BE|MO_128));
|
||||
a_bits = get_alignment_bits(mop);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, ra);
|
||||
}
|
||||
|
||||
/* Construct an unaligned 64-bit replacement MemOpIdx. */
|
||||
mop = (mop & ~(MO_SIZE | MO_AMASK)) | MO_64 | MO_UNALN;
|
||||
new_oi = make_memop_idx(mop, mmu_idx);
|
||||
|
||||
helper_be_stq_mmu(env, addr, int128_gethi(val), new_oi, ra);
|
||||
helper_be_stq_mmu(env, addr + 8, int128_getlo(val), new_oi, ra);
|
||||
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
void cpu_st16_le_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
MemOp mop = get_memop(oi);
|
||||
int mmu_idx = get_mmuidx(oi);
|
||||
MemOpIdx new_oi;
|
||||
unsigned a_bits;
|
||||
|
||||
tcg_debug_assert((mop & (MO_BSWAP|MO_SSIZE)) == (MO_LE|MO_128));
|
||||
a_bits = get_alignment_bits(mop);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
cpu_unaligned_access(env_cpu(env), addr, MMU_DATA_STORE,
|
||||
mmu_idx, ra);
|
||||
}
|
||||
|
||||
/* Construct an unaligned 64-bit replacement MemOpIdx. */
|
||||
mop = (mop & ~(MO_SIZE | MO_AMASK)) | MO_64 | MO_UNALN;
|
||||
new_oi = make_memop_idx(mop, mmu_idx);
|
||||
|
||||
helper_le_stq_mmu(env, addr, int128_getlo(val), new_oi, ra);
|
||||
helper_le_stq_mmu(env, addr + 8, int128_gethi(val), new_oi, ra);
|
||||
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
#include "ldst_common.c.inc"
|
||||
|
||||
/*
|
||||
|
96
accel/tcg/debuginfo.c
Normal file
96
accel/tcg/debuginfo.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Debug information support.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/lockable.h"
|
||||
|
||||
#include <elfutils/libdwfl.h>
|
||||
|
||||
#include "debuginfo.h"
|
||||
|
||||
static QemuMutex lock;
|
||||
static Dwfl *dwfl;
|
||||
static const Dwfl_Callbacks dwfl_callbacks = {
|
||||
.find_elf = NULL,
|
||||
.find_debuginfo = dwfl_standard_find_debuginfo,
|
||||
.section_address = NULL,
|
||||
.debuginfo_path = NULL,
|
||||
};
|
||||
|
||||
__attribute__((constructor))
|
||||
static void debuginfo_init(void)
|
||||
{
|
||||
qemu_mutex_init(&lock);
|
||||
}
|
||||
|
||||
void debuginfo_report_elf(const char *name, int fd, uint64_t bias)
|
||||
{
|
||||
QEMU_LOCK_GUARD(&lock);
|
||||
|
||||
if (dwfl) {
|
||||
dwfl_report_begin_add(dwfl);
|
||||
} else {
|
||||
dwfl = dwfl_begin(&dwfl_callbacks);
|
||||
}
|
||||
|
||||
if (dwfl) {
|
||||
dwfl_report_elf(dwfl, name, name, fd, bias, true);
|
||||
dwfl_report_end(dwfl, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void debuginfo_lock(void)
|
||||
{
|
||||
qemu_mutex_lock(&lock);
|
||||
}
|
||||
|
||||
void debuginfo_query(struct debuginfo_query *q, size_t n)
|
||||
{
|
||||
const char *symbol, *file;
|
||||
Dwfl_Module *dwfl_module;
|
||||
Dwfl_Line *dwfl_line;
|
||||
GElf_Off dwfl_offset;
|
||||
GElf_Sym dwfl_sym;
|
||||
size_t i;
|
||||
int line;
|
||||
|
||||
if (!dwfl) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dwfl_module = dwfl_addrmodule(dwfl, q[i].address);
|
||||
if (!dwfl_module) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (q[i].flags & DEBUGINFO_SYMBOL) {
|
||||
symbol = dwfl_module_addrinfo(dwfl_module, q[i].address,
|
||||
&dwfl_offset, &dwfl_sym,
|
||||
NULL, NULL, NULL);
|
||||
if (symbol) {
|
||||
q[i].symbol = symbol;
|
||||
q[i].offset = dwfl_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (q[i].flags & DEBUGINFO_LINE) {
|
||||
dwfl_line = dwfl_module_getsrc(dwfl_module, q[i].address);
|
||||
if (dwfl_line) {
|
||||
file = dwfl_lineinfo(dwfl_line, NULL, &line, 0, NULL, NULL);
|
||||
if (file) {
|
||||
q[i].file = file;
|
||||
q[i].line = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void debuginfo_unlock(void)
|
||||
{
|
||||
qemu_mutex_unlock(&lock);
|
||||
}
|
79
accel/tcg/debuginfo.h
Normal file
79
accel/tcg/debuginfo.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Debug information support.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef ACCEL_TCG_DEBUGINFO_H
|
||||
#define ACCEL_TCG_DEBUGINFO_H
|
||||
|
||||
#include "qemu/bitops.h"
|
||||
|
||||
/*
|
||||
* Debuginfo describing a certain address.
|
||||
*/
|
||||
struct debuginfo_query {
|
||||
uint64_t address; /* Input: address. */
|
||||
int flags; /* Input: debuginfo subset. */
|
||||
const char *symbol; /* Symbol that the address is part of. */
|
||||
uint64_t offset; /* Offset from the symbol. */
|
||||
const char *file; /* Source file associated with the address. */
|
||||
int line; /* Line number in the source file. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Debuginfo subsets.
|
||||
*/
|
||||
#define DEBUGINFO_SYMBOL BIT(1)
|
||||
#define DEBUGINFO_LINE BIT(2)
|
||||
|
||||
#if defined(CONFIG_TCG) && defined(CONFIG_LIBDW)
|
||||
/*
|
||||
* Load debuginfo for the specified guest ELF image.
|
||||
* Return true on success, false on failure.
|
||||
*/
|
||||
void debuginfo_report_elf(const char *name, int fd, uint64_t bias);
|
||||
|
||||
/*
|
||||
* Take the debuginfo lock.
|
||||
*/
|
||||
void debuginfo_lock(void);
|
||||
|
||||
/*
|
||||
* Fill each on N Qs with the debuginfo about Q->ADDRESS as specified by
|
||||
* Q->FLAGS:
|
||||
*
|
||||
* - DEBUGINFO_SYMBOL: update Q->SYMBOL and Q->OFFSET. If symbol debuginfo is
|
||||
* missing, then leave them as is.
|
||||
* - DEBUINFO_LINE: update Q->FILE and Q->LINE. If line debuginfo is missing,
|
||||
* then leave them as is.
|
||||
*
|
||||
* This function must be called under the debuginfo lock. The results can be
|
||||
* accessed only until the debuginfo lock is released.
|
||||
*/
|
||||
void debuginfo_query(struct debuginfo_query *q, size_t n);
|
||||
|
||||
/*
|
||||
* Release the debuginfo lock.
|
||||
*/
|
||||
void debuginfo_unlock(void);
|
||||
#else
|
||||
static inline void debuginfo_report_elf(const char *image_name, int image_fd,
|
||||
uint64_t load_bias)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void debuginfo_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void debuginfo_query(struct debuginfo_query *q, size_t n)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void debuginfo_unlock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -12,6 +12,8 @@ tcg_ss.add(files(
|
||||
tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
|
||||
tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c'))
|
||||
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c')])
|
||||
tcg_ss.add(when: libdw, if_true: files('debuginfo.c'))
|
||||
tcg_ss.add(when: 'CONFIG_LINUX', if_true: files('perf.c'))
|
||||
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
|
||||
|
||||
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files(
|
||||
|
375
accel/tcg/perf.c
Normal file
375
accel/tcg/perf.c
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Linux perf perf-<pid>.map and jit-<pid>.dump integration.
|
||||
*
|
||||
* The jitdump spec can be found at [1].
|
||||
*
|
||||
* [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/tools/perf/Documentation/jitdump-specification.txt
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "elf.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "tcg/tcg.h"
|
||||
|
||||
#include "debuginfo.h"
|
||||
#include "perf.h"
|
||||
|
||||
static FILE *safe_fopen_w(const char *path)
|
||||
{
|
||||
int saved_errno;
|
||||
FILE *f;
|
||||
int fd;
|
||||
|
||||
/* Delete the old file, if any. */
|
||||
unlink(path);
|
||||
|
||||
/* Avoid symlink attacks by using O_CREAT | O_EXCL. */
|
||||
fd = open(path, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
if (fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert fd to FILE*. */
|
||||
f = fdopen(fd, "w");
|
||||
if (f == NULL) {
|
||||
saved_errno = errno;
|
||||
close(fd);
|
||||
errno = saved_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static FILE *perfmap;
|
||||
|
||||
void perf_enable_perfmap(void)
|
||||
{
|
||||
char map_file[32];
|
||||
|
||||
snprintf(map_file, sizeof(map_file), "/tmp/perf-%d.map", getpid());
|
||||
perfmap = safe_fopen_w(map_file);
|
||||
if (perfmap == NULL) {
|
||||
warn_report("Could not open %s: %s, proceeding without perfmap",
|
||||
map_file, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* Get PC and size of code JITed for guest instruction #INSN. */
|
||||
static void get_host_pc_size(uintptr_t *host_pc, uint16_t *host_size,
|
||||
const void *start, size_t insn)
|
||||
{
|
||||
uint16_t start_off = insn ? tcg_ctx->gen_insn_end_off[insn - 1] : 0;
|
||||
|
||||
if (host_pc) {
|
||||
*host_pc = (uintptr_t)start + start_off;
|
||||
}
|
||||
if (host_size) {
|
||||
*host_size = tcg_ctx->gen_insn_end_off[insn] - start_off;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *pretty_symbol(const struct debuginfo_query *q, size_t *len)
|
||||
{
|
||||
static __thread char buf[64];
|
||||
int tmp;
|
||||
|
||||
if (!q->symbol) {
|
||||
tmp = snprintf(buf, sizeof(buf), "guest-0x%"PRIx64, q->address);
|
||||
if (len) {
|
||||
*len = MIN(tmp + 1, sizeof(buf));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (!q->offset) {
|
||||
if (len) {
|
||||
*len = strlen(q->symbol) + 1;
|
||||
}
|
||||
return q->symbol;
|
||||
}
|
||||
|
||||
tmp = snprintf(buf, sizeof(buf), "%s+0x%"PRIx64, q->symbol, q->offset);
|
||||
if (len) {
|
||||
*len = MIN(tmp + 1, sizeof(buf));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void write_perfmap_entry(const void *start, size_t insn,
|
||||
const struct debuginfo_query *q)
|
||||
{
|
||||
uint16_t host_size;
|
||||
uintptr_t host_pc;
|
||||
|
||||
get_host_pc_size(&host_pc, &host_size, start, insn);
|
||||
fprintf(perfmap, "%"PRIxPTR" %"PRIx16" %s\n",
|
||||
host_pc, host_size, pretty_symbol(q, NULL));
|
||||
}
|
||||
|
||||
static FILE *jitdump;
|
||||
|
||||
#define JITHEADER_MAGIC 0x4A695444
|
||||
#define JITHEADER_VERSION 1
|
||||
|
||||
struct jitheader {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t total_size;
|
||||
uint32_t elf_mach;
|
||||
uint32_t pad1;
|
||||
uint32_t pid;
|
||||
uint64_t timestamp;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
enum jit_record_type {
|
||||
JIT_CODE_LOAD = 0,
|
||||
JIT_CODE_DEBUG_INFO = 2,
|
||||
};
|
||||
|
||||
struct jr_prefix {
|
||||
uint32_t id;
|
||||
uint32_t total_size;
|
||||
uint64_t timestamp;
|
||||
};
|
||||
|
||||
struct jr_code_load {
|
||||
struct jr_prefix p;
|
||||
|
||||
uint32_t pid;
|
||||
uint32_t tid;
|
||||
uint64_t vma;
|
||||
uint64_t code_addr;
|
||||
uint64_t code_size;
|
||||
uint64_t code_index;
|
||||
};
|
||||
|
||||
struct debug_entry {
|
||||
uint64_t addr;
|
||||
int lineno;
|
||||
int discrim;
|
||||
const char name[];
|
||||
};
|
||||
|
||||
struct jr_code_debug_info {
|
||||
struct jr_prefix p;
|
||||
|
||||
uint64_t code_addr;
|
||||
uint64_t nr_entry;
|
||||
struct debug_entry entries[];
|
||||
};
|
||||
|
||||
static uint32_t get_e_machine(void)
|
||||
{
|
||||
Elf64_Ehdr elf_header;
|
||||
FILE *exe;
|
||||
size_t n;
|
||||
|
||||
QEMU_BUILD_BUG_ON(offsetof(Elf32_Ehdr, e_machine) !=
|
||||
offsetof(Elf64_Ehdr, e_machine));
|
||||
|
||||
exe = fopen("/proc/self/exe", "r");
|
||||
if (exe == NULL) {
|
||||
return EM_NONE;
|
||||
}
|
||||
|
||||
n = fread(&elf_header, sizeof(elf_header), 1, exe);
|
||||
fclose(exe);
|
||||
if (n != 1) {
|
||||
return EM_NONE;
|
||||
}
|
||||
|
||||
return elf_header.e_machine;
|
||||
}
|
||||
|
||||
void perf_enable_jitdump(void)
|
||||
{
|
||||
struct jitheader header;
|
||||
char jitdump_file[32];
|
||||
void *perf_marker;
|
||||
|
||||
if (!use_rt_clock) {
|
||||
warn_report("CLOCK_MONOTONIC is not available, proceeding without jitdump");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(jitdump_file, sizeof(jitdump_file), "jit-%d.dump", getpid());
|
||||
jitdump = safe_fopen_w(jitdump_file);
|
||||
if (jitdump == NULL) {
|
||||
warn_report("Could not open %s: %s, proceeding without jitdump",
|
||||
jitdump_file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* `perf inject` will see that the mapped file name in the corresponding
|
||||
* PERF_RECORD_MMAP or PERF_RECORD_MMAP2 event is of the form jit-%d.dump
|
||||
* and will process it as a jitdump file.
|
||||
*/
|
||||
perf_marker = mmap(NULL, qemu_real_host_page_size(), PROT_READ | PROT_EXEC,
|
||||
MAP_PRIVATE, fileno(jitdump), 0);
|
||||
if (perf_marker == MAP_FAILED) {
|
||||
warn_report("Could not map %s: %s, proceeding without jitdump",
|
||||
jitdump_file, strerror(errno));
|
||||
fclose(jitdump);
|
||||
jitdump = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
header.magic = JITHEADER_MAGIC;
|
||||
header.version = JITHEADER_VERSION;
|
||||
header.total_size = sizeof(header);
|
||||
header.elf_mach = get_e_machine();
|
||||
header.pad1 = 0;
|
||||
header.pid = getpid();
|
||||
header.timestamp = get_clock();
|
||||
header.flags = 0;
|
||||
fwrite(&header, sizeof(header), 1, jitdump);
|
||||
}
|
||||
|
||||
void perf_report_prologue(const void *start, size_t size)
|
||||
{
|
||||
if (perfmap) {
|
||||
fprintf(perfmap, "%"PRIxPTR" %zx tcg-prologue-buffer\n",
|
||||
(uintptr_t)start, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a JIT_CODE_DEBUG_INFO jitdump entry. */
|
||||
static void write_jr_code_debug_info(const void *start,
|
||||
const struct debuginfo_query *q,
|
||||
size_t icount)
|
||||
{
|
||||
struct jr_code_debug_info rec;
|
||||
struct debug_entry ent;
|
||||
uintptr_t host_pc;
|
||||
int insn;
|
||||
|
||||
/* Write the header. */
|
||||
rec.p.id = JIT_CODE_DEBUG_INFO;
|
||||
rec.p.total_size = sizeof(rec) + sizeof(ent) + 1;
|
||||
rec.p.timestamp = get_clock();
|
||||
rec.code_addr = (uintptr_t)start;
|
||||
rec.nr_entry = 1;
|
||||
for (insn = 0; insn < icount; insn++) {
|
||||
if (q[insn].file) {
|
||||
rec.p.total_size += sizeof(ent) + strlen(q[insn].file) + 1;
|
||||
rec.nr_entry++;
|
||||
}
|
||||
}
|
||||
fwrite(&rec, sizeof(rec), 1, jitdump);
|
||||
|
||||
/* Write the main debug entries. */
|
||||
for (insn = 0; insn < icount; insn++) {
|
||||
if (q[insn].file) {
|
||||
get_host_pc_size(&host_pc, NULL, start, insn);
|
||||
ent.addr = host_pc;
|
||||
ent.lineno = q[insn].line;
|
||||
ent.discrim = 0;
|
||||
fwrite(&ent, sizeof(ent), 1, jitdump);
|
||||
fwrite(q[insn].file, strlen(q[insn].file) + 1, 1, jitdump);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the trailing debug_entry. */
|
||||
ent.addr = (uintptr_t)start + tcg_ctx->gen_insn_end_off[icount - 1];
|
||||
ent.lineno = 0;
|
||||
ent.discrim = 0;
|
||||
fwrite(&ent, sizeof(ent), 1, jitdump);
|
||||
fwrite("", 1, 1, jitdump);
|
||||
}
|
||||
|
||||
/* Write a JIT_CODE_LOAD jitdump entry. */
|
||||
static void write_jr_code_load(const void *start, uint16_t host_size,
|
||||
const struct debuginfo_query *q)
|
||||
{
|
||||
static uint64_t code_index;
|
||||
struct jr_code_load rec;
|
||||
const char *symbol;
|
||||
size_t symbol_size;
|
||||
|
||||
symbol = pretty_symbol(q, &symbol_size);
|
||||
rec.p.id = JIT_CODE_LOAD;
|
||||
rec.p.total_size = sizeof(rec) + symbol_size + host_size;
|
||||
rec.p.timestamp = get_clock();
|
||||
rec.pid = getpid();
|
||||
rec.tid = qemu_get_thread_id();
|
||||
rec.vma = (uintptr_t)start;
|
||||
rec.code_addr = (uintptr_t)start;
|
||||
rec.code_size = host_size;
|
||||
rec.code_index = code_index++;
|
||||
fwrite(&rec, sizeof(rec), 1, jitdump);
|
||||
fwrite(symbol, symbol_size, 1, jitdump);
|
||||
fwrite(start, host_size, 1, jitdump);
|
||||
}
|
||||
|
||||
void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
|
||||
const void *start)
|
||||
{
|
||||
struct debuginfo_query *q;
|
||||
size_t insn;
|
||||
|
||||
if (!perfmap && !jitdump) {
|
||||
return;
|
||||
}
|
||||
|
||||
q = g_try_malloc0_n(tb->icount, sizeof(*q));
|
||||
if (!q) {
|
||||
return;
|
||||
}
|
||||
|
||||
debuginfo_lock();
|
||||
|
||||
/* Query debuginfo for each guest instruction. */
|
||||
for (insn = 0; insn < tb->icount; insn++) {
|
||||
/* FIXME: This replicates the restore_state_to_opc() logic. */
|
||||
q[insn].address = tcg_ctx->gen_insn_data[insn][0];
|
||||
if (TARGET_TB_PCREL) {
|
||||
q[insn].address |= (guest_pc & TARGET_PAGE_MASK);
|
||||
} else {
|
||||
#if defined(TARGET_I386)
|
||||
q[insn].address -= tb->cs_base;
|
||||
#endif
|
||||
}
|
||||
q[insn].flags = DEBUGINFO_SYMBOL | (jitdump ? DEBUGINFO_LINE : 0);
|
||||
}
|
||||
debuginfo_query(q, tb->icount);
|
||||
|
||||
/* Emit perfmap entries if needed. */
|
||||
if (perfmap) {
|
||||
flockfile(perfmap);
|
||||
for (insn = 0; insn < tb->icount; insn++) {
|
||||
write_perfmap_entry(start, insn, &q[insn]);
|
||||
}
|
||||
funlockfile(perfmap);
|
||||
}
|
||||
|
||||
/* Emit jitdump entries if needed. */
|
||||
if (jitdump) {
|
||||
flockfile(jitdump);
|
||||
write_jr_code_debug_info(start, q, tb->icount);
|
||||
write_jr_code_load(start, tcg_ctx->gen_insn_end_off[tb->icount - 1],
|
||||
q);
|
||||
funlockfile(jitdump);
|
||||
}
|
||||
|
||||
debuginfo_unlock();
|
||||
g_free(q);
|
||||
}
|
||||
|
||||
void perf_exit(void)
|
||||
{
|
||||
if (perfmap) {
|
||||
fclose(perfmap);
|
||||
perfmap = NULL;
|
||||
}
|
||||
|
||||
if (jitdump) {
|
||||
fclose(jitdump);
|
||||
jitdump = NULL;
|
||||
}
|
||||
}
|
49
accel/tcg/perf.h
Normal file
49
accel/tcg/perf.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Linux perf perf-<pid>.map and jit-<pid>.dump integration.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef ACCEL_TCG_PERF_H
|
||||
#define ACCEL_TCG_PERF_H
|
||||
|
||||
#if defined(CONFIG_TCG) && defined(CONFIG_LINUX)
|
||||
/* Start writing perf-<pid>.map. */
|
||||
void perf_enable_perfmap(void);
|
||||
|
||||
/* Start writing jit-<pid>.dump. */
|
||||
void perf_enable_jitdump(void);
|
||||
|
||||
/* Add information about TCG prologue to profiler maps. */
|
||||
void perf_report_prologue(const void *start, size_t size);
|
||||
|
||||
/* Add information about JITted guest code to profiler maps. */
|
||||
void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
|
||||
const void *start);
|
||||
|
||||
/* Stop writing perf-<pid>.map and/or jit-<pid>.dump. */
|
||||
void perf_exit(void);
|
||||
#else
|
||||
static inline void perf_enable_perfmap(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void perf_enable_jitdump(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void perf_report_prologue(const void *start, size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
|
||||
const void *start)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void perf_exit(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -579,7 +579,8 @@ static void inject_mem_helper(TCGOp *begin_op, GArray *arr)
|
||||
* is possible that the code we generate after the instruction is
|
||||
* dead, we also add checks before generating tb_exit etc.
|
||||
*/
|
||||
static void inject_mem_enable_helper(struct qemu_plugin_insn *plugin_insn,
|
||||
static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb,
|
||||
struct qemu_plugin_insn *plugin_insn,
|
||||
TCGOp *begin_op)
|
||||
{
|
||||
GArray *cbs[2];
|
||||
@ -599,6 +600,7 @@ static void inject_mem_enable_helper(struct qemu_plugin_insn *plugin_insn,
|
||||
rm_ops(begin_op);
|
||||
return;
|
||||
}
|
||||
ptb->mem_helper = true;
|
||||
|
||||
arr = g_array_sized_new(false, false,
|
||||
sizeof(struct qemu_plugin_dyn_cb), n_cbs);
|
||||
@ -626,15 +628,22 @@ void plugin_gen_disable_mem_helpers(void)
|
||||
{
|
||||
TCGv_ptr ptr;
|
||||
|
||||
if (likely(tcg_ctx->plugin_insn == NULL ||
|
||||
!tcg_ctx->plugin_insn->mem_helper)) {
|
||||
/*
|
||||
* We could emit the clearing unconditionally and be done. However, this can
|
||||
* be wasteful if for instance plugins don't track memory accesses, or if
|
||||
* most TBs don't use helpers. Instead, emit the clearing iff the TB calls
|
||||
* helpers that might access guest memory.
|
||||
*
|
||||
* Note: we do not reset plugin_tb->mem_helper here; a TB might have several
|
||||
* exit points, and we want to emit the clearing from all of them.
|
||||
*/
|
||||
if (!tcg_ctx->plugin_tb->mem_helper) {
|
||||
return;
|
||||
}
|
||||
ptr = tcg_const_ptr(NULL);
|
||||
tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
|
||||
offsetof(ArchCPU, env));
|
||||
tcg_temp_free_ptr(ptr);
|
||||
tcg_ctx->plugin_insn->mem_helper = false;
|
||||
}
|
||||
|
||||
static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
|
||||
@ -682,14 +691,14 @@ static void plugin_gen_mem_inline(const struct qemu_plugin_tb *ptb,
|
||||
inject_inline_cb(cbs, begin_op, op_rw);
|
||||
}
|
||||
|
||||
static void plugin_gen_enable_mem_helper(const struct qemu_plugin_tb *ptb,
|
||||
static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
|
||||
TCGOp *begin_op, int insn_idx)
|
||||
{
|
||||
struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
|
||||
inject_mem_enable_helper(insn, begin_op);
|
||||
inject_mem_enable_helper(ptb, insn, begin_op);
|
||||
}
|
||||
|
||||
static void plugin_gen_disable_mem_helper(const struct qemu_plugin_tb *ptb,
|
||||
static void plugin_gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
|
||||
TCGOp *begin_op, int insn_idx)
|
||||
{
|
||||
struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
|
||||
@ -750,7 +759,7 @@ static void pr_ops(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void plugin_gen_inject(const struct qemu_plugin_tb *plugin_tb)
|
||||
static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
|
||||
{
|
||||
TCGOp *op;
|
||||
int insn_idx = -1;
|
||||
@ -870,6 +879,7 @@ bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
|
||||
ptb->haddr1 = db->host_addr[0];
|
||||
ptb->haddr2 = NULL;
|
||||
ptb->mem_only = mem_only;
|
||||
ptb->mem_helper = false;
|
||||
|
||||
plugin_gen_empty_callback(PLUGIN_GEN_FROM_TB);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef CONFIG_PLUGIN
|
||||
DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb, TCG_CALL_NO_RWG, void, i32, ptr)
|
||||
DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG, void, i32, i32, i64, ptr)
|
||||
DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb, TCG_CALL_NO_RWG | TCG_CALL_PLUGIN, void, i32, ptr)
|
||||
DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG | TCG_CALL_PLUGIN, void, i32, i32, i64, ptr)
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
* a load_acquire/store_release to 'tb'.
|
||||
*/
|
||||
struct CPUJumpCache {
|
||||
struct rcu_head rcu;
|
||||
struct {
|
||||
TranslationBlock *tb;
|
||||
#if TARGET_TB_PCREL
|
||||
|
@ -55,6 +55,17 @@ DEF_HELPER_FLAGS_5(atomic_cmpxchgq_be, TCG_CALL_NO_WG,
|
||||
DEF_HELPER_FLAGS_5(atomic_cmpxchgq_le, TCG_CALL_NO_WG,
|
||||
i64, env, tl, i64, i64, i32)
|
||||
#endif
|
||||
#ifdef CONFIG_CMPXCHG128
|
||||
DEF_HELPER_FLAGS_5(atomic_cmpxchgo_be, TCG_CALL_NO_WG,
|
||||
i128, env, tl, i128, i128, i32)
|
||||
DEF_HELPER_FLAGS_5(atomic_cmpxchgo_le, TCG_CALL_NO_WG,
|
||||
i128, env, tl, i128, i128, i32)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_FLAGS_5(nonatomic_cmpxchgo_be, TCG_CALL_NO_WG,
|
||||
i128, env, tl, i128, i128, i32)
|
||||
DEF_HELPER_FLAGS_5(nonatomic_cmpxchgo_le, TCG_CALL_NO_WG,
|
||||
i128, env, tl, i128, i128, i32)
|
||||
|
||||
#ifdef CONFIG_ATOMIC64
|
||||
#define GEN_ATOMIC_HELPERS(NAME) \
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "tb-hash.h"
|
||||
#include "tb-context.h"
|
||||
#include "internal.h"
|
||||
#include "perf.h"
|
||||
|
||||
//// --- Begin LibAFL code ---
|
||||
|
||||
@ -1170,7 +1171,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||
tb->trace_vcpu_dstate = *cpu->trace_dstate;
|
||||
tb_set_page_addr0(tb, phys_pc);
|
||||
tb_set_page_addr1(tb, -1);
|
||||
tcg_ctx->tb_cflags = cflags;
|
||||
tcg_ctx->gen_tb = tb;
|
||||
tb_overflow:
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
@ -1227,6 +1228,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||
}
|
||||
tb->tc.size = gen_code_size;
|
||||
|
||||
/*
|
||||
* For TARGET_TB_PCREL, attribute all executions of the generated
|
||||
* code to its first mapping.
|
||||
*/
|
||||
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
qatomic_set(&prof->code_time, prof->code_time + profile_getclock() - ti);
|
||||
qatomic_set(&prof->code_in_len, prof->code_in_len + tb->size);
|
||||
@ -1322,10 +1329,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||
tb->jmp_dest[1] = (uintptr_t)NULL;
|
||||
|
||||
/* init original jump addresses which have been set during tcg_gen_code() */
|
||||
if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
|
||||
if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
|
||||
tb_reset_jump(tb, 0);
|
||||
}
|
||||
if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
|
||||
if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
|
||||
tb_reset_jump(tb, 1);
|
||||
}
|
||||
|
||||
@ -1507,9 +1514,9 @@ static gboolean tb_tree_stats_iter(gpointer key, gpointer value, gpointer data)
|
||||
if (tb_page_addr1(tb) != -1) {
|
||||
tst->cross_page++;
|
||||
}
|
||||
if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) {
|
||||
if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
|
||||
tst->direct_jmp_count++;
|
||||
if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) {
|
||||
if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
|
||||
tst->direct_jmp2_count++;
|
||||
}
|
||||
}
|
||||
|
@ -210,20 +210,24 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
|
||||
}
|
||||
|
||||
post_translate_insn:
|
||||
/*
|
||||
* We can't instrument after instructions that change control
|
||||
* flow although this only really affects post-load operations.
|
||||
*
|
||||
* Calling plugin_gen_insn_end() before we possibly stop translation
|
||||
* is important. Even if this ends up as dead code, plugin generation
|
||||
* needs to see a matching plugin_gen_insn_{start,end}() pair in order
|
||||
* to accurately track instrumented helpers that might access memory.
|
||||
*/
|
||||
if (plugin_enabled) {
|
||||
plugin_gen_insn_end();
|
||||
}
|
||||
|
||||
/* Stop translation if translate_insn so indicated. */
|
||||
if (db->is_jmp != DISAS_NEXT) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't instrument after instructions that change control
|
||||
* flow although this only really affects post-load operations.
|
||||
*/
|
||||
if (plugin_enabled) {
|
||||
plugin_gen_insn_end();
|
||||
}
|
||||
|
||||
/* Stop translation if the output buffer is full,
|
||||
or we have executed all of the allowed instructions. */
|
||||
if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
|
||||
|
@ -1031,6 +1031,42 @@ uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
Int128 cpu_ld16_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
void *haddr;
|
||||
Int128 ret;
|
||||
|
||||
validate_memop(oi, MO_128 | MO_BE);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
memcpy(&ret, haddr, 16);
|
||||
clear_helper_retaddr();
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
|
||||
if (!HOST_BIG_ENDIAN) {
|
||||
ret = bswap128(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Int128 cpu_ld16_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
void *haddr;
|
||||
Int128 ret;
|
||||
|
||||
validate_memop(oi, MO_128 | MO_LE);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
memcpy(&ret, haddr, 16);
|
||||
clear_helper_retaddr();
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
|
||||
if (HOST_BIG_ENDIAN) {
|
||||
ret = bswap128(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
@ -1115,6 +1151,36 @@ void cpu_stq_le_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
void cpu_st16_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
Int128 val, MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_128 | MO_BE);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
if (!HOST_BIG_ENDIAN) {
|
||||
val = bswap128(val);
|
||||
}
|
||||
memcpy(haddr, &val, 16);
|
||||
clear_helper_retaddr();
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
void cpu_st16_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
Int128 val, MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_128 | MO_LE);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
if (HOST_BIG_ENDIAN) {
|
||||
val = bswap128(val);
|
||||
}
|
||||
memcpy(haddr, &val, 16);
|
||||
clear_helper_retaddr();
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
|
||||
uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr ptr)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
83
audio/audio-hmp-cmds.c
Normal file
83
audio/audio-hmp-cmds.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* HMP commands related to audio backends
|
||||
*
|
||||
* Copyright (c) 2003-2004 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "audio/audio.h"
|
||||
#include "monitor/hmp.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
|
||||
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
|
||||
|
||||
void hmp_info_capture(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
int i;
|
||||
CaptureState *s;
|
||||
|
||||
for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
|
||||
monitor_printf(mon, "[%d]: ", i);
|
||||
s->ops.info (s->opaque);
|
||||
}
|
||||
}
|
||||
|
||||
void hmp_stopcapture(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
int i;
|
||||
int n = qdict_get_int(qdict, "n");
|
||||
CaptureState *s;
|
||||
|
||||
for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
|
||||
if (i == n) {
|
||||
s->ops.destroy (s->opaque);
|
||||
QLIST_REMOVE (s, entries);
|
||||
g_free (s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hmp_wavcapture(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *path = qdict_get_str(qdict, "path");
|
||||
int freq = qdict_get_try_int(qdict, "freq", 44100);
|
||||
int bits = qdict_get_try_int(qdict, "bits", 16);
|
||||
int nchannels = qdict_get_try_int(qdict, "nchannels", 2);
|
||||
const char *audiodev = qdict_get_str(qdict, "audiodev");
|
||||
CaptureState *s;
|
||||
AudioState *as = audio_state_by_name(audiodev);
|
||||
|
||||
if (!as) {
|
||||
monitor_printf(mon, "Audiodev '%s' not found\n", audiodev);
|
||||
return;
|
||||
}
|
||||
|
||||
s = g_malloc0 (sizeof (*s));
|
||||
|
||||
if (wav_start_capture(as, s, path, freq, bits, nchannels)) {
|
||||
monitor_printf(mon, "Failed to add wave capture\n");
|
||||
g_free (s);
|
||||
return;
|
||||
}
|
||||
QLIST_INSERT_HEAD (&capture_head, s, entries);
|
||||
}
|
@ -28,8 +28,10 @@
|
||||
#include "monitor/monitor.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/clone-visitor.h"
|
||||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/qapi-visit-audio.h"
|
||||
#include "qapi/qapi-commands-audio.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/help_option.h"
|
||||
@ -2046,16 +2048,36 @@ void audio_create_pdos(Audiodev *dev)
|
||||
break
|
||||
|
||||
CASE(NONE, none, );
|
||||
#ifdef CONFIG_AUDIO_ALSA
|
||||
CASE(ALSA, alsa, Alsa);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_COREAUDIO
|
||||
CASE(COREAUDIO, coreaudio, Coreaudio);
|
||||
#endif
|
||||
#ifdef CONFIG_DBUS_DISPLAY
|
||||
CASE(DBUS, dbus, );
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_DSOUND
|
||||
CASE(DSOUND, dsound, );
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_JACK
|
||||
CASE(JACK, jack, Jack);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_OSS
|
||||
CASE(OSS, oss, Oss);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_PA
|
||||
CASE(PA, pa, Pa);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_SDL
|
||||
CASE(SDL, sdl, Sdl);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_SNDIO
|
||||
CASE(SNDIO, sndio, );
|
||||
#endif
|
||||
#ifdef CONFIG_SPICE
|
||||
CASE(SPICE, spice, );
|
||||
#endif
|
||||
CASE(WAV, wav, );
|
||||
|
||||
case AUDIODEV_DRIVER__MAX:
|
||||
@ -2311,3 +2333,13 @@ size_t audio_rate_get_bytes(RateCtl *rate, struct audio_pcm_info *info,
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
AudiodevList *qmp_query_audiodevs(Error **errp)
|
||||
{
|
||||
AudiodevList *ret = NULL;
|
||||
AudiodevListEntry *e;
|
||||
QSIMPLEQ_FOREACH(e, &audiodevs, next) {
|
||||
QAPI_LIST_PREPEND(ret, QAPI_CLONE(Audiodev, e->dev));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ static void get_fmt(const char *env, AudioFormat *dst, bool *has_dst)
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_AUDIO_ALSA) || defined(CONFIG_AUDIO_DSOUND)
|
||||
static void get_millis_to_usecs(const char *env, uint32_t *dst, bool *has_dst)
|
||||
{
|
||||
const char *val = getenv(env);
|
||||
@ -98,15 +99,20 @@ static void get_millis_to_usecs(const char *env, uint32_t *dst, bool *has_dst)
|
||||
*has_dst = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AUDIO_ALSA) || defined(CONFIG_AUDIO_COREAUDIO) || \
|
||||
defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL) || \
|
||||
defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
|
||||
static uint32_t frames_to_usecs(uint32_t frames,
|
||||
AudiodevPerDirectionOptions *pdo)
|
||||
{
|
||||
uint32_t freq = pdo->has_frequency ? pdo->frequency : 44100;
|
||||
return (frames * 1000000 + freq / 2) / freq;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_AUDIO_COREAUDIO
|
||||
static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||
AudiodevPerDirectionOptions *pdo)
|
||||
{
|
||||
@ -116,14 +122,19 @@ static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||
*has_dst = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL) || \
|
||||
defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
|
||||
static uint32_t samples_to_usecs(uint32_t samples,
|
||||
AudiodevPerDirectionOptions *pdo)
|
||||
{
|
||||
uint32_t channels = pdo->has_channels ? pdo->channels : 2;
|
||||
return frames_to_usecs(samples / channels, pdo);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL)
|
||||
static void get_samples_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||
AudiodevPerDirectionOptions *pdo)
|
||||
{
|
||||
@ -133,7 +144,9 @@ static void get_samples_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||
*has_dst = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
|
||||
static uint32_t bytes_to_usecs(uint32_t bytes, AudiodevPerDirectionOptions *pdo)
|
||||
{
|
||||
AudioFormat fmt = pdo->has_format ? pdo->format : AUDIO_FORMAT_S16;
|
||||
@ -150,8 +163,11 @@ static void get_bytes_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
|
||||
*has_dst = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* backend specific functions */
|
||||
|
||||
#ifdef CONFIG_AUDIO_ALSA
|
||||
/* ALSA */
|
||||
static void handle_alsa_per_direction(
|
||||
AudiodevAlsaPerDirectionOptions *apdo, const char *prefix)
|
||||
@ -197,7 +213,9 @@ static void handle_alsa(Audiodev *dev)
|
||||
get_millis_to_usecs("QEMU_ALSA_THRESHOLD",
|
||||
&aopt->threshold, &aopt->has_threshold);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_COREAUDIO
|
||||
/* coreaudio */
|
||||
static void handle_coreaudio(Audiodev *dev)
|
||||
{
|
||||
@ -210,7 +228,9 @@ static void handle_coreaudio(Audiodev *dev)
|
||||
&dev->u.coreaudio.out->buffer_count,
|
||||
&dev->u.coreaudio.out->has_buffer_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_DSOUND
|
||||
/* dsound */
|
||||
static void handle_dsound(Audiodev *dev)
|
||||
{
|
||||
@ -225,7 +245,9 @@ static void handle_dsound(Audiodev *dev)
|
||||
&dev->u.dsound.in->has_buffer_length,
|
||||
dev->u.dsound.in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_OSS
|
||||
/* OSS */
|
||||
static void handle_oss_per_direction(
|
||||
AudiodevOssPerDirectionOptions *opdo, const char *try_poll_env,
|
||||
@ -253,7 +275,9 @@ static void handle_oss(Audiodev *dev)
|
||||
get_bool("QEMU_OSS_EXCLUSIVE", &oopt->exclusive, &oopt->has_exclusive);
|
||||
get_int("QEMU_OSS_POLICY", &oopt->dsp_policy, &oopt->has_dsp_policy);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_PA
|
||||
/* pulseaudio */
|
||||
static void handle_pa_per_direction(
|
||||
AudiodevPaPerDirectionOptions *ppdo, const char *env)
|
||||
@ -277,7 +301,9 @@ static void handle_pa(Audiodev *dev)
|
||||
|
||||
get_str("QEMU_PA_SERVER", &dev->u.pa.server);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_SDL
|
||||
/* SDL */
|
||||
static void handle_sdl(Audiodev *dev)
|
||||
{
|
||||
@ -286,6 +312,7 @@ static void handle_sdl(Audiodev *dev)
|
||||
&dev->u.sdl.out->has_buffer_length,
|
||||
qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.out));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* wav */
|
||||
static void handle_wav(Audiodev *dev)
|
||||
@ -345,29 +372,41 @@ static AudiodevListEntry *legacy_opt(const char *drvname)
|
||||
}
|
||||
|
||||
switch (e->dev->driver) {
|
||||
#ifdef CONFIG_AUDIO_ALSA
|
||||
case AUDIODEV_DRIVER_ALSA:
|
||||
handle_alsa(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_COREAUDIO
|
||||
case AUDIODEV_DRIVER_COREAUDIO:
|
||||
handle_coreaudio(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_DSOUND
|
||||
case AUDIODEV_DRIVER_DSOUND:
|
||||
handle_dsound(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_OSS
|
||||
case AUDIODEV_DRIVER_OSS:
|
||||
handle_oss(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_PA
|
||||
case AUDIODEV_DRIVER_PA:
|
||||
handle_pa(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO_SDL
|
||||
case AUDIODEV_DRIVER_SDL:
|
||||
handle_sdl(e->dev);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AUDIODEV_DRIVER_WAV:
|
||||
handle_wav(e->dev);
|
||||
|
@ -326,27 +326,47 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
switch (dev->driver) {
|
||||
case AUDIODEV_DRIVER_NONE:
|
||||
return dev->u.none.TYPE;
|
||||
#ifdef CONFIG_AUDIO_ALSA
|
||||
case AUDIODEV_DRIVER_ALSA:
|
||||
return qapi_AudiodevAlsaPerDirectionOptions_base(dev->u.alsa.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_COREAUDIO
|
||||
case AUDIODEV_DRIVER_COREAUDIO:
|
||||
return qapi_AudiodevCoreaudioPerDirectionOptions_base(
|
||||
dev->u.coreaudio.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_DBUS_DISPLAY
|
||||
case AUDIODEV_DRIVER_DBUS:
|
||||
return dev->u.dbus.TYPE;
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_DSOUND
|
||||
case AUDIODEV_DRIVER_DSOUND:
|
||||
return dev->u.dsound.TYPE;
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_JACK
|
||||
case AUDIODEV_DRIVER_JACK:
|
||||
return qapi_AudiodevJackPerDirectionOptions_base(dev->u.jack.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_OSS
|
||||
case AUDIODEV_DRIVER_OSS:
|
||||
return qapi_AudiodevOssPerDirectionOptions_base(dev->u.oss.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_PA
|
||||
case AUDIODEV_DRIVER_PA:
|
||||
return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_SDL
|
||||
case AUDIODEV_DRIVER_SDL:
|
||||
return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_SNDIO
|
||||
case AUDIODEV_DRIVER_SNDIO:
|
||||
return dev->u.sndio.TYPE;
|
||||
#endif
|
||||
#ifdef CONFIG_SPICE
|
||||
case AUDIODEV_DRIVER_SPICE:
|
||||
return dev->u.spice.TYPE;
|
||||
#endif
|
||||
case AUDIODEV_DRIVER_WAV:
|
||||
return dev->u.wav.TYPE;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
softmmu_ss.add([spice_headers, files('audio.c')])
|
||||
softmmu_ss.add(files(
|
||||
'audio-hmp-cmds.c',
|
||||
'audio_legacy.c',
|
||||
'mixeng.c',
|
||||
'noaudio.c',
|
||||
|
@ -14,9 +14,9 @@
|
||||
* to recording, which is what guest systems expect.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <poll.h>
|
||||
#include <sndio.h>
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "audio.h"
|
||||
#include "trace.h"
|
||||
|
@ -9,9 +9,9 @@
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qapi/error.h"
|
||||
#include "sysemu/hostmem.h"
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "sysemu/runstate.h"
|
||||
#include "sysemu/tpm_backend.h"
|
||||
#include "sysemu/tpm_util.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "tpm_int.h"
|
||||
#include "tpm_ioctl.h"
|
||||
#include "migration/blocker.h"
|
||||
@ -553,7 +552,7 @@ static int tpm_emulator_prepare_data_fd(TPMEmulator *tpm_emu)
|
||||
Error *err = NULL;
|
||||
int fds[2] = { -1, -1 };
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
|
||||
if (qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
|
||||
error_report("tpm-emulator: Failed to create socketpair");
|
||||
return -1;
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
# define __USE_LINUX_IOCTL_DEFS
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
129
block.c
129
block.c
@ -27,6 +27,7 @@
|
||||
#include "block/trace.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/fuse.h"
|
||||
#include "block/nbd.h"
|
||||
#include "block/qdict.h"
|
||||
@ -656,8 +657,8 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
|
||||
options = qdict_new();
|
||||
qdict_put_str(options, "driver", drv->format_name);
|
||||
|
||||
blk = blk_new_open(filename, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE, errp);
|
||||
blk = blk_co_new_open(filename, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE, errp);
|
||||
if (!blk) {
|
||||
error_prepend(errp, "Protocol driver '%s' does not support image "
|
||||
"creation, and opening the image failed: ",
|
||||
@ -1034,7 +1035,8 @@ static int find_image_format(BlockBackend *file, const char *filename,
|
||||
* Set the current 'total_sectors' value
|
||||
* Return 0 on success, -errno on error.
|
||||
*/
|
||||
int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
|
||||
int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
|
||||
int64_t hint)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
IO_CODE();
|
||||
@ -1043,13 +1045,13 @@ int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
/* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
|
||||
/* Do not attempt drv->bdrv_co_getlength() on scsi-generic devices */
|
||||
if (bdrv_is_sg(bs))
|
||||
return 0;
|
||||
|
||||
/* query actual device if possible, otherwise just trust the hint */
|
||||
if (drv->bdrv_getlength) {
|
||||
int64_t length = drv->bdrv_getlength(bs);
|
||||
if (drv->bdrv_co_getlength) {
|
||||
int64_t length = drv->bdrv_co_getlength(bs);
|
||||
if (length < 0) {
|
||||
return length;
|
||||
}
|
||||
@ -1600,6 +1602,11 @@ out:
|
||||
g_free(gen_node_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must always hold @bs AioContext lock, because this function calls
|
||||
* bdrv_refresh_total_sectors() which polls when called from non-coroutine
|
||||
* context.
|
||||
*/
|
||||
static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
|
||||
const char *node_name, QDict *options,
|
||||
int open_flags, Error **errp)
|
||||
@ -1651,7 +1658,7 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
|
||||
bs->supported_read_flags |= BDRV_REQ_REGISTERED_BUF;
|
||||
bs->supported_write_flags |= BDRV_REQ_REGISTERED_BUF;
|
||||
|
||||
ret = refresh_total_sectors(bs, bs->total_sectors);
|
||||
ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
||||
return ret;
|
||||
@ -3795,14 +3802,16 @@ out:
|
||||
* The reference parameter may be used to specify an existing block device which
|
||||
* should be opened. If specified, neither options nor a filename may be given,
|
||||
* nor can an existing BDS be reused (that is, *pbs has to be NULL).
|
||||
*
|
||||
* The caller must always hold @filename AioContext lock, because this
|
||||
* function eventually calls bdrv_refresh_total_sectors() which polls
|
||||
* when called from non-coroutine context.
|
||||
*/
|
||||
static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
const char *reference,
|
||||
QDict *options, int flags,
|
||||
BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
Error **errp)
|
||||
static BlockDriverState * no_coroutine_fn
|
||||
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
||||
int flags, BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class, BdrvChildRole child_role,
|
||||
Error **errp)
|
||||
{
|
||||
int ret;
|
||||
BlockBackend *file = NULL;
|
||||
@ -3818,6 +3827,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
assert(!child_class || !flags);
|
||||
assert(!child_class == !parent);
|
||||
GLOBAL_STATE_CODE();
|
||||
assert(!qemu_in_coroutine());
|
||||
|
||||
if (reference) {
|
||||
bool options_non_empty = options ? qdict_size(options) : false;
|
||||
@ -4083,6 +4093,11 @@ close_and_fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller must always hold @filename AioContext lock, because this
|
||||
* function eventually calls bdrv_refresh_total_sectors() which polls
|
||||
* when called from non-coroutine context.
|
||||
*/
|
||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp)
|
||||
{
|
||||
@ -5250,6 +5265,8 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
|
||||
* child.
|
||||
*
|
||||
* This function does not create any image files.
|
||||
*
|
||||
* The caller must hold the AioContext lock for @bs_top.
|
||||
*/
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp)
|
||||
@ -5257,11 +5274,14 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
int ret;
|
||||
BdrvChild *child;
|
||||
Transaction *tran = tran_new();
|
||||
AioContext *old_context, *new_context = NULL;
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
assert(!bs_new->backing);
|
||||
|
||||
old_context = bdrv_get_aio_context(bs_top);
|
||||
|
||||
child = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
|
||||
&child_of_bds, bdrv_backing_role(bs_new),
|
||||
tran, errp);
|
||||
@ -5270,6 +5290,19 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* bdrv_attach_child_noperm could change the AioContext of bs_top.
|
||||
* bdrv_replace_node_noperm calls bdrv_drained_begin, so let's temporarily
|
||||
* hold the new AioContext, since bdrv_drained_begin calls BDRV_POLL_WHILE
|
||||
* that assumes the new lock is taken.
|
||||
*/
|
||||
new_context = bdrv_get_aio_context(bs_top);
|
||||
|
||||
if (old_context != new_context) {
|
||||
aio_context_release(old_context);
|
||||
aio_context_acquire(new_context);
|
||||
}
|
||||
|
||||
ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
@ -5281,6 +5314,11 @@ out:
|
||||
|
||||
bdrv_refresh_limits(bs_top, NULL, NULL);
|
||||
|
||||
if (new_context && old_context != new_context) {
|
||||
aio_context_release(new_context);
|
||||
aio_context_acquire(old_context);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -5704,7 +5742,7 @@ exit:
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of BlockDriver.bdrv_get_allocated_file_size() that
|
||||
* Implementation of BlockDriver.bdrv_co_get_allocated_file_size() that
|
||||
* sums the size of all data-bearing children. (This excludes backing
|
||||
* children.)
|
||||
*/
|
||||
@ -5717,7 +5755,7 @@ static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
|
||||
if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
|
||||
BDRV_CHILD_FILTERED))
|
||||
{
|
||||
child_size = bdrv_get_allocated_file_size(child->bs);
|
||||
child_size = bdrv_co_get_allocated_file_size(child->bs);
|
||||
if (child_size < 0) {
|
||||
return child_size;
|
||||
}
|
||||
@ -5732,7 +5770,7 @@ static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
|
||||
* Length of a allocated file in bytes. Sparse files are counted by actual
|
||||
* allocated space. Return < 0 if error or unknown.
|
||||
*/
|
||||
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
|
||||
int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
IO_CODE();
|
||||
@ -5740,8 +5778,8 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
|
||||
if (!drv) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
if (drv->bdrv_get_allocated_file_size) {
|
||||
return drv->bdrv_get_allocated_file_size(bs);
|
||||
if (drv->bdrv_co_get_allocated_file_size) {
|
||||
return drv->bdrv_co_get_allocated_file_size(bs);
|
||||
}
|
||||
|
||||
if (drv->bdrv_file_open) {
|
||||
@ -5753,7 +5791,7 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
|
||||
return -ENOTSUP;
|
||||
} else if (drv->is_filter) {
|
||||
/* Filter drivers default to the size of their filtered child */
|
||||
return bdrv_get_allocated_file_size(bdrv_filter_bs(bs));
|
||||
return bdrv_co_get_allocated_file_size(bdrv_filter_bs(bs));
|
||||
} else {
|
||||
/* Other drivers default to summing their children's sizes */
|
||||
return bdrv_sum_allocated_file_size(bs);
|
||||
@ -5799,7 +5837,7 @@ BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
||||
/**
|
||||
* Return number of sectors on success, -errno on error.
|
||||
*/
|
||||
int64_t bdrv_nb_sectors(BlockDriverState *bs)
|
||||
int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
IO_CODE();
|
||||
@ -5808,7 +5846,7 @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
|
||||
return -ENOMEDIUM;
|
||||
|
||||
if (drv->has_variable_length) {
|
||||
int ret = refresh_total_sectors(bs, bs->total_sectors);
|
||||
int ret = bdrv_co_refresh_total_sectors(bs, bs->total_sectors);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -5820,11 +5858,12 @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
|
||||
* Return length in bytes on success, -errno on error.
|
||||
* The length is always a multiple of BDRV_SECTOR_SIZE.
|
||||
*/
|
||||
int64_t bdrv_getlength(BlockDriverState *bs)
|
||||
int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
int64_t ret = bdrv_nb_sectors(bs);
|
||||
int64_t ret;
|
||||
IO_CODE();
|
||||
|
||||
ret = bdrv_co_nb_sectors(bs);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -6284,7 +6323,7 @@ void bdrv_get_backing_filename(BlockDriverState *bs,
|
||||
pstrcpy(filename, filename_size, bs->backing_file);
|
||||
}
|
||||
|
||||
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
int coroutine_fn bdrv_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
int ret;
|
||||
BlockDriver *drv = bs->drv;
|
||||
@ -6293,15 +6332,15 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
if (!drv) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
if (!drv->bdrv_get_info) {
|
||||
if (!drv->bdrv_co_get_info) {
|
||||
BlockDriverState *filtered = bdrv_filter_bs(bs);
|
||||
if (filtered) {
|
||||
return bdrv_get_info(filtered, bdi);
|
||||
return bdrv_co_get_info(filtered, bdi);
|
||||
}
|
||||
return -ENOTSUP;
|
||||
}
|
||||
memset(bdi, 0, sizeof(*bdi));
|
||||
ret = drv->bdrv_get_info(bs, bdi);
|
||||
ret = drv->bdrv_co_get_info(bs, bdi);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -6334,14 +6373,14 @@ BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
|
||||
return drv->bdrv_get_specific_stats(bs);
|
||||
}
|
||||
|
||||
void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||
void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||
{
|
||||
IO_CODE();
|
||||
if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
|
||||
if (!bs || !bs->drv || !bs->drv->bdrv_co_debug_event) {
|
||||
return;
|
||||
}
|
||||
|
||||
bs->drv->bdrv_debug_event(bs, event);
|
||||
bs->drv->bdrv_co_debug_event(bs, event);
|
||||
}
|
||||
|
||||
static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
|
||||
@ -6590,7 +6629,7 @@ int bdrv_activate(BlockDriverState *bs, Error **errp)
|
||||
bdrv_dirty_bitmap_skip_store(bm, false);
|
||||
}
|
||||
|
||||
ret = refresh_total_sectors(bs, bs->total_sectors);
|
||||
ret = bdrv_refresh_total_sectors(bs, bs->total_sectors);
|
||||
if (ret < 0) {
|
||||
bs->open_flags |= BDRV_O_INACTIVE;
|
||||
error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
||||
@ -6781,7 +6820,7 @@ out:
|
||||
/**
|
||||
* Return TRUE if the media is present
|
||||
*/
|
||||
bool bdrv_is_inserted(BlockDriverState *bs)
|
||||
bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
BdrvChild *child;
|
||||
@ -6790,11 +6829,11 @@ bool bdrv_is_inserted(BlockDriverState *bs)
|
||||
if (!drv) {
|
||||
return false;
|
||||
}
|
||||
if (drv->bdrv_is_inserted) {
|
||||
return drv->bdrv_is_inserted(bs);
|
||||
if (drv->bdrv_co_is_inserted) {
|
||||
return drv->bdrv_co_is_inserted(bs);
|
||||
}
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
if (!bdrv_is_inserted(child->bs)) {
|
||||
if (!bdrv_co_is_inserted(child->bs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -6804,13 +6843,13 @@ bool bdrv_is_inserted(BlockDriverState *bs)
|
||||
/**
|
||||
* If eject_flag is TRUE, eject the media. Otherwise, close the tray
|
||||
*/
|
||||
void bdrv_eject(BlockDriverState *bs, bool eject_flag)
|
||||
void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
IO_CODE();
|
||||
|
||||
if (drv && drv->bdrv_eject) {
|
||||
drv->bdrv_eject(bs, eject_flag);
|
||||
if (drv && drv->bdrv_co_eject) {
|
||||
drv->bdrv_co_eject(bs, eject_flag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6818,14 +6857,14 @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag)
|
||||
* Lock or unlock the media (if it is locked, the user won't be able
|
||||
* to eject it manually).
|
||||
*/
|
||||
void bdrv_lock_medium(BlockDriverState *bs, bool locked)
|
||||
void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
IO_CODE();
|
||||
trace_bdrv_lock_medium(bs, locked);
|
||||
|
||||
if (drv && drv->bdrv_lock_medium) {
|
||||
drv->bdrv_lock_medium(bs, locked);
|
||||
if (drv && drv->bdrv_co_lock_medium) {
|
||||
drv->bdrv_co_lock_medium(bs, locked);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7177,12 +7216,6 @@ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
|
||||
{
|
||||
IO_CODE();
|
||||
aio_co_enter(bdrv_get_aio_context(bs), co);
|
||||
}
|
||||
|
||||
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
|
@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/job.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "block/blockjob_int.h"
|
||||
#include "block/block_backup.h"
|
||||
#include "block/block-copy.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "qemu/module.h"
|
||||
@ -835,7 +836,8 @@ static void process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
|
||||
}
|
||||
}
|
||||
|
||||
static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||
static void coroutine_fn
|
||||
blkdebug_co_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
struct BlkdebugRule *rule, *next;
|
||||
@ -965,9 +967,9 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs)
|
||||
@ -1074,7 +1076,7 @@ static BlockDriver bdrv_blkdebug = {
|
||||
.bdrv_reopen_prepare = blkdebug_reopen_prepare,
|
||||
.bdrv_child_perm = blkdebug_child_perm,
|
||||
|
||||
.bdrv_getlength = blkdebug_getlength,
|
||||
.bdrv_co_getlength = blkdebug_co_getlength,
|
||||
.bdrv_refresh_filename = blkdebug_refresh_filename,
|
||||
.bdrv_refresh_limits = blkdebug_refresh_limits,
|
||||
|
||||
@ -1085,7 +1087,7 @@ static BlockDriver bdrv_blkdebug = {
|
||||
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
|
||||
.bdrv_co_block_status = blkdebug_co_block_status,
|
||||
|
||||
.bdrv_debug_event = blkdebug_debug_event,
|
||||
.bdrv_co_debug_event = blkdebug_co_debug_event,
|
||||
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
|
||||
.bdrv_debug_remove_breakpoint
|
||||
= blkdebug_debug_remove_breakpoint,
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "qemu/module.h"
|
||||
#include "exec/memory.h" /* for ram_block_discard_disable() */
|
||||
|
||||
#include "block/block-io.h"
|
||||
|
||||
/*
|
||||
* Keep the QEMU BlockDriver names identical to the libblkio driver names.
|
||||
* Using macros instead of typing out the string literals avoids typos.
|
||||
@ -477,7 +479,7 @@ static int coroutine_fn blkio_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
return cod.ret;
|
||||
}
|
||||
|
||||
static void blkio_io_unplug(BlockDriverState *bs)
|
||||
static void coroutine_fn blkio_co_io_unplug(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkioState *s = bs->opaque;
|
||||
|
||||
@ -837,7 +839,7 @@ static void blkio_close(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t blkio_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn blkio_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkioState *s = bs->opaque;
|
||||
uint64_t capacity;
|
||||
@ -865,7 +867,7 @@ static int coroutine_fn blkio_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
current_length = blkio_getlength(bs);
|
||||
current_length = blkio_co_getlength(bs);
|
||||
|
||||
if (offset > current_length) {
|
||||
error_setg(errp, "Cannot grow device");
|
||||
@ -878,7 +880,8 @@ static int coroutine_fn blkio_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blkio_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
blkio_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -996,9 +999,9 @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
.instance_size = sizeof(BDRVBlkioState), \
|
||||
.bdrv_file_open = blkio_file_open, \
|
||||
.bdrv_close = blkio_close, \
|
||||
.bdrv_getlength = blkio_getlength, \
|
||||
.bdrv_co_getlength = blkio_co_getlength, \
|
||||
.bdrv_co_truncate = blkio_truncate, \
|
||||
.bdrv_get_info = blkio_get_info, \
|
||||
.bdrv_co_get_info = blkio_co_get_info, \
|
||||
.bdrv_attach_aio_context = blkio_attach_aio_context, \
|
||||
.bdrv_detach_aio_context = blkio_detach_aio_context, \
|
||||
.bdrv_co_pdiscard = blkio_co_pdiscard, \
|
||||
@ -1006,7 +1009,7 @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
.bdrv_co_pwritev = blkio_co_pwritev, \
|
||||
.bdrv_co_flush_to_disk = blkio_co_flush, \
|
||||
.bdrv_co_pwrite_zeroes = blkio_co_pwrite_zeroes, \
|
||||
.bdrv_io_unplug = blkio_io_unplug, \
|
||||
.bdrv_co_io_unplug = blkio_co_io_unplug, \
|
||||
.bdrv_refresh_limits = blkio_refresh_limits, \
|
||||
.bdrv_register_buf = blkio_register_buf, \
|
||||
.bdrv_unregister_buf = blkio_unregister_buf, \
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
@ -266,9 +267,9 @@ static void blk_log_writes_close(BlockDriverState *bs)
|
||||
s->log_file = NULL;
|
||||
}
|
||||
|
||||
static int64_t blk_log_writes_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||
@ -497,7 +498,7 @@ static BlockDriver bdrv_blk_log_writes = {
|
||||
|
||||
.bdrv_open = blk_log_writes_open,
|
||||
.bdrv_close = blk_log_writes_close,
|
||||
.bdrv_getlength = blk_log_writes_getlength,
|
||||
.bdrv_co_getlength = blk_log_writes_co_getlength,
|
||||
.bdrv_child_perm = blk_log_writes_child_perm,
|
||||
.bdrv_refresh_limits = blk_log_writes_refresh_limits,
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/module.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "qapi/error.h"
|
||||
@ -39,9 +40,9 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t blkreplay_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
/* This bh is used for synchronization of return from coroutines.
|
||||
@ -135,7 +136,7 @@ static BlockDriver bdrv_blkreplay = {
|
||||
|
||||
.bdrv_open = blkreplay_open,
|
||||
.bdrv_child_perm = bdrv_default_perms,
|
||||
.bdrv_getlength = blkreplay_getlength,
|
||||
.bdrv_co_getlength = blkreplay_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = blkreplay_co_preadv,
|
||||
.bdrv_co_pwritev = blkreplay_co_pwritev,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
@ -154,11 +155,11 @@ static void blkverify_close(BlockDriverState *bs)
|
||||
s->test_file = NULL;
|
||||
}
|
||||
|
||||
static int64_t blkverify_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkverifyState *s = bs->opaque;
|
||||
|
||||
return bdrv_getlength(s->test_file->bs);
|
||||
return bdrv_co_getlength(s->test_file->bs);
|
||||
}
|
||||
|
||||
static void coroutine_fn blkverify_do_test_req(void *opaque)
|
||||
@ -313,7 +314,7 @@ static BlockDriver bdrv_blkverify = {
|
||||
.bdrv_file_open = blkverify_open,
|
||||
.bdrv_close = blkverify_close,
|
||||
.bdrv_child_perm = bdrv_default_perms,
|
||||
.bdrv_getlength = blkverify_getlength,
|
||||
.bdrv_co_getlength = blkverify_co_getlength,
|
||||
.bdrv_refresh_filename = blkverify_refresh_filename,
|
||||
.bdrv_dirname = blkverify_dirname,
|
||||
|
||||
|
@ -1235,8 +1235,8 @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
|
||||
blk->disable_request_queuing = disable;
|
||||
}
|
||||
|
||||
static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
|
||||
int64_t bytes)
|
||||
static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
|
||||
int64_t offset, int64_t bytes)
|
||||
{
|
||||
int64_t len;
|
||||
|
||||
@ -1253,7 +1253,7 @@ static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
|
||||
}
|
||||
|
||||
if (!blk->allow_write_beyond_eof) {
|
||||
len = blk_getlength(blk);
|
||||
len = bdrv_co_getlength(blk_bs(blk));
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
@ -1555,7 +1555,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
|
||||
acb->has_returned = false;
|
||||
|
||||
co = qemu_coroutine_create(co_entry, acb);
|
||||
bdrv_coroutine_enter(blk_bs(blk), co);
|
||||
aio_co_enter(blk_get_aio_context(blk), co);
|
||||
|
||||
acb->has_returned = true;
|
||||
if (acb->rwco.ret != NOT_DONE) {
|
||||
@ -1599,14 +1599,15 @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
|
||||
flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
|
||||
}
|
||||
|
||||
int64_t blk_getlength(BlockBackend *blk)
|
||||
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
|
||||
{
|
||||
IO_CODE();
|
||||
|
||||
if (!blk_is_available(blk)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
return bdrv_getlength(blk_bs(blk));
|
||||
return bdrv_co_getlength(blk_bs(blk));
|
||||
}
|
||||
|
||||
void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
|
||||
@ -1619,14 +1620,15 @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
int64_t blk_nb_sectors(BlockBackend *blk)
|
||||
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
|
||||
{
|
||||
IO_CODE();
|
||||
|
||||
if (!blk_is_available(blk)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
return bdrv_nb_sectors(blk_bs(blk));
|
||||
return bdrv_co_nb_sectors(blk_bs(blk));
|
||||
}
|
||||
|
||||
BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
|
||||
@ -1983,12 +1985,12 @@ void blk_activate(BlockBackend *blk, Error **errp)
|
||||
bdrv_activate(bs, errp);
|
||||
}
|
||||
|
||||
bool blk_is_inserted(BlockBackend *blk)
|
||||
bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
IO_CODE();
|
||||
|
||||
return bs && bdrv_is_inserted(bs);
|
||||
return bs && bdrv_co_is_inserted(bs);
|
||||
}
|
||||
|
||||
bool blk_is_available(BlockBackend *blk)
|
||||
@ -1997,24 +1999,24 @@ bool blk_is_available(BlockBackend *blk)
|
||||
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
|
||||
}
|
||||
|
||||
void blk_lock_medium(BlockBackend *blk, bool locked)
|
||||
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
IO_CODE();
|
||||
|
||||
if (bs) {
|
||||
bdrv_lock_medium(bs, locked);
|
||||
bdrv_co_lock_medium(bs, locked);
|
||||
}
|
||||
}
|
||||
|
||||
void blk_eject(BlockBackend *blk, bool eject_flag)
|
||||
void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
char *id;
|
||||
IO_CODE();
|
||||
|
||||
if (bs) {
|
||||
bdrv_eject(bs, eject_flag);
|
||||
bdrv_co_eject(bs, eject_flag);
|
||||
}
|
||||
|
||||
/* Whether or not we ejected on the backend,
|
||||
@ -2315,23 +2317,23 @@ void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
|
||||
notifier_list_add(&blk->insert_bs_notifiers, notify);
|
||||
}
|
||||
|
||||
void blk_io_plug(BlockBackend *blk)
|
||||
void coroutine_fn blk_co_io_plug(BlockBackend *blk)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
IO_CODE();
|
||||
|
||||
if (bs) {
|
||||
bdrv_io_plug(bs);
|
||||
bdrv_co_io_plug(bs);
|
||||
}
|
||||
}
|
||||
|
||||
void blk_io_unplug(BlockBackend *blk)
|
||||
void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
|
||||
{
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
IO_CODE();
|
||||
|
||||
if (bs) {
|
||||
bdrv_io_unplug(bs);
|
||||
bdrv_co_io_unplug(bs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,14 @@
|
||||
#include "trace.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-copy.h"
|
||||
#include "block/block_int-io.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/reqlist.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/co-shared-resource.h"
|
||||
#include "qemu/coroutine.h"
|
||||
#include "qemu/ratelimit.h"
|
||||
#include "block/aio_task.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/memalign.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/bswap.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/bswap.h"
|
||||
|
@ -123,13 +123,13 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
|
||||
QEMU_AUTO_VFREE void *buf = NULL;
|
||||
int64_t len, base_len;
|
||||
|
||||
len = blk_getlength(s->top);
|
||||
len = blk_co_getlength(s->top);
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
job_progress_set_remaining(&s->common.job, len);
|
||||
|
||||
base_len = blk_getlength(s->base);
|
||||
base_len = blk_co_getlength(s->base);
|
||||
if (base_len < 0) {
|
||||
return base_len;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "block/block-copy.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
|
||||
#include "block/copy-before-write.h"
|
||||
#include "block/reqlist.h"
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/error.h"
|
||||
@ -120,9 +121,9 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||
}
|
||||
|
||||
|
||||
static int64_t cor_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
|
||||
@ -216,15 +217,15 @@ static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
|
||||
static void cor_eject(BlockDriverState *bs, bool eject_flag)
|
||||
static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
bdrv_eject(bs->file->bs, eject_flag);
|
||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||
}
|
||||
|
||||
|
||||
static void cor_lock_medium(BlockDriverState *bs, bool locked)
|
||||
static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
bdrv_lock_medium(bs->file->bs, locked);
|
||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||
}
|
||||
|
||||
|
||||
@ -249,7 +250,7 @@ static BlockDriver bdrv_copy_on_read = {
|
||||
.bdrv_close = cor_close,
|
||||
.bdrv_child_perm = cor_child_perm,
|
||||
|
||||
.bdrv_getlength = cor_getlength,
|
||||
.bdrv_co_getlength = cor_co_getlength,
|
||||
|
||||
.bdrv_co_preadv_part = cor_co_preadv_part,
|
||||
.bdrv_co_pwritev_part = cor_co_pwritev_part,
|
||||
@ -257,8 +258,8 @@ static BlockDriver bdrv_copy_on_read = {
|
||||
.bdrv_co_pdiscard = cor_co_pdiscard,
|
||||
.bdrv_co_pwritev_compressed = cor_co_pwritev_compressed,
|
||||
|
||||
.bdrv_eject = cor_eject,
|
||||
.bdrv_lock_medium = cor_lock_medium,
|
||||
.bdrv_co_eject = cor_co_eject,
|
||||
.bdrv_co_lock_medium = cor_co_lock_medium,
|
||||
|
||||
.has_variable_length = true,
|
||||
.is_filter = true,
|
||||
|
@ -314,19 +314,18 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
|
||||
}
|
||||
|
||||
|
||||
static int block_crypto_co_create_generic(BlockDriverState *bs,
|
||||
int64_t size,
|
||||
QCryptoBlockCreateOptions *opts,
|
||||
PreallocMode prealloc,
|
||||
Error **errp)
|
||||
static int coroutine_fn
|
||||
block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
|
||||
QCryptoBlockCreateOptions *opts,
|
||||
PreallocMode prealloc, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
BlockBackend *blk;
|
||||
QCryptoBlock *crypto = NULL;
|
||||
struct BlockCryptoCreateData data;
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto cleanup;
|
||||
@ -531,10 +530,10 @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
|
||||
|
||||
static int64_t block_crypto_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BlockCrypto *crypto = bs->opaque;
|
||||
int64_t len = bdrv_getlength(bs->file->bs);
|
||||
int64_t len = bdrv_co_getlength(bs->file->bs);
|
||||
|
||||
uint64_t offset = qcrypto_block_get_payload_offset(crypto->block);
|
||||
assert(offset < INT64_MAX);
|
||||
@ -639,7 +638,7 @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
|
||||
assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
|
||||
luks_opts = &create_options->u.luks;
|
||||
|
||||
bs = bdrv_open_blockdev_ref(luks_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(luks_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
@ -708,8 +707,8 @@ static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (!bs) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -737,13 +736,13 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int block_crypto_get_info_luks(BlockDriverState *bs,
|
||||
BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
block_crypto_co_get_info_luks(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BlockDriverInfo subbdi;
|
||||
int ret;
|
||||
|
||||
ret = bdrv_get_info(bs->file->bs, &subbdi);
|
||||
ret = bdrv_co_get_info(bs->file->bs, &subbdi);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -953,9 +952,9 @@ static BlockDriver bdrv_crypto_luks = {
|
||||
.bdrv_refresh_limits = block_crypto_refresh_limits,
|
||||
.bdrv_co_preadv = block_crypto_co_preadv,
|
||||
.bdrv_co_pwritev = block_crypto_co_pwritev,
|
||||
.bdrv_getlength = block_crypto_getlength,
|
||||
.bdrv_co_getlength = block_crypto_co_getlength,
|
||||
.bdrv_measure = block_crypto_measure,
|
||||
.bdrv_get_info = block_crypto_get_info_luks,
|
||||
.bdrv_co_get_info = block_crypto_co_get_info_luks,
|
||||
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
|
||||
.bdrv_amend_options = block_crypto_amend_options_luks,
|
||||
.bdrv_co_amend = block_crypto_co_amend_luks,
|
||||
|
61
block/curl.c
61
block/curl.c
@ -27,6 +27,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
@ -37,8 +38,15 @@
|
||||
|
||||
// #define DEBUG_VERBOSE
|
||||
|
||||
/* CURL 7.85.0 switches to a string based API for specifying
|
||||
* the desired protocols.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500
|
||||
#define PROTOCOLS "HTTP,HTTPS,FTP,FTPS"
|
||||
#else
|
||||
#define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
|
||||
CURLPROTO_FTP | CURLPROTO_FTPS)
|
||||
#endif
|
||||
|
||||
#define CURL_NUM_STATES 8
|
||||
#define CURL_NUM_ACB 8
|
||||
@ -509,9 +517,18 @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
|
||||
* obscure protocols. For example, do not allow POP3/SMTP/IMAP see
|
||||
* CVE-2013-0249.
|
||||
*
|
||||
* Restricting protocols is only supported from 7.19.4 upwards.
|
||||
* Restricting protocols is only supported from 7.19.4 upwards. Note:
|
||||
* version 7.85.0 deprecates CURLOPT_*PROTOCOLS in favour of a string
|
||||
* based CURLOPT_*PROTOCOLS_STR API.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
#if LIBCURL_VERSION_NUM >= 0x075500
|
||||
if (curl_easy_setopt(state->curl,
|
||||
CURLOPT_PROTOCOLS_STR, PROTOCOLS) ||
|
||||
curl_easy_setopt(state->curl,
|
||||
CURLOPT_REDIR_PROTOCOLS_STR, PROTOCOLS)) {
|
||||
goto err;
|
||||
}
|
||||
#elif LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (curl_easy_setopt(state->curl, CURLOPT_PROTOCOLS, PROTOCOLS) ||
|
||||
curl_easy_setopt(state->curl, CURLOPT_REDIR_PROTOCOLS, PROTOCOLS)) {
|
||||
goto err;
|
||||
@ -669,7 +686,12 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
const char *file;
|
||||
const char *cookie;
|
||||
const char *cookie_secret;
|
||||
double d;
|
||||
/* CURL >= 7.55.0 uses curl_off_t for content length instead of a double */
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700
|
||||
curl_off_t cl;
|
||||
#else
|
||||
double cl;
|
||||
#endif
|
||||
const char *secretid;
|
||||
const char *protocol_delimiter;
|
||||
int ret;
|
||||
@ -796,27 +818,36 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
if (curl_easy_perform(state->curl))
|
||||
goto out;
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) {
|
||||
/* CURL 7.55.0 deprecates CURLINFO_CONTENT_LENGTH_DOWNLOAD in favour of
|
||||
* the *_T version which returns a more sensible type for content length.
|
||||
*/
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cl)) {
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl)) {
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
/* Prior CURL 7.19.4 return value of 0 could mean that the file size is not
|
||||
* know or the size is zero. From 7.19.4 CURL returns -1 if size is not
|
||||
* known and zero if it is really zero-length file. */
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (d < 0) {
|
||||
if (cl < 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Server didn't report file size.");
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (d <= 0) {
|
||||
if (cl <= 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Unknown file size or zero-length file.");
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->len = d;
|
||||
s->len = cl;
|
||||
|
||||
if ((!strncasecmp(s->url, "http://", strlen("http://"))
|
||||
|| !strncasecmp(s->url, "https://", strlen("https://")))
|
||||
@ -849,8 +880,10 @@ out_noclean:
|
||||
g_free(s->username);
|
||||
g_free(s->proxyusername);
|
||||
g_free(s->proxypassword);
|
||||
curl_drop_all_sockets(s->sockets);
|
||||
g_hash_table_destroy(s->sockets);
|
||||
if (s->sockets) {
|
||||
curl_drop_all_sockets(s->sockets);
|
||||
g_hash_table_destroy(s->sockets);
|
||||
}
|
||||
qemu_opts_del(opts);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -957,7 +990,7 @@ static void curl_close(BlockDriverState *bs)
|
||||
g_free(s->proxypassword);
|
||||
}
|
||||
|
||||
static int64_t curl_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn curl_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVCURLState *s = bs->opaque;
|
||||
return s->len;
|
||||
@ -1001,7 +1034,7 @@ static BlockDriver bdrv_http = {
|
||||
.bdrv_parse_filename = curl_parse_filename,
|
||||
.bdrv_file_open = curl_open,
|
||||
.bdrv_close = curl_close,
|
||||
.bdrv_getlength = curl_getlength,
|
||||
.bdrv_co_getlength = curl_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = curl_co_preadv,
|
||||
|
||||
@ -1020,7 +1053,7 @@ static BlockDriver bdrv_https = {
|
||||
.bdrv_parse_filename = curl_parse_filename,
|
||||
.bdrv_file_open = curl_open,
|
||||
.bdrv_close = curl_close,
|
||||
.bdrv_getlength = curl_getlength,
|
||||
.bdrv_co_getlength = curl_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = curl_co_preadv,
|
||||
|
||||
@ -1039,7 +1072,7 @@ static BlockDriver bdrv_ftp = {
|
||||
.bdrv_parse_filename = curl_parse_filename,
|
||||
.bdrv_file_open = curl_open,
|
||||
.bdrv_close = curl_close,
|
||||
.bdrv_getlength = curl_getlength,
|
||||
.bdrv_co_getlength = curl_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = curl_co_preadv,
|
||||
|
||||
@ -1058,7 +1091,7 @@ static BlockDriver bdrv_ftps = {
|
||||
.bdrv_parse_filename = curl_parse_filename,
|
||||
.bdrv_file_open = curl_open,
|
||||
.bdrv_close = curl_close,
|
||||
.bdrv_getlength = curl_getlength,
|
||||
.bdrv_co_getlength = curl_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = curl_co_preadv,
|
||||
|
||||
|
@ -24,8 +24,10 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "trace.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
struct BdrvDirtyBitmap {
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
@ -21,12 +21,13 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/memalign.h"
|
||||
#include "block/aio.h"
|
||||
#include "block/block.h"
|
||||
#include "block/block_int-common.h"
|
||||
#include "block/export.h"
|
||||
#include "block/fuse.h"
|
||||
#include "block/qapi.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
|
||||
#include <fuse.h>
|
||||
|
@ -10,9 +10,9 @@
|
||||
* later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/export.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
@ -188,7 +189,7 @@ static int fd_open(BlockDriverState *bs)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int64_t raw_getlength(BlockDriverState *bs);
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs);
|
||||
|
||||
typedef struct RawPosixAIOData {
|
||||
BlockDriverState *bs;
|
||||
@ -1737,7 +1738,7 @@ static int handle_aiocb_write_zeroes(void *opaque)
|
||||
#ifdef CONFIG_FALLOCATE
|
||||
/* Last resort: we are trying to extend the file with zeroed data. This
|
||||
* can be done via fallocate(fd, 0) */
|
||||
len = bdrv_getlength(aiocb->bs);
|
||||
len = raw_co_getlength(aiocb->bs);
|
||||
if (s->has_fallocate && len >= 0 && aiocb->aio_offset >= len) {
|
||||
int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0 || ret != -ENOTSUP) {
|
||||
@ -2131,7 +2132,7 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
|
||||
return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE);
|
||||
}
|
||||
|
||||
static void raw_aio_plug(BlockDriverState *bs)
|
||||
static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState __attribute__((unused)) *s = bs->opaque;
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
@ -2148,7 +2149,7 @@ static void raw_aio_plug(BlockDriverState *bs)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void raw_aio_unplug(BlockDriverState *bs)
|
||||
static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState __attribute__((unused)) *s = bs->opaque;
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
@ -2279,7 +2280,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
}
|
||||
|
||||
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
|
||||
int64_t cur_length = raw_getlength(bs);
|
||||
int64_t cur_length = raw_co_getlength(bs);
|
||||
|
||||
if (offset != cur_length && exact) {
|
||||
error_setg(errp, "Cannot resize device files");
|
||||
@ -2297,7 +2298,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
}
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int fd = s->fd;
|
||||
@ -2316,7 +2317,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
|
||||
return st.st_size;
|
||||
}
|
||||
#elif defined(__NetBSD__)
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int fd = s->fd;
|
||||
@ -2341,7 +2342,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
|
||||
return st.st_size;
|
||||
}
|
||||
#elif defined(__sun__)
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
struct dk_minfo minfo;
|
||||
@ -2372,7 +2373,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
|
||||
return size;
|
||||
}
|
||||
#elif defined(CONFIG_BSD)
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int fd = s->fd;
|
||||
@ -2444,7 +2445,7 @@ again:
|
||||
return size;
|
||||
}
|
||||
#else
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
@ -2463,7 +2464,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
struct stat st;
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -2829,7 +2830,7 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
|
||||
* round up if necessary.
|
||||
*/
|
||||
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
|
||||
int64_t file_length = raw_getlength(bs);
|
||||
int64_t file_length = raw_co_getlength(bs);
|
||||
if (file_length > 0) {
|
||||
/* Ignore errors, this is just a safeguard */
|
||||
assert(hole == file_length);
|
||||
@ -2851,7 +2852,7 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Verify that the file is not in the page cache */
|
||||
static void check_cache_dropped(BlockDriverState *bs, Error **errp)
|
||||
static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
const size_t window_size = 128 * 1024 * 1024;
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -2866,7 +2867,7 @@ static void check_cache_dropped(BlockDriverState *bs, Error **errp)
|
||||
page_size = sysconf(_SC_PAGESIZE);
|
||||
vec = g_malloc(DIV_ROUND_UP(window_size, page_size));
|
||||
|
||||
end = raw_getlength(bs);
|
||||
end = raw_co_getlength(bs);
|
||||
|
||||
for (offset = 0; offset < end; offset += window_size) {
|
||||
void *new_window;
|
||||
@ -3085,11 +3086,40 @@ static int coroutine_fn raw_co_pwrite_zeroes(
|
||||
return raw_do_pwrite_zeroes(bs, offset, bytes, flags, false);
|
||||
}
|
||||
|
||||
static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ImageInfoSpecific *raw_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp)
|
||||
{
|
||||
ImageInfoSpecificFile *file_info = g_new0(ImageInfoSpecificFile, 1);
|
||||
ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
|
||||
|
||||
*spec_info = (ImageInfoSpecific){
|
||||
.type = IMAGE_INFO_SPECIFIC_KIND_FILE,
|
||||
.u.file.data = file_info,
|
||||
};
|
||||
|
||||
#ifdef FS_IOC_FSGETXATTR
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
struct fsxattr attr;
|
||||
int ret;
|
||||
|
||||
ret = ioctl(s->fd, FS_IOC_FSGETXATTR, &attr);
|
||||
if (!ret && attr.fsx_extsize != 0) {
|
||||
file_info->has_extent_size_hint = true;
|
||||
file_info->extent_size_hint = attr.fsx_extsize;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return spec_info;
|
||||
}
|
||||
|
||||
static BlockStatsSpecificFile get_blockstats_specific_file(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@ -3316,15 +3346,15 @@ BlockDriver bdrv_file = {
|
||||
.bdrv_co_copy_range_from = raw_co_copy_range_from,
|
||||
.bdrv_co_copy_range_to = raw_co_copy_range_to,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
.bdrv_io_plug = raw_aio_plug,
|
||||
.bdrv_io_unplug = raw_aio_unplug,
|
||||
.bdrv_co_io_plug = raw_co_io_plug,
|
||||
.bdrv_co_io_unplug = raw_co_io_unplug,
|
||||
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_info = raw_get_info,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.bdrv_co_get_info = raw_co_get_info,
|
||||
.bdrv_get_specific_info = raw_get_specific_info,
|
||||
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
|
||||
.bdrv_get_specific_stats = raw_get_specific_stats,
|
||||
.bdrv_check_perm = raw_check_perm,
|
||||
.bdrv_set_perm = raw_set_perm,
|
||||
@ -3688,15 +3718,15 @@ static BlockDriver bdrv_host_device = {
|
||||
.bdrv_co_copy_range_from = raw_co_copy_range_from,
|
||||
.bdrv_co_copy_range_to = raw_co_copy_range_to,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
.bdrv_io_plug = raw_aio_plug,
|
||||
.bdrv_io_unplug = raw_aio_unplug,
|
||||
.bdrv_co_io_plug = raw_co_io_plug,
|
||||
.bdrv_co_io_unplug = raw_co_io_unplug,
|
||||
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_info = raw_get_info,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.bdrv_co_get_info = raw_co_get_info,
|
||||
.bdrv_get_specific_info = raw_get_specific_info,
|
||||
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
|
||||
.bdrv_get_specific_stats = hdev_get_specific_stats,
|
||||
.bdrv_check_perm = raw_check_perm,
|
||||
.bdrv_set_perm = raw_set_perm,
|
||||
@ -3756,7 +3786,7 @@ out:
|
||||
return prio;
|
||||
}
|
||||
|
||||
static bool cdrom_is_inserted(BlockDriverState *bs)
|
||||
static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
@ -3765,7 +3795,7 @@ static bool cdrom_is_inserted(BlockDriverState *bs)
|
||||
return ret == CDS_DISC_OK;
|
||||
}
|
||||
|
||||
static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
|
||||
static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
@ -3778,7 +3808,7 @@ static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
|
||||
}
|
||||
}
|
||||
|
||||
static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
|
||||
static void coroutine_fn cdrom_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
@ -3812,20 +3842,19 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.bdrv_co_pwritev = raw_co_pwritev,
|
||||
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
.bdrv_io_plug = raw_aio_plug,
|
||||
.bdrv_io_unplug = raw_aio_unplug,
|
||||
.bdrv_co_io_plug = raw_co_io_plug,
|
||||
.bdrv_co_io_unplug = raw_co_io_unplug,
|
||||
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.has_variable_length = true,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.has_variable_length = true,
|
||||
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
|
||||
|
||||
/* removable device support */
|
||||
.bdrv_is_inserted = cdrom_is_inserted,
|
||||
.bdrv_eject = cdrom_eject,
|
||||
.bdrv_lock_medium = cdrom_lock_medium,
|
||||
.bdrv_co_is_inserted = cdrom_co_is_inserted,
|
||||
.bdrv_co_eject = cdrom_co_eject,
|
||||
.bdrv_co_lock_medium = cdrom_co_lock_medium,
|
||||
|
||||
/* generic scsi device */
|
||||
.bdrv_co_ioctl = hdev_co_ioctl,
|
||||
@ -3882,12 +3911,12 @@ static int cdrom_reopen(BlockDriverState *bs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cdrom_is_inserted(BlockDriverState *bs)
|
||||
static bool coroutine_fn cdrom_co_is_inserted(BlockDriverState *bs)
|
||||
{
|
||||
return raw_getlength(bs) > 0;
|
||||
return raw_co_getlength(bs) > 0;
|
||||
}
|
||||
|
||||
static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
|
||||
static void coroutine_fn cdrom_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
@ -3907,7 +3936,7 @@ static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
|
||||
cdrom_reopen(bs);
|
||||
}
|
||||
|
||||
static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
|
||||
static void coroutine_fn cdrom_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
@ -3942,20 +3971,19 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.bdrv_co_pwritev = raw_co_pwritev,
|
||||
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
.bdrv_io_plug = raw_aio_plug,
|
||||
.bdrv_io_unplug = raw_aio_unplug,
|
||||
.bdrv_co_io_plug = raw_co_io_plug,
|
||||
.bdrv_co_io_unplug = raw_co_io_unplug,
|
||||
.bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.has_variable_length = true,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.has_variable_length = true,
|
||||
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
|
||||
|
||||
/* removable device support */
|
||||
.bdrv_is_inserted = cdrom_is_inserted,
|
||||
.bdrv_eject = cdrom_eject,
|
||||
.bdrv_lock_medium = cdrom_lock_medium,
|
||||
.bdrv_co_is_inserted = cdrom_co_is_inserted,
|
||||
.bdrv_co_eject = cdrom_co_eject,
|
||||
.bdrv_co_lock_medium = cdrom_co_lock_medium,
|
||||
};
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
@ -525,7 +526,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
LARGE_INTEGER l;
|
||||
@ -558,7 +559,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
|
||||
return l.QuadPart;
|
||||
}
|
||||
|
||||
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
|
||||
DWORD * high);
|
||||
@ -763,9 +764,9 @@ BlockDriver bdrv_file = {
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size
|
||||
= raw_co_get_allocated_file_size,
|
||||
|
||||
.create_opts = &raw_create_opts,
|
||||
};
|
||||
@ -932,11 +933,9 @@ static BlockDriver bdrv_host_device = {
|
||||
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.has_variable_length = true,
|
||||
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
.has_variable_length = true,
|
||||
.bdrv_co_get_allocated_file_size = raw_co_get_allocated_file_size,
|
||||
};
|
||||
|
||||
static void bdrv_file_init(void)
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/error.h"
|
||||
@ -54,9 +55,9 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
|
||||
static int64_t compress_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
|
||||
@ -116,15 +117,17 @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
}
|
||||
|
||||
|
||||
static void compress_eject(BlockDriverState *bs, bool eject_flag)
|
||||
static void coroutine_fn
|
||||
compress_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
bdrv_eject(bs->file->bs, eject_flag);
|
||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||
}
|
||||
|
||||
|
||||
static void compress_lock_medium(BlockDriverState *bs, bool locked)
|
||||
static void coroutine_fn
|
||||
compress_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
bdrv_lock_medium(bs->file->bs, locked);
|
||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||
}
|
||||
|
||||
|
||||
@ -134,7 +137,7 @@ static BlockDriver bdrv_compress = {
|
||||
.bdrv_open = compress_open,
|
||||
.bdrv_child_perm = bdrv_default_perms,
|
||||
|
||||
.bdrv_getlength = compress_getlength,
|
||||
.bdrv_co_getlength = compress_co_getlength,
|
||||
|
||||
.bdrv_co_preadv_part = compress_co_preadv_part,
|
||||
.bdrv_co_pwritev_part = compress_co_pwritev_part,
|
||||
@ -142,8 +145,8 @@ static BlockDriver bdrv_compress = {
|
||||
.bdrv_co_pdiscard = compress_co_pdiscard,
|
||||
.bdrv_refresh_limits = compress_refresh_limits,
|
||||
|
||||
.bdrv_eject = compress_eject,
|
||||
.bdrv_lock_medium = compress_lock_medium,
|
||||
.bdrv_co_eject = compress_co_eject,
|
||||
.bdrv_co_lock_medium = compress_co_lock_medium,
|
||||
|
||||
.has_variable_length = true,
|
||||
.is_filter = true,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/units.h"
|
||||
#include <glusterfs/api/glfs.h>
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "qapi/error.h"
|
||||
@ -1317,7 +1318,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int64_t qemu_gluster_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn qemu_gluster_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVGlusterState *s = bs->opaque;
|
||||
int64_t ret;
|
||||
@ -1330,7 +1331,8 @@ static int64_t qemu_gluster_getlength(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t qemu_gluster_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn
|
||||
qemu_gluster_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
BDRVGlusterState *s = bs->opaque;
|
||||
struct stat st;
|
||||
@ -1509,7 +1511,7 @@ static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
|
||||
* round up if necessary.
|
||||
*/
|
||||
if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
|
||||
int64_t file_length = qemu_gluster_getlength(bs);
|
||||
int64_t file_length = qemu_gluster_co_getlength(bs);
|
||||
if (file_length > 0) {
|
||||
/* Ignore errors, this is just a safeguard */
|
||||
assert(hole == file_length);
|
||||
@ -1558,8 +1560,8 @@ static BlockDriver bdrv_gluster = {
|
||||
.bdrv_close = qemu_gluster_close,
|
||||
.bdrv_co_create = qemu_gluster_co_create,
|
||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||
.bdrv_getlength = qemu_gluster_getlength,
|
||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||
.bdrv_co_getlength = qemu_gluster_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
|
||||
.bdrv_co_truncate = qemu_gluster_co_truncate,
|
||||
.bdrv_co_readv = qemu_gluster_co_readv,
|
||||
.bdrv_co_writev = qemu_gluster_co_writev,
|
||||
@ -1587,8 +1589,8 @@ static BlockDriver bdrv_gluster_tcp = {
|
||||
.bdrv_close = qemu_gluster_close,
|
||||
.bdrv_co_create = qemu_gluster_co_create,
|
||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||
.bdrv_getlength = qemu_gluster_getlength,
|
||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||
.bdrv_co_getlength = qemu_gluster_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
|
||||
.bdrv_co_truncate = qemu_gluster_co_truncate,
|
||||
.bdrv_co_readv = qemu_gluster_co_readv,
|
||||
.bdrv_co_writev = qemu_gluster_co_writev,
|
||||
@ -1616,8 +1618,8 @@ static BlockDriver bdrv_gluster_unix = {
|
||||
.bdrv_close = qemu_gluster_close,
|
||||
.bdrv_co_create = qemu_gluster_co_create,
|
||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||
.bdrv_getlength = qemu_gluster_getlength,
|
||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||
.bdrv_co_getlength = qemu_gluster_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
|
||||
.bdrv_co_truncate = qemu_gluster_co_truncate,
|
||||
.bdrv_co_readv = qemu_gluster_co_readv,
|
||||
.bdrv_co_writev = qemu_gluster_co_writev,
|
||||
@ -1651,8 +1653,8 @@ static BlockDriver bdrv_gluster_rdma = {
|
||||
.bdrv_close = qemu_gluster_close,
|
||||
.bdrv_co_create = qemu_gluster_co_create,
|
||||
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
|
||||
.bdrv_getlength = qemu_gluster_getlength,
|
||||
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
|
||||
.bdrv_co_getlength = qemu_gluster_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = qemu_gluster_co_get_allocated_file_size,
|
||||
.bdrv_co_truncate = qemu_gluster_co_truncate,
|
||||
.bdrv_co_readv = qemu_gluster_co_readv,
|
||||
.bdrv_co_writev = qemu_gluster_co_writev,
|
||||
|
80
block/io.c
80
block/io.c
@ -30,6 +30,7 @@
|
||||
#include "block/blockjob_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/coroutines.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/write-threshold.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/memalign.h"
|
||||
@ -721,14 +722,14 @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
|
||||
/**
|
||||
* Round a region to cluster boundaries
|
||||
*/
|
||||
void bdrv_round_to_clusters(BlockDriverState *bs,
|
||||
void coroutine_fn bdrv_round_to_clusters(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes,
|
||||
int64_t *cluster_offset,
|
||||
int64_t *cluster_bytes)
|
||||
{
|
||||
BlockDriverInfo bdi;
|
||||
IO_CODE();
|
||||
if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
|
||||
if (bdrv_co_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
|
||||
*cluster_offset = offset;
|
||||
*cluster_bytes = bytes;
|
||||
} else {
|
||||
@ -738,12 +739,12 @@ void bdrv_round_to_clusters(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
static int bdrv_get_cluster_size(BlockDriverState *bs)
|
||||
static coroutine_fn int bdrv_get_cluster_size(BlockDriverState *bs)
|
||||
{
|
||||
BlockDriverInfo bdi;
|
||||
int ret;
|
||||
|
||||
ret = bdrv_get_info(bs, &bdi);
|
||||
ret = bdrv_co_get_info(bs, &bdi);
|
||||
if (ret < 0 || bdi.cluster_size == 0) {
|
||||
return bs->bl.request_alignment;
|
||||
} else {
|
||||
@ -1250,7 +1251,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
|
||||
goto err;
|
||||
}
|
||||
|
||||
bdrv_debug_event(bs, BLKDBG_COR_WRITE);
|
||||
bdrv_co_debug_event(bs, BLKDBG_COR_WRITE);
|
||||
if (drv->bdrv_co_pwrite_zeroes &&
|
||||
buffer_is_zero(bounce_buffer, pnum)) {
|
||||
/* FIXME: Should we (perhaps conditionally) be setting
|
||||
@ -1495,10 +1496,10 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
|
||||
qemu_iovec_init_buf(&local_qiov, pad->buf, bytes);
|
||||
|
||||
if (pad->head) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
|
||||
}
|
||||
if (pad->merge_reads && pad->tail) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
|
||||
}
|
||||
ret = bdrv_aligned_preadv(child, req, req->overlap_offset, bytes,
|
||||
align, &local_qiov, 0, 0);
|
||||
@ -1506,10 +1507,10 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
|
||||
return ret;
|
||||
}
|
||||
if (pad->head) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
|
||||
}
|
||||
if (pad->merge_reads && pad->tail) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
|
||||
}
|
||||
|
||||
if (pad->merge_reads) {
|
||||
@ -1520,7 +1521,7 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
|
||||
if (pad->tail) {
|
||||
qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align);
|
||||
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
|
||||
ret = bdrv_aligned_preadv(
|
||||
child, req,
|
||||
req->overlap_offset + req->overlap_bytes - align,
|
||||
@ -1528,7 +1529,7 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
|
||||
}
|
||||
|
||||
zero_mem:
|
||||
@ -1621,7 +1622,7 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
|
||||
|
||||
trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
|
||||
|
||||
if (!bdrv_is_inserted(bs)) {
|
||||
if (!bdrv_co_is_inserted(bs)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
@ -1925,21 +1926,24 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
|
||||
if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
|
||||
flags |= BDRV_REQ_MAY_UNMAP;
|
||||
}
|
||||
|
||||
/* Can't use optimization hint with bufferless zero write */
|
||||
flags &= ~BDRV_REQ_REGISTERED_BUF;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
/* Do nothing, write notifier decided to fail this request */
|
||||
} else if (flags & BDRV_REQ_ZERO_WRITE) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_ZERO);
|
||||
ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags);
|
||||
} else if (flags & BDRV_REQ_WRITE_COMPRESSED) {
|
||||
ret = bdrv_driver_pwritev_compressed(bs, offset, bytes,
|
||||
qiov, qiov_offset);
|
||||
} else if (bytes <= max_transfer) {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
|
||||
ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, qiov_offset, flags);
|
||||
} else {
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV);
|
||||
while (bytes_remaining) {
|
||||
int num = MIN(bytes_remaining, max_transfer);
|
||||
int local_flags = flags;
|
||||
@ -1962,7 +1966,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
|
||||
bytes_remaining -= num;
|
||||
}
|
||||
}
|
||||
bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
|
||||
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_DONE);
|
||||
|
||||
if (ret >= 0) {
|
||||
ret = 0;
|
||||
@ -2066,7 +2070,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
|
||||
|
||||
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
|
||||
|
||||
if (!bdrv_is_inserted(bs)) {
|
||||
if (!bdrv_co_is_inserted(bs)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
@ -2719,8 +2723,8 @@ bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||
|
||||
bdrv_inc_in_flight(bs);
|
||||
|
||||
if (drv->bdrv_load_vmstate) {
|
||||
ret = drv->bdrv_load_vmstate(bs, qiov, pos);
|
||||
if (drv->bdrv_co_load_vmstate) {
|
||||
ret = drv->bdrv_co_load_vmstate(bs, qiov, pos);
|
||||
} else if (child_bs) {
|
||||
ret = bdrv_co_readv_vmstate(child_bs, qiov, pos);
|
||||
} else {
|
||||
@ -2752,8 +2756,8 @@ bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
||||
|
||||
bdrv_inc_in_flight(bs);
|
||||
|
||||
if (drv->bdrv_save_vmstate) {
|
||||
ret = drv->bdrv_save_vmstate(bs, qiov, pos);
|
||||
if (drv->bdrv_co_save_vmstate) {
|
||||
ret = drv->bdrv_co_save_vmstate(bs, qiov, pos);
|
||||
} else if (child_bs) {
|
||||
ret = bdrv_co_writev_vmstate(child_bs, qiov, pos);
|
||||
} else {
|
||||
@ -2834,7 +2838,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
||||
|
||||
bdrv_inc_in_flight(bs);
|
||||
|
||||
if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
|
||||
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
|
||||
bdrv_is_sg(bs)) {
|
||||
goto early_exit;
|
||||
}
|
||||
@ -2958,7 +2962,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
||||
BlockDriverState *bs = child->bs;
|
||||
IO_CODE();
|
||||
|
||||
if (!bs || !bs->drv || !bdrv_is_inserted(bs)) {
|
||||
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
@ -3136,24 +3140,24 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
|
||||
return mem;
|
||||
}
|
||||
|
||||
void bdrv_io_plug(BlockDriverState *bs)
|
||||
void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child;
|
||||
IO_CODE();
|
||||
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
bdrv_io_plug(child->bs);
|
||||
bdrv_co_io_plug(child->bs);
|
||||
}
|
||||
|
||||
if (qatomic_fetch_inc(&bs->io_plugged) == 0) {
|
||||
BlockDriver *drv = bs->drv;
|
||||
if (drv && drv->bdrv_io_plug) {
|
||||
drv->bdrv_io_plug(bs);
|
||||
if (drv && drv->bdrv_co_io_plug) {
|
||||
drv->bdrv_co_io_plug(bs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bdrv_io_unplug(BlockDriverState *bs)
|
||||
void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child;
|
||||
IO_CODE();
|
||||
@ -3161,13 +3165,13 @@ void bdrv_io_unplug(BlockDriverState *bs)
|
||||
assert(bs->io_plugged);
|
||||
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
|
||||
BlockDriver *drv = bs->drv;
|
||||
if (drv && drv->bdrv_io_unplug) {
|
||||
drv->bdrv_io_unplug(bs);
|
||||
if (drv && drv->bdrv_co_io_unplug) {
|
||||
drv->bdrv_co_io_unplug(bs);
|
||||
}
|
||||
}
|
||||
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
bdrv_io_unplug(child->bs);
|
||||
bdrv_co_io_unplug(child->bs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3240,7 +3244,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
|
||||
assert(!(read_flags & BDRV_REQ_NO_WAIT));
|
||||
assert(!(write_flags & BDRV_REQ_NO_WAIT));
|
||||
|
||||
if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
|
||||
if (!dst || !dst->bs || !bdrv_co_is_inserted(dst->bs)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
ret = bdrv_check_request32(dst_offset, bytes, NULL, 0);
|
||||
@ -3251,7 +3255,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
|
||||
return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, write_flags);
|
||||
}
|
||||
|
||||
if (!src || !src->bs || !bdrv_is_inserted(src->bs)) {
|
||||
if (!src || !src->bs || !bdrv_co_is_inserted(src->bs)) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
ret = bdrv_check_request32(src_offset, bytes, NULL, 0);
|
||||
@ -3443,7 +3447,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
if (new_bytes && backing) {
|
||||
int64_t backing_len;
|
||||
|
||||
backing_len = bdrv_getlength(backing->bs);
|
||||
backing_len = bdrv_co_getlength(backing->bs);
|
||||
if (backing_len < 0) {
|
||||
ret = backing_len;
|
||||
error_setg_errno(errp, -ret, "Could not get backing file size");
|
||||
@ -3473,15 +3477,17 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
|
||||
ret = bdrv_co_refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not refresh total sector count");
|
||||
} else {
|
||||
offset = bs->total_sectors * BDRV_SECTOR_SIZE;
|
||||
}
|
||||
/* It's possible that truncation succeeded but refresh_total_sectors
|
||||
/*
|
||||
* It's possible that truncation succeeded but bdrv_refresh_total_sectors
|
||||
* failed, but the latter doesn't affect how we should finish the request.
|
||||
* Pass 0 as the last parameter so that dirty bitmaps etc. are handled. */
|
||||
* Pass 0 as the last parameter so that dirty bitmaps etc. are handled.
|
||||
*/
|
||||
bdrv_co_write_req_finish(child, offset - new_bytes, new_bytes, &req, 0);
|
||||
|
||||
out:
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/bitmap.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "scsi/constants.h"
|
||||
@ -268,6 +269,7 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
|
||||
timer_mod(&iTask->retry_timer,
|
||||
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time);
|
||||
iTask->do_retry = 1;
|
||||
return;
|
||||
} else if (status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
int error = iscsi_translate_sense(&task->sense);
|
||||
if (error == EAGAIN) {
|
||||
@ -1126,8 +1128,8 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
|
||||
|
||||
#endif
|
||||
|
||||
static int64_t
|
||||
iscsi_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn
|
||||
iscsi_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
int64_t len;
|
||||
@ -1352,6 +1354,9 @@ static void apply_chap(struct iscsi_context *iscsi, QemuOpts *opts,
|
||||
} else if (!password) {
|
||||
error_setg(errp, "CHAP username specified but no password was given");
|
||||
return;
|
||||
} else {
|
||||
warn_report("iSCSI block driver 'password' option is deprecated, "
|
||||
"use 'password-secret' instead");
|
||||
}
|
||||
|
||||
if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
|
||||
@ -2154,7 +2159,7 @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cur_length = iscsi_getlength(bs);
|
||||
cur_length = iscsi_co_getlength(bs);
|
||||
if (offset != cur_length && exact) {
|
||||
error_setg(errp, "Cannot resize iSCSI devices");
|
||||
return -ENOTSUP;
|
||||
@ -2170,7 +2175,8 @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
iscsi_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
bdi->cluster_size = iscsilun->cluster_size;
|
||||
@ -2433,8 +2439,8 @@ static BlockDriver bdrv_iscsi = {
|
||||
.bdrv_reopen_commit = iscsi_reopen_commit,
|
||||
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
|
||||
|
||||
.bdrv_getlength = iscsi_getlength,
|
||||
.bdrv_get_info = iscsi_get_info,
|
||||
.bdrv_co_getlength = iscsi_co_getlength,
|
||||
.bdrv_co_get_info = iscsi_co_get_info,
|
||||
.bdrv_co_truncate = iscsi_co_truncate,
|
||||
.bdrv_refresh_limits = iscsi_refresh_limits,
|
||||
|
||||
@ -2472,8 +2478,8 @@ static BlockDriver bdrv_iser = {
|
||||
.bdrv_reopen_commit = iscsi_reopen_commit,
|
||||
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
|
||||
|
||||
.bdrv_getlength = iscsi_getlength,
|
||||
.bdrv_get_info = iscsi_get_info,
|
||||
.bdrv_co_getlength = iscsi_co_getlength,
|
||||
.bdrv_co_get_info = iscsi_co_get_info,
|
||||
.bdrv_co_truncate = iscsi_co_truncate,
|
||||
.bdrv_refresh_limits = iscsi_refresh_limits,
|
||||
|
||||
|
@ -139,7 +139,9 @@ block_gen_c = custom_target('block-gen.c',
|
||||
input: files(
|
||||
'../include/block/block-io.h',
|
||||
'../include/block/dirty-bitmap.h',
|
||||
'../include/block/block_int-io.h',
|
||||
'../include/block/block-global-state.h',
|
||||
'../include/sysemu/block-backend-global-state.h',
|
||||
'../include/sysemu/block-backend-io.h',
|
||||
'coroutines.h'
|
||||
),
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "trace.h"
|
||||
#include "block/blockjob_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
@ -909,13 +910,13 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
goto immediate_exit;
|
||||
}
|
||||
|
||||
s->bdev_length = bdrv_getlength(bs);
|
||||
s->bdev_length = bdrv_co_getlength(bs);
|
||||
if (s->bdev_length < 0) {
|
||||
ret = s->bdev_length;
|
||||
goto immediate_exit;
|
||||
}
|
||||
|
||||
target_length = blk_getlength(s->target);
|
||||
target_length = blk_co_getlength(s->target);
|
||||
if (target_length < 0) {
|
||||
ret = target_length;
|
||||
goto immediate_exit;
|
||||
@ -956,7 +957,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
*/
|
||||
bdrv_get_backing_filename(target_bs, backing_filename,
|
||||
sizeof(backing_filename));
|
||||
if (!bdrv_get_info(target_bs, &bdi) && bdi.cluster_size) {
|
||||
if (!bdrv_co_get_info(target_bs, &bdi) && bdi.cluster_size) {
|
||||
s->target_cluster_size = bdi.cluster_size;
|
||||
} else {
|
||||
s->target_cluster_size = BDRV_SECTOR_SIZE;
|
||||
|
@ -32,7 +32,9 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
|
@ -725,7 +725,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
||||
monitor_printf(mon, "\nImages:\n");
|
||||
image_info = inserted->image;
|
||||
while (1) {
|
||||
bdrv_image_info_dump(image_info);
|
||||
bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0, false);
|
||||
if (image_info->backing_image) {
|
||||
image_info = image_info->backing_image;
|
||||
} else {
|
||||
@ -1005,3 +1005,24 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
g_free(sn_tab);
|
||||
g_free(global_snapshots);
|
||||
}
|
||||
|
||||
void hmp_change_medium(Monitor *mon, const char *device, const char *target,
|
||||
const char *arg, const char *read_only, bool force,
|
||||
Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
BlockdevChangeReadOnlyMode read_only_mode = 0;
|
||||
|
||||
if (read_only) {
|
||||
read_only_mode =
|
||||
qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
|
||||
read_only,
|
||||
BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qmp_blockdev_change_medium(device, NULL, target, arg, true, force,
|
||||
!!read_only, read_only_mode, errp);
|
||||
}
|
||||
|
@ -1992,7 +1992,7 @@ static int coroutine_fn nbd_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t nbd_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn nbd_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNBDState *s = bs->opaque;
|
||||
|
||||
@ -2124,7 +2124,7 @@ static BlockDriver bdrv_nbd = {
|
||||
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_co_truncate = nbd_co_truncate,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_co_getlength = nbd_co_getlength,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
@ -2152,7 +2152,7 @@ static BlockDriver bdrv_nbd_tcp = {
|
||||
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_co_truncate = nbd_co_truncate,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_co_getlength = nbd_co_getlength,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
@ -2180,7 +2180,7 @@ static BlockDriver bdrv_nbd_unix = {
|
||||
.bdrv_co_pdiscard = nbd_client_co_pdiscard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_co_truncate = nbd_co_truncate,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_co_getlength = nbd_co_getlength,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
.bdrv_co_block_status = nbd_client_co_block_status,
|
||||
.bdrv_dirname = nbd_dirname,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "trace.h"
|
||||
@ -731,7 +732,7 @@ nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
|
||||
bdrv_wakeup(task->bs);
|
||||
}
|
||||
|
||||
static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
NFSClient *client = bs->opaque;
|
||||
NFSRPC task = {0};
|
||||
@ -884,7 +885,7 @@ static BlockDriver bdrv_nfs = {
|
||||
.bdrv_has_zero_init = nfs_has_zero_init,
|
||||
/* libnfs does not provide the allocated filesize of a file on win32. */
|
||||
#if !defined(_WIN32)
|
||||
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
|
||||
.bdrv_co_get_allocated_file_size = nfs_co_get_allocated_file_size,
|
||||
#endif
|
||||
.bdrv_co_truncate = nfs_file_co_truncate,
|
||||
|
||||
|
14
block/null.c
14
block/null.c
@ -16,6 +16,7 @@
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "sysemu/replay.h"
|
||||
|
||||
@ -99,7 +100,7 @@ static int null_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t null_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn null_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNullState *s = bs->opaque;
|
||||
return s->length;
|
||||
@ -264,7 +265,8 @@ static void null_refresh_filename(BlockDriverState *bs)
|
||||
bs->drv->format_name);
|
||||
}
|
||||
|
||||
static int64_t null_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn
|
||||
null_co_get_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -283,8 +285,8 @@ static BlockDriver bdrv_null_co = {
|
||||
|
||||
.bdrv_file_open = null_file_open,
|
||||
.bdrv_parse_filename = null_co_parse_filename,
|
||||
.bdrv_getlength = null_getlength,
|
||||
.bdrv_get_allocated_file_size = null_allocated_file_size,
|
||||
.bdrv_co_getlength = null_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = null_co_get_allocated_file_size,
|
||||
|
||||
.bdrv_co_preadv = null_co_preadv,
|
||||
.bdrv_co_pwritev = null_co_pwritev,
|
||||
@ -304,8 +306,8 @@ static BlockDriver bdrv_null_aio = {
|
||||
|
||||
.bdrv_file_open = null_file_open,
|
||||
.bdrv_parse_filename = null_aio_parse_filename,
|
||||
.bdrv_getlength = null_getlength,
|
||||
.bdrv_get_allocated_file_size = null_allocated_file_size,
|
||||
.bdrv_co_getlength = null_co_getlength,
|
||||
.bdrv_co_get_allocated_file_size = null_co_get_allocated_file_size,
|
||||
|
||||
.bdrv_aio_preadv = null_aio_preadv,
|
||||
.bdrv_aio_pwritev = null_aio_pwritev,
|
||||
|
15
block/nvme.c
15
block/nvme.c
@ -23,6 +23,7 @@
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/memalign.h"
|
||||
#include "qemu/vfio-helpers.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "trace.h"
|
||||
@ -1001,7 +1002,7 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t nvme_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn nvme_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
return s->nsze << s->blkshift;
|
||||
@ -1485,7 +1486,7 @@ static int coroutine_fn nvme_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
cur_length = nvme_getlength(bs);
|
||||
cur_length = nvme_co_getlength(bs);
|
||||
if (offset != cur_length && exact) {
|
||||
error_setg(errp, "Cannot resize NVMe devices");
|
||||
return -ENOTSUP;
|
||||
@ -1566,14 +1567,14 @@ static void nvme_attach_aio_context(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
static void nvme_aio_plug(BlockDriverState *bs)
|
||||
static void coroutine_fn nvme_co_io_plug(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
assert(!s->plugged);
|
||||
s->plugged = true;
|
||||
}
|
||||
|
||||
static void nvme_aio_unplug(BlockDriverState *bs)
|
||||
static void coroutine_fn nvme_co_io_unplug(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
assert(s->plugged);
|
||||
@ -1642,7 +1643,7 @@ static BlockDriver bdrv_nvme = {
|
||||
.bdrv_parse_filename = nvme_parse_filename,
|
||||
.bdrv_file_open = nvme_file_open,
|
||||
.bdrv_close = nvme_close,
|
||||
.bdrv_getlength = nvme_getlength,
|
||||
.bdrv_co_getlength = nvme_co_getlength,
|
||||
.bdrv_probe_blocksizes = nvme_probe_blocksizes,
|
||||
.bdrv_co_truncate = nvme_co_truncate,
|
||||
|
||||
@ -1663,8 +1664,8 @@ static BlockDriver bdrv_nvme = {
|
||||
.bdrv_detach_aio_context = nvme_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nvme_attach_aio_context,
|
||||
|
||||
.bdrv_io_plug = nvme_aio_plug,
|
||||
.bdrv_io_unplug = nvme_aio_unplug,
|
||||
.bdrv_co_io_plug = nvme_co_io_plug,
|
||||
.bdrv_co_io_unplug = nvme_co_io_unplug,
|
||||
|
||||
.bdrv_register_buf = nvme_register_buf,
|
||||
.bdrv_unregister_buf = nvme_unregister_buf,
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "parallels.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "qemu/uuid.h"
|
||||
|
@ -565,13 +565,13 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(parallels_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(parallels_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -651,8 +651,8 @@ static int coroutine_fn parallels_co_create_opts(BlockDriver *drv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/units.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
|
||||
|
||||
@ -286,7 +287,7 @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
|
||||
}
|
||||
|
||||
if (s->data_end < 0) {
|
||||
s->data_end = bdrv_getlength(bs->file->bs);
|
||||
s->data_end = bdrv_co_getlength(bs->file->bs);
|
||||
if (s->data_end < 0) {
|
||||
return false;
|
||||
}
|
||||
@ -308,7 +309,7 @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
|
||||
}
|
||||
|
||||
if (s->file_end < 0) {
|
||||
s->file_end = bdrv_getlength(bs->file->bs);
|
||||
s->file_end = bdrv_co_getlength(bs->file->bs);
|
||||
if (s->file_end < 0) {
|
||||
return false;
|
||||
}
|
||||
@ -380,7 +381,7 @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
if (s->data_end >= 0 && offset > s->data_end) {
|
||||
if (s->file_end < 0) {
|
||||
s->file_end = bdrv_getlength(bs->file->bs);
|
||||
s->file_end = bdrv_co_getlength(bs->file->bs);
|
||||
if (s->file_end < 0) {
|
||||
error_setg(errp, "failed to get file length");
|
||||
return s->file_end;
|
||||
@ -441,7 +442,7 @@ static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
|
||||
return bdrv_co_flush(bs->file->bs);
|
||||
}
|
||||
|
||||
static int64_t preallocate_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
int64_t ret;
|
||||
BDRVPreallocateState *s = bs->opaque;
|
||||
@ -450,7 +451,7 @@ static int64_t preallocate_getlength(BlockDriverState *bs)
|
||||
return s->data_end;
|
||||
}
|
||||
|
||||
ret = bdrv_getlength(bs->file->bs);
|
||||
ret = bdrv_co_getlength(bs->file->bs);
|
||||
|
||||
if (has_prealloc_perms(bs)) {
|
||||
s->file_end = s->zero_start = s->data_end = ret;
|
||||
@ -536,9 +537,9 @@ BlockDriver bdrv_preallocate_filter = {
|
||||
.format_name = "preallocate",
|
||||
.instance_size = sizeof(BDRVPreallocateState),
|
||||
|
||||
.bdrv_getlength = preallocate_getlength,
|
||||
.bdrv_open = preallocate_open,
|
||||
.bdrv_close = preallocate_close,
|
||||
.bdrv_co_getlength = preallocate_co_getlength,
|
||||
.bdrv_open = preallocate_open,
|
||||
.bdrv_close = preallocate_close,
|
||||
|
||||
.bdrv_reopen_prepare = preallocate_reopen_prepare,
|
||||
.bdrv_reopen_commit = preallocate_reopen_commit,
|
||||
|
@ -23,7 +23,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/coroutine.h"
|
||||
#include "qemu/progress_meter.h"
|
||||
|
||||
void progress_init(ProgressMeter *pm)
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-block.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
|
319
block/qapi.c
319
block/qapi.c
@ -26,6 +26,7 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "block/qapi.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/throttle-groups.h"
|
||||
#include "block/write-threshold.h"
|
||||
#include "qapi/error.h"
|
||||
@ -39,7 +40,6 @@
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||
BlockDriverState *bs,
|
||||
@ -47,8 +47,10 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||
Error **errp)
|
||||
{
|
||||
ImageInfo **p_image_info;
|
||||
ImageInfo *backing_info;
|
||||
BlockDriverState *bs0, *backing;
|
||||
BlockDeviceInfo *info;
|
||||
ERRP_GUARD();
|
||||
|
||||
if (!bs->drv) {
|
||||
error_setg(errp, "Block device %s is ejected", bs->node_name);
|
||||
@ -146,37 +148,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||
bs0 = bs;
|
||||
p_image_info = &info->image;
|
||||
info->backing_file_depth = 0;
|
||||
while (1) {
|
||||
Error *local_err = NULL;
|
||||
bdrv_query_image_info(bs0, p_image_info, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
qapi_free_BlockDeviceInfo(info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* stop gathering data for flat output */
|
||||
if (flat) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Skip automatically inserted nodes that the user isn't aware of for
|
||||
* query-block (blk != NULL), but not for query-named-block-nodes
|
||||
*/
|
||||
bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
|
||||
if (*errp) {
|
||||
qapi_free_BlockDeviceInfo(info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bs0->drv && bdrv_filter_or_cow_child(bs0)) {
|
||||
/*
|
||||
* Put any filtered child here (for backwards compatibility to when
|
||||
* we put bs0->backing here, which might be any filtered child).
|
||||
*/
|
||||
info->backing_file_depth++;
|
||||
bs0 = bdrv_filter_or_cow_bs(bs0);
|
||||
p_image_info = &((*p_image_info)->backing_image);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skip automatically inserted nodes that the user isn't aware of for
|
||||
* query-block (blk != NULL), but not for query-named-block-nodes */
|
||||
if (blk) {
|
||||
bs0 = bdrv_skip_implicit_filters(bs0);
|
||||
}
|
||||
backing_info = info->image->backing_image;
|
||||
while (backing_info) {
|
||||
info->backing_file_depth++;
|
||||
backing_info = backing_info->backing_image;
|
||||
}
|
||||
|
||||
return info;
|
||||
@ -237,30 +223,18 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
||||
}
|
||||
|
||||
/**
|
||||
* bdrv_query_image_info:
|
||||
* @bs: block device to examine
|
||||
* @p_info: location to store image information
|
||||
* @errp: location to store error information
|
||||
*
|
||||
* Store "flat" image information in @p_info.
|
||||
*
|
||||
* "Flat" means it does *not* query backing image information,
|
||||
* i.e. (*pinfo)->has_backing_image will be set to false and
|
||||
* (*pinfo)->backing_image to NULL even when the image does in fact have
|
||||
* a backing image.
|
||||
*
|
||||
* @p_info will be set only on success. On error, store error in @errp.
|
||||
* Helper function for other query info functions. Store information about @bs
|
||||
* in @info, setting @errp on error.
|
||||
*/
|
||||
void bdrv_query_image_info(BlockDriverState *bs,
|
||||
ImageInfo **p_info,
|
||||
Error **errp)
|
||||
static void bdrv_do_query_node_info(BlockDriverState *bs,
|
||||
BlockNodeInfo *info,
|
||||
Error **errp)
|
||||
{
|
||||
int64_t size;
|
||||
const char *backing_filename;
|
||||
BlockDriverInfo bdi;
|
||||
int ret;
|
||||
Error *err = NULL;
|
||||
ImageInfo *info;
|
||||
|
||||
aio_context_acquire(bdrv_get_aio_context(bs));
|
||||
|
||||
@ -273,7 +247,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
|
||||
bdrv_refresh_filename(bs);
|
||||
|
||||
info = g_new0(ImageInfo, 1);
|
||||
info->filename = g_strdup(bs->filename);
|
||||
info->format = g_strdup(bdrv_get_format_name(bs));
|
||||
info->virtual_size = size;
|
||||
@ -294,7 +267,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
info->format_specific = bdrv_get_specific_info(bs, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
qapi_free_ImageInfo(info);
|
||||
goto out;
|
||||
}
|
||||
backing_filename = bs->backing_file;
|
||||
@ -330,16 +302,154 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
break;
|
||||
default:
|
||||
error_propagate(errp, err);
|
||||
qapi_free_ImageInfo(info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
*p_info = info;
|
||||
|
||||
out:
|
||||
aio_context_release(bdrv_get_aio_context(bs));
|
||||
}
|
||||
|
||||
/**
|
||||
* bdrv_query_block_node_info:
|
||||
* @bs: block node to examine
|
||||
* @p_info: location to store node information
|
||||
* @errp: location to store error information
|
||||
*
|
||||
* Store image information about @bs in @p_info.
|
||||
*
|
||||
* @p_info will be set only on success. On error, store error in @errp.
|
||||
*/
|
||||
void bdrv_query_block_node_info(BlockDriverState *bs,
|
||||
BlockNodeInfo **p_info,
|
||||
Error **errp)
|
||||
{
|
||||
BlockNodeInfo *info;
|
||||
ERRP_GUARD();
|
||||
|
||||
info = g_new0(BlockNodeInfo, 1);
|
||||
bdrv_do_query_node_info(bs, info, errp);
|
||||
if (*errp) {
|
||||
qapi_free_BlockNodeInfo(info);
|
||||
return;
|
||||
}
|
||||
|
||||
*p_info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* bdrv_query_image_info:
|
||||
* @bs: block node to examine
|
||||
* @p_info: location to store image information
|
||||
* @flat: skip backing node information
|
||||
* @skip_implicit_filters: skip implicit filters in the backing chain
|
||||
* @errp: location to store error information
|
||||
*
|
||||
* Store image information in @p_info, potentially recursively covering the
|
||||
* backing chain.
|
||||
*
|
||||
* If @flat is true, do not query backing image information, i.e.
|
||||
* (*p_info)->has_backing_image will be set to false and
|
||||
* (*p_info)->backing_image to NULL even when the image does in fact have a
|
||||
* backing image.
|
||||
*
|
||||
* If @skip_implicit_filters is true, implicit filter nodes in the backing chain
|
||||
* will be skipped when querying backing image information.
|
||||
* (@skip_implicit_filters is ignored when @flat is true.)
|
||||
*
|
||||
* @p_info will be set only on success. On error, store error in @errp.
|
||||
*/
|
||||
void bdrv_query_image_info(BlockDriverState *bs,
|
||||
ImageInfo **p_info,
|
||||
bool flat,
|
||||
bool skip_implicit_filters,
|
||||
Error **errp)
|
||||
{
|
||||
ImageInfo *info;
|
||||
ERRP_GUARD();
|
||||
|
||||
info = g_new0(ImageInfo, 1);
|
||||
bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!flat) {
|
||||
BlockDriverState *backing;
|
||||
|
||||
/*
|
||||
* Use any filtered child here (for backwards compatibility to when
|
||||
* we always took bs->backing, which might be any filtered child).
|
||||
*/
|
||||
backing = bdrv_filter_or_cow_bs(bs);
|
||||
if (skip_implicit_filters) {
|
||||
backing = bdrv_skip_implicit_filters(backing);
|
||||
}
|
||||
|
||||
if (backing) {
|
||||
bdrv_query_image_info(backing, &info->backing_image, false,
|
||||
skip_implicit_filters, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*p_info = info;
|
||||
return;
|
||||
|
||||
fail:
|
||||
assert(*errp);
|
||||
qapi_free_ImageInfo(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* bdrv_query_block_graph_info:
|
||||
* @bs: root node to start from
|
||||
* @p_info: location to store image information
|
||||
* @errp: location to store error information
|
||||
*
|
||||
* Store image information about the graph starting from @bs in @p_info.
|
||||
*
|
||||
* @p_info will be set only on success. On error, store error in @errp.
|
||||
*/
|
||||
void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||
BlockGraphInfo **p_info,
|
||||
Error **errp)
|
||||
{
|
||||
BlockGraphInfo *info;
|
||||
BlockChildInfoList **children_list_tail;
|
||||
BdrvChild *c;
|
||||
ERRP_GUARD();
|
||||
|
||||
info = g_new0(BlockGraphInfo, 1);
|
||||
bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
children_list_tail = &info->children;
|
||||
|
||||
QLIST_FOREACH(c, &bs->children, next) {
|
||||
BlockChildInfo *c_info;
|
||||
|
||||
c_info = g_new0(BlockChildInfo, 1);
|
||||
QAPI_LIST_APPEND(children_list_tail, c_info);
|
||||
|
||||
c_info->name = g_strdup(c->name);
|
||||
bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
*p_info = info;
|
||||
return;
|
||||
|
||||
fail:
|
||||
assert(*errp != NULL);
|
||||
qapi_free_BlockGraphInfo(info);
|
||||
}
|
||||
|
||||
/* @p_info will be set only on success. */
|
||||
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
|
||||
Error **errp)
|
||||
@ -759,7 +869,36 @@ static void dump_qdict(int indentation, QDict *dict)
|
||||
}
|
||||
}
|
||||
|
||||
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
|
||||
/*
|
||||
* Return whether dumping the given QObject with dump_qobject() would
|
||||
* yield an empty dump, i.e. not print anything.
|
||||
*/
|
||||
static bool qobject_is_empty_dump(const QObject *obj)
|
||||
{
|
||||
switch (qobject_type(obj)) {
|
||||
case QTYPE_QNUM:
|
||||
case QTYPE_QSTRING:
|
||||
case QTYPE_QBOOL:
|
||||
return false;
|
||||
|
||||
case QTYPE_QDICT:
|
||||
return qdict_size(qobject_to(QDict, obj)) == 0;
|
||||
|
||||
case QTYPE_QLIST:
|
||||
return qlist_empty(qobject_to(QList, obj));
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the given ImageInfoSpecific object in a human-readable form,
|
||||
* prepending an optional prefix if the dump is not empty.
|
||||
*/
|
||||
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||
const char *prefix,
|
||||
int indentation)
|
||||
{
|
||||
QObject *obj, *data;
|
||||
Visitor *v = qobject_output_visitor_new(&obj);
|
||||
@ -767,45 +906,78 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
|
||||
visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
|
||||
visit_complete(v, &obj);
|
||||
data = qdict_get(qobject_to(QDict, obj), "data");
|
||||
dump_qobject(1, data);
|
||||
if (!qobject_is_empty_dump(data)) {
|
||||
if (prefix) {
|
||||
qemu_printf("%*s%s", indentation * 4, "", prefix);
|
||||
}
|
||||
dump_qobject(indentation + 1, data);
|
||||
}
|
||||
qobject_unref(obj);
|
||||
visit_free(v);
|
||||
}
|
||||
|
||||
void bdrv_image_info_dump(ImageInfo *info)
|
||||
/**
|
||||
* Print the given @info object in human-readable form. Every field is indented
|
||||
* using the given @indentation (four spaces per indentation level).
|
||||
*
|
||||
* When using this to print a whole block graph, @protocol can be set to true to
|
||||
* signify that the given information is associated with a protocol node, i.e.
|
||||
* just data storage for an image, such that the data it presents is not really
|
||||
* a full VM disk. If so, several fields change name: For example, "virtual
|
||||
* size" is printed as "file length".
|
||||
* (Consider a qcow2 image, which is represented by a qcow2 node and a file
|
||||
* node. Printing a "virtual size" for the file node does not make sense,
|
||||
* because without the qcow2 node, it is not really a guest disk, so it does not
|
||||
* have a "virtual size". Therefore, we call it "file length" instead.)
|
||||
*
|
||||
* @protocol is ignored when @indentation is 0, because we take that to mean
|
||||
* that the associated node is the root node in the queried block graph, and
|
||||
* thus is always to be interpreted as a standalone guest disk.
|
||||
*/
|
||||
void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
|
||||
{
|
||||
char *size_buf, *dsize_buf;
|
||||
g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
|
||||
|
||||
if (indentation == 0) {
|
||||
/* Top level, consider this a normal image */
|
||||
protocol = false;
|
||||
}
|
||||
|
||||
if (!info->has_actual_size) {
|
||||
dsize_buf = g_strdup("unavailable");
|
||||
} else {
|
||||
dsize_buf = size_to_str(info->actual_size);
|
||||
}
|
||||
size_buf = size_to_str(info->virtual_size);
|
||||
qemu_printf("image: %s\n"
|
||||
"file format: %s\n"
|
||||
"virtual size: %s (%" PRId64 " bytes)\n"
|
||||
"disk size: %s\n",
|
||||
info->filename, info->format, size_buf,
|
||||
info->virtual_size,
|
||||
dsize_buf);
|
||||
qemu_printf("%s%s: %s\n"
|
||||
"%s%s: %s\n"
|
||||
"%s%s: %s (%" PRId64 " bytes)\n"
|
||||
"%sdisk size: %s\n",
|
||||
ind_s, protocol ? "filename" : "image", info->filename,
|
||||
ind_s, protocol ? "protocol type" : "file format",
|
||||
info->format,
|
||||
ind_s, protocol ? "file length" : "virtual size",
|
||||
size_buf, info->virtual_size,
|
||||
ind_s, dsize_buf);
|
||||
g_free(size_buf);
|
||||
g_free(dsize_buf);
|
||||
|
||||
if (info->has_encrypted && info->encrypted) {
|
||||
qemu_printf("encrypted: yes\n");
|
||||
qemu_printf("%sencrypted: yes\n", ind_s);
|
||||
}
|
||||
|
||||
if (info->has_cluster_size) {
|
||||
qemu_printf("cluster_size: %" PRId64 "\n",
|
||||
info->cluster_size);
|
||||
qemu_printf("%scluster_size: %" PRId64 "\n",
|
||||
ind_s, info->cluster_size);
|
||||
}
|
||||
|
||||
if (info->has_dirty_flag && info->dirty_flag) {
|
||||
qemu_printf("cleanly shut down: no\n");
|
||||
qemu_printf("%scleanly shut down: no\n", ind_s);
|
||||
}
|
||||
|
||||
if (info->backing_filename) {
|
||||
qemu_printf("backing file: %s", info->backing_filename);
|
||||
qemu_printf("%sbacking file: %s", ind_s, info->backing_filename);
|
||||
if (!info->full_backing_filename) {
|
||||
qemu_printf(" (cannot determine actual path)");
|
||||
} else if (strcmp(info->backing_filename,
|
||||
@ -814,15 +986,16 @@ void bdrv_image_info_dump(ImageInfo *info)
|
||||
}
|
||||
qemu_printf("\n");
|
||||
if (info->backing_filename_format) {
|
||||
qemu_printf("backing file format: %s\n",
|
||||
info->backing_filename_format);
|
||||
qemu_printf("%sbacking file format: %s\n",
|
||||
ind_s, info->backing_filename_format);
|
||||
}
|
||||
}
|
||||
|
||||
if (info->has_snapshots) {
|
||||
SnapshotInfoList *elem;
|
||||
|
||||
qemu_printf("Snapshot list:\n");
|
||||
qemu_printf("%sSnapshot list:\n", ind_s);
|
||||
qemu_printf("%s", ind_s);
|
||||
bdrv_snapshot_dump(NULL);
|
||||
qemu_printf("\n");
|
||||
|
||||
@ -842,13 +1015,15 @@ void bdrv_image_info_dump(ImageInfo *info)
|
||||
|
||||
pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
|
||||
pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
|
||||
qemu_printf("%s", ind_s);
|
||||
bdrv_snapshot_dump(&sn);
|
||||
qemu_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (info->format_specific) {
|
||||
qemu_printf("Format specific information:\n");
|
||||
bdrv_image_info_specific_dump(info->format_specific);
|
||||
bdrv_image_info_specific_dump(info->format_specific,
|
||||
"Format specific information:\n",
|
||||
indentation);
|
||||
}
|
||||
}
|
||||
|
15
block/qcow.c
15
block/qcow.c
@ -833,13 +833,13 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(qcow_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qcow_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
qcow_blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
qcow_blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
if (!qcow_blk) {
|
||||
ret = -EPERM;
|
||||
goto exit;
|
||||
@ -978,8 +978,8 @@ static int coroutine_fn qcow_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
@ -1129,7 +1129,8 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
qcow_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
bdi->cluster_size = s->cluster_size;
|
||||
@ -1198,7 +1199,7 @@ static BlockDriver bdrv_qcow = {
|
||||
|
||||
.bdrv_make_empty = qcow_make_empty,
|
||||
.bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,
|
||||
.bdrv_get_info = qcow_get_info,
|
||||
.bdrv_co_get_info = qcow_co_get_info,
|
||||
|
||||
.create_opts = &qcow_create_opts,
|
||||
.strong_runtime_opts = qcow_strong_runtime_opts,
|
||||
|
@ -26,6 +26,8 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
@ -115,7 +117,7 @@ static int update_header_sync(BlockDriverState *bs)
|
||||
return bdrv_flush(bs->file->bs);
|
||||
}
|
||||
|
||||
static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
|
||||
static inline void bitmap_table_bswap_be(uint64_t *bitmap_table, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@ -1401,9 +1403,10 @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bitmap_table_to_be(tb, tb_size);
|
||||
bitmap_table_bswap_be(tb, tb_size);
|
||||
ret = bdrv_pwrite(bs->file, tb_offset, tb_size * sizeof(tb[0]), tb, 0);
|
||||
if (ret < 0) {
|
||||
bitmap_table_bswap_be(tb, tb_size);
|
||||
error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
|
||||
bm_name);
|
||||
goto fail;
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "qemu/memalign.h"
|
||||
#include "qcow2.h"
|
||||
#include "trace.h"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include "block/block-io.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/bswap.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qcow2.h"
|
||||
#include "qemu/range.h"
|
||||
@ -3719,7 +3720,7 @@ int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs)
|
||||
return file_length;
|
||||
}
|
||||
|
||||
real_allocation = bdrv_get_allocated_file_size(bs->file->bs);
|
||||
real_allocation = bdrv_co_get_allocated_file_size(bs->file->bs);
|
||||
if (real_allocation < 0) {
|
||||
return real_allocation;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#include "qcow2.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/thread-pool.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "qapi/qapi-visit-block-core.h"
|
||||
#include "crypto.h"
|
||||
#include "block/aio_task.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
|
||||
/*
|
||||
Differences with QCOW:
|
||||
@ -1616,9 +1617,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||
|
||||
if (open_data_file) {
|
||||
/* Open external data file */
|
||||
s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
|
||||
&child_of_bds, BDRV_CHILD_DATA,
|
||||
true, errp);
|
||||
s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs,
|
||||
&child_of_bds, BDRV_CHILD_DATA,
|
||||
true, errp);
|
||||
if (*errp) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -1626,9 +1627,10 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
|
||||
|
||||
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
|
||||
if (!s->data_file && s->image_data_file) {
|
||||
s->data_file = bdrv_open_child(s->image_data_file, options,
|
||||
"data-file", bs, &child_of_bds,
|
||||
BDRV_CHILD_DATA, false, errp);
|
||||
s->data_file = bdrv_co_open_child(s->image_data_file, options,
|
||||
"data-file", bs,
|
||||
&child_of_bds,
|
||||
BDRV_CHILD_DATA, false, errp);
|
||||
if (!s->data_file) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
@ -3453,7 +3455,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
assert(create_options->driver == BLOCKDEV_DRIVER_QCOW2);
|
||||
qcow2_opts = &create_options->u.qcow2;
|
||||
|
||||
bs = bdrv_open_blockdev_ref(qcow2_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qcow2_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
@ -3595,7 +3597,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
data_bs = bdrv_open_blockdev_ref(qcow2_opts->data_file, errp);
|
||||
data_bs = bdrv_co_open_blockdev_ref(qcow2_opts->data_file, errp);
|
||||
if (data_bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3628,8 +3630,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -3711,9 +3713,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
if (data_bs) {
|
||||
qdict_put_str(options, "data-file", data_bs->node_name);
|
||||
}
|
||||
blk = blk_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
|
||||
errp);
|
||||
blk = blk_co_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
|
||||
errp);
|
||||
if (blk == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3792,9 +3794,9 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
|
||||
if (data_bs) {
|
||||
qdict_put_str(options, "data-file", data_bs->node_name);
|
||||
}
|
||||
blk = blk_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
|
||||
errp);
|
||||
blk = blk_co_new_open(NULL, NULL, options,
|
||||
BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
|
||||
errp);
|
||||
if (blk == NULL) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
@ -3876,8 +3878,8 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto finish;
|
||||
@ -3891,9 +3893,9 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
data_bs = bdrv_open(val, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
data_bs = bdrv_co_open(val, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,
|
||||
errp);
|
||||
if (data_bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto finish;
|
||||
@ -5142,7 +5144,8 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
qcow2_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
bdi->cluster_size = s->cluster_size;
|
||||
@ -5285,8 +5288,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
|
||||
return pos;
|
||||
}
|
||||
|
||||
static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs,
|
||||
QEMUIOVector *qiov, int64_t pos)
|
||||
static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
|
||||
QEMUIOVector *qiov, int64_t pos)
|
||||
{
|
||||
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||
if (offset < 0) {
|
||||
@ -5297,8 +5300,8 @@ static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs,
|
||||
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
|
||||
}
|
||||
|
||||
static coroutine_fn int qcow2_load_vmstate(BlockDriverState *bs,
|
||||
QEMUIOVector *qiov, int64_t pos)
|
||||
static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs,
|
||||
QEMUIOVector *qiov, int64_t pos)
|
||||
{
|
||||
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
|
||||
if (offset < 0) {
|
||||
@ -6076,11 +6079,11 @@ BlockDriver bdrv_qcow2 = {
|
||||
.bdrv_snapshot_list = qcow2_snapshot_list,
|
||||
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
|
||||
.bdrv_measure = qcow2_measure,
|
||||
.bdrv_get_info = qcow2_get_info,
|
||||
.bdrv_co_get_info = qcow2_co_get_info,
|
||||
.bdrv_get_specific_info = qcow2_get_specific_info,
|
||||
|
||||
.bdrv_save_vmstate = qcow2_save_vmstate,
|
||||
.bdrv_load_vmstate = qcow2_load_vmstate,
|
||||
.bdrv_co_save_vmstate = qcow2_co_save_vmstate,
|
||||
.bdrv_co_load_vmstate = qcow2_co_load_vmstate,
|
||||
|
||||
.is_format = true,
|
||||
.supports_backing = true,
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "qed.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "trace.h"
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "qed.h"
|
||||
|
21
block/qed.c
21
block/qed.c
@ -424,7 +424,7 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
|
||||
/* Round down file size to the last cluster */
|
||||
file_size = bdrv_getlength(bs->file->bs);
|
||||
file_size = bdrv_co_getlength(bs->file->bs);
|
||||
if (file_size < 0) {
|
||||
error_setg(errp, "Failed to get file length");
|
||||
return file_size;
|
||||
@ -676,13 +676,13 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs = bdrv_open_blockdev_ref(qed_opts->file, errp);
|
||||
bs = bdrv_co_open_blockdev_ref(qed_opts->file, errp);
|
||||
if (bs == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
blk = blk_co_new_with_bs(bs, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
@ -783,8 +783,8 @@ static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (bs == NULL) {
|
||||
ret = -EIO;
|
||||
goto fail;
|
||||
@ -1480,13 +1480,14 @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t bdrv_qed_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn bdrv_qed_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
return s->header.image_size;
|
||||
}
|
||||
|
||||
static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
bdrv_qed_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
|
||||
@ -1653,8 +1654,8 @@ static BlockDriver bdrv_qed = {
|
||||
.bdrv_co_writev = bdrv_qed_co_writev,
|
||||
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
|
||||
.bdrv_co_truncate = bdrv_qed_co_truncate,
|
||||
.bdrv_getlength = bdrv_qed_getlength,
|
||||
.bdrv_get_info = bdrv_qed_get_info,
|
||||
.bdrv_co_getlength = bdrv_qed_co_getlength,
|
||||
.bdrv_co_get_info = bdrv_qed_co_get_info,
|
||||
.bdrv_refresh_limits = bdrv_qed_refresh_limits,
|
||||
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
|
||||
.bdrv_co_invalidate_cache = bdrv_qed_co_invalidate_cache,
|
||||
|
@ -754,19 +754,19 @@ static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
flags | BDRV_REQ_ZERO_WRITE);
|
||||
}
|
||||
|
||||
static int64_t quorum_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVQuorumState *s = bs->opaque;
|
||||
int64_t result;
|
||||
int i;
|
||||
|
||||
/* check that all file have the same length */
|
||||
result = bdrv_getlength(s->children[0]->bs);
|
||||
result = bdrv_co_getlength(s->children[0]->bs);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
for (i = 1; i < s->num_children; i++) {
|
||||
int64_t value = bdrv_getlength(s->children[i]->bs);
|
||||
int64_t value = bdrv_co_getlength(s->children[i]->bs);
|
||||
if (value < 0) {
|
||||
return value;
|
||||
}
|
||||
@ -1283,7 +1283,7 @@ static BlockDriver bdrv_quorum = {
|
||||
|
||||
.bdrv_co_flush = quorum_co_flush,
|
||||
|
||||
.bdrv_getlength = quorum_getlength,
|
||||
.bdrv_co_getlength = quorum_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = quorum_co_preadv,
|
||||
.bdrv_co_pwritev = quorum_co_pwritev,
|
||||
|
@ -27,6 +27,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
@ -316,14 +317,14 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
|
||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
}
|
||||
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
int64_t len;
|
||||
BDRVRawState *s = bs->opaque;
|
||||
|
||||
/* Update size. It should not change unless the file was externally
|
||||
* modified. */
|
||||
len = bdrv_getlength(bs->file->bs);
|
||||
len = bdrv_co_getlength(bs->file->bs);
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
@ -367,9 +368,10 @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
|
||||
return info;
|
||||
}
|
||||
|
||||
static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
raw_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
return bdrv_get_info(bs->file->bs, bdi);
|
||||
return bdrv_co_get_info(bs->file->bs, bdi);
|
||||
}
|
||||
|
||||
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
@ -403,14 +405,14 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
|
||||
}
|
||||
|
||||
static void raw_eject(BlockDriverState *bs, bool eject_flag)
|
||||
static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
|
||||
{
|
||||
bdrv_eject(bs->file->bs, eject_flag);
|
||||
bdrv_co_eject(bs->file->bs, eject_flag);
|
||||
}
|
||||
|
||||
static void raw_lock_medium(BlockDriverState *bs, bool locked)
|
||||
static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
|
||||
{
|
||||
bdrv_lock_medium(bs->file->bs, locked);
|
||||
bdrv_co_lock_medium(bs->file->bs, locked);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_ioctl(BlockDriverState *bs,
|
||||
@ -621,16 +623,16 @@ BlockDriver bdrv_raw = {
|
||||
.bdrv_co_copy_range_from = &raw_co_copy_range_from,
|
||||
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
|
||||
.bdrv_co_truncate = &raw_co_truncate,
|
||||
.bdrv_getlength = &raw_getlength,
|
||||
.bdrv_co_getlength = &raw_co_getlength,
|
||||
.is_format = true,
|
||||
.has_variable_length = true,
|
||||
.bdrv_measure = &raw_measure,
|
||||
.bdrv_get_info = &raw_get_info,
|
||||
.bdrv_co_get_info = &raw_co_get_info,
|
||||
.bdrv_refresh_limits = &raw_refresh_limits,
|
||||
.bdrv_probe_blocksizes = &raw_probe_blocksizes,
|
||||
.bdrv_probe_geometry = &raw_probe_geometry,
|
||||
.bdrv_eject = &raw_eject,
|
||||
.bdrv_lock_medium = &raw_lock_medium,
|
||||
.bdrv_co_eject = &raw_co_eject,
|
||||
.bdrv_co_lock_medium = &raw_co_lock_medium,
|
||||
.bdrv_co_ioctl = &raw_co_ioctl,
|
||||
.create_opts = &raw_create_opts,
|
||||
.bdrv_has_zero_init = &raw_has_zero_init,
|
||||
|
10
block/rbd.c
10
block/rbd.c
@ -18,6 +18,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "crypto/secret.h"
|
||||
@ -1239,7 +1240,8 @@ coroutine_fn qemu_rbd_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
qemu_rbd_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
BDRVRBDState *s = bs->opaque;
|
||||
bdi->cluster_size = s->object_size;
|
||||
@ -1429,7 +1431,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int64_t qemu_rbd_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn qemu_rbd_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRBDState *s = bs->opaque;
|
||||
int r;
|
||||
@ -1650,10 +1652,10 @@ static BlockDriver bdrv_rbd = {
|
||||
.bdrv_co_create = qemu_rbd_co_create,
|
||||
.bdrv_co_create_opts = qemu_rbd_co_create_opts,
|
||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||
.bdrv_get_info = qemu_rbd_getinfo,
|
||||
.bdrv_co_get_info = qemu_rbd_co_get_info,
|
||||
.bdrv_get_specific_info = qemu_rbd_get_specific_info,
|
||||
.create_opts = &qemu_rbd_create_opts,
|
||||
.bdrv_getlength = qemu_rbd_getlength,
|
||||
.bdrv_co_getlength = qemu_rbd_co_getlength,
|
||||
.bdrv_co_truncate = qemu_rbd_co_truncate,
|
||||
.protocol_name = "rbd",
|
||||
|
||||
|
@ -179,9 +179,9 @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
|
||||
return;
|
||||
}
|
||||
|
||||
static int64_t replication_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static int replication_get_io_status(BDRVReplicationState *s)
|
||||
@ -758,7 +758,7 @@ static BlockDriver bdrv_replication = {
|
||||
.bdrv_close = replication_close,
|
||||
.bdrv_child_perm = replication_child_perm,
|
||||
|
||||
.bdrv_getlength = replication_getlength,
|
||||
.bdrv_co_getlength = replication_co_getlength,
|
||||
.bdrv_co_readv = replication_co_readv,
|
||||
.bdrv_co_writev = replication_co_writev,
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qdict.h"
|
||||
#include "qapi/error.h"
|
||||
@ -1252,7 +1253,7 @@ static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t ssh_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn ssh_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVSSHState *s = bs->opaque;
|
||||
int64_t length;
|
||||
@ -1363,7 +1364,7 @@ static BlockDriver bdrv_ssh = {
|
||||
.bdrv_has_zero_init = ssh_has_zero_init,
|
||||
.bdrv_co_readv = ssh_co_readv,
|
||||
.bdrv_co_writev = ssh_co_writev,
|
||||
.bdrv_getlength = ssh_getlength,
|
||||
.bdrv_co_getlength = ssh_co_getlength,
|
||||
.bdrv_co_truncate = ssh_co_truncate,
|
||||
.bdrv_co_flush_to_disk = ssh_co_flush,
|
||||
.bdrv_refresh_filename = ssh_refresh_filename,
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/throttle-groups.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
@ -104,9 +106,9 @@ static void throttle_close(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
|
||||
static int64_t throttle_getlength(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file->bs);
|
||||
return bdrv_co_getlength(bs->file->bs);
|
||||
}
|
||||
|
||||
static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
|
||||
@ -245,7 +247,7 @@ static BlockDriver bdrv_throttle = {
|
||||
|
||||
.bdrv_child_perm = bdrv_default_perms,
|
||||
|
||||
.bdrv_getlength = throttle_getlength,
|
||||
.bdrv_co_getlength = throttle_co_getlength,
|
||||
|
||||
.bdrv_co_preadv = throttle_co_preadv,
|
||||
.bdrv_co_pwritev = throttle_co_pwritev,
|
||||
|
17
block/vdi.c
17
block/vdi.c
@ -327,9 +327,10 @@ static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vdi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
static int coroutine_fn
|
||||
vdi_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||
{
|
||||
/* TODO: vdi_get_info would be needed for machine snapshots.
|
||||
/* TODO: vdi_co_get_info would be needed for machine snapshots.
|
||||
vm_state_offset is still missing. */
|
||||
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
|
||||
logout("\n");
|
||||
@ -799,14 +800,14 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
|
||||
}
|
||||
|
||||
/* Create BlockBackend to write to the image */
|
||||
bs_file = bdrv_open_blockdev_ref(vdi_opts->file, errp);
|
||||
bs_file = bdrv_co_open_blockdev_ref(vdi_opts->file, errp);
|
||||
if (!bs_file) {
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
blk = blk_new_with_bs(bs_file, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
blk = blk_co_new_with_bs(bs_file, BLK_PERM_WRITE | BLK_PERM_RESIZE,
|
||||
BLK_PERM_ALL, errp);
|
||||
if (!blk) {
|
||||
ret = -EPERM;
|
||||
goto exit;
|
||||
@ -939,8 +940,8 @@ static int coroutine_fn vdi_co_create_opts(BlockDriver *drv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
bs_file = bdrv_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
bs_file = bdrv_co_open(filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp);
|
||||
if (!bs_file) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
@ -1049,7 +1050,7 @@ static BlockDriver bdrv_vdi = {
|
||||
.bdrv_co_pwritev = vdi_co_pwritev,
|
||||
#endif
|
||||
|
||||
.bdrv_get_info = vdi_get_info,
|
||||
.bdrv_co_get_info = vdi_co_get_info,
|
||||
|
||||
.is_format = true,
|
||||
.create_opts = &vdi_create_opts,
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "block/block-io.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/bswap.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user