Commit f69f0bca authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'mdroth/qga-pull-2013-9-9' into staging



# By Tomoki Sekiyama (10) and Paul Burton (1)
# Via Michael Roth
* mdroth/qga-pull-2013-9-9:
  QMP/qemu-ga-client: Make timeout longer for guest-fsfreeze-freeze command
  qemu-ga: Install Windows VSS provider on `qemu-ga -s install'
  qemu-ga: Call Windows VSS requester in fsfreeze command handler
  qemu-ga: Add Windows VSS provider and requester as DLL
  error: Add error_set_win32 and error_setg_win32
  qemu-ga: Add configure options to specify path to Windows/VSS SDK
  Add a script to extract VSS SDK headers on POSIX system
  checkpatch.pl: Check .cpp files
  Add c++ keywords to QAPI helper script
  configure: Support configuring C++ compiler
  mips_malta: support up to 2GiB RAM

Message-id: 1378755701-2051-1-git-send-email-mdroth@linux.vnet.ibm.com
Signed-off-by: default avatarAnthony Liguori <anthony@codemonkey.ws>
parents 97fdb941 e2682db0
...@@ -82,6 +82,7 @@ fsdev/virtfs-proxy-helper.pod ...@@ -82,6 +82,7 @@ fsdev/virtfs-proxy-helper.pod
*.la *.la
*.pc *.pc
.libs .libs
.sdk
*.swp *.swp
*.orig *.orig
.pc .pc
......
...@@ -235,7 +235,7 @@ clean: ...@@ -235,7 +235,7 @@ clean:
rm -f qemu-options.def rm -f qemu-options.def
find . -name '*.[oda]' -type f -exec rm -f {} + find . -name '*.[oda]' -type f -exec rm -f {} +
find . -name '*.l[oa]' -type f -exec rm -f {} + find . -name '*.l[oa]' -type f -exec rm -f {} +
rm -f $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -Rf .libs rm -Rf .libs
rm -f qemu-img-cmds.h rm -f qemu-img-cmds.h
@# May not be present in GENERATED_HEADERS @# May not be present in GENERATED_HEADERS
...@@ -272,6 +272,7 @@ distclean: clean ...@@ -272,6 +272,7 @@ distclean: clean
for d in $(TARGET_DIRS); do \ for d in $(TARGET_DIRS); do \
rm -rf $$d || exit 1 ; \ rm -rf $$d || exit 1 ; \
done done
rm -Rf .sdk
if test -f pixman/config.log; then make -C pixman distclean; fi if test -f pixman/config.log; then make -C pixman distclean; fi
if test -f dtc/version_gen.h; then make $(DTC_MAKE_ARGS) clean; fi if test -f dtc/version_gen.h; then make $(DTC_MAKE_ARGS) clean; fi
......
...@@ -109,6 +109,7 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo ...@@ -109,6 +109,7 @@ version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
# FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
# by libqemuutil.a. These should be moved to a separate .json schema. # by libqemuutil.a. These should be moved to a separate .json schema.
qga-obj-y = qga/ qapi-types.o qapi-visit.o qga-obj-y = qga/ qapi-types.o qapi-visit.o
qga-vss-dll-obj-y = qga/
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
...@@ -120,6 +121,7 @@ nested-vars += \ ...@@ -120,6 +121,7 @@ nested-vars += \
stub-obj-y \ stub-obj-y \
util-obj-y \ util-obj-y \
qga-obj-y \ qga-obj-y \
qga-vss-dll-obj-y \
block-obj-y \ block-obj-y \
common-obj-y common-obj-y
dummy := $(call unnest-vars) dummy := $(call unnest-vars)
...@@ -267,7 +267,9 @@ def main(address, cmd, args): ...@@ -267,7 +267,9 @@ def main(address, cmd, args):
print('Hint: qemu is not running?') print('Hint: qemu is not running?')
sys.exit(1) sys.exit(1)
if cmd != 'ping': if cmd == 'fsfreeze' and args[0] == 'freeze':
client.sync(60)
elif cmd != 'ping':
client.sync() client.sync()
globals()['_cmd_' + cmd](client, args) globals()['_cmd_' + cmd](client, args)
......
...@@ -232,6 +232,9 @@ usb_redir="" ...@@ -232,6 +232,9 @@ usb_redir=""
glx="" glx=""
zlib="yes" zlib="yes"
guest_agent="" guest_agent=""
guest_agent_with_vss="no"
vss_win32_sdk=""
win_sdk="no"
want_tools="yes" want_tools="yes"
libiscsi="" libiscsi=""
coroutine="" coroutine=""
...@@ -252,6 +255,8 @@ for opt do ...@@ -252,6 +255,8 @@ for opt do
;; ;;
--cc=*) CC="$optarg" --cc=*) CC="$optarg"
;; ;;
--cxx=*) CXX="$optarg"
;;
--source-path=*) source_path="$optarg" --source-path=*) source_path="$optarg"
;; ;;
--cpu=*) cpu="$optarg" --cpu=*) cpu="$optarg"
...@@ -282,6 +287,12 @@ else ...@@ -282,6 +287,12 @@ else
cc="${CC-${cross_prefix}gcc}" cc="${CC-${cross_prefix}gcc}"
fi fi
if test -z "${CXX}${cross_prefix}"; then
cxx="c++"
else
cxx="${CXX-${cross_prefix}g++}"
fi
ar="${AR-${cross_prefix}ar}" ar="${AR-${cross_prefix}ar}"
as="${AS-${cross_prefix}as}" as="${AS-${cross_prefix}as}"
cpp="${CPP-$cc -E}" cpp="${CPP-$cc -E}"
...@@ -626,6 +637,8 @@ for opt do ...@@ -626,6 +637,8 @@ for opt do
;; ;;
--host-cc=*) host_cc="$optarg" --host-cc=*) host_cc="$optarg"
;; ;;
--cxx=*)
;;
--objcc=*) objcc="$optarg" --objcc=*) objcc="$optarg"
;; ;;
--make=*) make="$optarg" --make=*) make="$optarg"
...@@ -917,6 +930,18 @@ for opt do ...@@ -917,6 +930,18 @@ for opt do
;; ;;
--disable-guest-agent) guest_agent="no" --disable-guest-agent) guest_agent="no"
;; ;;
--with-vss-sdk) vss_win32_sdk=""
;;
--with-vss-sdk=*) vss_win32_sdk="$optarg"
;;
--without-vss-sdk) vss_win32_sdk="no"
;;
--with-win-sdk) win_sdk=""
;;
--with-win-sdk=*) win_sdk="$optarg"
;;
--without-win-sdk) win_sdk="no"
;;
--enable-tools) want_tools="yes" --enable-tools) want_tools="yes"
;; ;;
--disable-tools) want_tools="no" --disable-tools) want_tools="no"
...@@ -1032,6 +1057,7 @@ echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" ...@@ -1032,6 +1057,7 @@ echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
echo " --cc=CC use C compiler CC [$cc]" echo " --cc=CC use C compiler CC [$cc]"
echo " --host-cc=CC use C compiler CC [$host_cc] for code run at" echo " --host-cc=CC use C compiler CC [$host_cc] for code run at"
echo " build time" echo " build time"
echo " --cxx=CXX use C++ compiler CXX [$cxx]"
echo " --objcc=OBJCC use Objective-C compiler OBJCC [$objcc]" echo " --objcc=OBJCC use Objective-C compiler OBJCC [$objcc]"
echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS" echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS"
echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS" echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS"
...@@ -1157,6 +1183,8 @@ echo " --disable-usb-redir disable usb network redirection support" ...@@ -1157,6 +1183,8 @@ echo " --disable-usb-redir disable usb network redirection support"
echo " --enable-usb-redir enable usb network redirection support" echo " --enable-usb-redir enable usb network redirection support"
echo " --disable-guest-agent disable building of the QEMU Guest Agent" echo " --disable-guest-agent disable building of the QEMU Guest Agent"
echo " --enable-guest-agent enable building of the QEMU Guest Agent" echo " --enable-guest-agent enable building of the QEMU Guest Agent"
echo " --with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent"
echo " --with-win-sdk=SDK-path path to Windows Platform SDK (to build VSS .tlb)"
echo " --disable-seccomp disable seccomp support" echo " --disable-seccomp disable seccomp support"
echo " --enable-seccomp enables seccomp support" echo " --enable-seccomp enables seccomp support"
echo " --with-coroutine=BACKEND coroutine backend. Supported options:" echo " --with-coroutine=BACKEND coroutine backend. Supported options:"
...@@ -3120,6 +3148,61 @@ if test "$usb_redir" != "no" ; then ...@@ -3120,6 +3148,61 @@ if test "$usb_redir" != "no" ; then
fi fi
fi fi
##########################################
# check if we have VSS SDK headers for win
if test "$mingw32" = "yes" -a "$guest_agent" != "no" -a "$vss_win32_sdk" != "no" ; then
case "$vss_win32_sdk" in
"") vss_win32_include="-I$source_path" ;;
*\ *) # The SDK is installed in "Program Files" by default, but we cannot
# handle path with spaces. So we symlink the headers into ".sdk/vss".
vss_win32_include="-I$source_path/.sdk/vss"
symlink "$vss_win32_sdk/inc" "$source_path/.sdk/vss/inc"
;;
*) vss_win32_include="-I$vss_win32_sdk"
esac
cat > $TMPC << EOF
#define __MIDL_user_allocate_free_DEFINED__
#include <inc/win2003/vss.h>
int main(void) { return VSS_CTX_BACKUP; }
EOF
if compile_prog "$vss_win32_include" "" ; then
guest_agent_with_vss="yes"
QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include"
libs_qga="-lole32 -loleaut32 -lshlwapi -luuid -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
else
if test "$vss_win32_sdk" != "" ; then
echo "ERROR: Please download and install Microsoft VSS SDK:"
echo "ERROR: http://www.microsoft.com/en-us/download/details.aspx?id=23490"
echo "ERROR: On POSIX-systems, you can extract the SDK headers by:"
echo "ERROR: scripts/extract-vsssdk-headers setup.exe"
echo "ERROR: The headers are extracted in the directory \`inc'."
feature_not_found "VSS support"
fi
guest_agent_with_vss="no"
fi
fi
##########################################
# lookup Windows platform SDK (if not specified)
# The SDK is needed only to build .tlb (type library) file of guest agent
# VSS provider from the source. It is usually unnecessary because the
# pre-compiled .tlb file is included.
if test "$mingw32" = "yes" -a "$guest_agent" != "no" -a "$guest_agent_with_vss" = "yes" ; then
if test -z "$win_sdk"; then
programfiles="$PROGRAMFILES"
test -n "$PROGRAMW6432" && programfiles="$PROGRAMW6432"
if test -n "$programfiles"; then
win_sdk=$(ls -d "$programfiles/Microsoft SDKs/Windows/v"* | tail -1) 2>/dev/null
else
feature_not_found "Windows SDK"
fi
elif test "$win_sdk" = "no"; then
win_sdk=""
fi
fi
########################################## ##########################################
########################################## ##########################################
...@@ -3485,8 +3568,11 @@ if test "$softmmu" = yes ; then ...@@ -3485,8 +3568,11 @@ if test "$softmmu" = yes ; then
fi fi
fi fi
if [ "$guest_agent" != "no" ]; then if [ "$guest_agent" != "no" ]; then
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
tools="qemu-ga\$(EXESUF) $tools" tools="qemu-ga\$(EXESUF) $tools"
if [ "$mingw32" = "yes" -a "$guest_agent_with_vss" = "yes" ]; then
tools="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb $tools"
fi
guest_agent=yes guest_agent=yes
elif [ "$guest_agent" != yes ]; then elif [ "$guest_agent" != yes ]; then
guest_agent=no guest_agent=no
...@@ -3557,10 +3643,12 @@ echo "Manual directory `eval echo $mandir`" ...@@ -3557,10 +3643,12 @@ echo "Manual directory `eval echo $mandir`"
echo "ELF interp prefix $interp_prefix" echo "ELF interp prefix $interp_prefix"
else else
echo "local state directory queried at runtime" echo "local state directory queried at runtime"
echo "Windows SDK $win_sdk"
fi fi
echo "Source path $source_path" echo "Source path $source_path"
echo "C compiler $cc" echo "C compiler $cc"
echo "Host C compiler $host_cc" echo "Host C compiler $host_cc"
echo "C++ compiler $cxx"
echo "Objective-C compiler $objcc" echo "Objective-C compiler $objcc"
echo "CFLAGS $CFLAGS" echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS" echo "QEMU_CFLAGS $QEMU_CFLAGS"
...@@ -3642,6 +3730,7 @@ echo "usb net redir $usb_redir" ...@@ -3642,6 +3730,7 @@ echo "usb net redir $usb_redir"
echo "GLX support $glx" echo "GLX support $glx"
echo "libiscsi support $libiscsi" echo "libiscsi support $libiscsi"
echo "build guest agent $guest_agent" echo "build guest agent $guest_agent"
echo "QGA VSS support $guest_agent_with_vss"
echo "seccomp support $seccomp" echo "seccomp support $seccomp"
echo "coroutine backend $coroutine" echo "coroutine backend $coroutine"
echo "GlusterFS support $glusterfs" echo "GlusterFS support $glusterfs"
...@@ -3716,6 +3805,10 @@ if test "$mingw32" = "yes" ; then ...@@ -3716,6 +3805,10 @@ if test "$mingw32" = "yes" ; then
version_micro=0 version_micro=0
echo "CONFIG_FILEVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak echo "CONFIG_FILEVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
echo "CONFIG_PRODUCTVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak echo "CONFIG_PRODUCTVERSION=$version_major,$version_minor,$version_subminor,$version_micro" >> $config_host_mak
if test "$guest_agent_with_vss" = "yes" ; then
echo "CONFIG_QGA_VSS=y" >> $config_host_mak
echo "WIN_SDK=\"$win_sdk\"" >> $config_host_mak
fi
else else
echo "CONFIG_POSIX=y" >> $config_host_mak echo "CONFIG_POSIX=y" >> $config_host_mak
fi fi
...@@ -4148,6 +4241,7 @@ echo "PYTHON=$python" >> $config_host_mak ...@@ -4148,6 +4241,7 @@ echo "PYTHON=$python" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak echo "CC=$cc" >> $config_host_mak
echo "CC_I386=$cc_i386" >> $config_host_mak echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak echo "HOST_CC=$host_cc" >> $config_host_mak
echo "CXX=$cxx" >> $config_host_mak
echo "OBJCC=$objcc" >> $config_host_mak echo "OBJCC=$objcc" >> $config_host_mak
echo "AR=$ar" >> $config_host_mak echo "AR=$ar" >> $config_host_mak
echo "AS=$as" >> $config_host_mak echo "AS=$as" >> $config_host_mak
......
...@@ -544,7 +544,7 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) ...@@ -544,7 +544,7 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
if (dev->class_info.has_desc) { if (dev->class_info.has_desc) {
monitor_printf(mon, "%s", dev->class_info.desc); monitor_printf(mon, "%s", dev->class_info.desc);
} else { } else {
monitor_printf(mon, "Class %04" PRId64, dev->class_info.class); monitor_printf(mon, "Class %04" PRId64, dev->class_info.q_class);
} }
monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
......
...@@ -827,7 +827,8 @@ static int64_t load_kernel (void) ...@@ -827,7 +827,8 @@ static int64_t load_kernel (void)
} }
prom_set(prom_buf, prom_index++, "memsize"); prom_set(prom_buf, prom_index++, "memsize");
prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size); prom_set(prom_buf, prom_index++, "%i",
MIN(loaderparams.ram_size, 256 << 20));
prom_set(prom_buf, prom_index++, "modetty0"); prom_set(prom_buf, prom_index++, "modetty0");
prom_set(prom_buf, prom_index++, "38400n8r"); prom_set(prom_buf, prom_index++, "38400n8r");
prom_set(prom_buf, prom_index++, NULL); prom_set(prom_buf, prom_index++, NULL);
...@@ -884,7 +885,9 @@ void mips_malta_init(QEMUMachineInitArgs *args) ...@@ -884,7 +885,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
char *filename; char *filename;
pflash_t *fl; pflash_t *fl;
MemoryRegion *system_memory = get_system_memory(); MemoryRegion *system_memory = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *ram_high = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
MemoryRegion *ram_low_postio;
MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
target_long bios_size = FLASH_SIZE; target_long bios_size = FLASH_SIZE;
const size_t smbus_eeprom_size = 8 * 256; const size_t smbus_eeprom_size = 8 * 256;
...@@ -951,15 +954,32 @@ void mips_malta_init(QEMUMachineInitArgs *args) ...@@ -951,15 +954,32 @@ void mips_malta_init(QEMUMachineInitArgs *args)
env = &cpu->env; env = &cpu->env;
/* allocate RAM */ /* allocate RAM */
if (ram_size > (256 << 20)) { if (ram_size > (2048u << 20)) {
fprintf(stderr, fprintf(stderr,
"qemu: Too much memory for this machine: %d MB, maximum 256 MB\n", "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
((unsigned int)ram_size / (1 << 20))); ((unsigned int)ram_size / (1 << 20)));
exit(1); exit(1);
} }
memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size);
vmstate_register_ram_global(ram); /* register RAM at high address where it is undisturbed by IO */
memory_region_add_subregion(system_memory, 0, ram); memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size);
vmstate_register_ram_global(ram_high);
memory_region_add_subregion(system_memory, 0x80000000, ram_high);
/* alias for pre IO hole access */
memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
ram_high, 0, MIN(ram_size, (256 << 20)));
memory_region_add_subregion(system_memory, 0, ram_low_preio);
/* alias for post IO hole access, if there is enough RAM */
if (ram_size > (512 << 20)) {
ram_low_postio = g_new(MemoryRegion, 1);
memory_region_init_alias(ram_low_postio, NULL,
"mips_malta_low_postio.ram",
ram_high, 512 << 20,
ram_size - (512 << 20));
memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
}
/* generate SPD EEPROM data */ /* generate SPD EEPROM data */
generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size); generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
...@@ -992,7 +1012,7 @@ void mips_malta_init(QEMUMachineInitArgs *args) ...@@ -992,7 +1012,7 @@ void mips_malta_init(QEMUMachineInitArgs *args)
fl_idx++; fl_idx++;
if (kernel_filename) { if (kernel_filename) {
/* Write a small bootloader to the flash location. */ /* Write a small bootloader to the flash location. */
loaderparams.ram_size = ram_size; loaderparams.ram_size = MIN(ram_size, 256 << 20);
loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_filename = kernel_filename;
loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.kernel_cmdline = kernel_cmdline;
loaderparams.initrd_filename = initrd_filename; loaderparams.initrd_filename = initrd_filename;
......
...@@ -1461,7 +1461,7 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus, ...@@ -1461,7 +1461,7 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
info->function = PCI_FUNC(dev->devfn); info->function = PCI_FUNC(dev->devfn);
class = pci_get_word(dev->config + PCI_CLASS_DEVICE); class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
info->class_info.class = class; info->class_info.q_class = class;
desc = get_class_desc(class); desc = get_class_desc(class);
if (desc->desc) { if (desc->desc) {
info->class_info.has_desc = true; info->class_info.has_desc = true;
......
...@@ -36,6 +36,15 @@ void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ ...@@ -36,6 +36,15 @@ void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_
*/ */
void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5); void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
#ifdef _WIN32
/**
* Set an indirect pointer to an error given a ErrorClass value and a
* printf-style human message, followed by a g_win32_error_message() string if
* @win32_err is not zero.
*/
void error_set_win32(Error **err, int win32_err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
#endif
/** /**
* Same as error_set(), but sets a generic error * Same as error_set(), but sets a generic error
*/ */
...@@ -43,6 +52,10 @@ void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char ...@@ -43,6 +52,10 @@ void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char
error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#define error_setg_errno(err, os_error, fmt, ...) \ #define error_setg_errno(err, os_error, fmt, ...) \
error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#ifdef _WIN32
#define error_setg_win32(err, win32_err, fmt, ...) \
error_set_win32(err, win32_err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#endif
/** /**
* Helper for open() errors * Helper for open() errors
......
qga-obj-y = commands.o guest-agent-command-state.o main.o qga-obj-y = commands.o guest-agent-command-state.o main.o
qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
qga-obj-$(CONFIG_WIN32) += vss-win32.o
qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
qga-obj-y += qapi-generated/qga-qmp-marshal.o qga-obj-y += qapi-generated/qga-qmp-marshal.o
qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <wtypes.h> #include <wtypes.h>
#include <powrprof.h> #include <powrprof.h>
#include "qga/guest-agent-core.h" #include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
#include "qga-qmp-commands.h" #include "qga-qmp-commands.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
...@@ -156,27 +157,89 @@ void qmp_guest_file_flush(int64_t handle, Error **err) ...@@ -156,27 +157,89 @@ void qmp_guest_file_flush(int64_t handle, Error **err)
*/ */
GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err) GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
{ {
error_set(err, QERR_UNSUPPORTED); if (!vss_initialized()) {
return 0; error_set(err, QERR_UNSUPPORTED);
return 0;
}
if (ga_is_frozen(ga_state)) {
return GUEST_FSFREEZE_STATUS_FROZEN;
}
return GUEST_FSFREEZE_STATUS_THAWED;
} }
/* /*
* Walk list of mounted file systems in the guest, and freeze the ones which * Freeze local file systems using Volume Shadow-copy Service.
* are real local file systems. * The frozen state is limited for up to 10 seconds by VSS.
*/ */
int64_t qmp_guest_fsfreeze_freeze(Error **err) int64_t qmp_guest_fsfreeze_freeze(Error **err)
{ {
error_set(err, QERR_UNSUPPORTED); int i;
Error *local_err = NULL;
if (!vss_initialized()) {
error_set(err, QERR_UNSUPPORTED);
return 0;
}
slog("guest-fsfreeze called");
/* cannot risk guest agent blocking itself on a write in this state */
ga_set_frozen(ga_state);
qga_vss_fsfreeze(&i, err, true);
if (error_is_set(err)) {
goto error;
}
return i;
error:
qmp_guest_fsfreeze_thaw(&local_err);
if (error_is_set(&local_err)) {
g_debug("cleanup thaw: %s", error_get_pretty(local_err));
error_free(local_err);
}
return 0; return 0;
} }
/* /*
* Walk list of frozen file systems in the guest, and thaw them. * Thaw local file systems using Volume Shadow-copy Service.
*/ */
int64_t qmp_guest_fsfreeze_thaw(Error **err) int64_t qmp_guest_fsfreeze_thaw(Error **err)
{ {
error_set(err, QERR_UNSUPPORTED); int i;
return 0;
if (!vss_initialized()) {
error_set(err, QERR_UNSUPPORTED);
return 0;
}
qga_vss_fsfreeze(&i, err, false);
ga_unset_frozen(ga_state);
return i;
}
static void guest_fsfreeze_cleanup(void)
{
Error *err = NULL;
if (!vss_initialized()) {
return;
}
if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
qmp_guest_fsfreeze_thaw(&err);
if (err) {
slog("failed to clean up frozen filesystems: %s",
error_get_pretty(err));
error_free(err);
}
}