From patchwork Tue May 21 15:34:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoki Sekiyama X-Patchwork-Id: 245327 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BEFBB2C009D for ; Wed, 22 May 2013 01:36:34 +1000 (EST) Received: from localhost ([::1]:43968 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ueoc4-0004LU-Tz for incoming@patchwork.ozlabs.org; Tue, 21 May 2013 11:36:32 -0400 Received: from eggs.gnu.org ([208.118.235.92]:59353) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UeoZm-0001Yt-J9 for qemu-devel@nongnu.org; Tue, 21 May 2013 11:34:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UeoZg-0002Jy-68 for qemu-devel@nongnu.org; Tue, 21 May 2013 11:34:10 -0400 Received: from usindpps04.hds.com ([207.126.252.17]:42032) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UeoZf-0002Jl-Of for qemu-devel@nongnu.org; Tue, 21 May 2013 11:34:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hds.com; h=subject : to : from : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=mail1; bh=UcHpyQEn0gx8vqIxwW9lCWOuEEhm57GqfYbu6QRNFvM=; b=M6Ki9pw19zbpCHmzIybbGdh/grMeC0HYI5SeHyOk3fH1XS5ka0ZGEjr6KBAtfS06ftqV rktJRGY3gAOmkg6s45qYdU3aE6TLn8NhYyB32Mfje/MrK+K1JzdRiVEqTdQy923wOtBm JKwPOjci08hJsUMOkzGwLcVU+sbd+K9XKAXQ2gqucNiZwo0f3vaqQp0qttPzYDpFzAKd PXUcd3/wh1+nWVeWCj7VU7yhCKs+5cx17Rgs9vDOX0hCoqv4pa35OGf/3AxRifQmDkxX tI37sr2azcdQrBO2HhWNqAGZuwDForrsRVNdDuDvy3h72tBtvw6f3+/nQ1JirTCgXNno XA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=hdsstg.com; h=subject : to : from : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=mail1; bh=UcHpyQEn0gx8vqIxwW9lCWOuEEhm57GqfYbu6QRNFvM=; b=BLuqr3cki/o0tNxPNWA5KUWIpgM2N09w2bd5pMhDkiYuPDy0hTmeqTTrPxY3XcHFhHmq VNC1jKSajokKK4zTlqYaqO07wYDBo7IcuPQ6+/KlV2I82g4X0w9hZhypapLxJqmPY4qr PqQaqEa2ShRxIQdk0F9FiSntO2q5+Kq1334Dc5nBCQBhdpTpbcP4BhHPKUvnvKY6585X LS74qZwFeZb3Gaa7KTXOMvEkx96EN3kihT16tkmElLdQiL8aNIprkUH6iTRZumt7qGry RM1UBbzUqZH4JPq6ul4svT7kukBjYwV+2lbPoxIKWv6Kz0MCrOYbfsn/aH78PQrXNfih Kg== Received: from usindmail01.hds.com (usindmail03 [207.126.252.22]) by usindpps04.hds.com (8.14.4/8.14.4) with ESMTP id r4LFY3Ea014877; Tue, 21 May 2013 11:34:03 -0400 Received: from hds.com (usindnetf5d-vlan47float.corp.hds.com [10.74.73.11]) by usindmail01.hds.com (8.14.1/8.14.1) with ESMTP id r4LFY1EI005535; Tue, 21 May 2013 11:34:02 -0400 (EDT) To: qemu-devel@nongnu.org From: Tomoki Sekiyama Date: Tue, 21 May 2013 11:34:01 -0400 Message-ID: <20130521153401.4880.52645.stgit@hds.com> In-Reply-To: <20130521153333.4880.74390.stgit@hds.com> References: <20130521153333.4880.74390.stgit@hds.com> User-Agent: StGit/0.16 MIME-Version: 1.0 X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 mx ip4:207.126.244.0/26 ip4:207.126.252.0/25 include:mktomail.com ~all X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.10.8626, 1.0.431, 0.0.0000 definitions=2013-05-21_04:2013-05-21, 2013-05-21, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=outbound_policy score=0 spamscore=0 ipscore=0 suspectscore=1 phishscore=0 bulkscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=6.0.2-1211240000 definitions=main-1305210137 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 207.126.252.17 Cc: mdroth@linux.vnet.ibm.com, lcapitulino@redhat.com, vrozenfe@redhat.com, pbonzini@redhat.com, seiji.aguchi@hds.com, areis@redhat.com Subject: [Qemu-devel] [RFC PATCH v3 07/11] qemu-ga: call Windows VSS requester in fsfreeze command handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- qga/commands-win32.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++---- qga/main.c | 33 ++++++++++++++++++++++ 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 24e4ad0..67dca60 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -15,6 +15,7 @@ #include #include #include "qga/guest-agent-core.h" +#include "qga/vss-win32-requester.h" #include "qga-qmp-commands.h" #include "qapi/qmp/qerror.h" @@ -151,34 +152,95 @@ void qmp_guest_file_flush(int64_t handle, Error **err) error_set(err, QERR_UNSUPPORTED); } +#ifdef HAS_VSS_SDK + /* * Return status of freeze/thaw */ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err) { - error_set(err, QERR_UNSUPPORTED); - return 0; + if (!vss_initialized()) { + 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 - * are real local file systems. + * Freeze local file systems using Volume Shadow-copy Service. + * The frozen state is limited for up to 10 seconds by VSS. */ int64_t qmp_guest_fsfreeze_freeze(Error **err) { - error_set(err, QERR_UNSUPPORTED); + int i; + + slog("guest-fsfreeze called"); + + if (!vss_initialized()) { + error_set(err, QERR_UNSUPPORTED); + return 0; + } + + /* cannot risk guest agent blocking itself on a write in this state */ + ga_set_frozen(ga_state); + + qga_vss_fsfreeze_freeze(&i, err); + if (error_is_set(err)) { + goto error; + } + + return i; + +error: + qmp_guest_fsfreeze_thaw(NULL); 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) { + int i; + + if (!vss_initialized()) { + error_set(err, QERR_UNSUPPORTED); + return 0; + } + + qga_vss_fsfreeze_thaw(&i, err); + + ga_unset_frozen(ga_state); + return i; +} + +#else + +GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err) +{ + error_set(err, QERR_UNSUPPORTED); + return 0; +} + +int64_t qmp_guest_fsfreeze_freeze(Error **err) +{ + error_set(err, QERR_UNSUPPORTED); + return 0; +} + +int64_t qmp_guest_fsfreeze_thaw(Error **err) +{ error_set(err, QERR_UNSUPPORTED); return 0; } +#endif + /* * Walk list of mounted file systems in the guest, and discard unused * areas. diff --git a/qga/main.c b/qga/main.c index 44a2836..3ffba14 100644 --- a/qga/main.c +++ b/qga/main.c @@ -34,6 +34,10 @@ #include "qemu/bswap.h" #ifdef _WIN32 #include "qga/service-win32.h" +#ifdef HAS_VSS_SDK +#include "qga/vss-win32-provider.h" +#include "qga/vss-win32-requester.h" +#endif #include #endif #ifdef __linux__ @@ -685,6 +689,25 @@ static gboolean channel_init(GAState *s, const gchar *method, const gchar *path) } #ifdef _WIN32 + +static gboolean vss_win32_init(void) +{ +#ifdef HAS_VSS_SDK + if (FAILED(vss_init())) { + g_critical("failed to initialize VSS"); + return false; + } +#endif + return true; +} + +static void vss_win32_deinit(void) +{ +#ifdef HAS_VSS_SDK + vss_deinit(); +#endif +} + DWORD WINAPI service_ctrl_handler(DWORD ctrl, DWORD type, LPVOID data, LPVOID ctx) { @@ -727,8 +750,12 @@ VOID WINAPI service_main(DWORD argc, TCHAR *argv[]) service->status.dwWaitHint = 0; SetServiceStatus(service->status_handle, &service->status); + if (!vss_win32_init()) { + goto out_bad; + } g_main_loop_run(ga_state->main_loop); - + vss_win32_deinit(); +out_bad: service->status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(service->status_handle, &service->status); } @@ -1132,7 +1159,11 @@ int main(int argc, char **argv) { (char *)QGA_SERVICE_NAME, service_main }, { NULL, NULL } }; StartServiceCtrlDispatcher(service_table); } else { + if (!vss_win32_init()) { + goto out_bad; + } g_main_loop_run(ga_state->main_loop); + vss_win32_deinit(); } #endif