mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'origin/master' into xbox
Conflicts: hw/pci/pci_ids.h
This commit is contained in:
commit
f5a5856665
|
@ -1,5 +1,6 @@
|
|||
config-devices.*
|
||||
config-all-devices.*
|
||||
config-all-disas.*
|
||||
config-host.*
|
||||
config-target.*
|
||||
trace.h
|
||||
|
@ -47,6 +48,7 @@ test-qmp-output-visitor
|
|||
test-string-input-visitor
|
||||
test-string-output-visitor
|
||||
test-visitor-serialization
|
||||
fsdev/virtfs-proxy-helper
|
||||
fsdev/virtfs-proxy-helper.1
|
||||
fsdev/virtfs-proxy-helper.pod
|
||||
.gdbinit
|
||||
|
|
20
HACKING
20
HACKING
|
@ -123,3 +123,23 @@ gcc's printf attribute directive in the prototype.
|
|||
This makes it so gcc's -Wformat and -Wformat-security options can do
|
||||
their jobs and cross-check format strings with the number and types
|
||||
of arguments.
|
||||
|
||||
6. C standard, implementation defined and undefined behaviors
|
||||
|
||||
C code in QEMU should be written to the C99 language specification. A copy
|
||||
of the final version of the C99 standard with corrigenda TC1, TC2, and TC3
|
||||
included, formatted as a draft, can be downloaded from:
|
||||
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
|
||||
|
||||
The C language specification defines regions of undefined behavior and
|
||||
implementation defined behavior (to give compiler authors enough leeway to
|
||||
produce better code). In general, code in QEMU should follow the language
|
||||
specification and avoid both undefined and implementation defined
|
||||
constructs. ("It works fine on the gcc I tested it with" is not a valid
|
||||
argument...) However there are a few areas where we allow ourselves to
|
||||
assume certain behaviors because in practice all the platforms we care about
|
||||
behave in the same way and writing strictly conformant code would be
|
||||
painful. These are:
|
||||
* you may assume that integers are 2s complement representation
|
||||
* you may assume that right shift of a signed integer duplicates
|
||||
the sign bit (ie it is an arithmetic shift, not a logical shift)
|
||||
|
|
|
@ -490,6 +490,7 @@ F: hw/omap*
|
|||
PCI
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
F: hw/pci/*
|
||||
F: hw/pci*
|
||||
F: hw/piix*
|
||||
|
||||
|
|
47
Makefile
47
Makefile
|
@ -99,6 +99,7 @@ defconfig:
|
|||
rm -f config-all-devices.mak $(SUBDIR_DEVICES_MAK)
|
||||
|
||||
-include config-all-devices.mak
|
||||
-include config-all-disas.mak
|
||||
|
||||
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all
|
||||
|
||||
|
@ -129,9 +130,9 @@ $(SRC_PATH)/pixman/configure:
|
|||
|
||||
$(SUBDIR_RULES): libqemustub.a
|
||||
|
||||
$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) subdir-libdis
|
||||
$(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y)
|
||||
|
||||
$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
|
||||
$(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(user-obj-y)
|
||||
|
||||
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
|
||||
romsubdir-%:
|
||||
|
@ -141,18 +142,6 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
|
|||
|
||||
recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
|
||||
|
||||
audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
|
||||
|
||||
QEMU_CFLAGS+=$(CURL_CFLAGS)
|
||||
|
||||
QEMU_CFLAGS += -I$(SRC_PATH)/include
|
||||
|
||||
ui/cocoa.o: ui/cocoa.m
|
||||
|
||||
ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o hw/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
|
||||
|
||||
ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
|
||||
|
||||
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
|
||||
|
||||
version.o: $(SRC_PATH)/version.rc config-host.h
|
||||
|
@ -169,19 +158,11 @@ libqemustub.a: $(stub-obj-y)
|
|||
# Support building shared library libcacard
|
||||
|
||||
.PHONY: libcacard.la install-libcacard
|
||||
ifeq ($(LIBTOOL),)
|
||||
libcacard.la:
|
||||
@echo "libtool is missing, please install and rerun configure"; exit 1
|
||||
|
||||
install-libcacard:
|
||||
@echo "libtool is missing, please install and rerun configure"; exit 1
|
||||
else
|
||||
libcacard.la: $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
|
||||
libcacard.la: $(oslib-obj-y) qemu-timer-common.o $(trace-obj-y)
|
||||
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,)
|
||||
|
||||
install-libcacard: libcacard.la
|
||||
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,)
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
||||
|
@ -197,8 +178,9 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
|
|||
|
||||
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
|
||||
|
||||
vscclient$(EXESUF): LIBS += $(libcacard_libs)
|
||||
vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o libqemustub.a
|
||||
$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS)," LINK $@")
|
||||
$(call LINK, $^)
|
||||
|
||||
fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o oslib-posix.o $(trace-obj-y)
|
||||
fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
|
||||
|
@ -218,13 +200,13 @@ endif
|
|||
qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
|
||||
|
||||
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
|
||||
$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
||||
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
|
||||
$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
||||
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
|
||||
$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
||||
|
||||
qapi-types.c qapi-types.h :\
|
||||
|
@ -240,9 +222,8 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
|||
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
|
||||
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
|
||||
|
||||
qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(oslib-obj-y) $(trace-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) libqemustub.a
|
||||
|
||||
QEMULIBS=libuser libdis libdis-user
|
||||
qemu-ga$(EXESUF): $(qga-obj-y) $(oslib-obj-y) $(trace-obj-y) $(qapi-obj-y) $(qobject-obj-y) $(version-obj-y) libqemustub.a
|
||||
$(call LINK, $^)
|
||||
|
||||
clean:
|
||||
# avoid old build problems by removing potentially incorrect old files
|
||||
|
@ -260,7 +241,7 @@ clean:
|
|||
rm -rf qapi-generated
|
||||
rm -rf qga/qapi-generated
|
||||
$(MAKE) -C tests/tcg clean
|
||||
for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
|
||||
for d in $(ALL_SUBDIRS) libcacard; do \
|
||||
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
|
||||
rm -f $$d/qemu-options.def; \
|
||||
done
|
||||
|
@ -274,7 +255,7 @@ qemu-%.tar.bz2:
|
|||
|
||||
distclean: clean
|
||||
rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi
|
||||
rm -f config-all-devices.mak
|
||||
rm -f config-all-devices.mak config-all-disas.mak
|
||||
rm -f roms/seabios/config.mak roms/vgabios/config.mak
|
||||
rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps qemu-doc.dvi
|
||||
rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
|
||||
|
@ -283,7 +264,7 @@ distclean: clean
|
|||
rm -f config.log
|
||||
rm -f linux-headers/asm
|
||||
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
|
||||
for d in $(TARGET_DIRS) $(QEMULIBS); do \
|
||||
for d in $(TARGET_DIRS); do \
|
||||
rm -rf $$d || exit 1 ; \
|
||||
done
|
||||
if test -f pixman/config.log; then make -C pixman distclean; fi
|
||||
|
|
20
Makefile.dis
20
Makefile.dis
|
@ -1,20 +0,0 @@
|
|||
# Makefile for disassemblers.
|
||||
|
||||
include ../config-host.mak
|
||||
include config.mak
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
.PHONY: all
|
||||
|
||||
$(call set-vpath, $(SRC_PATH))
|
||||
|
||||
QEMU_CFLAGS+=-I..
|
||||
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
|
||||
all: $(libdis-y)
|
||||
# Dummy command so that make thinks it has done something
|
||||
@true
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.a *~
|
|
@ -66,10 +66,9 @@ endif
|
|||
# single QEMU executable should support all CPUs and machines.
|
||||
|
||||
common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
|
||||
common-obj-y += net.o net/
|
||||
common-obj-y += net/
|
||||
common-obj-y += qom/
|
||||
common-obj-y += readline.o console.o cursor.o
|
||||
common-obj-y += qemu-pixman.o
|
||||
common-obj-y += readline.o
|
||||
common-obj-y += $(oslib-obj-y)
|
||||
common-obj-$(CONFIG_WIN32) += os-win32.o
|
||||
common-obj-$(CONFIG_POSIX) += os-posix.o
|
||||
|
@ -78,8 +77,8 @@ common-obj-$(CONFIG_LINUX) += fsdev/
|
|||
extra-obj-$(CONFIG_LINUX) += fsdev/
|
||||
|
||||
common-obj-y += tcg-runtime.o host-utils.o main-loop.o
|
||||
common-obj-y += input.o
|
||||
common-obj-y += buffered_file.o migration.o migration-tcp.o
|
||||
common-obj-y += migration.o migration-tcp.o
|
||||
common-obj-y += migration.o migration-tcp.o
|
||||
common-obj-y += qemu-char.o #aio.o
|
||||
common-obj-y += block-migration.o iohandler.o
|
||||
common-obj-y += bitmap.o bitops.o
|
||||
|
@ -92,6 +91,8 @@ common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
|
|||
|
||||
common-obj-y += audio/
|
||||
common-obj-y += hw/
|
||||
extra-obj-y += hw/
|
||||
|
||||
common-obj-y += ui/
|
||||
common-obj-y += bt-host.o bt-vhci.o
|
||||
|
||||
|
@ -121,28 +122,13 @@ user-obj-y += tcg-runtime.o host-utils.o
|
|||
user-obj-y += cache-utils.o
|
||||
user-obj-y += module.o
|
||||
user-obj-y += qemu-user.o
|
||||
user-obj-y += $(trace-obj-y)
|
||||
user-obj-y += qom/
|
||||
|
||||
######################################################################
|
||||
# libdis
|
||||
# disassemblers
|
||||
# NOTE: the disassembler code is only needed for debugging
|
||||
|
||||
libdis-y =
|
||||
libdis-$(CONFIG_ALPHA_DIS) += alpha-dis.o
|
||||
libdis-$(CONFIG_ARM_DIS) += arm-dis.o
|
||||
libdis-$(CONFIG_CRIS_DIS) += cris-dis.o
|
||||
libdis-$(CONFIG_HPPA_DIS) += hppa-dis.o
|
||||
libdis-$(CONFIG_I386_DIS) += i386-dis.o
|
||||
libdis-$(CONFIG_IA64_DIS) += ia64-dis.o
|
||||
libdis-$(CONFIG_M68K_DIS) += m68k-dis.o
|
||||
libdis-$(CONFIG_MICROBLAZE_DIS) += microblaze-dis.o
|
||||
libdis-$(CONFIG_MIPS_DIS) += mips-dis.o
|
||||
libdis-$(CONFIG_PPC_DIS) += ppc-dis.o
|
||||
libdis-$(CONFIG_S390_DIS) += s390-dis.o
|
||||
libdis-$(CONFIG_SH4_DIS) += sh4-dis.o
|
||||
libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
|
||||
libdis-$(CONFIG_LM32_DIS) += lm32-dis.o
|
||||
universal-obj-y += disas/
|
||||
|
||||
######################################################################
|
||||
# trace
|
||||
|
@ -208,6 +194,8 @@ trace-obj-y += trace/control.o
|
|||
|
||||
$(trace-obj-y): $(GENERATED_HEADERS)
|
||||
|
||||
universal-obj-y += $(trace-obj-y)
|
||||
|
||||
######################################################################
|
||||
# smartcard
|
||||
|
||||
|
@ -233,7 +221,7 @@ universal-obj-y += $(qapi-obj-y)
|
|||
######################################################################
|
||||
# guest agent
|
||||
|
||||
qga-obj-y = qga/ qemu-ga.o module.o qemu-tool.o
|
||||
qga-obj-y = qga/ module.o qemu-tool.o
|
||||
qga-obj-$(CONFIG_POSIX) += qemu-sockets.o qemu-option.o
|
||||
|
||||
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
||||
|
@ -250,5 +238,6 @@ nested-vars += \
|
|||
block-obj-y \
|
||||
user-obj-y \
|
||||
common-obj-y \
|
||||
universal-obj-y \
|
||||
extra-obj-y
|
||||
dummy := $(call unnest-vars)
|
||||
|
|
|
@ -70,9 +70,8 @@ obj-y = exec.o translate-all.o cpu-exec.o
|
|||
obj-y += tcg/tcg.o tcg/optimize.o
|
||||
obj-$(CONFIG_TCG_INTERPRETER) += tci.o
|
||||
obj-y += fpu/softfloat.o
|
||||
obj-y += disas.o
|
||||
obj-$(CONFIG_TCI_DIS) += tci-dis.o
|
||||
obj-y += target-$(TARGET_BASE_ARCH)/
|
||||
obj-y += disas.o
|
||||
obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
|
||||
|
||||
tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci
|
||||
|
@ -121,11 +120,6 @@ obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
|
|||
obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o
|
||||
LIBS+=-lz
|
||||
|
||||
QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
|
||||
QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
|
||||
QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
|
||||
QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
|
||||
|
||||
# xen support
|
||||
obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o
|
||||
obj-$(CONFIG_NO_XEN) += xen-stub.o
|
||||
|
@ -156,11 +150,8 @@ all-obj-y += $(addprefix ../, $(universal-obj-y))
|
|||
|
||||
ifdef CONFIG_SOFTMMU
|
||||
all-obj-y += $(addprefix ../, $(common-obj-y))
|
||||
all-obj-y += $(addprefix ../libdis/, $(libdis-y))
|
||||
all-obj-y += $(addprefix ../, $(trace-obj-y))
|
||||
else
|
||||
all-obj-y += $(addprefix ../libuser/, $(user-obj-y))
|
||||
all-obj-y += $(addprefix ../libdis-user/, $(libdis-y))
|
||||
all-obj-y += $(addprefix ../, $(user-obj-y))
|
||||
endif #CONFIG_LINUX_USER
|
||||
|
||||
ifdef QEMU_PROGW
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# Makefile for qemu target independent user files.
|
||||
|
||||
include ../config-host.mak
|
||||
include $(SRC_PATH)/rules.mak
|
||||
-include config.mak
|
||||
|
||||
.PHONY: all
|
||||
|
||||
$(call set-vpath, $(SRC_PATH))
|
||||
|
||||
QEMU_CFLAGS+=-I..
|
||||
QEMU_CFLAGS += -I$(SRC_PATH)/include
|
||||
QEMU_CFLAGS += -DCONFIG_USER_ONLY
|
||||
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
|
||||
all: $(user-obj-y)
|
||||
# Dummy command so that make thinks it has done something
|
||||
@true
|
||||
|
||||
clean:
|
||||
for d in . trace; do \
|
||||
rm -f $$d/*.o $$d/*.d $$d/*.a $$d/*~; \
|
||||
done
|
430
a.out.h
430
a.out.h
|
@ -1,430 +0,0 @@
|
|||
/* a.out.h
|
||||
|
||||
Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _A_OUT_H_
|
||||
#define _A_OUT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define COFF_IMAGE_WITH_PE
|
||||
#define COFF_LONG_SECTION_NAMES
|
||||
|
||||
/*** coff information for Intel 386/486. */
|
||||
|
||||
|
||||
/********************** FILE HEADER **********************/
|
||||
|
||||
struct external_filehdr {
|
||||
short f_magic; /* magic number */
|
||||
short f_nscns; /* number of sections */
|
||||
host_ulong f_timdat; /* time & date stamp */
|
||||
host_ulong f_symptr; /* file pointer to symtab */
|
||||
host_ulong f_nsyms; /* number of symtab entries */
|
||||
short f_opthdr; /* sizeof(optional hdr) */
|
||||
short f_flags; /* flags */
|
||||
};
|
||||
|
||||
/* Bits for f_flags:
|
||||
* F_RELFLG relocation info stripped from file
|
||||
* F_EXEC file is executable (no unresolved external references)
|
||||
* F_LNNO line numbers stripped from file
|
||||
* F_LSYMS local symbols stripped from file
|
||||
* F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
|
||||
*/
|
||||
|
||||
#define F_RELFLG (0x0001)
|
||||
#define F_EXEC (0x0002)
|
||||
#define F_LNNO (0x0004)
|
||||
#define F_LSYMS (0x0008)
|
||||
|
||||
|
||||
|
||||
#define I386MAGIC 0x14c
|
||||
#define I386PTXMAGIC 0x154
|
||||
#define I386AIXMAGIC 0x175
|
||||
|
||||
/* This is Lynx's all-platform magic number for executables. */
|
||||
|
||||
#define LYNXCOFFMAGIC 0415
|
||||
|
||||
#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
|
||||
&& (x).f_magic != I386AIXMAGIC \
|
||||
&& (x).f_magic != I386PTXMAGIC \
|
||||
&& (x).f_magic != LYNXCOFFMAGIC)
|
||||
|
||||
#define FILHDR struct external_filehdr
|
||||
#define FILHSZ 20
|
||||
|
||||
|
||||
/********************** AOUT "OPTIONAL HEADER"=
|
||||
**********************/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short magic; /* type of file */
|
||||
unsigned short vstamp; /* version stamp */
|
||||
host_ulong tsize; /* text size in bytes, padded to FW bdry*/
|
||||
host_ulong dsize; /* initialized data " " */
|
||||
host_ulong bsize; /* uninitialized data " " */
|
||||
host_ulong entry; /* entry pt. */
|
||||
host_ulong text_start; /* base of text used for this file */
|
||||
host_ulong data_start; /* base of data used for this file=
|
||||
*/
|
||||
}
|
||||
AOUTHDR;
|
||||
|
||||
#define AOUTSZ 28
|
||||
#define AOUTHDRSZ 28
|
||||
|
||||
#define OMAGIC 0404 /* object files, eg as output */
|
||||
#define ZMAGIC 0413 /* demand load format, eg normal ld output */
|
||||
#define STMAGIC 0401 /* target shlib */
|
||||
#define SHMAGIC 0443 /* host shlib */
|
||||
|
||||
|
||||
/* define some NT default values */
|
||||
/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
|
||||
#define NT_SECTION_ALIGNMENT 0x1000
|
||||
#define NT_FILE_ALIGNMENT 0x200
|
||||
#define NT_DEF_RESERVE 0x100000
|
||||
#define NT_DEF_COMMIT 0x1000
|
||||
|
||||
/********************** SECTION HEADER **********************/
|
||||
|
||||
|
||||
struct external_scnhdr {
|
||||
char s_name[8]; /* section name */
|
||||
host_ulong s_paddr; /* physical address, offset
|
||||
of last addr in scn */
|
||||
host_ulong s_vaddr; /* virtual address */
|
||||
host_ulong s_size; /* section size */
|
||||
host_ulong s_scnptr; /* file ptr to raw data for section */
|
||||
host_ulong s_relptr; /* file ptr to relocation */
|
||||
host_ulong s_lnnoptr; /* file ptr to line numbers */
|
||||
unsigned short s_nreloc; /* number of relocation entries */
|
||||
unsigned short s_nlnno; /* number of line number entries*/
|
||||
host_ulong s_flags; /* flags */
|
||||
};
|
||||
|
||||
#define SCNHDR struct external_scnhdr
|
||||
#define SCNHSZ 40
|
||||
|
||||
/*
|
||||
* names of "special" sections
|
||||
*/
|
||||
#define _TEXT ".text"
|
||||
#define _DATA ".data"
|
||||
#define _BSS ".bss"
|
||||
#define _COMMENT ".comment"
|
||||
#define _LIB ".lib"
|
||||
|
||||
/********************** LINE NUMBERS **********************/
|
||||
|
||||
/* 1 line number entry for every "breakpointable" source line in a section.
|
||||
* Line numbers are grouped on a per function basis; first entry in a function
|
||||
* grouping will have l_lnno = 0 and in place of physical address will be the
|
||||
* symbol table index of the function name.
|
||||
*/
|
||||
struct external_lineno {
|
||||
union {
|
||||
host_ulong l_symndx; /* function name symbol index, iff l_lnno 0 */
|
||||
host_ulong l_paddr; /* (physical) address of line number */
|
||||
} l_addr;
|
||||
unsigned short l_lnno; /* line number */
|
||||
};
|
||||
|
||||
#define LINENO struct external_lineno
|
||||
#define LINESZ 6
|
||||
|
||||
/********************** SYMBOLS **********************/
|
||||
|
||||
#define E_SYMNMLEN 8 /* # characters in a symbol name */
|
||||
#define E_FILNMLEN 14 /* # characters in a file name */
|
||||
#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
|
||||
|
||||
struct QEMU_PACKED external_syment
|
||||
{
|
||||
union {
|
||||
char e_name[E_SYMNMLEN];
|
||||
struct {
|
||||
host_ulong e_zeroes;
|
||||
host_ulong e_offset;
|
||||
} e;
|
||||
} e;
|
||||
host_ulong e_value;
|
||||
unsigned short e_scnum;
|
||||
unsigned short e_type;
|
||||
char e_sclass[1];
|
||||
char e_numaux[1];
|
||||
};
|
||||
|
||||
#define N_BTMASK (0xf)
|
||||
#define N_TMASK (0x30)
|
||||
#define N_BTSHFT (4)
|
||||
#define N_TSHIFT (2)
|
||||
|
||||
union external_auxent {
|
||||
struct {
|
||||
host_ulong x_tagndx; /* str, un, or enum tag indx */
|
||||
union {
|
||||
struct {
|
||||
unsigned short x_lnno; /* declaration line number */
|
||||
unsigned short x_size; /* str/union/array size */
|
||||
} x_lnsz;
|
||||
host_ulong x_fsize; /* size of function */
|
||||
} x_misc;
|
||||
union {
|
||||
struct { /* if ISFCN, tag, or .bb */
|
||||
host_ulong x_lnnoptr;/* ptr to fcn line # */
|
||||
host_ulong x_endndx; /* entry ndx past block end */
|
||||
} x_fcn;
|
||||
struct { /* if ISARY, up to 4 dimen. */
|
||||
char x_dimen[E_DIMNUM][2];
|
||||
} x_ary;
|
||||
} x_fcnary;
|
||||
unsigned short x_tvndx; /* tv index */
|
||||
} x_sym;
|
||||
|
||||
union {
|
||||
char x_fname[E_FILNMLEN];
|
||||
struct {
|
||||
host_ulong x_zeroes;
|
||||
host_ulong x_offset;
|
||||
} x_n;
|
||||
} x_file;
|
||||
|
||||
struct {
|
||||
host_ulong x_scnlen; /* section length */
|
||||
unsigned short x_nreloc; /* # relocation entries */
|
||||
unsigned short x_nlinno; /* # line numbers */
|
||||
host_ulong x_checksum; /* section COMDAT checksum */
|
||||
unsigned short x_associated;/* COMDAT associated section index */
|
||||
char x_comdat[1]; /* COMDAT selection number */
|
||||
} x_scn;
|
||||
|
||||
struct {
|
||||
host_ulong x_tvfill; /* tv fill value */
|
||||
unsigned short x_tvlen; /* length of .tv */
|
||||
char x_tvran[2][2]; /* tv range */
|
||||
} x_tv; /* info about .tv section (in auxent of symbol .tv)) */
|
||||
|
||||
};
|
||||
|
||||
#define SYMENT struct external_syment
|
||||
#define SYMESZ 18
|
||||
#define AUXENT union external_auxent
|
||||
#define AUXESZ 18
|
||||
|
||||
#define _ETEXT "etext"
|
||||
|
||||
/********************** RELOCATION DIRECTIVES **********************/
|
||||
|
||||
struct external_reloc {
|
||||
char r_vaddr[4];
|
||||
char r_symndx[4];
|
||||
char r_type[2];
|
||||
};
|
||||
|
||||
#define RELOC struct external_reloc
|
||||
#define RELSZ 10
|
||||
|
||||
/* end of coff/i386.h */
|
||||
|
||||
/* PE COFF header information */
|
||||
|
||||
#ifndef _PE_H
|
||||
#define _PE_H
|
||||
|
||||
/* NT specific file attributes */
|
||||
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
|
||||
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
|
||||
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
|
||||
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
|
||||
#define IMAGE_FILE_32BIT_MACHINE 0x0100
|
||||
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
|
||||
#define IMAGE_FILE_SYSTEM 0x1000
|
||||
#define IMAGE_FILE_DLL 0x2000
|
||||
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
|
||||
|
||||
/* additional flags to be set for section headers to allow the NT loader to
|
||||
read and write to the section data (to replace the addresses of data in
|
||||
dlls for one thing); also to execute the section in .text's case=
|
||||
*/
|
||||
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
/*
|
||||
* Section characteristics added for ppc-nt
|
||||
*/
|
||||
|
||||
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
|
||||
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
|
||||
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
|
||||
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
|
||||
|
||||
#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
|
||||
#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
|
||||
#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
|
||||
#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
|
||||
|
||||
#define IMAGE_SCN_MEM_FARDATA 0x00008000
|
||||
|
||||
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
|
||||
#define IMAGE_SCN_MEM_16BIT 0x00020000
|
||||
#define IMAGE_SCN_MEM_LOCKED 0x00040000
|
||||
#define IMAGE_SCN_MEM_PRELOAD 0x00080000
|
||||
|
||||
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
|
||||
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
|
||||
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
|
||||
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
|
||||
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
|
||||
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
|
||||
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
|
||||
|
||||
|
||||
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
|
||||
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
|
||||
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
|
||||
#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
|
||||
|
||||
/* COMDAT selection codes. */
|
||||
|
||||
#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
|
||||
#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
|
||||
#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
|
||||
#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
|
||||
#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
|
||||
|
||||
/* Magic values that are true for all dos/nt implementations */
|
||||
#define DOSMAGIC 0x5a4d
|
||||
#define NT_SIGNATURE 0x00004550
|
||||
|
||||
/* NT allows long filenames, we want to accommodate this. This may break
|
||||
some of the bfd functions */
|
||||
#undef FILNMLEN
|
||||
#define FILNMLEN 18 /* # characters in a file name */
|
||||
|
||||
|
||||
#ifdef COFF_IMAGE_WITH_PE
|
||||
/* The filehdr is only weired in images */
|
||||
|
||||
#undef FILHDR
|
||||
struct external_PE_filehdr
|
||||
{
|
||||
/* DOS header fields */
|
||||
unsigned short e_magic; /* Magic number, 0x5a4d */
|
||||
unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
|
||||
unsigned short e_cp; /* Pages in file, 0x3 */
|
||||
unsigned short e_crlc; /* Relocations, 0x0 */
|
||||
unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
|
||||
unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
|
||||
unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
|
||||
unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
|
||||
unsigned short e_sp; /* Initial SP value, 0xb8 */
|
||||
unsigned short e_csum; /* Checksum, 0x0 */
|
||||
unsigned short e_ip; /* Initial IP value, 0x0 */
|
||||
unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
|
||||
unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
|
||||
unsigned short e_ovno; /* Overlay number, 0x0 */
|
||||
char e_res[4][2]; /* Reserved words, all 0x0 */
|
||||
unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
|
||||
unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
|
||||
char e_res2[10][2]; /* Reserved words, all 0x0 */
|
||||
host_ulong e_lfanew; /* File address of new exe header, 0x80 */
|
||||
char dos_message[16][4]; /* other stuff, always follow DOS header */
|
||||
unsigned int nt_signature; /* required NT signature, 0x4550 */
|
||||
|
||||
/* From standard header */
|
||||
|
||||
unsigned short f_magic; /* magic number */
|
||||
unsigned short f_nscns; /* number of sections */
|
||||
host_ulong f_timdat; /* time & date stamp */
|
||||
host_ulong f_symptr; /* file pointer to symtab */
|
||||
host_ulong f_nsyms; /* number of symtab entries */
|
||||
unsigned short f_opthdr; /* sizeof(optional hdr) */
|
||||
unsigned short f_flags; /* flags */
|
||||
};
|
||||
|
||||
|
||||
#define FILHDR struct external_PE_filehdr
|
||||
#undef FILHSZ
|
||||
#define FILHSZ 152
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short magic; /* type of file */
|
||||
unsigned short vstamp; /* version stamp */
|
||||
host_ulong tsize; /* text size in bytes, padded to FW bdry*/
|
||||
host_ulong dsize; /* initialized data " " */
|
||||
host_ulong bsize; /* uninitialized data " " */
|
||||
host_ulong entry; /* entry pt. */
|
||||
host_ulong text_start; /* base of text used for this file */
|
||||
host_ulong data_start; /* base of all data used for this file */
|
||||
|
||||
/* NT extra fields; see internal.h for descriptions */
|
||||
host_ulong ImageBase;
|
||||
host_ulong SectionAlignment;
|
||||
host_ulong FileAlignment;
|
||||
unsigned short MajorOperatingSystemVersion;
|
||||
unsigned short MinorOperatingSystemVersion;
|
||||
unsigned short MajorImageVersion;
|
||||
unsigned short MinorImageVersion;
|
||||
unsigned short MajorSubsystemVersion;
|
||||
unsigned short MinorSubsystemVersion;
|
||||
char Reserved1[4];
|
||||
host_ulong SizeOfImage;
|
||||
host_ulong SizeOfHeaders;
|
||||
host_ulong CheckSum;
|
||||
unsigned short Subsystem;
|
||||
unsigned short DllCharacteristics;
|
||||
host_ulong SizeOfStackReserve;
|
||||
host_ulong SizeOfStackCommit;
|
||||
host_ulong SizeOfHeapReserve;
|
||||
host_ulong SizeOfHeapCommit;
|
||||
host_ulong LoaderFlags;
|
||||
host_ulong NumberOfRvaAndSizes;
|
||||
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
|
||||
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
|
||||
|
||||
} PEAOUTHDR;
|
||||
|
||||
|
||||
#undef AOUTSZ
|
||||
#define AOUTSZ (AOUTHDRSZ + 196)
|
||||
|
||||
#undef E_FILNMLEN
|
||||
#define E_FILNMLEN 18 /* # characters in a file name */
|
||||
#endif
|
||||
|
||||
/* end of coff/pe.h */
|
||||
|
||||
#define DT_NON (0) /* no derived type */
|
||||
#define DT_PTR (1) /* pointer */
|
||||
#define DT_FCN (2) /* function */
|
||||
#define DT_ARY (3) /* array */
|
||||
|
||||
#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
|
||||
#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
|
||||
#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _A_OUT_H_ */
|
2
acl.c
2
acl.c
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "acl.h"
|
||||
#include "qemu/acl.h"
|
||||
|
||||
#ifdef CONFIG_FNMATCH
|
||||
#include <fnmatch.h>
|
||||
|
|
2
aes.c
2
aes.c
|
@ -28,7 +28,7 @@
|
|||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "aes.h"
|
||||
#include "block/aes.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "block/block.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
struct AioHandler
|
||||
{
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "block/block.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
struct AioHandler {
|
||||
EventNotifier *e;
|
||||
|
|
256
arch_init.c
256
arch_init.c
|
@ -29,25 +29,26 @@
|
|||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
#include "monitor.h"
|
||||
#include "sysemu.h"
|
||||
#include "bitops.h"
|
||||
#include "bitmap.h"
|
||||
#include "arch_init.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/bitmap.h"
|
||||
#include "sysemu/arch_init.h"
|
||||
#include "audio/audio.h"
|
||||
#include "hw/pc.h"
|
||||
#include "hw/pci.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/audiodev.h"
|
||||
#include "kvm.h"
|
||||
#include "migration.h"
|
||||
#include "net.h"
|
||||
#include "gdbstub.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "migration/migration.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "hw/smbios.h"
|
||||
#include "exec-memory.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/pcspk.h"
|
||||
#include "qemu/page_cache.h"
|
||||
#include "migration/page_cache.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "trace.h"
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
#ifdef DEBUG_ARCH_INIT
|
||||
#define DPRINTF(fmt, ...) \
|
||||
|
@ -264,16 +265,21 @@ uint64_t xbzrle_mig_pages_overflow(void)
|
|||
return acct_info.xbzrle_overflows;
|
||||
}
|
||||
|
||||
static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
|
||||
static size_t save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
|
||||
int cont, int flag)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
qemu_put_be64(f, offset | cont | flag);
|
||||
size = 8;
|
||||
|
||||
if (!cont) {
|
||||
qemu_put_byte(f, strlen(block->idstr));
|
||||
qemu_put_buffer(f, (uint8_t *)block->idstr,
|
||||
strlen(block->idstr));
|
||||
size += 1 + strlen(block->idstr);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#define ENCODING_FLAG_XBZRLE 0x1
|
||||
|
@ -320,34 +326,43 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|||
}
|
||||
|
||||
/* Send XBZRLE based compressed page */
|
||||
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
|
||||
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
|
||||
qemu_put_byte(f, ENCODING_FLAG_XBZRLE);
|
||||
qemu_put_be16(f, encoded_len);
|
||||
qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
|
||||
bytes_sent = encoded_len + 1 + 2;
|
||||
bytes_sent += encoded_len + 1 + 2;
|
||||
acct_info.xbzrle_pages++;
|
||||
acct_info.xbzrle_bytes += bytes_sent;
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
static RAMBlock *last_block;
|
||||
|
||||
/* This is the last block that we have visited serching for dirty pages
|
||||
*/
|
||||
static RAMBlock *last_seen_block;
|
||||
/* This is the last block from where we have sent data */
|
||||
static RAMBlock *last_sent_block;
|
||||
static ram_addr_t last_offset;
|
||||
static unsigned long *migration_bitmap;
|
||||
static uint64_t migration_dirty_pages;
|
||||
static uint32_t last_version;
|
||||
|
||||
static inline bool migration_bitmap_test_and_reset_dirty(MemoryRegion *mr,
|
||||
ram_addr_t offset)
|
||||
static inline
|
||||
ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
|
||||
ram_addr_t start)
|
||||
{
|
||||
bool ret;
|
||||
int nr = (mr->ram_addr + offset) >> TARGET_PAGE_BITS;
|
||||
unsigned long base = mr->ram_addr >> TARGET_PAGE_BITS;
|
||||
unsigned long nr = base + (start >> TARGET_PAGE_BITS);
|
||||
unsigned long size = base + (int128_get64(mr->size) >> TARGET_PAGE_BITS);
|
||||
|
||||
ret = test_and_clear_bit(nr, migration_bitmap);
|
||||
unsigned long next = find_next_bit(migration_bitmap, size, nr);
|
||||
|
||||
if (ret) {
|
||||
if (next < size) {
|
||||
clear_bit(next, migration_bitmap);
|
||||
migration_dirty_pages--;
|
||||
}
|
||||
return ret;
|
||||
return (next - base) << TARGET_PAGE_BITS;
|
||||
}
|
||||
|
||||
static inline bool migration_bitmap_set_dirty(MemoryRegion *mr,
|
||||
|
@ -381,15 +396,14 @@ static void migration_bitmap_sync(void)
|
|||
trace_migration_bitmap_sync_start();
|
||||
memory_global_sync_dirty_bitmap(get_system_memory());
|
||||
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
|
||||
if (memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
|
||||
if (memory_region_test_and_clear_dirty(block->mr,
|
||||
addr, TARGET_PAGE_SIZE,
|
||||
DIRTY_MEMORY_MIGRATION)) {
|
||||
migration_bitmap_set_dirty(block->mr, addr);
|
||||
}
|
||||
}
|
||||
memory_region_reset_dirty(block->mr, 0, block->length,
|
||||
DIRTY_MEMORY_MIGRATION);
|
||||
}
|
||||
trace_migration_bitmap_sync_end(migration_dirty_pages
|
||||
- num_dirty_pages_init);
|
||||
|
@ -405,39 +419,54 @@ static void migration_bitmap_sync(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ram_save_block: Writes a page of memory to the stream f
|
||||
*
|
||||
* Returns: 0: if the page hasn't changed
|
||||
* -1: if there are no more dirty pages
|
||||
* n: the amount of bytes written in other case
|
||||
* Returns: The number of bytes written.
|
||||
* 0 means no dirty pages
|
||||
*/
|
||||
|
||||
static int ram_save_block(QEMUFile *f, bool last_stage)
|
||||
{
|
||||
RAMBlock *block = last_block;
|
||||
RAMBlock *block = last_seen_block;
|
||||
ram_addr_t offset = last_offset;
|
||||
int bytes_sent = -1;
|
||||
bool complete_round = false;
|
||||
int bytes_sent = 0;
|
||||
MemoryRegion *mr;
|
||||
ram_addr_t current_addr;
|
||||
|
||||
if (!block)
|
||||
block = QLIST_FIRST(&ram_list.blocks);
|
||||
block = QTAILQ_FIRST(&ram_list.blocks);
|
||||
|
||||
do {
|
||||
while (true) {
|
||||
mr = block->mr;
|
||||
if (migration_bitmap_test_and_reset_dirty(mr, offset)) {
|
||||
offset = migration_bitmap_find_and_reset_dirty(mr, offset);
|
||||
if (complete_round && block == last_seen_block &&
|
||||
offset >= last_offset) {
|
||||
break;
|
||||
}
|
||||
if (offset >= block->length) {
|
||||
offset = 0;
|
||||
block = QTAILQ_NEXT(block, next);
|
||||
if (!block) {
|
||||
block = QTAILQ_FIRST(&ram_list.blocks);
|
||||
complete_round = true;
|
||||
}
|
||||
} else {
|
||||
uint8_t *p;
|
||||
int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
|
||||
int cont = (block == last_sent_block) ?
|
||||
RAM_SAVE_FLAG_CONTINUE : 0;
|
||||
|
||||
p = memory_region_get_ram_ptr(mr) + offset;
|
||||
|
||||
/* In doubt sent page as normal */
|
||||
bytes_sent = -1;
|
||||
if (is_dup_page(p)) {
|
||||
acct_info.dup_pages++;
|
||||
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
|
||||
bytes_sent = save_block_hdr(f, block, offset, cont,
|
||||
RAM_SAVE_FLAG_COMPRESS);
|
||||
qemu_put_byte(f, *p);
|
||||
bytes_sent = 1;
|
||||
bytes_sent += 1;
|
||||
} else if (migrate_use_xbzrle()) {
|
||||
current_addr = block->offset + offset;
|
||||
bytes_sent = save_xbzrle_page(f, p, current_addr, block,
|
||||
|
@ -447,30 +476,22 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
|
|||
}
|
||||
}
|
||||
|
||||
/* either we didn't send yet (we may have had XBZRLE overflow) */
|
||||
/* XBZRLE overflow or normal page */
|
||||
if (bytes_sent == -1) {
|
||||
save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
|
||||
bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
|
||||
qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
|
||||
bytes_sent = TARGET_PAGE_SIZE;
|
||||
bytes_sent += TARGET_PAGE_SIZE;
|
||||
acct_info.norm_pages++;
|
||||
}
|
||||
|
||||
/* if page is unmodified, continue to the next */
|
||||
if (bytes_sent != 0) {
|
||||
if (bytes_sent > 0) {
|
||||
last_sent_block = block;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offset += TARGET_PAGE_SIZE;
|
||||
if (offset >= block->length) {
|
||||
offset = 0;
|
||||
block = QLIST_NEXT(block, next);
|
||||
if (!block)
|
||||
block = QLIST_FIRST(&ram_list.blocks);
|
||||
}
|
||||
} while (block != last_block || offset != last_offset);
|
||||
|
||||
last_block = block;
|
||||
last_seen_block = block;
|
||||
last_offset = offset;
|
||||
|
||||
return bytes_sent;
|
||||
|
@ -498,46 +519,21 @@ uint64_t ram_bytes_total(void)
|
|||
RAMBlock *block;
|
||||
uint64_t total = 0;
|
||||
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next)
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next)
|
||||
total += block->length;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static int block_compar(const void *a, const void *b)
|
||||
{
|
||||
RAMBlock * const *ablock = a;
|
||||
RAMBlock * const *bblock = b;
|
||||
|
||||
return strcmp((*ablock)->idstr, (*bblock)->idstr);
|
||||
}
|
||||
|
||||
static void sort_ram_list(void)
|
||||
{
|
||||
RAMBlock *block, *nblock, **blocks;
|
||||
int n;
|
||||
n = 0;
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
++n;
|
||||
}
|
||||
blocks = g_malloc(n * sizeof *blocks);
|
||||
n = 0;
|
||||
QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) {
|
||||
blocks[n++] = block;
|
||||
QLIST_REMOVE(block, next);
|
||||
}
|
||||
qsort(blocks, n, sizeof *blocks, block_compar);
|
||||
while (--n >= 0) {
|
||||
QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
|
||||
}
|
||||
g_free(blocks);
|
||||
}
|
||||
|
||||
static void migration_end(void)
|
||||
{
|
||||
if (migration_bitmap) {
|
||||
memory_global_dirty_log_stop();
|
||||
g_free(migration_bitmap);
|
||||
migration_bitmap = NULL;
|
||||
}
|
||||
|
||||
if (migrate_use_xbzrle()) {
|
||||
if (XBZRLE.cache) {
|
||||
cache_fini(XBZRLE.cache);
|
||||
g_free(XBZRLE.cache);
|
||||
g_free(XBZRLE.encoded_buf);
|
||||
|
@ -552,12 +548,12 @@ static void ram_migration_cancel(void *opaque)
|
|||
migration_end();
|
||||
}
|
||||
|
||||
|
||||
static void reset_ram_globals(void)
|
||||
{
|
||||
last_block = NULL;
|
||||
last_seen_block = NULL;
|
||||
last_sent_block = NULL;
|
||||
last_offset = 0;
|
||||
sort_ram_list();
|
||||
last_version = ram_list.version;
|
||||
}
|
||||
|
||||
#define MAX_WAIT 50 /* ms, half buffered_file limit */
|
||||
|
@ -568,9 +564,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||
int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
|
||||
|
||||
migration_bitmap = bitmap_new(ram_pages);
|
||||
bitmap_set(migration_bitmap, 1, ram_pages);
|
||||
bitmap_set(migration_bitmap, 0, ram_pages);
|
||||
migration_dirty_pages = ram_pages;
|
||||
|
||||
qemu_mutex_lock_ramlist();
|
||||
bytes_transferred = 0;
|
||||
reset_ram_globals();
|
||||
|
||||
|
@ -592,12 +589,13 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||
|
||||
qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
|
||||
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
qemu_put_byte(f, strlen(block->idstr));
|
||||
qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
|
||||
qemu_put_be64(f, block->length);
|
||||
}
|
||||
|
||||
qemu_mutex_unlock_ramlist();
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
|
||||
return 0;
|
||||
|
@ -605,26 +603,28 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||
|
||||
static int ram_save_iterate(QEMUFile *f, void *opaque)
|
||||
{
|
||||
uint64_t bytes_transferred_last;
|
||||
double bwidth = 0;
|
||||
int ret;
|
||||
int i;
|
||||
uint64_t expected_downtime;
|
||||
MigrationState *s = migrate_get_current();
|
||||
int64_t t0;
|
||||
int total_sent = 0;
|
||||
|
||||
bytes_transferred_last = bytes_transferred;
|
||||
bwidth = qemu_get_clock_ns(rt_clock);
|
||||
qemu_mutex_lock_ramlist();
|
||||
|
||||
if (ram_list.version != last_version) {
|
||||
reset_ram_globals();
|
||||
}
|
||||
|
||||
t0 = qemu_get_clock_ns(rt_clock);
|
||||
i = 0;
|
||||
while ((ret = qemu_file_rate_limit(f)) == 0) {
|
||||
int bytes_sent;
|
||||
|
||||
bytes_sent = ram_save_block(f, false);
|
||||
/* no more blocks to sent */
|
||||
if (bytes_sent < 0) {
|
||||
if (bytes_sent == 0) {
|
||||
break;
|
||||
}
|
||||
bytes_transferred += bytes_sent;
|
||||
total_sent += bytes_sent;
|
||||
acct_info.iterations++;
|
||||
/* we want to check in the 1st loop, just in case it was the 1st time
|
||||
and we had to sync the dirty bitmap.
|
||||
|
@ -632,7 +632,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
|||
iterations
|
||||
*/
|
||||
if ((i & 63) == 0) {
|
||||
uint64_t t1 = (qemu_get_clock_ns(rt_clock) - bwidth) / 1000000;
|
||||
uint64_t t1 = (qemu_get_clock_ns(rt_clock) - t0) / 1000000;
|
||||
if (t1 > MAX_WAIT) {
|
||||
DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
|
||||
t1, i);
|
||||
|
@ -643,39 +643,24 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
|||
}
|
||||
|
||||
if (ret < 0) {
|
||||
bytes_transferred += total_sent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
|
||||
bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
|
||||
|
||||
/* if we haven't transferred anything this round, force
|
||||
* expected_downtime to a very high value, but without
|
||||
* crashing */
|
||||
if (bwidth == 0) {
|
||||
bwidth = 0.000001;
|
||||
}
|
||||
|
||||
qemu_mutex_unlock_ramlist();
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
total_sent += 8;
|
||||
bytes_transferred += total_sent;
|
||||
|
||||
expected_downtime = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
|
||||
DPRINTF("ram_save_live: expected(%" PRIu64 ") <= max(" PRIu64 ")?\n",
|
||||
expected_downtime, migrate_max_downtime());
|
||||
|
||||
if (expected_downtime <= migrate_max_downtime()) {
|
||||
migration_bitmap_sync();
|
||||
expected_downtime = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
|
||||
s->expected_downtime = expected_downtime / 1000000; /* ns -> ms */
|
||||
|
||||
return expected_downtime <= migrate_max_downtime();
|
||||
}
|
||||
return 0;
|
||||
return total_sent;
|
||||
}
|
||||
|
||||
static int ram_save_complete(QEMUFile *f, void *opaque)
|
||||
{
|
||||
migration_bitmap_sync();
|
||||
|
||||
qemu_mutex_lock_ramlist();
|
||||
|
||||
/* try transferring iterative blocks of memory */
|
||||
|
||||
/* flush all remaining blocks regardless of rate limiting */
|
||||
|
@ -684,21 +669,32 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
|||
|
||||
bytes_sent = ram_save_block(f, true);
|
||||
/* no more blocks to sent */
|
||||
if (bytes_sent < 0) {
|
||||
if (bytes_sent == 0) {
|
||||
break;
|
||||
}
|
||||
bytes_transferred += bytes_sent;
|
||||
}
|
||||
memory_global_dirty_log_stop();
|
||||
migration_end();
|
||||
|
||||
qemu_mutex_unlock_ramlist();
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
|
||||
g_free(migration_bitmap);
|
||||
migration_bitmap = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
|
||||
{
|
||||
uint64_t remaining_size;
|
||||
|
||||
remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE;
|
||||
|
||||
if (remaining_size < max_size) {
|
||||
migration_bitmap_sync();
|
||||
remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE;
|
||||
}
|
||||
return remaining_size;
|
||||
}
|
||||
|
||||
static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
|
||||
{
|
||||
int ret, rc = 0;
|
||||
|
@ -761,7 +757,7 @@ static inline void *host_from_stream_offset(QEMUFile *f,
|
|||
qemu_get_buffer(f, (uint8_t *)id, len);
|
||||
id[len] = 0;
|
||||
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
if (!strncmp(id, block->idstr, sizeof(id)))
|
||||
return memory_region_get_ram_ptr(block->mr) + offset;
|
||||
}
|
||||
|
@ -805,7 +801,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||
id[len] = 0;
|
||||
length = qemu_get_be64(f);
|
||||
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
if (!strncmp(id, block->idstr, sizeof(id))) {
|
||||
if (block->length != length) {
|
||||
ret = -EINVAL;
|
||||
|
@ -840,7 +836,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||
memset(host, ch, TARGET_PAGE_SIZE);
|
||||
#ifndef _WIN32
|
||||
if (ch == 0 &&
|
||||
(!kvm_enabled() || kvm_has_sync_mmu())) {
|
||||
(!kvm_enabled() || kvm_has_sync_mmu()) &&
|
||||
getpagesize() <= TARGET_PAGE_SIZE) {
|
||||
qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
|
||||
}
|
||||
#endif
|
||||
|
@ -884,6 +881,7 @@ SaveVMHandlers savevm_ram_handlers = {
|
|||
.save_live_setup = ram_save_setup,
|
||||
.save_live_iterate = ram_save_iterate,
|
||||
.save_live_complete = ram_save_complete,
|
||||
.save_live_pending = ram_save_pending,
|
||||
.load_state = ram_load,
|
||||
.cancel = ram_migration_cancel,
|
||||
};
|
||||
|
|
9
async.c
9
async.c
|
@ -23,8 +23,8 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-aio.h"
|
||||
#include "main-loop.h"
|
||||
#include "block/aio.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
/***********************************************************/
|
||||
/* bottom halves (can be seen as timers which expire ASAP) */
|
||||
|
@ -215,8 +215,3 @@ void aio_context_unref(AioContext *ctx)
|
|||
{
|
||||
g_source_unref(&ctx->source);
|
||||
}
|
||||
|
||||
void aio_flush(AioContext *ctx)
|
||||
{
|
||||
while (aio_poll(ctx, true));
|
||||
}
|
||||
|
|
|
@ -12,3 +12,6 @@ common-obj-$(CONFIG_WINWAVE) += winwaveaudio.o
|
|||
common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
|
||||
common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
|
||||
common-obj-y += wavcapture.o
|
||||
|
||||
$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
|
||||
$(obj)/sdlaudio.o: QEMU_CFLAGS += $(SDL_CFLAGS)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "audio.h"
|
||||
|
||||
#if QEMU_GNUC_PREREQ(4, 3)
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
*/
|
||||
#include "hw/hw.h"
|
||||
#include "audio.h"
|
||||
#include "monitor.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "sysemu.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
#define AUDIO_CAP "audio"
|
||||
#include "audio_int.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#define QEMU_AUDIO_H
|
||||
|
||||
#include "config-host.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "qemu/queue.h"
|
||||
|
||||
typedef void (*audio_callback_fn) (void *opaque, int avail);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "audio.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
#define AUDIO_CAP "noaudio"
|
||||
#include "audio_int.h"
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
#include "qemu-common.h"
|
||||
#include "host-utils.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define AUDIO_CAP "oss"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "hw/hw.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "ui/qemu-spice.h"
|
||||
|
||||
#define AUDIO_CAP "spice"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "hw/hw.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define AUDIO_CAP "wav"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "hw/hw.h"
|
||||
#include "monitor.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "audio.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* public domain */
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define AUDIO_CAP "winwave"
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
*/
|
||||
|
||||
#include "qemu/rng.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qerror.h"
|
||||
#include "char/char.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "hw/qdev.h" /* just for DEFINE_PROP_CHR */
|
||||
|
||||
#define TYPE_RNG_EGD "rng-egd"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
#include "qemu/rng-random.h"
|
||||
#include "qemu/rng.h"
|
||||
#include "qerror.h"
|
||||
#include "main-loop.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
struct RndRandom
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu/rng.h"
|
||||
#include "qerror.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
|
||||
void rng_backend_request_entropy(RngBackend *s, size_t size,
|
||||
EntropyReceiveFunc *receive_entropy,
|
||||
|
|
10
balloon.c
10
balloon.c
|
@ -24,13 +24,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "monitor.h"
|
||||
#include "cpu-common.h"
|
||||
#include "kvm.h"
|
||||
#include "balloon.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/balloon.h"
|
||||
#include "trace.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qjson.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
|
||||
static QEMUBalloonEvent *balloon_event_fn;
|
||||
static QEMUBalloonStatus *balloon_stat_fn;
|
||||
|
|
4
bitmap.c
4
bitmap.c
|
@ -9,8 +9,8 @@
|
|||
* Version 2.
|
||||
*/
|
||||
|
||||
#include "bitops.h"
|
||||
#include "bitmap.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/bitmap.h"
|
||||
|
||||
/*
|
||||
* bitmaps provide an array of bits, implemented using an an
|
||||
|
|
2
bitops.c
2
bitops.c
|
@ -11,7 +11,7 @@
|
|||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "bitops.h"
|
||||
#include "qemu/bitops.h"
|
||||
|
||||
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "hw/hw.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "block-migration.h"
|
||||
#include "migration.h"
|
||||
#include "blockdev.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "migration/block.h"
|
||||
#include "migration/migration.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define BLOCK_SIZE (BDRV_SECTORS_PER_DIRTY_CHUNK << BDRV_SECTOR_BITS)
|
||||
|
@ -77,9 +77,7 @@ typedef struct BlkMigState {
|
|||
int64_t total_sector_sum;
|
||||
int prev_progress;
|
||||
int bulk_completed;
|
||||
long double total_time;
|
||||
long double prev_time_offset;
|
||||
int reads;
|
||||
} BlkMigState;
|
||||
|
||||
static BlkMigState block_mig_state;
|
||||
|
@ -132,12 +130,6 @@ uint64_t blk_mig_bytes_total(void)
|
|||
return sum << BDRV_SECTOR_BITS;
|
||||
}
|
||||
|
||||
static inline long double compute_read_bwidth(void)
|
||||
{
|
||||
assert(block_mig_state.total_time != 0);
|
||||
return (block_mig_state.reads / block_mig_state.total_time) * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
|
||||
{
|
||||
int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK;
|
||||
|
@ -191,8 +183,6 @@ static void blk_mig_read_cb(void *opaque, int ret)
|
|||
|
||||
blk->ret = ret;
|
||||
|
||||
block_mig_state.reads++;
|
||||
block_mig_state.total_time += (curr_time - block_mig_state.prev_time_offset);
|
||||
block_mig_state.prev_time_offset = curr_time;
|
||||
|
||||
QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
|
||||
|
@ -310,8 +300,6 @@ static void init_blk_migration(QEMUFile *f)
|
|||
block_mig_state.total_sector_sum = 0;
|
||||
block_mig_state.prev_progress = -1;
|
||||
block_mig_state.bulk_completed = 0;
|
||||
block_mig_state.total_time = 0;
|
||||
block_mig_state.reads = 0;
|
||||
|
||||
bdrv_iterate(init_blk_migration_it, NULL);
|
||||
}
|
||||
|
@ -493,32 +481,6 @@ static int64_t get_remaining_dirty(void)
|
|||
return dirty * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
static int is_stage2_completed(void)
|
||||
{
|
||||
int64_t remaining_dirty;
|
||||
long double bwidth;
|
||||
|
||||
if (block_mig_state.bulk_completed == 1) {
|
||||
|
||||
remaining_dirty = get_remaining_dirty();
|
||||
if (remaining_dirty == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bwidth = compute_read_bwidth();
|
||||
|
||||
if ((remaining_dirty / bwidth) <=
|
||||
migrate_max_downtime()) {
|
||||
/* finish stage2 because we think that we can finish remaining work
|
||||
below max_downtime */
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blk_mig_cleanup(void)
|
||||
{
|
||||
BlkMigDevState *bmds;
|
||||
|
@ -619,7 +581,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
|
|||
|
||||
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
|
||||
|
||||
return is_stage2_completed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int block_save_complete(QEMUFile *f, void *opaque)
|
||||
|
@ -659,6 +621,14 @@ static int block_save_complete(QEMUFile *f, void *opaque)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
|
||||
{
|
||||
|
||||
DPRINTF("Enter save live pending %ld\n", get_remaining_dirty());
|
||||
|
||||
return get_remaining_dirty();
|
||||
}
|
||||
|
||||
static int block_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
static int banner_printed;
|
||||
|
@ -755,6 +725,7 @@ SaveVMHandlers savevm_block_handlers = {
|
|||
.save_live_setup = block_save_setup,
|
||||
.save_live_iterate = block_save_iterate,
|
||||
.save_live_complete = block_save_complete,
|
||||
.save_live_pending = block_save_pending,
|
||||
.load_state = block_load,
|
||||
.cancel = block_migration_cancel,
|
||||
.is_active = block_is_active,
|
||||
|
|
225
block.c
225
block.c
|
@ -24,16 +24,16 @@
|
|||
#include "config-host.h"
|
||||
#include "qemu-common.h"
|
||||
#include "trace.h"
|
||||
#include "monitor.h"
|
||||
#include "block_int.h"
|
||||
#include "blockjob.h"
|
||||
#include "module.h"
|
||||
#include "qjson.h"
|
||||
#include "sysemu.h"
|
||||
#include "notify.h"
|
||||
#include "qemu-coroutine.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/notify.h"
|
||||
#include "block/coroutine.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
#ifdef CONFIG_BSD
|
||||
#include <sys/types.h>
|
||||
|
@ -518,22 +518,16 @@ BlockDriver *bdrv_find_protocol(const char *filename)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int find_image_format(const char *filename, BlockDriver **pdrv)
|
||||
static int find_image_format(BlockDriverState *bs, const char *filename,
|
||||
BlockDriver **pdrv)
|
||||
{
|
||||
int ret, score, score_max;
|
||||
int score, score_max;
|
||||
BlockDriver *drv1, *drv;
|
||||
uint8_t buf[2048];
|
||||
BlockDriverState *bs;
|
||||
|
||||
ret = bdrv_file_open(&bs, filename, 0);
|
||||
if (ret < 0) {
|
||||
*pdrv = NULL;
|
||||
return ret;
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
|
||||
if (bs->sg || !bdrv_is_inserted(bs)) {
|
||||
bdrv_delete(bs);
|
||||
drv = bdrv_find_format("raw");
|
||||
if (!drv) {
|
||||
ret = -ENOENT;
|
||||
|
@ -543,7 +537,6 @@ static int find_image_format(const char *filename, BlockDriver **pdrv)
|
|||
}
|
||||
|
||||
ret = bdrv_pread(bs, 0, buf, sizeof(buf));
|
||||
bdrv_delete(bs);
|
||||
if (ret < 0) {
|
||||
*pdrv = NULL;
|
||||
return ret;
|
||||
|
@ -634,10 +627,31 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
|
|||
bs->copy_on_read--;
|
||||
}
|
||||
|
||||
static int bdrv_open_flags(BlockDriverState *bs, int flags)
|
||||
{
|
||||
int open_flags = flags | BDRV_O_CACHE_WB;
|
||||
|
||||
/*
|
||||
* Clear flags that are internal to the block layer before opening the
|
||||
* image.
|
||||
*/
|
||||
open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
|
||||
|
||||
/*
|
||||
* Snapshots should be writable.
|
||||
*/
|
||||
if (bs->is_temporary) {
|
||||
open_flags |= BDRV_O_RDWR;
|
||||
}
|
||||
|
||||
return open_flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common part for opening disk images and files
|
||||
*/
|
||||
static int bdrv_open_common(BlockDriverState *bs, const char *filename,
|
||||
static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||
const char *filename,
|
||||
int flags, BlockDriver *drv)
|
||||
{
|
||||
int ret, open_flags;
|
||||
|
@ -665,31 +679,22 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
|
|||
bs->opaque = g_malloc0(drv->instance_size);
|
||||
|
||||
bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
|
||||
open_flags = flags | BDRV_O_CACHE_WB;
|
||||
|
||||
/*
|
||||
* Clear flags that are internal to the block layer before opening the
|
||||
* image.
|
||||
*/
|
||||
open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
|
||||
|
||||
/*
|
||||
* Snapshots should be writable.
|
||||
*/
|
||||
if (bs->is_temporary) {
|
||||
open_flags |= BDRV_O_RDWR;
|
||||
}
|
||||
open_flags = bdrv_open_flags(bs, flags);
|
||||
|
||||
bs->read_only = !(open_flags & BDRV_O_RDWR);
|
||||
|
||||
/* Open the image, either directly or using a protocol */
|
||||
if (drv->bdrv_file_open) {
|
||||
ret = drv->bdrv_file_open(bs, filename, open_flags);
|
||||
if (file != NULL) {
|
||||
bdrv_swap(file, bs);
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = bdrv_file_open(&bs->file, filename, open_flags);
|
||||
if (ret >= 0) {
|
||||
ret = drv->bdrv_open(bs, open_flags);
|
||||
ret = drv->bdrv_file_open(bs, filename, open_flags);
|
||||
}
|
||||
} else {
|
||||
assert(file != NULL);
|
||||
bs->file = file;
|
||||
ret = drv->bdrv_open(bs, open_flags);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
|
@ -709,10 +714,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
|
|||
return 0;
|
||||
|
||||
free_and_fail:
|
||||
if (bs->file) {
|
||||
bdrv_delete(bs->file);
|
||||
bs->file = NULL;
|
||||
}
|
||||
g_free(bs->opaque);
|
||||
bs->opaque = NULL;
|
||||
bs->drv = NULL;
|
||||
|
@ -734,7 +736,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
|
|||
}
|
||||
|
||||
bs = bdrv_new("");
|
||||
ret = bdrv_open_common(bs, filename, flags, drv);
|
||||
ret = bdrv_open_common(bs, NULL, filename, flags, drv);
|
||||
if (ret < 0) {
|
||||
bdrv_delete(bs);
|
||||
return ret;
|
||||
|
@ -789,6 +791,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
|
|||
int ret;
|
||||
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
|
||||
char tmp_filename[PATH_MAX + 1];
|
||||
BlockDriverState *file = NULL;
|
||||
|
||||
if (flags & BDRV_O_SNAPSHOT) {
|
||||
BlockDriverState *bs1;
|
||||
|
@ -848,25 +851,36 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
|
|||
bs->is_temporary = 1;
|
||||
}
|
||||
|
||||
/* Find the right image format driver */
|
||||
if (!drv) {
|
||||
ret = find_image_format(filename, &drv);
|
||||
}
|
||||
|
||||
if (!drv) {
|
||||
goto unlink_and_fail;
|
||||
}
|
||||
|
||||
/* Open image file without format layer */
|
||||
if (flags & BDRV_O_RDWR) {
|
||||
flags |= BDRV_O_ALLOW_RDWR;
|
||||
}
|
||||
|
||||
ret = bdrv_file_open(&file, filename, bdrv_open_flags(bs, flags));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Find the right image format driver */
|
||||
if (!drv) {
|
||||
ret = find_image_format(file, filename, &drv);
|
||||
}
|
||||
|
||||
if (!drv) {
|
||||
goto unlink_and_fail;
|
||||
}
|
||||
|
||||
/* Open the image */
|
||||
ret = bdrv_open_common(bs, filename, flags, drv);
|
||||
ret = bdrv_open_common(bs, file, filename, flags, drv);
|
||||
if (ret < 0) {
|
||||
goto unlink_and_fail;
|
||||
}
|
||||
|
||||
if (bs->file != file) {
|
||||
bdrv_delete(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
/* If there is a backing file, use it */
|
||||
if ((flags & BDRV_O_NO_BACKING) == 0) {
|
||||
ret = bdrv_open_backing_file(bs);
|
||||
|
@ -888,6 +902,9 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
|
|||
return 0;
|
||||
|
||||
unlink_and_fail:
|
||||
if (file != NULL) {
|
||||
bdrv_delete(file);
|
||||
}
|
||||
if (bs->is_temporary) {
|
||||
unlink(filename);
|
||||
}
|
||||
|
@ -3028,7 +3045,46 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
|
|||
}
|
||||
|
||||
drv->bdrv_debug_event(bs, event);
|
||||
}
|
||||
|
||||
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||
const char *tag)
|
||||
{
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
|
||||
bs = bs->file;
|
||||
}
|
||||
|
||||
if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) {
|
||||
return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
|
||||
bs = bs->file;
|
||||
}
|
||||
|
||||
if (bs && bs->drv && bs->drv->bdrv_debug_resume) {
|
||||
return bs->drv->bdrv_debug_resume(bs, tag);
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
|
||||
bs = bs->file;
|
||||
}
|
||||
|
||||
if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) {
|
||||
return bs->drv->bdrv_debug_is_suspended(bs, tag);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
@ -3778,12 +3834,20 @@ typedef struct BlockDriverAIOCBCoroutine {
|
|||
BlockDriverAIOCB common;
|
||||
BlockRequest req;
|
||||
bool is_write;
|
||||
bool *done;
|
||||
QEMUBH* bh;
|
||||
} BlockDriverAIOCBCoroutine;
|
||||
|
||||
static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
qemu_aio_flush();
|
||||
BlockDriverAIOCBCoroutine *acb =
|
||||
container_of(blockacb, BlockDriverAIOCBCoroutine, common);
|
||||
bool done = false;
|
||||
|
||||
acb->done = &done;
|
||||
while (!done) {
|
||||
qemu_aio_wait();
|
||||
}
|
||||
}
|
||||
|
||||
static const AIOCBInfo bdrv_em_co_aiocb_info = {
|
||||
|
@ -3796,6 +3860,11 @@ static void bdrv_co_em_bh(void *opaque)
|
|||
BlockDriverAIOCBCoroutine *acb = opaque;
|
||||
|
||||
acb->common.cb(acb->common.opaque, acb->req.error);
|
||||
|
||||
if (acb->done) {
|
||||
*acb->done = true;
|
||||
}
|
||||
|
||||
qemu_bh_delete(acb->bh);
|
||||
qemu_aio_release(acb);
|
||||
}
|
||||
|
@ -3834,6 +3903,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
|
|||
acb->req.nb_sectors = nb_sectors;
|
||||
acb->req.qiov = qiov;
|
||||
acb->is_write = is_write;
|
||||
acb->done = NULL;
|
||||
|
||||
co = qemu_coroutine_create(bdrv_co_do_rw);
|
||||
qemu_coroutine_enter(co, acb);
|
||||
|
@ -3860,6 +3930,8 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
|
|||
BlockDriverAIOCBCoroutine *acb;
|
||||
|
||||
acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
|
||||
acb->done = NULL;
|
||||
|
||||
co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
|
||||
qemu_coroutine_enter(co, acb);
|
||||
|
||||
|
@ -3888,6 +3960,7 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
|
|||
acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
|
||||
acb->req.sector = sector_num;
|
||||
acb->req.nb_sectors = nb_sectors;
|
||||
acb->done = NULL;
|
||||
co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
|
||||
qemu_coroutine_enter(co, acb);
|
||||
|
||||
|
@ -4408,9 +4481,9 @@ bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
|
|||
bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
|
||||
}
|
||||
|
||||
int bdrv_img_create(const char *filename, const char *fmt,
|
||||
void bdrv_img_create(const char *filename, const char *fmt,
|
||||
const char *base_filename, const char *base_fmt,
|
||||
char *options, uint64_t img_size, int flags)
|
||||
char *options, uint64_t img_size, int flags, Error **errp)
|
||||
{
|
||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
||||
QEMUOptionParameter *backing_fmt, *backing_file, *size;
|
||||
|
@ -4422,16 +4495,14 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
/* Find driver and parse its options */
|
||||
drv = bdrv_find_format(fmt);
|
||||
if (!drv) {
|
||||
error_report("Unknown file format '%s'", fmt);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
error_setg(errp, "Unknown file format '%s'", fmt);
|
||||
return;
|
||||
}
|
||||
|
||||
proto_drv = bdrv_find_protocol(filename);
|
||||
if (!proto_drv) {
|
||||
error_report("Unknown protocol '%s'", filename);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
error_setg(errp, "Unknown protocol '%s'", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
create_options = append_option_parameters(create_options,
|
||||
|
@ -4448,8 +4519,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
if (options) {
|
||||
param = parse_option_parameters(options, create_options, param);
|
||||
if (param == NULL) {
|
||||
error_report("Invalid options for file format '%s'.", fmt);
|
||||
ret = -EINVAL;
|
||||
error_setg(errp, "Invalid options for file format '%s'.", fmt);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -4457,18 +4527,16 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
if (base_filename) {
|
||||
if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
|
||||
base_filename)) {
|
||||
error_report("Backing file not supported for file format '%s'",
|
||||
error_setg(errp, "Backing file not supported for file format '%s'",
|
||||
fmt);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (base_fmt) {
|
||||
if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
|
||||
error_report("Backing file format not supported for file "
|
||||
error_setg(errp, "Backing file format not supported for file "
|
||||
"format '%s'", fmt);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -4476,9 +4544,8 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
|
||||
if (backing_file && backing_file->value.s) {
|
||||
if (!strcmp(filename, backing_file->value.s)) {
|
||||
error_report("Error: Trying to create an image with the "
|
||||
error_setg(errp, "Error: Trying to create an image with the "
|
||||
"same filename as the backing file");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -4487,9 +4554,8 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
if (backing_fmt && backing_fmt->value.s) {
|
||||
backing_drv = bdrv_find_format(backing_fmt->value.s);
|
||||
if (!backing_drv) {
|
||||
error_report("Unknown backing file format '%s'",
|
||||
error_setg(errp, "Unknown backing file format '%s'",
|
||||
backing_fmt->value.s);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -4511,7 +4577,8 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
|
||||
ret = bdrv_open(bs, backing_file->value.s, back_flags, backing_drv);
|
||||
if (ret < 0) {
|
||||
error_report("Could not open '%s'", backing_file->value.s);
|
||||
error_setg_errno(errp, -ret, "Could not open '%s'",
|
||||
backing_file->value.s);
|
||||
goto out;
|
||||
}
|
||||
bdrv_get_geometry(bs, &size);
|
||||
|
@ -4520,8 +4587,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
snprintf(buf, sizeof(buf), "%" PRId64, size);
|
||||
set_option_parameter(param, BLOCK_OPT_SIZE, buf);
|
||||
} else {
|
||||
error_report("Image creation needs a size parameter");
|
||||
ret = -EINVAL;
|
||||
error_setg(errp, "Image creation needs a size parameter");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -4531,16 +4597,15 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
|||
puts("");
|
||||
|
||||
ret = bdrv_create(drv, filename, param);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret == -ENOTSUP) {
|
||||
error_report("Formatting or formatting option not supported for "
|
||||
error_setg(errp,"Formatting or formatting option not supported for "
|
||||
"file format '%s'", fmt);
|
||||
} else if (ret == -EFBIG) {
|
||||
error_report("The image size is too large for file format '%s'",
|
||||
error_setg(errp, "The image size is too large for file format '%s'",
|
||||
fmt);
|
||||
} else {
|
||||
error_report("%s: error while creating %s: %s", filename, fmt,
|
||||
error_setg(errp, "%s: error while creating %s: %s", filename, fmt,
|
||||
strerror(-ret));
|
||||
}
|
||||
}
|
||||
|
@ -4552,6 +4617,4 @@ out:
|
|||
if (bs) {
|
||||
bdrv_delete(bs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -18,3 +18,5 @@ endif
|
|||
common-obj-y += stream.o
|
||||
common-obj-y += commit.o
|
||||
common-obj-y += mirror.o
|
||||
|
||||
$(obj)/curl.o: QEMU_CFLAGS+=$(CURL_CFLAGS)
|
||||
|
|
131
block/blkdebug.c
131
block/blkdebug.c
|
@ -23,14 +23,17 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
typedef struct BDRVBlkdebugState {
|
||||
int state;
|
||||
int new_state;
|
||||
|
||||
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
|
||||
QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
|
||||
QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
|
||||
} BDRVBlkdebugState;
|
||||
|
||||
typedef struct BlkdebugAIOCB {
|
||||
|
@ -39,6 +42,12 @@ typedef struct BlkdebugAIOCB {
|
|||
int ret;
|
||||
} BlkdebugAIOCB;
|
||||
|
||||
typedef struct BlkdebugSuspendedReq {
|
||||
Coroutine *co;
|
||||
char *tag;
|
||||
QLIST_ENTRY(BlkdebugSuspendedReq) next;
|
||||
} BlkdebugSuspendedReq;
|
||||
|
||||
static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb);
|
||||
|
||||
static const AIOCBInfo blkdebug_aiocb_info = {
|
||||
|
@ -49,6 +58,7 @@ static const AIOCBInfo blkdebug_aiocb_info = {
|
|||
enum {
|
||||
ACTION_INJECT_ERROR,
|
||||
ACTION_SET_STATE,
|
||||
ACTION_SUSPEND,
|
||||
};
|
||||
|
||||
typedef struct BlkdebugRule {
|
||||
|
@ -65,6 +75,9 @@ typedef struct BlkdebugRule {
|
|||
struct {
|
||||
int new_state;
|
||||
} set_state;
|
||||
struct {
|
||||
char *tag;
|
||||
} suspend;
|
||||
} options;
|
||||
QLIST_ENTRY(BlkdebugRule) next;
|
||||
QSIMPLEQ_ENTRY(BlkdebugRule) active_next;
|
||||
|
@ -226,6 +239,11 @@ static int add_rule(QemuOpts *opts, void *opaque)
|
|||
rule->options.set_state.new_state =
|
||||
qemu_opt_get_number(opts, "new_state", 0);
|
||||
break;
|
||||
|
||||
case ACTION_SUSPEND:
|
||||
rule->options.suspend.tag =
|
||||
g_strdup(qemu_opt_get(opts, "tag"));
|
||||
break;
|
||||
};
|
||||
|
||||
/* Add the rule */
|
||||
|
@ -234,12 +252,32 @@ static int add_rule(QemuOpts *opts, void *opaque)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void remove_rule(BlkdebugRule *rule)
|
||||
{
|
||||
switch (rule->action) {
|
||||
case ACTION_INJECT_ERROR:
|
||||
case ACTION_SET_STATE:
|
||||
break;
|
||||
case ACTION_SUSPEND:
|
||||
g_free(rule->options.suspend.tag);
|
||||
break;
|
||||
}
|
||||
|
||||
QLIST_REMOVE(rule, next);
|
||||
g_free(rule);
|
||||
}
|
||||
|
||||
static int read_config(BDRVBlkdebugState *s, const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int ret;
|
||||
struct add_rule_data d;
|
||||
|
||||
/* Allow usage without config file */
|
||||
if (!*filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
return -errno;
|
||||
|
@ -389,6 +427,7 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
|
|||
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
|
||||
}
|
||||
|
||||
|
||||
static void blkdebug_close(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
|
@ -397,12 +436,32 @@ static void blkdebug_close(BlockDriverState *bs)
|
|||
|
||||
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
|
||||
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
|
||||
QLIST_REMOVE(rule, next);
|
||||
g_free(rule);
|
||||
remove_rule(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
BlkdebugSuspendedReq r;
|
||||
|
||||
r = (BlkdebugSuspendedReq) {
|
||||
.co = qemu_coroutine_self(),
|
||||
.tag = g_strdup(rule->options.suspend.tag),
|
||||
};
|
||||
|
||||
remove_rule(rule);
|
||||
QLIST_INSERT_HEAD(&s->suspended_reqs, &r, next);
|
||||
|
||||
printf("blkdebug: Suspended request '%s'\n", r.tag);
|
||||
qemu_coroutine_yield();
|
||||
printf("blkdebug: Resuming request '%s'\n", r.tag);
|
||||
|
||||
QLIST_REMOVE(&r, next);
|
||||
g_free(r.tag);
|
||||
}
|
||||
|
||||
static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
|
||||
bool injected)
|
||||
{
|
||||
|
@ -426,6 +485,10 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
|
|||
case ACTION_SET_STATE:
|
||||
s->new_state = rule->options.set_state.new_state;
|
||||
break;
|
||||
|
||||
case ACTION_SUSPEND:
|
||||
suspend_request(bs, rule);
|
||||
break;
|
||||
}
|
||||
return injected;
|
||||
}
|
||||
|
@ -433,19 +496,72 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
|
|||
static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
struct BlkdebugRule *rule;
|
||||
struct BlkdebugRule *rule, *next;
|
||||
bool injected;
|
||||
|
||||
assert((int)event >= 0 && event < BLKDBG_EVENT_MAX);
|
||||
|
||||
injected = false;
|
||||
s->new_state = s->state;
|
||||
QLIST_FOREACH(rule, &s->rules[event], next) {
|
||||
QLIST_FOREACH_SAFE(rule, &s->rules[event], next, next) {
|
||||
injected = process_rule(bs, rule, injected);
|
||||
}
|
||||
s->state = s->new_state;
|
||||
}
|
||||
|
||||
static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||
const char *tag)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
struct BlkdebugRule *rule;
|
||||
BlkDebugEvent blkdebug_event;
|
||||
|
||||
if (get_event_by_name(event, &blkdebug_event) < 0) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
rule = g_malloc(sizeof(*rule));
|
||||
*rule = (struct BlkdebugRule) {
|
||||
.event = blkdebug_event,
|
||||
.action = ACTION_SUSPEND,
|
||||
.state = 0,
|
||||
.options.suspend.tag = g_strdup(tag),
|
||||
};
|
||||
|
||||
QLIST_INSERT_HEAD(&s->rules[blkdebug_event], rule, next);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blkdebug_debug_resume(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
BlkdebugSuspendedReq *r;
|
||||
|
||||
QLIST_FOREACH(r, &s->suspended_reqs, next) {
|
||||
if (!strcmp(r->tag, tag)) {
|
||||
qemu_coroutine_enter(r->co, NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
BlkdebugSuspendedReq *r;
|
||||
|
||||
QLIST_FOREACH(r, &s->suspended_reqs, next) {
|
||||
if (!strcmp(r->tag, tag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
{
|
||||
return bdrv_getlength(bs->file);
|
||||
|
@ -465,6 +581,9 @@ static BlockDriver bdrv_blkdebug = {
|
|||
.bdrv_aio_writev = blkdebug_aio_writev,
|
||||
|
||||
.bdrv_debug_event = blkdebug_debug_event,
|
||||
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
|
||||
.bdrv_debug_resume = blkdebug_debug_resume,
|
||||
.bdrv_debug_is_suspended = blkdebug_debug_is_suspended,
|
||||
};
|
||||
|
||||
static void bdrv_blkdebug_init(void)
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "qemu_socket.h" /* for EINPROGRESS on Windows */
|
||||
#include "block_int.h"
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "block/block_int.h"
|
||||
|
||||
typedef struct {
|
||||
BlockDriverState *test_file;
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
|
||||
typedef struct BDRVCloopState {
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
*/
|
||||
|
||||
#include "trace.h"
|
||||
#include "block_int.h"
|
||||
#include "blockjob.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "qemu/ratelimit.h"
|
||||
|
||||
enum {
|
||||
|
@ -103,7 +103,7 @@ static void coroutine_fn commit_run(void *opaque)
|
|||
|
||||
wait:
|
||||
/* Note that even when no rate limit is applied we need to yield
|
||||
* with no pending I/O here so that qemu_aio_flush() returns.
|
||||
* with no pending I/O here so that bdrv_drain_all() returns.
|
||||
*/
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
/**************************************************************/
|
||||
/* COW block driver using file system holes */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
// #define DEBUG
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "bswap.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
|
||||
typedef struct BDRVDMGState {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
#include <glusterfs/api/glfs.h>
|
||||
#include "block_int.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "uri.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/uri.h"
|
||||
|
||||
typedef struct GlusterAIOCB {
|
||||
BlockDriverAIOCB common;
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include <poll.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "block_int.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "block/block_int.h"
|
||||
#include "trace.h"
|
||||
#include "hw/scsi-defs.h"
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-aio.h"
|
||||
#include "qemu-queue.h"
|
||||
#include "block/aio.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "block/raw-aio.h"
|
||||
#include "event_notifier.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
|
||||
#include <libaio.h>
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
*/
|
||||
|
||||
#include "trace.h"
|
||||
#include "blockjob.h"
|
||||
#include "block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/ratelimit.h"
|
||||
|
||||
enum {
|
||||
|
@ -205,7 +205,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
|||
}
|
||||
|
||||
/* Note that even when no rate limit is applied we need to yield
|
||||
* with no pending I/O here so that qemu_aio_flush() returns.
|
||||
* with no pending I/O here so that bdrv_drain_all() returns.
|
||||
*/
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
|
|
10
block/nbd.c
10
block/nbd.c
|
@ -27,11 +27,11 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "nbd.h"
|
||||
#include "uri.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "block/nbd.h"
|
||||
#include "qemu/uri.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
#include "aes.h"
|
||||
#include "migration.h"
|
||||
#include "block/aes.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
/**************************************************************/
|
||||
/* QEMU COW block driver with compression and encryption support */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qcow2.h"
|
||||
#include "trace.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <zlib.h>
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
#include "trace.h"
|
||||
|
||||
|
@ -615,57 +615,67 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
|
|||
return cluster_offset;
|
||||
}
|
||||
|
||||
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
|
||||
static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int i, j = 0, l2_index, ret;
|
||||
uint64_t *old_cluster, start_sect, *l2_table;
|
||||
uint64_t cluster_offset = m->alloc_offset;
|
||||
bool cow = false;
|
||||
int ret;
|
||||
|
||||
trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters);
|
||||
|
||||
if (m->nb_clusters == 0)
|
||||
if (r->nb_sectors == 0) {
|
||||
return 0;
|
||||
|
||||
old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
|
||||
|
||||
/* copy content of unmodified sectors */
|
||||
start_sect = (m->offset & ~(s->cluster_size - 1)) >> 9;
|
||||
if (m->n_start) {
|
||||
cow = true;
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
ret = copy_sectors(bs, start_sect, cluster_offset, 0, m->n_start);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (m->nb_available & (s->cluster_sectors - 1)) {
|
||||
cow = true;
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
ret = copy_sectors(bs, start_sect, cluster_offset, m->nb_available,
|
||||
align_offset(m->nb_available, s->cluster_sectors));
|
||||
ret = copy_sectors(bs, m->offset / BDRV_SECTOR_SIZE, m->alloc_offset,
|
||||
r->offset / BDRV_SECTOR_SIZE,
|
||||
r->offset / BDRV_SECTOR_SIZE + r->nb_sectors);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update L2 table.
|
||||
*
|
||||
* Before we update the L2 table to actually point to the new cluster, we
|
||||
* need to be sure that the refcounts have been increased and COW was
|
||||
* handled.
|
||||
*/
|
||||
if (cow) {
|
||||
qcow2_cache_depends_on_flush(s->l2_table_cache);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int i, j = 0, l2_index, ret;
|
||||
uint64_t *old_cluster, *l2_table;
|
||||
uint64_t cluster_offset = m->alloc_offset;
|
||||
|
||||
trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters);
|
||||
assert(m->nb_clusters > 0);
|
||||
|
||||
old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
|
||||
|
||||
/* copy content of unmodified sectors */
|
||||
ret = perform_cow(bs, m, &m->cow_start);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = perform_cow(bs, m, &m->cow_end);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Update L2 table. */
|
||||
if (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS) {
|
||||
qcow2_mark_dirty(bs);
|
||||
}
|
||||
if (qcow2_need_accurate_refcounts(s)) {
|
||||
qcow2_cache_set_dependency(bs, s->l2_table_cache,
|
||||
s->refcount_block_cache);
|
||||
}
|
||||
|
||||
ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
|
@ -742,39 +752,17 @@ out:
|
|||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates new clusters for the given guest_offset.
|
||||
*
|
||||
* At most *nb_clusters are allocated, and on return *nb_clusters is updated to
|
||||
* contain the number of clusters that have been allocated and are contiguous
|
||||
* in the image file.
|
||||
*
|
||||
* If *host_offset is non-zero, it specifies the offset in the image file at
|
||||
* which the new clusters must start. *nb_clusters can be 0 on return in this
|
||||
* case if the cluster at host_offset is already in use. If *host_offset is
|
||||
* zero, the clusters can be allocated anywhere in the image file.
|
||||
*
|
||||
* *host_offset is updated to contain the offset into the image file at which
|
||||
* the first allocated cluster starts.
|
||||
*
|
||||
* Return 0 on success and -errno in error cases. -EAGAIN means that the
|
||||
* function has been waiting for another request and the allocation must be
|
||||
* restarted, but the whole request should not be failed.
|
||||
*/
|
||||
static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
||||
uint64_t *host_offset, unsigned int *nb_clusters)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
QCowL2Meta *old_alloc;
|
||||
|
||||
trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset,
|
||||
*host_offset, *nb_clusters);
|
||||
|
||||
/*
|
||||
* Check if there already is an AIO write request in flight which allocates
|
||||
* the same cluster. In this case we need to wait until the previous
|
||||
* request has completed and updated the L2 table accordingly.
|
||||
*/
|
||||
static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset,
|
||||
unsigned int *nb_clusters)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
QCowL2Meta *old_alloc;
|
||||
|
||||
QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) {
|
||||
|
||||
uint64_t start = guest_offset >> s->cluster_bits;
|
||||
|
@ -807,6 +795,42 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
|||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates new clusters for the given guest_offset.
|
||||
*
|
||||
* At most *nb_clusters are allocated, and on return *nb_clusters is updated to
|
||||
* contain the number of clusters that have been allocated and are contiguous
|
||||
* in the image file.
|
||||
*
|
||||
* If *host_offset is non-zero, it specifies the offset in the image file at
|
||||
* which the new clusters must start. *nb_clusters can be 0 on return in this
|
||||
* case if the cluster at host_offset is already in use. If *host_offset is
|
||||
* zero, the clusters can be allocated anywhere in the image file.
|
||||
*
|
||||
* *host_offset is updated to contain the offset into the image file at which
|
||||
* the first allocated cluster starts.
|
||||
*
|
||||
* Return 0 on success and -errno in error cases. -EAGAIN means that the
|
||||
* function has been waiting for another request and the allocation must be
|
||||
* restarted, but the whole request should not be failed.
|
||||
*/
|
||||
static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
||||
uint64_t *host_offset, unsigned int *nb_clusters)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset,
|
||||
*host_offset, *nb_clusters);
|
||||
|
||||
ret = handle_dependencies(bs, guest_offset, nb_clusters);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate new clusters */
|
||||
trace_qcow2_cluster_alloc_phys(qemu_coroutine_self());
|
||||
if (*host_offset == 0) {
|
||||
|
@ -818,7 +842,7 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
|||
*host_offset = cluster_offset;
|
||||
return 0;
|
||||
} else {
|
||||
int ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters);
|
||||
ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -847,7 +871,7 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
|||
* Return 0 on success and -errno in error cases
|
||||
*/
|
||||
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
int n_start, int n_end, int *num, QCowL2Meta *m)
|
||||
int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int l2_index, ret, sectors;
|
||||
|
@ -919,12 +943,6 @@ again:
|
|||
}
|
||||
|
||||
/* If there is something left to allocate, do that now */
|
||||
*m = (QCowL2Meta) {
|
||||
.cluster_offset = cluster_offset,
|
||||
.nb_clusters = 0,
|
||||
};
|
||||
qemu_co_queue_init(&m->dependent_requests);
|
||||
|
||||
if (nb_clusters > 0) {
|
||||
uint64_t alloc_offset;
|
||||
uint64_t alloc_cluster_offset;
|
||||
|
@ -957,22 +975,40 @@ again:
|
|||
*
|
||||
* avail_sectors: Number of sectors from the start of the first
|
||||
* newly allocated to the end of the last newly allocated cluster.
|
||||
*
|
||||
* nb_sectors: The number of sectors from the start of the first
|
||||
* newly allocated cluster to the end of the aread that the write
|
||||
* request actually writes to (excluding COW at the end)
|
||||
*/
|
||||
int requested_sectors = n_end - keep_clusters * s->cluster_sectors;
|
||||
int avail_sectors = nb_clusters
|
||||
<< (s->cluster_bits - BDRV_SECTOR_BITS);
|
||||
int alloc_n_start = keep_clusters == 0 ? n_start : 0;
|
||||
int nb_sectors = MIN(requested_sectors, avail_sectors);
|
||||
|
||||
*m = (QCowL2Meta) {
|
||||
.cluster_offset = keep_clusters == 0 ?
|
||||
alloc_cluster_offset : cluster_offset,
|
||||
if (keep_clusters == 0) {
|
||||
cluster_offset = alloc_cluster_offset;
|
||||
}
|
||||
|
||||
*m = g_malloc0(sizeof(**m));
|
||||
|
||||
**m = (QCowL2Meta) {
|
||||
.alloc_offset = alloc_cluster_offset,
|
||||
.offset = alloc_offset,
|
||||
.n_start = keep_clusters == 0 ? n_start : 0,
|
||||
.offset = alloc_offset & ~(s->cluster_size - 1),
|
||||
.nb_clusters = nb_clusters,
|
||||
.nb_available = MIN(requested_sectors, avail_sectors),
|
||||
.nb_available = nb_sectors,
|
||||
|
||||
.cow_start = {
|
||||
.offset = 0,
|
||||
.nb_sectors = alloc_n_start,
|
||||
},
|
||||
.cow_end = {
|
||||
.offset = nb_sectors * BDRV_SECTOR_SIZE,
|
||||
.nb_sectors = avail_sectors - nb_sectors,
|
||||
},
|
||||
};
|
||||
qemu_co_queue_init(&m->dependent_requests);
|
||||
QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight);
|
||||
qemu_co_queue_init(&(*m)->dependent_requests);
|
||||
QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -984,12 +1020,13 @@ again:
|
|||
|
||||
assert(sectors > n_start);
|
||||
*num = sectors - n_start;
|
||||
*host_offset = cluster_offset;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (m->nb_clusters > 0) {
|
||||
QLIST_REMOVE(m, next_in_flight);
|
||||
if (*m && (*m)->nb_clusters > 0) {
|
||||
QLIST_REMOVE(*m, next_in_flight);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
|
||||
static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/qcow2.h"
|
||||
|
||||
typedef struct QEMU_PACKED QCowSnapshotHeader {
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
#include "aes.h"
|
||||
#include "block/aes.h"
|
||||
#include "block/qcow2.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qerror.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "trace.h"
|
||||
|
||||
/*
|
||||
|
@ -222,7 +222,7 @@ static void report_unsupported_feature(BlockDriverState *bs,
|
|||
* updated successfully. Therefore it is not required to check the return
|
||||
* value of this function.
|
||||
*/
|
||||
static int qcow2_mark_dirty(BlockDriverState *bs)
|
||||
int qcow2_mark_dirty(BlockDriverState *bs)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
uint64_t val;
|
||||
|
@ -745,21 +745,6 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m)
|
||||
{
|
||||
/* Take the request off the list of running requests */
|
||||
if (m->nb_clusters != 0) {
|
||||
QLIST_REMOVE(m, next_in_flight);
|
||||
}
|
||||
|
||||
/* Restart all dependent requests */
|
||||
if (!qemu_co_queue_empty(&m->dependent_requests)) {
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
qemu_co_queue_restart_all(&m->dependent_requests);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
||||
int64_t sector_num,
|
||||
int remaining_sectors,
|
||||
|
@ -774,15 +759,11 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
QEMUIOVector hd_qiov;
|
||||
uint64_t bytes_done = 0;
|
||||
uint8_t *cluster_data = NULL;
|
||||
QCowL2Meta l2meta = {
|
||||
.nb_clusters = 0,
|
||||
};
|
||||
QCowL2Meta *l2meta;
|
||||
|
||||
trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num,
|
||||
remaining_sectors);
|
||||
|
||||
qemu_co_queue_init(&l2meta.dependent_requests);
|
||||
|
||||
qemu_iovec_init(&hd_qiov, qiov->niov);
|
||||
|
||||
s->cluster_cache_offset = -1; /* disable compressed cache */
|
||||
|
@ -791,6 +772,8 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
|
||||
while (remaining_sectors != 0) {
|
||||
|
||||
l2meta = NULL;
|
||||
|
||||
trace_qcow2_writev_start_part(qemu_coroutine_self());
|
||||
index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
||||
n_end = index_in_cluster + remaining_sectors;
|
||||
|
@ -800,17 +783,11 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
|
||||
index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
|
||||
index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, &l2meta);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (l2meta.nb_clusters > 0 &&
|
||||
(s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS)) {
|
||||
qcow2_mark_dirty(bs);
|
||||
}
|
||||
|
||||
cluster_offset = l2meta.cluster_offset;
|
||||
assert((cluster_offset & 511) == 0);
|
||||
|
||||
qemu_iovec_reset(&hd_qiov);
|
||||
|
@ -835,8 +812,8 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
cur_nr_sectors * 512);
|
||||
}
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
|
||||
trace_qcow2_writev_data(qemu_coroutine_self(),
|
||||
(cluster_offset >> 9) + index_in_cluster);
|
||||
ret = bdrv_co_writev(bs->file,
|
||||
|
@ -847,12 +824,24 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
|
||||
if (l2meta != NULL) {
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, l2meta);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
run_dependent_requests(s, &l2meta);
|
||||
/* Take the request off the list of running requests */
|
||||
if (l2meta->nb_clusters != 0) {
|
||||
QLIST_REMOVE(l2meta, next_in_flight);
|
||||
}
|
||||
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
qemu_co_queue_restart_all(&l2meta->dependent_requests);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
|
||||
g_free(l2meta);
|
||||
l2meta = NULL;
|
||||
}
|
||||
|
||||
remaining_sectors -= cur_nr_sectors;
|
||||
sector_num += cur_nr_sectors;
|
||||
|
@ -862,10 +851,16 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
|
|||
ret = 0;
|
||||
|
||||
fail:
|
||||
run_dependent_requests(s, &l2meta);
|
||||
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
|
||||
if (l2meta != NULL) {
|
||||
if (l2meta->nb_clusters != 0) {
|
||||
QLIST_REMOVE(l2meta, next_in_flight);
|
||||
}
|
||||
qemu_co_queue_restart_all(&l2meta->dependent_requests);
|
||||
g_free(l2meta);
|
||||
}
|
||||
|
||||
qemu_iovec_destroy(&hd_qiov);
|
||||
qemu_vfree(cluster_data);
|
||||
trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);
|
||||
|
@ -1128,31 +1123,33 @@ static int preallocate(BlockDriverState *bs)
|
|||
{
|
||||
uint64_t nb_sectors;
|
||||
uint64_t offset;
|
||||
uint64_t host_offset = 0;
|
||||
int num;
|
||||
int ret;
|
||||
QCowL2Meta meta;
|
||||
QCowL2Meta *meta;
|
||||
|
||||
nb_sectors = bdrv_getlength(bs) >> 9;
|
||||
offset = 0;
|
||||
qemu_co_queue_init(&meta.dependent_requests);
|
||||
meta.cluster_offset = 0;
|
||||
|
||||
while (nb_sectors) {
|
||||
num = MIN(nb_sectors, INT_MAX >> 9);
|
||||
ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta);
|
||||
ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num,
|
||||
&host_offset, &meta);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, &meta);
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, meta);
|
||||
if (ret < 0) {
|
||||
qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters);
|
||||
qcow2_free_any_clusters(bs, meta->alloc_offset, meta->nb_clusters);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* There are no dependent requests, but we need to remove our request
|
||||
* from the list of in-flight requests */
|
||||
run_dependent_requests(bs->opaque, &meta);
|
||||
if (meta != NULL) {
|
||||
QLIST_REMOVE(meta, next_in_flight);
|
||||
}
|
||||
|
||||
/* TODO Preallocate data if requested */
|
||||
|
||||
|
@ -1165,10 +1162,10 @@ static int preallocate(BlockDriverState *bs)
|
|||
* all of the allocated clusters (otherwise we get failing reads after
|
||||
* EOF). Extend the image to the last allocated sector.
|
||||
*/
|
||||
if (meta.cluster_offset != 0) {
|
||||
if (host_offset != 0) {
|
||||
uint8_t buf[512];
|
||||
memset(buf, 0, 512);
|
||||
ret = bdrv_write(bs->file, (meta.cluster_offset >> 9) + num - 1, buf, 1);
|
||||
ret = bdrv_write(bs->file, (host_offset >> 9) + num - 1, buf, 1);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#ifndef BLOCK_QCOW2_H
|
||||
#define BLOCK_QCOW2_H
|
||||
|
||||
#include "aes.h"
|
||||
#include "qemu-coroutine.h"
|
||||
#include "block/aes.h"
|
||||
#include "block/coroutine.h"
|
||||
|
||||
//#define DEBUG_ALLOC
|
||||
//#define DEBUG_ALLOC2
|
||||
|
@ -196,17 +196,56 @@ typedef struct QCowCreateState {
|
|||
|
||||
struct QCowAIOCB;
|
||||
|
||||
/* XXX This could be private for qcow2-cluster.c */
|
||||
typedef struct Qcow2COWRegion {
|
||||
/**
|
||||
* Offset of the COW region in bytes from the start of the first cluster
|
||||
* touched by the request.
|
||||
*/
|
||||
uint64_t offset;
|
||||
|
||||
/** Number of sectors to copy */
|
||||
int nb_sectors;
|
||||
} Qcow2COWRegion;
|
||||
|
||||
/**
|
||||
* Describes an in-flight (part of a) write request that writes to clusters
|
||||
* that are not referenced in their L2 table yet.
|
||||
*/
|
||||
typedef struct QCowL2Meta
|
||||
{
|
||||
/** Guest offset of the first newly allocated cluster */
|
||||
uint64_t offset;
|
||||
uint64_t cluster_offset;
|
||||
|
||||
/** Host offset of the first newly allocated cluster */
|
||||
uint64_t alloc_offset;
|
||||
int n_start;
|
||||
|
||||
/**
|
||||
* Number of sectors from the start of the first allocated cluster to
|
||||
* the end of the (possibly shortened) request
|
||||
*/
|
||||
int nb_available;
|
||||
|
||||
/** Number of newly allocated clusters */
|
||||
int nb_clusters;
|
||||
|
||||
/**
|
||||
* Requests that overlap with this allocation and wait to be restarted
|
||||
* when the allocating request has completed.
|
||||
*/
|
||||
CoQueue dependent_requests;
|
||||
|
||||
/**
|
||||
* The COW Region between the start of the first allocated cluster and the
|
||||
* area the guest actually writes to.
|
||||
*/
|
||||
Qcow2COWRegion cow_start;
|
||||
|
||||
/**
|
||||
* The COW Region between the area the guest actually writes to and the
|
||||
* end of the last allocated cluster.
|
||||
*/
|
||||
Qcow2COWRegion cow_end;
|
||||
|
||||
QLIST_ENTRY(QCowL2Meta) next_in_flight;
|
||||
} QCowL2Meta;
|
||||
|
||||
|
@ -264,6 +303,8 @@ static inline bool qcow2_need_accurate_refcounts(BDRVQcowState *s)
|
|||
/* qcow2.c functions */
|
||||
int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
|
||||
int64_t sector_num, int nb_sectors);
|
||||
|
||||
int qcow2_mark_dirty(BlockDriverState *bs);
|
||||
int qcow2_update_header(BlockDriverState *bs);
|
||||
|
||||
/* qcow2-refcount.c functions */
|
||||
|
@ -297,7 +338,7 @@ void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
|
|||
int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
int *num, uint64_t *cluster_offset);
|
||||
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
int n_start, int n_end, int *num, QCowL2Meta *m);
|
||||
int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m);
|
||||
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
|
||||
uint64_t offset,
|
||||
int compressed_size);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
|
||||
#include "trace.h"
|
||||
#include "qemu_socket.h" /* for EINPROGRESS on Windows */
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "qed.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "trace.h"
|
||||
#include "qed.h"
|
||||
#include "qerror.h"
|
||||
#include "migration.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef BLOCK_QED_H
|
||||
#define BLOCK_QED_H
|
||||
|
||||
#include "block_int.h"
|
||||
#include "block/block_int.h"
|
||||
|
||||
/* The layout of a QED file is as follows:
|
||||
*
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-log.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/log.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "trace.h"
|
||||
#include "thread-pool.h"
|
||||
#include "iov.h"
|
||||
#include "block/thread-pool.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "raw-aio.h"
|
||||
|
||||
#if defined(__APPLE__) && (__MACH__)
|
||||
|
@ -708,22 +707,6 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
|
|||
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,
|
||||
unsigned long int req, void *buf,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
|
||||
|
||||
acb->bs = bs;
|
||||
acb->aio_type = QEMU_AIO_IOCTL;
|
||||
acb->aio_fildes = fd;
|
||||
acb->aio_offset = 0;
|
||||
acb->aio_ioctl_buf = buf;
|
||||
acb->aio_ioctl_cmd = req;
|
||||
|
||||
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockDriverCompletionFunc *cb, void *opaque, int type)
|
||||
|
@ -1346,10 +1329,19 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
|
|||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
RawPosixAIOData *acb;
|
||||
|
||||
if (fd_open(bs) < 0)
|
||||
return NULL;
|
||||
return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
|
||||
|
||||
acb = g_slice_new(RawPosixAIOData);
|
||||
acb->bs = bs;
|
||||
acb->aio_type = QEMU_AIO_IOCTL;
|
||||
acb->aio_fildes = s->fd;
|
||||
acb->aio_offset = 0;
|
||||
acb->aio_ioctl_buf = buf;
|
||||
acb->aio_ioctl_cmd = req;
|
||||
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "raw-aio.h"
|
||||
#include "trace.h"
|
||||
#include "thread-pool.h"
|
||||
#include "iov.h"
|
||||
#include "block/thread-pool.h"
|
||||
#include "qemu/iov.h"
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
|
@ -303,13 +303,24 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset)
|
|||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
LONG low, high;
|
||||
DWORD dwPtrLow;
|
||||
|
||||
low = offset;
|
||||
high = offset >> 32;
|
||||
if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
|
||||
|
||||
/*
|
||||
* An error has occurred if the return value is INVALID_SET_FILE_POINTER
|
||||
* and GetLastError doesn't return NO_ERROR.
|
||||
*/
|
||||
dwPtrLow = SetFilePointer(s->hfile, low, &high, FILE_BEGIN);
|
||||
if (dwPtrLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
|
||||
fprintf(stderr, "SetFilePointer error: %d\n", GetLastError());
|
||||
return -EIO;
|
||||
if (!SetEndOfFile(s->hfile))
|
||||
}
|
||||
if (SetEndOfFile(s->hfile) == 0) {
|
||||
fprintf(stderr, "SetEndOfFile error: %d\n", GetLastError());
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
static int raw_open(BlockDriverState *bs, int flags)
|
||||
{
|
||||
|
|
22
block/rbd.c
22
block/rbd.c
|
@ -14,8 +14,8 @@
|
|||
#include <inttypes.h>
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "block_int.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "block/block_int.h"
|
||||
|
||||
#include <rbd/librbd.h>
|
||||
|
||||
|
@ -77,6 +77,7 @@ typedef struct RBDAIOCB {
|
|||
int error;
|
||||
struct BDRVRBDState *s;
|
||||
int cancelled;
|
||||
int status;
|
||||
} RBDAIOCB;
|
||||
|
||||
typedef struct RADOSCB {
|
||||
|
@ -376,12 +377,6 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
|||
RBDAIOCB *acb = rcb->acb;
|
||||
int64_t r;
|
||||
|
||||
if (acb->cancelled) {
|
||||
qemu_vfree(acb->bounce);
|
||||
qemu_aio_release(acb);
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = rcb->ret;
|
||||
|
||||
if (acb->cmd == RBD_AIO_WRITE ||
|
||||
|
@ -409,7 +404,6 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
|||
/* Note that acb->bh can be NULL in case where the aio was cancelled */
|
||||
acb->bh = qemu_bh_new(rbd_aio_bh_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
done:
|
||||
g_free(rcb);
|
||||
}
|
||||
|
||||
|
@ -568,6 +562,12 @@ static void qemu_rbd_aio_cancel(BlockDriverAIOCB *blockacb)
|
|||
{
|
||||
RBDAIOCB *acb = (RBDAIOCB *) blockacb;
|
||||
acb->cancelled = 1;
|
||||
|
||||
while (acb->status == -EINPROGRESS) {
|
||||
qemu_aio_wait();
|
||||
}
|
||||
|
||||
qemu_aio_release(acb);
|
||||
}
|
||||
|
||||
static const AIOCBInfo rbd_aiocb_info = {
|
||||
|
@ -639,9 +639,12 @@ static void rbd_aio_bh_cb(void *opaque)
|
|||
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
|
||||
qemu_bh_delete(acb->bh);
|
||||
acb->bh = NULL;
|
||||
acb->status = 0;
|
||||
|
||||
if (!acb->cancelled) {
|
||||
qemu_aio_release(acb);
|
||||
}
|
||||
}
|
||||
|
||||
static int rbd_aio_discard_wrapper(rbd_image_t image,
|
||||
uint64_t off,
|
||||
|
@ -685,6 +688,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
|||
acb->s = s;
|
||||
acb->cancelled = 0;
|
||||
acb->bh = NULL;
|
||||
acb->status = -EINPROGRESS;
|
||||
|
||||
if (cmd == RBD_AIO_WRITE) {
|
||||
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "block_int.h"
|
||||
#include "bitops.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/bitops.h"
|
||||
|
||||
#define SD_PROTO_VER 0x01
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
*/
|
||||
|
||||
#include "trace.h"
|
||||
#include "block_int.h"
|
||||
#include "blockjob.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "qemu/ratelimit.h"
|
||||
|
||||
enum {
|
||||
|
@ -108,7 +108,7 @@ static void coroutine_fn stream_run(void *opaque)
|
|||
|
||||
wait:
|
||||
/* Note that even when no rate limit is applied we need to yield
|
||||
* with no pending I/O here so that qemu_aio_flush() returns.
|
||||
* with no pending I/O here so that bdrv_drain_all() returns.
|
||||
*/
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
|
|
|
@ -50,15 +50,15 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "migration.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
#if defined(CONFIG_UUID)
|
||||
#include <uuid/uuid.h>
|
||||
#else
|
||||
/* TODO: move uuid emulation to some central place in QEMU. */
|
||||
#include "sysemu.h" /* UUID_FMT */
|
||||
#include "sysemu/sysemu.h" /* UUID_FMT */
|
||||
typedef unsigned char uuid_t[16];
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "migration.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
|
||||
|
|
28
block/vpc.c
28
block/vpc.c
|
@ -23,9 +23,12 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "migration.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
#if defined(CONFIG_UUID)
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
|
@ -198,7 +201,8 @@ static int vpc_open(BlockDriverState *bs, int flags)
|
|||
bs->total_sectors = (int64_t)
|
||||
be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
|
||||
|
||||
if (bs->total_sectors >= 65535 * 16 * 255) {
|
||||
/* Allow a maximum disk size of approximately 2 TB */
|
||||
if (bs->total_sectors >= 65535LL * 255 * 255) {
|
||||
err = -EFBIG;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -524,19 +528,27 @@ static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
|
|||
* Note that the geometry doesn't always exactly match total_sectors but
|
||||
* may round it down.
|
||||
*
|
||||
* Returns 0 on success, -EFBIG if the size is larger than 127 GB
|
||||
* Returns 0 on success, -EFBIG if the size is larger than ~2 TB. Override
|
||||
* the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
|
||||
* and instead allow up to 255 heads.
|
||||
*/
|
||||
static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
||||
uint8_t* heads, uint8_t* secs_per_cyl)
|
||||
{
|
||||
uint32_t cyls_times_heads;
|
||||
|
||||
if (total_sectors > 65535 * 16 * 255)
|
||||
/* Allow a maximum disk size of approximately 2 TB */
|
||||
if (total_sectors > 65535LL * 255 * 255) {
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
if (total_sectors > 65535 * 16 * 63) {
|
||||
*secs_per_cyl = 255;
|
||||
if (total_sectors > 65535 * 16 * 255) {
|
||||
*heads = 255;
|
||||
} else {
|
||||
*heads = 16;
|
||||
}
|
||||
cyls_times_heads = total_sectors / *secs_per_cyl;
|
||||
} else {
|
||||
*secs_per_cyl = 17;
|
||||
|
@ -739,7 +751,9 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
|
|||
|
||||
footer->type = be32_to_cpu(disk_type);
|
||||
|
||||
/* TODO uuid is missing */
|
||||
#if defined(CONFIG_UUID)
|
||||
uuid_generate(footer->uuid);
|
||||
#endif
|
||||
|
||||
footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include "qemu-common.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "migration.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
#ifndef S_IWGRP
|
||||
#define S_IWGRP 0
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-aio.h"
|
||||
#include "block/aio.h"
|
||||
#include "raw-aio.h"
|
||||
#include "event_notifier.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
* later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "blockdev.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "hw/block-common.h"
|
||||
#include "monitor.h"
|
||||
#include "qerror.h"
|
||||
#include "sysemu.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "trace.h"
|
||||
#include "nbd.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "block/nbd.h"
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
static int server_fd = -1;
|
||||
|
||||
|
|
47
blockdev.c
47
blockdev.c
|
@ -7,19 +7,19 @@
|
|||
* later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "blockdev.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "hw/block-common.h"
|
||||
#include "blockjob.h"
|
||||
#include "monitor.h"
|
||||
#include "qerror.h"
|
||||
#include "qemu-option.h"
|
||||
#include "qemu-config.h"
|
||||
#include "qemu-objects.h"
|
||||
#include "sysemu.h"
|
||||
#include "block_int.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qapi/qmp/types.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "trace.h"
|
||||
#include "arch_init.h"
|
||||
#include "sysemu/arch_init.h"
|
||||
|
||||
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
|
||||
|
||||
|
@ -275,7 +275,7 @@ static bool do_check_io_limits(BlockIOLimit *io_limits)
|
|||
return true;
|
||||
}
|
||||
|
||||
DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
|
||||
DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType block_default_type)
|
||||
{
|
||||
const char *buf;
|
||||
const char *file = NULL;
|
||||
|
@ -328,7 +328,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
|
|||
return NULL;
|
||||
}
|
||||
} else {
|
||||
type = default_to_scsi ? IF_SCSI : IF_IDE;
|
||||
type = block_default_type;
|
||||
}
|
||||
|
||||
max_devs = if_max_devs[type];
|
||||
|
@ -572,7 +572,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
|
|||
break;
|
||||
case IF_VIRTIO:
|
||||
/* add virtio block device */
|
||||
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
|
||||
opts = qemu_opts_create_nofail(qemu_find_opts("device"));
|
||||
if (arch_type == QEMU_ARCH_S390X) {
|
||||
qemu_opt_set(opts, "driver", "virtio-blk-s390");
|
||||
} else {
|
||||
|
@ -711,6 +711,7 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
|
|||
int ret = 0;
|
||||
BlockdevActionList *dev_entry = dev_list;
|
||||
BlkTransactionStates *states, *next;
|
||||
Error *local_err = NULL;
|
||||
|
||||
QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;
|
||||
QSIMPLEQ_INIT(&snap_bdrv_states);
|
||||
|
@ -790,12 +791,12 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
|
|||
|
||||
/* create new image w/backing file */
|
||||
if (mode != NEW_IMAGE_MODE_EXISTING) {
|
||||
ret = bdrv_img_create(new_image_file, format,
|
||||
bdrv_img_create(new_image_file, format,
|
||||
states->old_bs->filename,
|
||||
states->old_bs->drv->format_name,
|
||||
NULL, -1, flags);
|
||||
if (ret) {
|
||||
error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);
|
||||
NULL, -1, flags, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_propagate(errp, local_err);
|
||||
goto delete_and_fail;
|
||||
}
|
||||
}
|
||||
|
@ -1267,8 +1268,8 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||
assert(format && drv);
|
||||
bdrv_get_geometry(bs, &size);
|
||||
size *= 512;
|
||||
ret = bdrv_img_create(target, format,
|
||||
NULL, NULL, NULL, size, flags);
|
||||
bdrv_img_create(target, format,
|
||||
NULL, NULL, NULL, size, flags, &local_err);
|
||||
} else {
|
||||
switch (mode) {
|
||||
case NEW_IMAGE_MODE_EXISTING:
|
||||
|
@ -1276,18 +1277,18 @@ void qmp_drive_mirror(const char *device, const char *target,
|
|||
break;
|
||||
case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
|
||||
/* create new image with backing file */
|
||||
ret = bdrv_img_create(target, format,
|
||||
bdrv_img_create(target, format,
|
||||
source->filename,
|
||||
source->drv->format_name,
|
||||
NULL, -1, flags);
|
||||
NULL, -1, flags, &local_err);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
error_set(errp, QERR_OPEN_FILE_FAILED, target);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
14
blockjob.c
14
blockjob.c
|
@ -26,14 +26,14 @@
|
|||
#include "config-host.h"
|
||||
#include "qemu-common.h"
|
||||
#include "trace.h"
|
||||
#include "monitor.h"
|
||||
#include "block.h"
|
||||
#include "blockjob.h"
|
||||
#include "block_int.h"
|
||||
#include "qjson.h"
|
||||
#include "qemu-coroutine.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "block/block.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "block/coroutine.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
|
||||
int64_t speed, BlockDriverCompletionFunc *cb,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "qemu.h"
|
||||
#include "disas.h"
|
||||
#include "disas/disas.h"
|
||||
|
||||
#ifdef _ARCH_PPC64
|
||||
#undef ARCH_DLINFO
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
/* For tb_lock */
|
||||
#include "cpu.h"
|
||||
#include "tcg.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "envlist.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/envlist.h"
|
||||
|
||||
#define DEBUG_LOGFILE "/tmp/qemu.log"
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef QEMU_TYPES_H
|
||||
#define QEMU_TYPES_H
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
typedef uint32_t abi_ulong;
|
||||
typedef int32_t abi_long;
|
||||
#define TARGET_ABI_FMT_lx "%08x"
|
||||
#define TARGET_ABI_FMT_ld "%d"
|
||||
#define TARGET_ABI_FMT_lu "%u"
|
||||
#define TARGET_ABI_BITS 32
|
||||
#else
|
||||
typedef target_ulong abi_ulong;
|
||||
typedef target_long abi_long;
|
||||
#define TARGET_ABI_FMT_lx TARGET_FMT_lx
|
||||
#define TARGET_ABI_FMT_ld TARGET_FMT_ld
|
||||
#define TARGET_ABI_FMT_lu TARGET_FMT_lu
|
||||
#define TARGET_ABI_BITS TARGET_LONG_BITS
|
||||
/* for consistency, define ABI32 too */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
#define TARGET_ABI32 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
|
@ -11,7 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
#endif /* DEBUG_REMAP */
|
||||
|
||||
#include "qemu-types.h"
|
||||
#include "exec/user/abitypes.h"
|
||||
|
||||
enum BSDType {
|
||||
target_freebsd,
|
||||
|
@ -23,7 +23,7 @@ extern enum BSDType bsd_type;
|
|||
#include "syscall_defs.h"
|
||||
#include "syscall.h"
|
||||
#include "target_signal.h"
|
||||
#include "gdbstub.h"
|
||||
#include "exec/gdbstub.h"
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#define THREAD __thread
|
||||
|
@ -146,7 +146,7 @@ int get_osversion(void);
|
|||
void fork_start(void);
|
||||
void fork_end(int child);
|
||||
|
||||
#include "qemu-log.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
/* strace.c */
|
||||
void
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-char.h"
|
||||
#include "net.h"
|
||||
#include "bt-host.h"
|
||||
#include "bt/bt.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <errno.h>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef BT_HOST_H
|
||||
#define BT_HOST_H
|
||||
|
||||
struct HCIInfo;
|
||||
|
||||
/* bt-host.c */
|
||||
struct HCIInfo *bt_host_hci(const char *id);
|
||||
|
||||
#endif
|
|
@ -18,9 +18,9 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-char.h"
|
||||
#include "net.h"
|
||||
#include "bt/bt.h"
|
||||
#include "hw/bt.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
#define VHCI_DEV "/dev/vhci"
|
||||
#define VHCI_UDEV "/dev/hci_vhci"
|
||||
|
|
269
buffered_file.c
269
buffered_file.c
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
* QEMU buffered QEMUFile
|
||||
*
|
||||
* Copyright IBM, Corp. 2008
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
* GNU GPL, version 2 or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "hw/hw.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu-char.h"
|
||||
#include "buffered_file.h"
|
||||
|
||||
//#define DEBUG_BUFFERED_FILE
|
||||
|
||||
typedef struct QEMUFileBuffered
|
||||
{
|
||||
MigrationState *migration_state;
|
||||
QEMUFile *file;
|
||||
int freeze_output;
|
||||
size_t bytes_xfer;
|
||||
size_t xfer_limit;
|
||||
uint8_t *buffer;
|
||||
size_t buffer_size;
|
||||
size_t buffer_capacity;
|
||||
QEMUTimer *timer;
|
||||
} QEMUFileBuffered;
|
||||
|
||||
#ifdef DEBUG_BUFFERED_FILE
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { printf("buffered-file: " fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
static void buffered_append(QEMUFileBuffered *s,
|
||||
const uint8_t *buf, size_t size)
|
||||
{
|
||||
if (size > (s->buffer_capacity - s->buffer_size)) {
|
||||
DPRINTF("increasing buffer capacity from %zu by %zu\n",
|
||||
s->buffer_capacity, size + 1024);
|
||||
|
||||
s->buffer_capacity += size + 1024;
|
||||
|
||||
s->buffer = g_realloc(s->buffer, s->buffer_capacity);
|
||||
}
|
||||
|
||||
memcpy(s->buffer + s->buffer_size, buf, size);
|
||||
s->buffer_size += size;
|
||||
}
|
||||
|
||||
static ssize_t buffered_flush(QEMUFileBuffered *s)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ssize_t ret = 0;
|
||||
|
||||
DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size);
|
||||
|
||||
while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) {
|
||||
|
||||
ret = migrate_fd_put_buffer(s->migration_state, s->buffer + offset,
|
||||
s->buffer_size - offset);
|
||||
if (ret == -EAGAIN) {
|
||||
DPRINTF("backend not ready, freezing\n");
|
||||
ret = 0;
|
||||
s->freeze_output = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
DPRINTF("error flushing data, %zd\n", ret);
|
||||
break;
|
||||
} else {
|
||||
DPRINTF("flushed %zd byte(s)\n", ret);
|
||||
offset += ret;
|
||||
s->bytes_xfer += ret;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTF("flushed %zu of %zu byte(s)\n", offset, s->buffer_size);
|
||||
memmove(s->buffer, s->buffer + offset, s->buffer_size - offset);
|
||||
s->buffer_size -= offset;
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
ssize_t error;
|
||||
|
||||
DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos);
|
||||
|
||||
error = qemu_file_get_error(s->file);
|
||||
if (error) {
|
||||
DPRINTF("flush when error, bailing: %s\n", strerror(-error));
|
||||
return error;
|
||||
}
|
||||
|
||||
DPRINTF("unfreezing output\n");
|
||||
s->freeze_output = 0;
|
||||
|
||||
if (size > 0) {
|
||||
DPRINTF("buffering %d bytes\n", size - offset);
|
||||
buffered_append(s, buf, size);
|
||||
}
|
||||
|
||||
error = buffered_flush(s);
|
||||
if (error < 0) {
|
||||
DPRINTF("buffered flush error. bailing: %s\n", strerror(-error));
|
||||
return error;
|
||||
}
|
||||
|
||||
if (pos == 0 && size == 0) {
|
||||
DPRINTF("file is ready\n");
|
||||
if (!s->freeze_output && s->bytes_xfer < s->xfer_limit) {
|
||||
DPRINTF("notifying client\n");
|
||||
migrate_fd_put_ready(s->migration_state);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int buffered_close(void *opaque)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
ssize_t ret = 0;
|
||||
int ret2;
|
||||
|
||||
DPRINTF("closing\n");
|
||||
|
||||
s->xfer_limit = INT_MAX;
|
||||
while (!qemu_file_get_error(s->file) && s->buffer_size) {
|
||||
ret = buffered_flush(s);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
if (s->freeze_output) {
|
||||
ret = migrate_fd_wait_for_unfreeze(s->migration_state);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret2 = migrate_fd_close(s->migration_state);
|
||||
if (ret >= 0) {
|
||||
ret = ret2;
|
||||
}
|
||||
qemu_del_timer(s->timer);
|
||||
qemu_free_timer(s->timer);
|
||||
g_free(s->buffer);
|
||||
g_free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The meaning of the return values is:
|
||||
* 0: We can continue sending
|
||||
* 1: Time to stop
|
||||
* negative: There has been an error
|
||||
*/
|
||||
static int buffered_get_fd(void *opaque)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
|
||||
return qemu_get_fd(s->file);
|
||||
}
|
||||
|
||||
static int buffered_rate_limit(void *opaque)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
int ret;
|
||||
|
||||
ret = qemu_file_get_error(s->file);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
if (s->freeze_output)
|
||||
return 1;
|
||||
|
||||
if (s->bytes_xfer > s->xfer_limit)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t buffered_set_rate_limit(void *opaque, int64_t new_rate)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
if (qemu_file_get_error(s->file)) {
|
||||
goto out;
|
||||
}
|
||||
if (new_rate > SIZE_MAX) {
|
||||
new_rate = SIZE_MAX;
|
||||
}
|
||||
|
||||
s->xfer_limit = new_rate / 10;
|
||||
|
||||
out:
|
||||
return s->xfer_limit;
|
||||
}
|
||||
|
||||
static int64_t buffered_get_rate_limit(void *opaque)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
|
||||
return s->xfer_limit;
|
||||
}
|
||||
|
||||
static void buffered_rate_tick(void *opaque)
|
||||
{
|
||||
QEMUFileBuffered *s = opaque;
|
||||
|
||||
if (qemu_file_get_error(s->file)) {
|
||||
buffered_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100);
|
||||
|
||||
if (s->freeze_output)
|
||||
return;
|
||||
|
||||
s->bytes_xfer = 0;
|
||||
|
||||
buffered_put_buffer(s, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static const QEMUFileOps buffered_file_ops = {
|
||||
.get_fd = buffered_get_fd,
|
||||
.put_buffer = buffered_put_buffer,
|
||||
.close = buffered_close,
|
||||
.rate_limit = buffered_rate_limit,
|
||||
.get_rate_limit = buffered_get_rate_limit,
|
||||
.set_rate_limit = buffered_set_rate_limit,
|
||||
};
|
||||
|
||||
QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state)
|
||||
{
|
||||
QEMUFileBuffered *s;
|
||||
|
||||
s = g_malloc0(sizeof(*s));
|
||||
|
||||
s->migration_state = migration_state;
|
||||
s->xfer_limit = migration_state->bandwidth_limit / 10;
|
||||
|
||||
s->file = qemu_fopen_ops(s, &buffered_file_ops);
|
||||
|
||||
s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s);
|
||||
|
||||
qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100);
|
||||
|
||||
return s->file;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* QEMU buffered QEMUFile
|
||||
*
|
||||
* Copyright IBM, Corp. 2008
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QEMU_BUFFERED_FILE_H
|
||||
#define QEMU_BUFFERED_FILE_H
|
||||
|
||||
#include "hw/hw.h"
|
||||
#include "migration.h"
|
||||
|
||||
QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state);
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#include "cache-utils.h"
|
||||
#include "qemu/cache-utils.h"
|
||||
|
||||
#if defined(_ARCH_PPC)
|
||||
struct qemu_cache_conf qemu_cache_conf = {
|
||||
|
|
4
cmd.c
4
cmd.c
|
@ -24,8 +24,8 @@
|
|||
#include <getopt.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "qemu-aio.h"
|
||||
#include "main-loop.h"
|
||||
#include "block/aio.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
#define _(x) x /* not gettext support yet */
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "compatfd.h"
|
||||
#include "qemu/compatfd.h"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <pthread.h>
|
||||
|
|
|
@ -116,7 +116,7 @@ audio_drv_list=""
|
|||
audio_card_list="ac97 es1370 sb16 hda"
|
||||
audio_possible_cards="ac97 es1370 sb16 cs4231a adlib gus hda"
|
||||
block_drv_whitelist=""
|
||||
host_cc="gcc"
|
||||
host_cc="cc"
|
||||
libs_softmmu=""
|
||||
libs_tools=""
|
||||
audio_pt_int=""
|
||||
|
@ -250,7 +250,16 @@ done
|
|||
# Using uname is really, really broken. Once we have the right set of checks
|
||||
# we can eliminate its usage altogether.
|
||||
|
||||
# Preferred compiler:
|
||||
# ${CC} (if set)
|
||||
# ${cross_prefix}gcc (if cross-prefix specified)
|
||||
# system compiler
|
||||
if test -z "${CC}${cross_prefix}"; then
|
||||
cc="$host_cc"
|
||||
else
|
||||
cc="${CC-${cross_prefix}gcc}"
|
||||
fi
|
||||
|
||||
ar="${AR-${cross_prefix}ar}"
|
||||
objcopy="${OBJCOPY-${cross_prefix}objcopy}"
|
||||
ld="${LD-${cross_prefix}ld}"
|
||||
|
@ -269,7 +278,7 @@ QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
|
|||
QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
|
||||
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
|
||||
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
|
||||
QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/fpu"
|
||||
QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/include"
|
||||
if test "$debug_info" = "yes"; then
|
||||
CFLAGS="-g $CFLAGS"
|
||||
LDFLAGS="-g $LDFLAGS"
|
||||
|
@ -1350,6 +1359,14 @@ esac
|
|||
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# pkg-config probe
|
||||
|
||||
if ! has "$pkg_config_exe"; then
|
||||
echo "Error: pkg-config binary '$pkg_config_exe' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# NPTL probe
|
||||
|
||||
|
@ -1580,14 +1597,6 @@ if test "$xen_pci_passthrough" != "no"; then
|
|||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# pkg-config probe
|
||||
|
||||
if ! has "$pkg_config_exe"; then
|
||||
echo "Error: pkg-config binary '$pkg_config_exe' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libtool probe
|
||||
|
||||
|
@ -1703,6 +1712,7 @@ EOF
|
|||
if compile_prog "$vnc_tls_cflags" "$vnc_tls_libs" ; then
|
||||
vnc_tls=yes
|
||||
libs_softmmu="$vnc_tls_libs $libs_softmmu"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_tls_cflags"
|
||||
else
|
||||
if test "$vnc_tls" = "yes" ; then
|
||||
feature_not_found "vnc-tls"
|
||||
|
@ -1725,6 +1735,7 @@ EOF
|
|||
if compile_prog "$vnc_sasl_cflags" "$vnc_sasl_libs" ; then
|
||||
vnc_sasl=yes
|
||||
libs_softmmu="$vnc_sasl_libs $libs_softmmu"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_sasl_cflags"
|
||||
else
|
||||
if test "$vnc_sasl" = "yes" ; then
|
||||
feature_not_found "vnc-sasl"
|
||||
|
@ -1746,6 +1757,7 @@ EOF
|
|||
if compile_prog "$vnc_jpeg_cflags" "$vnc_jpeg_libs" ; then
|
||||
vnc_jpeg=yes
|
||||
libs_softmmu="$vnc_jpeg_libs $libs_softmmu"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $vnc_jpeg_cflags"
|
||||
else
|
||||
if test "$vnc_jpeg" = "yes" ; then
|
||||
feature_not_found "vnc-jpeg"
|
||||
|
@ -2130,7 +2142,7 @@ if test "$pixman" = "system"; then
|
|||
else
|
||||
if test ! -d ${source_path}/pixman/pixman; then
|
||||
echo "ERROR: pixman not present. Your options:"
|
||||
echo " (1) Prefered: Install the pixman devel package (any recent"
|
||||
echo " (1) Preferred: Install the pixman devel package (any recent"
|
||||
echo " distro should have packages as Xorg needs pixman too)."
|
||||
echo " (2) Fetch the pixman submodule, using:"
|
||||
echo " git submodule update --init pixman"
|
||||
|
@ -2982,8 +2994,6 @@ EOF
|
|||
else
|
||||
coroutine_backend=gthread
|
||||
fi
|
||||
else
|
||||
echo "Silently falling back into gthread backend under darwin"
|
||||
fi
|
||||
elif test "$coroutine" = "gthread" ; then
|
||||
coroutine_backend=gthread
|
||||
|
@ -3349,7 +3359,6 @@ fi
|
|||
if test "$slirp" = "yes" ; then
|
||||
echo "CONFIG_SLIRP=y" >> $config_host_mak
|
||||
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
|
||||
QEMU_INCLUDES="-I\$(SRC_PATH)/slirp $QEMU_INCLUDES"
|
||||
fi
|
||||
if test "$vde" = "yes" ; then
|
||||
echo "CONFIG_VDE=y" >> $config_host_mak
|
||||
|
@ -3384,19 +3393,15 @@ if test "$vnc" = "yes" ; then
|
|||
fi
|
||||
if test "$vnc_tls" = "yes" ; then
|
||||
echo "CONFIG_VNC_TLS=y" >> $config_host_mak
|
||||
echo "VNC_TLS_CFLAGS=$vnc_tls_cflags" >> $config_host_mak
|
||||
fi
|
||||
if test "$vnc_sasl" = "yes" ; then
|
||||
echo "CONFIG_VNC_SASL=y" >> $config_host_mak
|
||||
echo "VNC_SASL_CFLAGS=$vnc_sasl_cflags" >> $config_host_mak
|
||||
fi
|
||||
if test "$vnc_jpeg" = "yes" ; then
|
||||
echo "CONFIG_VNC_JPEG=y" >> $config_host_mak
|
||||
echo "VNC_JPEG_CFLAGS=$vnc_jpeg_cflags" >> $config_host_mak
|
||||
fi
|
||||
if test "$vnc_png" = "yes" ; then
|
||||
echo "CONFIG_VNC_PNG=y" >> $config_host_mak
|
||||
echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak
|
||||
fi
|
||||
if test "$fnmatch" = "yes" ; then
|
||||
echo "CONFIG_FNMATCH=y" >> $config_host_mak
|
||||
|
@ -3704,11 +3709,6 @@ if test -f ${config_host_ld}~ ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
for d in libdis libdis-user; do
|
||||
symlink "$source_path/Makefile.dis" "$d/Makefile"
|
||||
echo > $d/config.mak
|
||||
done
|
||||
|
||||
# use included Linux headers
|
||||
if test "$linux" = "yes" ; then
|
||||
mkdir -p linux-headers
|
||||
|
@ -4049,83 +4049,77 @@ if test "$linux" = "yes" ; then
|
|||
includes="-I\$(SRC_PATH)/linux-headers $includes"
|
||||
fi
|
||||
|
||||
if test "$target_user_only" = "yes" ; then
|
||||
libdis_config_mak=libdis-user/config.mak
|
||||
else
|
||||
libdis_config_mak=libdis/config.mak
|
||||
fi
|
||||
|
||||
for i in $ARCH $TARGET_BASE_ARCH ; do
|
||||
case "$i" in
|
||||
alpha)
|
||||
echo "CONFIG_ALPHA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ALPHA_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_ALPHA_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
arm)
|
||||
echo "CONFIG_ARM_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ARM_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
cris)
|
||||
echo "CONFIG_CRIS_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_CRIS_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_CRIS_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
hppa)
|
||||
echo "CONFIG_HPPA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_HPPA_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_HPPA_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
i386|x86_64)
|
||||
echo "CONFIG_I386_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_I386_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_I386_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
ia64*)
|
||||
echo "CONFIG_IA64_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_IA64_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_IA64_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
lm32)
|
||||
echo "CONFIG_LM32_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_LM32_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_LM32_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
m68k)
|
||||
echo "CONFIG_M68K_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_M68K_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_M68K_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
microblaze*)
|
||||
echo "CONFIG_MICROBLAZE_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_MICROBLAZE_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_MICROBLAZE_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
mips*)
|
||||
echo "CONFIG_MIPS_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_MIPS_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
or32)
|
||||
echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_OPENRISC_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
ppc*)
|
||||
echo "CONFIG_PPC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_PPC_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_PPC_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
s390*)
|
||||
echo "CONFIG_S390_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_S390_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_S390_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
sh4)
|
||||
echo "CONFIG_SH4_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_SH4_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_SH4_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
sparc*)
|
||||
echo "CONFIG_SPARC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_SPARC_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_SPARC_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
xtensa*)
|
||||
echo "CONFIG_XTENSA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_XTENSA_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_XTENSA_DIS=y" >> config-all-disas.mak
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if test "$tcg_interpreter" = "yes" ; then
|
||||
echo "CONFIG_TCI_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_TCI_DIS=y" >> $libdis_config_mak
|
||||
echo "CONFIG_TCI_DIS=y" >> config-all-disas.mak
|
||||
fi
|
||||
|
||||
case "$ARCH" in
|
||||
|
@ -4164,7 +4158,7 @@ fi
|
|||
if test "$ARCH" = "tci"; then
|
||||
linker_script=""
|
||||
else
|
||||
linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/\$(ARCH).ld"
|
||||
linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/ldscripts/\$(ARCH).ld"
|
||||
fi
|
||||
|
||||
if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
|
||||
|
@ -4229,9 +4223,6 @@ for rom in seabios vgabios ; do
|
|||
echo "LD=$ld" >> $config_mak
|
||||
done
|
||||
|
||||
d=libuser
|
||||
symlink "$source_path/Makefile.user" "$d/Makefile"
|
||||
|
||||
if test "$docs" = "yes" ; then
|
||||
mkdir -p QMP
|
||||
fi
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-coroutine-int.h"
|
||||
#include "block/coroutine_int.h"
|
||||
|
||||
typedef struct {
|
||||
Coroutine base;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-coroutine-int.h"
|
||||
#include "block/coroutine_int.h"
|
||||
|
||||
enum {
|
||||
/* Maximum free pool size prevents holding too many freed coroutines */
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <pthread.h>
|
||||
#include <ucontext.h>
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-coroutine-int.h"
|
||||
#include "block/coroutine_int.h"
|
||||
|
||||
#ifdef CONFIG_VALGRIND_H
|
||||
#include <valgrind/valgrind.h>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-coroutine-int.h"
|
||||
#include "block/coroutine_int.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "disas.h"
|
||||
#include "disas/disas.h"
|
||||
#include "tcg.h"
|
||||
#include "qemu-barrier.h"
|
||||
#include "qtest.h"
|
||||
#include "qemu/atomic.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
int tb_invalidated_flag;
|
||||
|
||||
|
|
22
cpus.c
22
cpus.c
|
@ -25,21 +25,21 @@
|
|||
/* Needed early for CONFIG_BSD etc. */
|
||||
#include "config-host.h"
|
||||
|
||||
#include "monitor.h"
|
||||
#include "sysemu.h"
|
||||
#include "gdbstub.h"
|
||||
#include "dma.h"
|
||||
#include "kvm.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "qmp-commands.h"
|
||||
|
||||
#include "qemu-thread.h"
|
||||
#include "cpus.h"
|
||||
#include "qtest.h"
|
||||
#include "main-loop.h"
|
||||
#include "bitmap.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/bitmap.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "compatfd.h"
|
||||
#include "qemu/compatfd.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
|
|
18
cputlb.c
18
cputlb.c
|
@ -19,13 +19,13 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "exec-all.h"
|
||||
#include "memory.h"
|
||||
#include "exec-memory.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/memory.h"
|
||||
#include "exec/address-spaces.h"
|
||||
|
||||
#include "cputlb.h"
|
||||
#include "exec/cputlb.h"
|
||||
|
||||
#include "memory-internal.h"
|
||||
#include "exec/memory-internal.h"
|
||||
|
||||
//#define DEBUG_TLB
|
||||
//#define DEBUG_TLB_CHECK
|
||||
|
@ -347,15 +347,15 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
|||
#define SOFTMMU_CODE_ACCESS
|
||||
|
||||
#define SHIFT 0
|
||||
#include "softmmu_template.h"
|
||||
#include "exec/softmmu_template.h"
|
||||
|
||||
#define SHIFT 1
|
||||
#include "softmmu_template.h"
|
||||
#include "exec/softmmu_template.h"
|
||||
|
||||
#define SHIFT 2
|
||||
#include "softmmu_template.h"
|
||||
#include "exec/softmmu_template.h"
|
||||
|
||||
#define SHIFT 3
|
||||
#include "softmmu_template.h"
|
||||
#include "exec/softmmu_template.h"
|
||||
|
||||
#undef env
|
||||
|
|
6
cutils.c
6
cutils.c
|
@ -22,11 +22,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu-common.h"
|
||||
#include "host-utils.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "qemu_socket.h"
|
||||
#include "iov.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/iov.h"
|
||||
|
||||
void strpadcpy(char *buf, int buf_size, const char *str, char pad)
|
||||
{
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "qemu-common.h"
|
||||
#include "device_tree.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/loader.h"
|
||||
#include "qemu-option.h"
|
||||
#include "qemu-config.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
|
|
6
disas.c
6
disas.c
|
@ -1,11 +1,11 @@
|
|||
/* General "disassemble this chunk" code. Used for debugging. */
|
||||
#include "config.h"
|
||||
#include "dis-asm.h"
|
||||
#include "disas/bfd.h"
|
||||
#include "elf.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "disas.h"
|
||||
#include "disas/disas.h"
|
||||
|
||||
typedef struct CPUDebug {
|
||||
struct disassemble_info info;
|
||||
|
@ -374,7 +374,7 @@ const char *lookup_symbol(target_ulong orig_addr)
|
|||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
#include "monitor.h"
|
||||
#include "monitor/monitor.h"
|
||||
|
||||
static int monitor_disas_is_physical;
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
universal-obj-$(CONFIG_ALPHA_DIS) += alpha.o
|
||||
universal-obj-$(CONFIG_ARM_DIS) += arm.o
|
||||
universal-obj-$(CONFIG_CRIS_DIS) += cris.o
|
||||
universal-obj-$(CONFIG_HPPA_DIS) += hppa.o
|
||||
universal-obj-$(CONFIG_I386_DIS) += i386.o
|
||||
universal-obj-$(CONFIG_IA64_DIS) += ia64.o
|
||||
universal-obj-$(CONFIG_M68K_DIS) += m68k.o
|
||||
universal-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
|
||||
universal-obj-$(CONFIG_MIPS_DIS) += mips.o
|
||||
universal-obj-$(CONFIG_PPC_DIS) += ppc.o
|
||||
universal-obj-$(CONFIG_S390_DIS) += s390.o
|
||||
universal-obj-$(CONFIG_SH4_DIS) += sh4.o
|
||||
universal-obj-$(CONFIG_SPARC_DIS) += sparc.o
|
||||
universal-obj-$(CONFIG_LM32_DIS) += lm32.o
|
||||
|
||||
universal-obj-$(CONFIG_TCI_DIS) += tci.o
|
|
@ -20,7 +20,7 @@ along with this file; see the file COPYING. If not, see
|
|||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dis-asm.h"
|
||||
#include "disas/bfd.h"
|
||||
|
||||
/* MAX is redefined below, so remove any previous definition. */
|
||||
#undef MAX
|
|
@ -22,7 +22,7 @@
|
|||
/* Start of qemu specific additions. Mostly this is stub definitions
|
||||
for things we don't care about. */
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "disas/bfd.h"
|
||||
#define ATTRIBUTE_UNUSED __attribute__((unused))
|
||||
#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "dis-asm.h"
|
||||
#include "disas/bfd.h"
|
||||
//#include "sysdep.h"
|
||||
#include "target-cris/opcode-cris.h"
|
||||
//#include "libiberty.h"
|
|
@ -18,7 +18,7 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "disas/bfd.h"
|
||||
|
||||
/* HP PA-RISC SOM object file format: definitions internal to BFD.
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue