From patchwork Wed Jul 3 15:49:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomoki Sekiyama X-Patchwork-Id: 256696 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4DDCD2C0085 for ; Thu, 4 Jul 2013 01:54:44 +1000 (EST) Received: from localhost ([::1]:48327 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UuPOE-0002C0-4t for incoming@patchwork.ozlabs.org; Wed, 03 Jul 2013 11:54:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60740) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UuPJr-0003Z5-FI for qemu-devel@nongnu.org; Wed, 03 Jul 2013 11:50:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UuPJn-0005xt-5P for qemu-devel@nongnu.org; Wed, 03 Jul 2013 11:50:11 -0400 Received: from usindpps03.hds.com ([207.126.252.16]:50381) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UuPJn-0005xj-09 for qemu-devel@nongnu.org; Wed, 03 Jul 2013 11:50:07 -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=DSD4RnNXOemHep+84b3YBgCECrkOCeb3ieNvVGvQHHs=; b=KcyDPkbarZq/HyD/9YyHui5sAjZCC7gT2yk38kkZ1DOhXkeKOCddu1INi4HJY9xaE1dn 1WXjSSvByLsPLE7DYH9c7f3dMCzTjzGHsRYGLrzZiwJMGfdklxkL3AG100tDJ7VZ5HMM 1zPsgFXjAUUilR95F3d2Sz3kDej0LWbeeTqBGQ4Nq1fayJB7GDfCxZUouYkFXN+QQmKG aoBUa/KDeGy7/IdlC+ijoqblsdYZldLT2Ptsj84IaDrn0OOJmfuEMx5irmOarh+IJoYc R2jebor51vNag360lFguOK3mkhL4xIKYkkGlfRNSJjRqOh8HeRWI8CBUi8LdPGY/MpT+ 0w== Received: from usindmail02.hds.com (usindmail02 [207.126.252.21]) by usindpps03.hds.com (8.14.5/8.14.5) with ESMTP id r63FnpOx026370; Wed, 3 Jul 2013 11:49:51 -0400 Received: from hds.com (usindnetf5d-vlan47float.corp.hds.com [10.74.73.11]) by usindmail02.hds.com (8.14.1/8.14.1) with ESMTP id r63FnnBf007602; Wed, 3 Jul 2013 11:49:50 -0400 (EDT) To: qemu-devel@nongnu.org From: Tomoki Sekiyama Date: Wed, 03 Jul 2013 11:49:49 -0400 Message-ID: <20130703154949.20767.93528.stgit@hds.com> In-Reply-To: <20130703154903.20767.27940.stgit@hds.com> References: <20130703154903.20767.27940.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 include:cloud.hds.com ~all X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.10.8794, 1.0.431, 0.0.0000 definitions=2013-07-03_09:2013-07-03, 2013-07-03, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=outbound_policy score=0 kscore.is_bulkscore=4.17776924166446e-13 kscore.compositescore=0 circleOfTrustscore=0 compositescore=0.207753582200735 urlsuspect_oldscore=0.997706424038378 suspectscore=3 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=349 rbsscore=0.207753582200735 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1305240000 definitions=main-1307030114 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 207.126.252.16 Cc: libaiqing@huawei.com, ghammer@redhat.com, stefanha@gmail.com, mdroth@linux.vnet.ibm.com, lcapitulino@redhat.com, vrozenfe@redhat.com, pbonzini@redhat.com, seiji.aguchi@hds.com, lersek@redhat.com, areis@redhat.com Subject: [Qemu-devel] [PATCH v5 09/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 | 84 +++++++++++++++++++++++++++++++++++++++++++++----- qga/main.c | 13 +++++++- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 24e4ad0..c72f821 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" @@ -156,29 +157,93 @@ void qmp_guest_file_flush(int64_t handle, Error **err) */ 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; + 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_freeze(&i, err); + 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; } /* - * 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) { - error_set(err, QERR_UNSUPPORTED); - return 0; + 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; +} + +#ifdef CONFIG_QGA_VSS + +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); + } + } } +#endif + /* * Walk list of mounted file systems in the guest, and discard unused * areas. @@ -354,4 +419,7 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) /* register init/cleanup routines for stateful command groups */ void ga_command_state_init(GAState *s, GACommandState *cs) { +#ifdef CONFIG_QGA_VSS + ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); +#endif } diff --git a/qga/main.c b/qga/main.c index 0e04e73..160ff28 100644 --- a/qga/main.c +++ b/qga/main.c @@ -34,6 +34,7 @@ #include "qemu/bswap.h" #ifdef _WIN32 #include "qga/service-win32.h" +#include "qga/vss-win32-requester.h" #include #endif #ifdef __linux__ @@ -701,6 +702,7 @@ static gboolean channel_init(GAState *s, const gchar *method, const gchar *path) } #ifdef _WIN32 + DWORD WINAPI service_ctrl_handler(DWORD ctrl, DWORD type, LPVOID data, LPVOID ctx) { @@ -743,8 +745,12 @@ VOID WINAPI service_main(DWORD argc, TCHAR *argv[]) service->status.dwWaitHint = 0; SetServiceStatus(service->status_handle, &service->status); + if (!vss_init()) { + goto out_bad; + } g_main_loop_run(ga_state->main_loop); - +out_bad: + vss_deinit(); service->status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(service->status_handle, &service->status); } @@ -1175,7 +1181,12 @@ int main(int argc, char **argv) { (char *)QGA_SERVICE_NAME, service_main }, { NULL, NULL } }; StartServiceCtrlDispatcher(service_table); } else { + if (!vss_init()) { + vss_deinit(); + goto out_bad; + } g_main_loop_run(ga_state->main_loop); + vss_deinit(); } #endif