summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2010-03-17 18:00:45 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2010-03-19 15:27:38 -0500
commit8af8ce4d6116e3d46ad298ca8fe50d3b515b1aac (patch)
treefc66597b1980b5257f21dc733e0a59227742481a
parentd7234f4d7e373a708e1df9ab565a71b71b189025 (diff)
downloadqemu-8af8ce4d6116e3d46ad298ca8fe50d3b515b1aac.tar.gz
tap: invoke downscript when we exit abnormally
Right now, downscript is not invoked reliably. If you execute 'quit' from the monitor, it won't be invoked. This fixes that by converting tap to use an exit_notifier to execute the downscript. In this case, allowing an exit notifier to include state is critically important for the conversion. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--net/tap.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/tap.c b/net/tap.c
index 672b0ee0b4..e42c555029 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -53,6 +53,7 @@ typedef struct TAPState {
char down_script[1024];
char down_script_arg[128];
uint8_t buf[TAP_BUFSIZE];
+ Notifier exit_notifier;
unsigned int read_poll : 1;
unsigned int write_poll : 1;
unsigned int has_vnet_hdr : 1;
@@ -261,6 +262,19 @@ static void tap_cleanup(VLANClientState *nc)
tap_read_poll(s, 0);
tap_write_poll(s, 0);
close(s->fd);
+ exit_notifier_remove(&s->exit_notifier);
+}
+
+/* Instead of exiting gracefully, we're exiting because someone called
+ * exit(), make sure to invoke down script at least
+ */
+static void tap_cleanup_at_exit(Notifier *notifier)
+{
+ TAPState *s = container_of(notifier, TAPState, exit_notifier);
+
+ if (s->down_script[0]) {
+ launch_script(s->down_script, s->down_script_arg, s->fd);
+ }
}
static void tap_poll(VLANClientState *nc, bool enable)
@@ -299,6 +313,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s->has_vnet_hdr = vnet_hdr != 0;
s->using_vnet_hdr = 0;
s->has_ufo = tap_probe_has_ufo(s->fd);
+ s->exit_notifier.notify = tap_cleanup_at_exit;
+ exit_notifier_add(&s->exit_notifier);
tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
tap_read_poll(s, 1);
return s;