From patchwork Thu Jun 21 10:21:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 10479591 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 27B206023A for ; Thu, 21 Jun 2018 10:26:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 165A5292F1 for ; Thu, 21 Jun 2018 10:26:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A63F292FD; Thu, 21 Jun 2018 10:26:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 701BA292F1 for ; Thu, 21 Jun 2018 10:26:21 +0000 (UTC) Received: from localhost ([::1]:54333 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fVwnE-0005wg-KT for patchwork-qemu-devel@patchwork.kernel.org; Thu, 21 Jun 2018 06:26:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53269) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fVwjJ-0002nI-SS for qemu-devel@nongnu.org; Thu, 21 Jun 2018 06:22:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fVwjI-0001fC-LZ for qemu-devel@nongnu.org; Thu, 21 Jun 2018 06:22:17 -0400 Received: from mail-qt0-x234.google.com ([2607:f8b0:400d:c0d::234]:33730) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fVwjI-0001f1-Fk for qemu-devel@nongnu.org; Thu, 21 Jun 2018 06:22:16 -0400 Received: by mail-qt0-x234.google.com with SMTP id l10-v6so2334688qtj.0 for ; Thu, 21 Jun 2018 03:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ln8RZqb7OwC/hVKcdLLgVg0PutO9s10cM3kjqcKgA3c=; b=biY3laAwlR0ANMdI+LdNGLmcI5A3j9LKcCnhzyVHGERa6VyrRKHMWl1twWAzbVLvuu M04beRu+65pm3iG73GFgA4CSIZCK01ZevXZwplryk7FsKdOwUNc0RmNVJfXr0fy+wnCu PFt2YedfqDLQr24Ew8j4MSOjJM6FZ/aaO6pyRAS+BPmCRgdN8etDyC0/SfSyxVvrus9T VNUP4+DONf6lBza+RsZp11h3csmL4KeM98jVrgf4PusXiL9/pm6gi8wx++eI/jSq/g5p k20GwSDex08eZqLlnsSNE0CPNg/AmySxxRqsSHdfIJb6a6ZBXJ58ah3MdZI14sl37cab Ga3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ln8RZqb7OwC/hVKcdLLgVg0PutO9s10cM3kjqcKgA3c=; b=kRSygoXq2dV/2aD/Aqv8cvqTwsKtgzws4WtV8XQm5H6Pa7ErQi0zpGHZoTN15czJP3 TFKBiDPlRbzoiYRR1D64hWqHp75bhdtzdgF3AAB71t08yrVhAibbXKfkdaMZvv8IS/7e sjZDhZXGGNlhfrp3ejZY69qSi7cR31Tk0VXg40CGmgYAsML2mu21Kd9D4kjFJnZfnR31 X1jsrTr50LB5n/McwCi7/MKHxhxMHDF8eL006jtnO/fo+wVUag9bPz7/HXgnZMAAFgG8 D24Mz7tZXQR5d77JO13Hb4OmtF7uiB3PbMfp6ye5v8Yyfkq84FO/69iKEoclObVKpcg1 sCWQ== X-Gm-Message-State: APt69E2j26UXYPK2PfCC/YHeWCJRSLoD4GEvJmc7JbP7ta682/ewtd0m vOjgGEum6QT6YKz/gIu70ruQgvxvYV0= X-Google-Smtp-Source: ADUXVKJFjVn7Bx1upyeALYSi9JWjrB3t2FZ2Anw+yRdxCE4mHcIbDB8IHgjbabpu0FigI8EQbyn+2Q== X-Received: by 2002:ac8:112:: with SMTP id e18-v6mr21194643qtg.91.1529576535763; Thu, 21 Jun 2018 03:22:15 -0700 (PDT) Received: from localhost.localdomain ([2804:431:f701:8296:fe0b:2550:5aa8:2171]) by smtp.gmail.com with ESMTPSA id d42-v6sm2256974qtd.88.2018.06.21.03.22.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 21 Jun 2018 03:22:15 -0700 (PDT) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Date: Thu, 21 Jun 2018 07:21:50 -0300 Message-Id: <20180621102153.28443-4-danielhb413@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180621102153.28443-1-danielhb413@gmail.com> References: <20180621102153.28443-1-danielhb413@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400d:c0d::234 Subject: [Qemu-devel] [PATCH v2 3/6] qga: guest_suspend: decoupling pm-utils and sys logic X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Henrique Barboza , marcandre.lureau@gmail.com, mdroth@linux.vnet.ibm.com, armbru@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Following the same logic of the previous patch, let's also decouple the suspend logic from guest_suspend into specialized functions, one for each strategy we support at this moment. Signed-off-by: Daniel Henrique Barboza --- qga/commands-posix.c | 170 +++++++++++++++++++++++++++---------------- 1 file changed, 108 insertions(+), 62 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 89ffd8dc88..4b6fbd9b80 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -1509,6 +1509,65 @@ out: return ret; } +static void pmutils_suspend(int suspend_mode, Error **errp) +{ + Error *local_err = NULL; + const char *pmutils_bin; + char *pmutils_path; + pid_t pid; + int status; + + switch (suspend_mode) { + + case SUSPEND_MODE_DISK: + pmutils_bin = "pm-hibernate"; + break; + case SUSPEND_MODE_RAM: + pmutils_bin = "pm-suspend"; + break; + case SUSPEND_MODE_HYBRID: + pmutils_bin = "pm-suspend-hybrid"; + break; + default: + error_setg(errp, "unknown guest suspend mode"); + return; + } + + pmutils_path = g_find_program_in_path(pmutils_bin); + if (!pmutils_path) { + error_setg(errp, "the helper program '%s' was not found", pmutils_bin); + return; + } + + pid = fork(); + if (!pid) { + setsid(); + execle(pmutils_path, pmutils_bin, NULL, environ); + /* + * If we get here execle() has failed. + */ + _exit(EXIT_FAILURE); + } else if (pid < 0) { + error_setg_errno(errp, errno, "failed to create child process"); + goto out; + } + + ga_wait_child(pid, &status, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto out; + } + + if (WEXITSTATUS(status)) { + error_setg(errp, + "the helper program '%s' returned an unexpected exit status" + " code (%d)", pmutils_path, WEXITSTATUS(status)); + } + +out: + g_free(pmutils_path); +} + static bool linux_sys_state_supports_mode(int suspend_mode, Error **errp) { const char *sysfile_str; @@ -1545,64 +1604,28 @@ static bool linux_sys_state_supports_mode(int suspend_mode, Error **errp) return false; } -static void bios_supports_mode(int suspend_mode, Error **errp) -{ - Error *local_err = NULL; - bool ret; - - ret = pmutils_supports_mode(suspend_mode, &local_err); - if (ret) { - return; - } - if (local_err) { - error_propagate(errp, local_err); - return; - } - ret = linux_sys_state_supports_mode(suspend_mode, errp); - if (!ret) { - error_setg(errp, - "the requested suspend mode is not supported by the guest"); - return; - } -} - -static void guest_suspend(int suspend_mode, Error **errp) +static void linux_sys_state_suspend(int suspend_mode, Error **errp) { Error *local_err = NULL; - const char *pmutils_bin, *sysfile_str; - char *pmutils_path; + const char *sysfile_str; pid_t pid; int status; - bios_supports_mode(suspend_mode, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - switch (suspend_mode) { case SUSPEND_MODE_DISK: - pmutils_bin = "pm-hibernate"; sysfile_str = "disk"; break; case SUSPEND_MODE_RAM: - pmutils_bin = "pm-suspend"; sysfile_str = "mem"; break; - case SUSPEND_MODE_HYBRID: - pmutils_bin = "pm-suspend-hybrid"; - sysfile_str = NULL; - break; default: error_setg(errp, "unknown guest suspend mode"); return; } - pmutils_path = g_find_program_in_path(pmutils_bin); - pid = fork(); - if (pid == 0) { + if (!pid) { /* child */ int fd; @@ -1611,19 +1634,6 @@ static void guest_suspend(int suspend_mode, Error **errp) reopen_fd_to_null(1); reopen_fd_to_null(2); - if (pmutils_path) { - execle(pmutils_path, pmutils_bin, NULL, environ); - } - - /* - * If we get here either pm-utils is not installed or execle() has - * failed. Let's try the manual method if the caller wants it. - */ - - if (!sysfile_str) { - _exit(EXIT_FAILURE); - } - fd = open(LINUX_SYS_STATE_FILE, O_WRONLY); if (fd < 0) { _exit(EXIT_FAILURE); @@ -1636,27 +1646,63 @@ static void guest_suspend(int suspend_mode, Error **errp) _exit(EXIT_SUCCESS); } else if (pid < 0) { error_setg_errno(errp, errno, "failed to create child process"); - goto out; + return; } ga_wait_child(pid, &status, &local_err); if (local_err) { error_propagate(errp, local_err); - goto out; - } - - if (!WIFEXITED(status)) { - error_setg(errp, "child process has terminated abnormally"); - goto out; + return; } if (WEXITSTATUS(status)) { error_setg(errp, "child process has failed to suspend"); - goto out; } -out: - g_free(pmutils_path); +} + +static void bios_supports_mode(int suspend_mode, Error **errp) +{ + Error *local_err = NULL; + bool ret; + + ret = pmutils_supports_mode(suspend_mode, &local_err); + if (ret) { + return; + } + if (local_err) { + error_propagate(errp, local_err); + return; + } + ret = linux_sys_state_supports_mode(suspend_mode, errp); + if (!ret) { + error_setg(errp, + "the requested suspend mode is not supported by the guest"); + return; + } +} + +static void guest_suspend(int suspend_mode, Error **errp) +{ + Error *local_err = NULL; + + bios_supports_mode(suspend_mode, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + pmutils_suspend(suspend_mode, &local_err); + if (!local_err) { + return; + } + + error_free(local_err); + + linux_sys_state_suspend(suspend_mode, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } } void qmp_guest_suspend_disk(Error **errp)