From nobody Sun May 5 06:53:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538559012824906.294630346336; Wed, 3 Oct 2018 02:30:12 -0700 (PDT) Received: from localhost ([::1]:47583 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7dTu-0005yr-P3 for importer@patchew.org; Wed, 03 Oct 2018 05:30:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51232) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7dRj-00048X-AM for qemu-devel@nongnu.org; Wed, 03 Oct 2018 05:27:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7dKW-0000OE-N3 for qemu-devel@nongnu.org; Wed, 03 Oct 2018 05:20:29 -0400 Received: from proxmox-new.maurer-it.com ([212.186.127.180]:64388) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g7dKS-0000GN-Rk for qemu-devel@nongnu.org; Wed, 03 Oct 2018 05:20:26 -0400 Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id B0E3544037; Wed, 3 Oct 2018 11:13:52 +0200 (CEST) From: Dominik Csapak To: qemu-devel@nongnu.org Date: Wed, 3 Oct 2018 11:13:44 +0200 Message-Id: <20181003091344.24496-2-d.csapak@proxmox.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181003091344.24496-1-d.csapak@proxmox.com> References: <20181003091344.24496-1-d.csapak@proxmox.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.186.127.180 Subject: [Qemu-devel] [PATCH 1/1] vl.c: call optional script when exiting 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: pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" some users might want to call a script when qemu exits, without listening to a qmp monitor for events when running with --daemonize this can be used for things like external cleanups Signed-off-by: Dominik Csapak --- qemu-options.hx | 18 ++++++++++++++++++ vl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx index f139459e80..03dcccee7f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3421,6 +3421,24 @@ This allows for instance switching to monitor to com= mit changes to the disk image. ETEXI =20 +DEF("exit-script", HAS_ARG, QEMU_OPTION_exit_script, \ + "-exit-script \n" + " Execute the script in file on exit.\n" + " The arguments are:\n" + " - the shutdown reason,\n" + " - if it was really a reset (if -no-reboot was = set)\n" + " - the name of the guest", + QEMU_ARCH_ALL) +STEXI +@item -exit-script @var{file} +@findex -exit-script +Execute the script $var{file} on exit. +The arguments are: + - the shutdown reason + - if it was really a reset (if -no-reboot was set) + - the name of the guest +ETEXI + DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \ "-loadvm [tag|id]\n" \ " start right away with a saved state (loadvm in monito= r)\n", diff --git a/vl.c b/vl.c index cc55fe04a2..818381cd76 100644 --- a/vl.c +++ b/vl.c @@ -1522,6 +1522,9 @@ void vm_state_notify(int running, RunState state) } } =20 +static ShutdownCause shutdown_reason; +static bool shutdown_was_reset; + static ShutdownCause reset_requested; static ShutdownCause shutdown_requested; static int shutdown_signal; @@ -1681,6 +1684,7 @@ void qemu_system_guest_panicked(GuestPanicInformation= *info) void qemu_system_reset_request(ShutdownCause reason) { if (no_reboot && reason !=3D SHUTDOWN_CAUSE_SUBSYSTEM_RESET) { + shutdown_was_reset =3D true; shutdown_requested =3D reason; } else { reset_requested =3D reason; @@ -1811,6 +1815,7 @@ static bool main_loop_should_exit(void) if (no_shutdown) { vm_stop(RUN_STATE_SHUTDOWN); } else { + shutdown_reason =3D request; return true; } } @@ -2899,6 +2904,7 @@ int main(int argc, char **argv, char **envp) Error *err =3D NULL; bool list_data_dirs =3D false; char *dir, **dirs; + const char *exit_script =3D NULL; typedef struct BlockdevOptions_queue { BlockdevOptions *bdo; Location loc; @@ -3587,6 +3593,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_no_shutdown: no_shutdown =3D 1; break; + case QEMU_OPTION_exit_script: + exit_script =3D optarg; + break; case QEMU_OPTION_show_cursor: cursor_hide =3D 0; break; @@ -4577,5 +4586,41 @@ int main(int argc, char **argv, char **envp) migration_object_finalize(); /* TODO: unref root container, check all devices are ok */ =20 + if (exit_script) { + int pid, status; + char *args[5]; + + /* try to launch network script */ + pid =3D fork(); + if (pid < 0) { + error_report("could not launch exit script '%s'", exit_script); + exit(1); + } + if (pid =3D=3D 0) { + int open_max =3D sysconf(_SC_OPEN_MAX), i; + + for (i =3D 3; i < open_max; i++) { + close(i); + } + args[0] =3D (char *)exit_script; + args[1] =3D g_strdup_printf("%d", shutdown_reason); + args[2] =3D g_strdup_printf("%d", shutdown_was_reset); + args[3] =3D qemu_get_vm_name(); + args[4] =3D NULL; + execv(exit_script, args); + _exit(1); + } else { + while (waitpid(pid, &status, 0) !=3D pid) { + /* loop */ + } + + if (!WIFEXITED(status) || WEXITSTATUS(status) !=3D 0) { + error_report("exit script '%s' failed with status %d", + exit_script, status); + exit(1); + } + } + } + return 0; } --=20 2.11.0