forked from aliguori/qemu
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
qemu-ga: Call Windows VSS requester in fsfreeze command handler
Support guest-fsfreeze-freeze and guest-fsfreeze-thaw commands for Windows guests. When fsfreeze command is issued, it calls the VSS requester to freeze filesystems and applications. On thaw command, it again tells the VSS requester to thaw them. This also adds calling of initialize functions for the VSS requester. Signed-off-by: Tomoki Sekiyama <[email protected]> Reviewed-by: Michael Roth <[email protected]> Signed-off-by: Michael Roth <[email protected]>
- Loading branch information
Showing
4 changed files
with
240 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
* QEMU Guest Agent VSS utility functions | ||
* | ||
* Copyright Hitachi Data Systems Corp. 2013 | ||
* | ||
* Authors: | ||
* Tomoki Sekiyama <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <windows.h> | ||
#include "qga/guest-agent-core.h" | ||
#include "qga/vss-win32.h" | ||
#include "qga/vss-win32/requester.h" | ||
|
||
#define QGA_VSS_DLL "qga-vss.dll" | ||
|
||
static HMODULE provider_lib; | ||
|
||
/* Call a function in qga-vss.dll with the specified name */ | ||
static HRESULT call_vss_provider_func(const char *func_name) | ||
{ | ||
FARPROC WINAPI func; | ||
|
||
g_assert(provider_lib); | ||
|
||
func = GetProcAddress(provider_lib, func_name); | ||
if (!func) { | ||
char *msg; | ||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | ||
FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
(char *)&msg, 0, NULL); | ||
fprintf(stderr, "failed to load %s from %s: %s", | ||
func_name, QGA_VSS_DLL, msg); | ||
LocalFree(msg); | ||
return E_FAIL; | ||
} | ||
|
||
return func(); | ||
} | ||
|
||
/* Check whether this OS version supports VSS providers */ | ||
static bool vss_check_os_version(void) | ||
{ | ||
OSVERSIONINFO OSver; | ||
|
||
OSver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | ||
GetVersionEx(&OSver); | ||
if ((OSver.dwMajorVersion == 5 && OSver.dwMinorVersion >= 2) || | ||
OSver.dwMajorVersion > 5) { | ||
BOOL wow64 = false; | ||
#ifndef _WIN64 | ||
/* Provider doesn't work under WOW64 (32bit agent on 64bit OS) */ | ||
if (!IsWow64Process(GetCurrentProcess(), &wow64)) { | ||
fprintf(stderr, "failed to IsWow64Process (Error: %lx\n)\n", | ||
GetLastError()); | ||
return false; | ||
} | ||
if (wow64) { | ||
fprintf(stderr, "Warning: Running under WOW64\n"); | ||
} | ||
#endif | ||
return !wow64; | ||
} | ||
return false; | ||
} | ||
|
||
/* Load qga-vss.dll */ | ||
bool vss_init(bool init_requester) | ||
{ | ||
if (!vss_check_os_version()) { | ||
/* Do nothing if OS doesn't support providers. */ | ||
fprintf(stderr, "VSS provider is not supported in this OS version: " | ||
"fsfreeze is disabled.\n"); | ||
return false; | ||
} | ||
|
||
provider_lib = LoadLibraryA(QGA_VSS_DLL); | ||
if (!provider_lib) { | ||
char *msg; | ||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | ||
FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | ||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
(char *)&msg, 0, NULL); | ||
fprintf(stderr, "failed to load %s: %sfsfreeze is disabled\n", | ||
QGA_VSS_DLL, msg); | ||
LocalFree(msg); | ||
return false; | ||
} | ||
|
||
if (init_requester) { | ||
HRESULT hr = call_vss_provider_func("requester_init"); | ||
if (FAILED(hr)) { | ||
fprintf(stderr, "fsfreeze is disabled.\n"); | ||
vss_deinit(false); | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/* Unload qga-provider.dll */ | ||
void vss_deinit(bool deinit_requester) | ||
{ | ||
if (deinit_requester) { | ||
call_vss_provider_func("requester_deinit"); | ||
} | ||
FreeLibrary(provider_lib); | ||
provider_lib = NULL; | ||
} | ||
|
||
bool vss_initialized(void) | ||
{ | ||
return !!provider_lib; | ||
} | ||
|
||
/* Call VSS requester and freeze/thaw filesystems and applications */ | ||
void qga_vss_fsfreeze(int *nr_volume, Error **err, bool freeze) | ||
{ | ||
const char *func_name = freeze ? "requester_freeze" : "requester_thaw"; | ||
QGAVSSRequesterFunc func; | ||
ErrorSet errset = { | ||
.error_set = (ErrorSetFunc)error_set_win32, | ||
.errp = (void **)err, | ||
.err_class = ERROR_CLASS_GENERIC_ERROR | ||
}; | ||
|
||
func = (QGAVSSRequesterFunc)GetProcAddress(provider_lib, func_name); | ||
if (!func) { | ||
error_setg_win32(err, GetLastError(), "failed to load %s from %s", | ||
func_name, QGA_VSS_DLL); | ||
return; | ||
} | ||
|
||
func(nr_volume, &errset); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* QEMU Guest Agent VSS utility declarations | ||
* | ||
* Copyright Hitachi Data Systems Corp. 2013 | ||
* | ||
* Authors: | ||
* Tomoki Sekiyama <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
*/ | ||
|
||
#ifndef VSS_WIN32_H | ||
#define VSS_WIN32_H | ||
|
||
#include "qapi/error.h" | ||
|
||
bool vss_init(bool init_requester); | ||
void vss_deinit(bool deinit_requester); | ||
bool vss_initialized(void); | ||
|
||
void qga_vss_fsfreeze(int *nr_volume, Error **err, bool freeze); | ||
|
||
#endif |