* [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu
@ 2018-10-04 11:43 Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 1/3] osdep: add qemu_launch_script for executing scripts Dominik Csapak
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Dominik Csapak @ 2018-10-04 11:43 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, sw, jasowang, thuth, philmd
this patch series aims to execute a script when qemu exits
so that one can do cleanups when using --daemonize without
having to use the qmp monitor
changes since v1:
* refactored as qemu_launch_script, only for non-windows platforms
* updated net/tap.c to use qemu_launch_script instead of launch_script
* fixed a small error in the option description
Dominik Csapak (3):
osdep: add qemu_launch_script for executing scripts
tap: use qemu_launch_script instead of launch_script
vl.c: call optional script when exiting
include/qemu/osdep.h | 12 +++++++++++
net/tap.c | 56 ++++++++++------------------------------------------
qemu-options.hx | 20 +++++++++++++++++++
util/oslib-posix.c | 34 +++++++++++++++++++++++++++++++
util/oslib-win32.c | 8 ++++++++
vl.c | 29 +++++++++++++++++++++++++++
6 files changed, 113 insertions(+), 46 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 1/3] osdep: add qemu_launch_script for executing scripts
2018-10-04 11:43 [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Dominik Csapak
@ 2018-10-04 11:43 ` Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 2/3] tap: use qemu_launch_script instead of launch_script Dominik Csapak
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Dominik Csapak @ 2018-10-04 11:43 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, sw, jasowang, thuth, philmd
this adds a small function for launching an external script
via fork/exec (not available for windows) and is intended
for replacing 'launch_script' in net/tap.c and to provide a general
way to launch scripts
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
i modeled the windows error after the qemu_fork implementation,
since it does not exist for the same reason
changes since v1:
* new in v2
include/qemu/osdep.h | 12 ++++++++++++
util/oslib-posix.c | 34 ++++++++++++++++++++++++++++++++++
util/oslib-win32.c | 8 ++++++++
3 files changed, 54 insertions(+)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 4f8559e550..26c1f01d55 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -564,6 +564,18 @@ char *qemu_get_pid_name(pid_t pid);
*/
pid_t qemu_fork(Error **errp);
+/**
+ * qemu_launch_script:
+ * @script: the path to the script
+ * @args: the arguments for the script
+ * @fd: a file descriptor that should not be closed
+ *
+ * fork and exec a script with the given arguments
+ * closes all file descriptors > 2 except the one given with fd
+ */
+void qemu_launch_script(const char *script, char *const args[], int fd,
+ Error **errp);
+
/* Using intptr_t ensures that qemu_*_page_mask is sign-extended even
* when intptr_t is 32-bit and we are aligning a long long.
*/
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index fbd0dc8c57..123b142591 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -698,3 +698,37 @@ void sigaction_invoke(struct sigaction *action,
}
action->sa_sigaction(info->ssi_signo, &si, NULL);
}
+
+void qemu_launch_script(const char *script, char *const args[], int fd,
+ Error **errp)
+{
+ int pid, status;
+
+ pid = fork();
+ if (pid < 0) {
+ error_setg_errno(errp, errno, "could not launch script %s",
+ script);
+ return;
+ }
+ if (pid == 0) {
+ int open_max = sysconf(_SC_OPEN_MAX), i;
+
+ for (i = 3; i < open_max; i++) {
+ if (i != fd) {
+ close(i);
+ }
+ }
+ execv(script, args);
+ _exit(1);
+ } else {
+ while (waitpid(pid, &status, 0) != pid) {
+ /* loop */
+ }
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ return;
+ }
+ error_setg(errp, "script %s failed with status %d",
+ script, status);
+ }
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index b4c17f5dfa..5e14c89dc7 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -803,3 +803,11 @@ bool qemu_write_pidfile(const char *filename, Error **errp)
}
return true;
}
+
+void qemu_launch_script(const char *script, char *const args[], int fd,
+ Error **errp)
+{
+ errno = ENOSYS;
+ error_setg_errno(errp, errno,
+ "cannot fork child process");
+}
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 2/3] tap: use qemu_launch_script instead of launch_script
2018-10-04 11:43 [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 1/3] osdep: add qemu_launch_script for executing scripts Dominik Csapak
@ 2018-10-04 11:43 ` Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 3/3] vl.c: call optional script when exiting Dominik Csapak
2018-10-08 3:28 ` [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Jason Wang
3 siblings, 0 replies; 6+ messages in thread
From: Dominik Csapak @ 2018-10-04 11:43 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, sw, jasowang, thuth, philmd
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes since v1:
* new in v2
net/tap.c | 56 ++++++++++----------------------------------------------
1 file changed, 10 insertions(+), 46 deletions(-)
diff --git a/net/tap.c b/net/tap.c
index cc8525f154..15a0dd65b8 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -62,9 +62,6 @@ typedef struct TAPState {
Notifier exit;
} TAPState;
-static void launch_script(const char *setup_script, const char *ifname,
- int fd, Error **errp);
-
static void tap_send(void *opaque);
static void tap_writable(void *opaque);
@@ -300,7 +297,11 @@ static void tap_exit_notify(Notifier *notifier, void *data)
Error *err = NULL;
if (s->down_script[0]) {
- launch_script(s->down_script, s->down_script_arg, s->fd, &err);
+ char *args[3];
+ args[0] = (char *)(s->down_script);
+ args[1] = (char *)(s->down_script_arg);
+ args[2] = NULL;
+ qemu_launch_script(s->down_script, args, s->fd, &err);
if (err) {
error_report_err(err);
}
@@ -397,47 +398,6 @@ static TAPState *net_tap_fd_init(NetClientState *peer,
return s;
}
-static void launch_script(const char *setup_script, const char *ifname,
- int fd, Error **errp)
-{
- int pid, status;
- char *args[3];
- char **parg;
-
- /* try to launch network script */
- pid = fork();
- if (pid < 0) {
- error_setg_errno(errp, errno, "could not launch network script %s",
- setup_script);
- return;
- }
- if (pid == 0) {
- int open_max = sysconf(_SC_OPEN_MAX), i;
-
- for (i = 3; i < open_max; i++) {
- if (i != fd) {
- close(i);
- }
- }
- parg = args;
- *parg++ = (char *)setup_script;
- *parg++ = (char *)ifname;
- *parg = NULL;
- execv(setup_script, args);
- _exit(1);
- } else {
- while (waitpid(pid, &status, 0) != pid) {
- /* loop */
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return;
- }
- error_setg(errp, "network script %s failed with status %d",
- setup_script, status);
- }
-}
-
static int recv_fd(int c)
{
int fd;
@@ -626,7 +586,11 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
if (setup_script &&
setup_script[0] != '\0' &&
strcmp(setup_script, "no") != 0) {
- launch_script(setup_script, ifname, fd, &err);
+ char *args[3];
+ args[0] = (char *)setup_script;
+ args[1] = (char *)ifname;
+ args[2] = NULL;
+ qemu_launch_script(setup_script, args, fd, &err);
if (err) {
error_propagate(errp, err);
close(fd);
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 3/3] vl.c: call optional script when exiting
2018-10-04 11:43 [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 1/3] osdep: add qemu_launch_script for executing scripts Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 2/3] tap: use qemu_launch_script instead of launch_script Dominik Csapak
@ 2018-10-04 11:43 ` Dominik Csapak
2018-10-08 3:28 ` [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Jason Wang
3 siblings, 0 replies; 6+ messages in thread
From: Dominik Csapak @ 2018-10-04 11:43 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, sw, jasowang, thuth, philmd
some users might want to call a script when qemu exits, without listening
to a qmp monitor for events when running with --daemonize
this option is only available on non windows systems,
since there is no fork there and no --daemonize option
this can be used for things like external cleanups
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes since v1:
* only for non WIN32
* use qemu_launch_script
* fix error in option description (@var{file} instead of $var{file})
qemu-options.hx | 20 ++++++++++++++++++++
vl.c | 29 +++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/qemu-options.hx b/qemu-options.hx
index f139459e80..6a67ec76fe 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3421,6 +3421,26 @@ This allows for instance switching to monitor to commit changes to the
disk image.
ETEXI
+#ifndef _WIN32
+DEF("exit-script", HAS_ARG, QEMU_OPTION_exit_script, \
+ "-exit-script <file>\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
+#endif
+
DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \
"-loadvm [tag|id]\n" \
" start right away with a saved state (loadvm in monitor)\n",
diff --git a/vl.c b/vl.c
index 0388852deb..5adf7c80f7 100644
--- a/vl.c
+++ b/vl.c
@@ -1522,6 +1522,9 @@ void vm_state_notify(int running, RunState state)
}
}
+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 != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
+ shutdown_was_reset = true;
shutdown_requested = reason;
} else {
reset_requested = reason;
@@ -1811,6 +1815,7 @@ static bool main_loop_should_exit(void)
if (no_shutdown) {
vm_stop(RUN_STATE_SHUTDOWN);
} else {
+ shutdown_reason = request;
return true;
}
}
@@ -2908,6 +2913,7 @@ int main(int argc, char **argv, char **envp)
Error *err = NULL;
bool list_data_dirs = false;
char *dir, **dirs;
+ const char *exit_script = NULL;
typedef struct BlockdevOptions_queue {
BlockdevOptions *bdo;
Location loc;
@@ -3596,6 +3602,11 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_no_shutdown:
no_shutdown = 1;
break;
+#ifndef _WIN32
+ case QEMU_OPTION_exit_script:
+ exit_script = optarg;
+ break;
+#endif
case QEMU_OPTION_show_cursor:
cursor_hide = 0;
break;
@@ -4590,5 +4601,23 @@ int main(int argc, char **argv, char **envp)
migration_object_finalize();
/* TODO: unref root container, check all devices are ok */
+ if (exit_script) {
+ char *args[5];
+ Error *local_err = NULL;
+ args[0] = (char *)exit_script;
+ args[1] = g_strdup_printf("%d", shutdown_reason);
+ args[2] = g_strdup_printf("%d", shutdown_was_reset);
+ args[3] = (char *)qemu_get_vm_name();
+ args[4] = NULL;
+
+ qemu_launch_script(exit_script, args, -1, &local_err);
+ g_free(args[1]);
+ g_free(args[2]);
+ if (local_err) {
+ error_report_err(local_err);
+ exit(1);
+ }
+ }
+
return 0;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu
2018-10-04 11:43 [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Dominik Csapak
` (2 preceding siblings ...)
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 3/3] vl.c: call optional script when exiting Dominik Csapak
@ 2018-10-08 3:28 ` Jason Wang
2018-10-08 7:39 ` Dominik Csapak
3 siblings, 1 reply; 6+ messages in thread
From: Jason Wang @ 2018-10-08 3:28 UTC (permalink / raw)
To: Dominik Csapak, qemu-devel; +Cc: pbonzini, philmd, thuth, sw
On 2018年10月04日 19:43, Dominik Csapak wrote:
> this patch series aims to execute a script when qemu exits
> so that one can do cleanups when using --daemonize without
> having to use the qmp monitor
Hi:
Can you give a example of why it must be done through this way? It looks
to me that we can do this by monitor the pid and behave accordingly
through bash.
Thanks
>
> changes since v1:
>
> * refactored as qemu_launch_script, only for non-windows platforms
> * updated net/tap.c to use qemu_launch_script instead of launch_script
> * fixed a small error in the option description
>
> Dominik Csapak (3):
> osdep: add qemu_launch_script for executing scripts
> tap: use qemu_launch_script instead of launch_script
> vl.c: call optional script when exiting
>
> include/qemu/osdep.h | 12 +++++++++++
> net/tap.c | 56 ++++++++++------------------------------------------
> qemu-options.hx | 20 +++++++++++++++++++
> util/oslib-posix.c | 34 +++++++++++++++++++++++++++++++
> util/oslib-win32.c | 8 ++++++++
> vl.c | 29 +++++++++++++++++++++++++++
> 6 files changed, 113 insertions(+), 46 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu
2018-10-08 3:28 ` [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Jason Wang
@ 2018-10-08 7:39 ` Dominik Csapak
0 siblings, 0 replies; 6+ messages in thread
From: Dominik Csapak @ 2018-10-08 7:39 UTC (permalink / raw)
To: Jason Wang, qemu-devel; +Cc: pbonzini, philmd, thuth, sw
On 10/8/18 5:28 AM, Jason Wang wrote:
>
>
> On 2018年10月04日 19:43, Dominik Csapak wrote:
>> this patch series aims to execute a script when qemu exits
>> so that one can do cleanups when using --daemonize without
>> having to use the qmp monitor
>
> Hi:
>
> Can you give a example of why it must be done through this way? It looks
> to me that we can do this by monitor the pid and behave accordingly
> through bash.
>
> Thanks
Hi,
as i said in a reply on my original patch, the reason was twofold
first, i thought having an additional process just for monitoring
the exit of qemu with qmp/pidfile was too much for some users, as
opposed to a simple script that executes then
ans second (more important), i wanted to know the reason qemu
exited (e.g. user initiated shutdown/reset/etc.),
especially when '-no-reboot' is set
please ignore this series (maybe the refactoring of the launch script
is interesting, i don't know), i will send a patch to be able
to distinguish the shutdown/reset with no-reboot in a seperate
patch for qmp
>
>>
>> changes since v1:
>>
>> * refactored as qemu_launch_script, only for non-windows platforms
>> * updated net/tap.c to use qemu_launch_script instead of launch_script
>> * fixed a small error in the option description
>>
>> Dominik Csapak (3):
>> osdep: add qemu_launch_script for executing scripts
>> tap: use qemu_launch_script instead of launch_script
>> vl.c: call optional script when exiting
>>
>> include/qemu/osdep.h | 12 +++++++++++
>> net/tap.c | 56
>> ++++++++++------------------------------------------
>> qemu-options.hx | 20 +++++++++++++++++++
>> util/oslib-posix.c | 34 +++++++++++++++++++++++++++++++
>> util/oslib-win32.c | 8 ++++++++
>> vl.c | 29 +++++++++++++++++++++++++++
>> 6 files changed, 113 insertions(+), 46 deletions(-)
>>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-10-08 7:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-04 11:43 [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 1/3] osdep: add qemu_launch_script for executing scripts Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 2/3] tap: use qemu_launch_script instead of launch_script Dominik Csapak
2018-10-04 11:43 ` [Qemu-devel] [PATCH v2 3/3] vl.c: call optional script when exiting Dominik Csapak
2018-10-08 3:28 ` [Qemu-devel] [PATCH v2 0/3] add exit-script option to qemu Jason Wang
2018-10-08 7:39 ` Dominik Csapak
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.