[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/5] Introduce yank feature
From: |
Lukas Straub |
Subject: |
[PATCH 1/5] Introduce yank feature |
Date: |
Mon, 11 May 2020 13:14:37 +0200 |
The yank feature allows to recover from hanging qemu by "yanking"
at various parts. Other qemu systems can register yank functions
which will be called by the 'yank' out-of-band qmp command.
Signed-off-by: Lukas Straub <address@hidden>
---
qapi/misc.json | 15 ++++++++++
softmmu/vl.c | 2 ++
yank.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
yank.h | 12 ++++++++
4 files changed, 104 insertions(+)
create mode 100644 yank.c
create mode 100644 yank.h
diff --git a/qapi/misc.json b/qapi/misc.json
index 99b90ac80b..de1ee494ae 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1550,3 +1550,18 @@
##
{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
+##
+# @yank:
+#
+# Recover from hanging qemu by calling yank functions.
+#
+# Returns: nothing.
+#
+# Example:
+#
+# -> { "execute": "yank" }
+# <- { "return": {} }
+#
+# Since: 5.1
+##
+{ 'command': 'yank', 'allow-oob': true }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 32c0047889..5d99749d29 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -112,6 +112,7 @@
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
#include "qemu/guest-random.h"
+#include "yank.h"
#define MAX_VIRTIO_CONSOLES 1
@@ -2906,6 +2907,7 @@ void qemu_init(int argc, char **argv, char **envp)
precopy_infrastructure_init();
postcopy_infrastructure_init();
monitor_init_globals();
+ yank_init();
if (qcrypto_init(&err) < 0) {
error_reportf_err(err, "cannot initialize crypto: ");
diff --git a/yank.c b/yank.c
new file mode 100644
index 0000000000..cefbfd8ab5
--- /dev/null
+++ b/yank.c
@@ -0,0 +1,75 @@
+/*
+ * QEMU yank feature
+ *
+ * Copyright (c) Lukas Straub <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/thread.h"
+#include "qemu/queue.h"
+#include "yank.h"
+
+struct YankFuncAndParam {
+ YankFn *func;
+ void *opaque;
+ QLIST_ENTRY(YankFuncAndParam) next;
+};
+
+static QemuMutex lock;
+static QLIST_HEAD(qlisthead, YankFuncAndParam) head
+ = QLIST_HEAD_INITIALIZER(head);
+
+void yank_register_function(YankFn *func, void *opaque)
+{
+ struct YankFuncAndParam *tmp = g_malloc(sizeof(struct YankFuncAndParam));
+ tmp->func = func;
+ tmp->opaque = opaque;
+
+ qemu_mutex_lock(&lock);
+ QLIST_INSERT_HEAD(&head, tmp, next);
+ qemu_mutex_unlock(&lock);
+}
+
+void yank_unregister_function(YankFn *func, void *opaque)
+{
+ qemu_mutex_lock(&lock);
+
+ struct YankFuncAndParam *tmp;
+ QLIST_FOREACH(tmp, &head, next) {
+ if (tmp->func == func && tmp->opaque == opaque) {
+ QLIST_REMOVE(tmp, next);
+ g_free(tmp);
+ qemu_mutex_unlock(&lock);
+ return;
+ }
+ }
+
+ abort();
+}
+
+void yank_call_functions(void)
+{
+ qemu_mutex_lock(&lock);
+
+ struct YankFuncAndParam *tmp;
+ QLIST_FOREACH(tmp, &head, next) {
+ tmp->func(tmp->opaque);
+ }
+
+ qemu_mutex_unlock(&lock);
+}
+
+void qmp_yank(Error **errp)
+{
+ yank_call_functions();
+}
+
+void yank_init(void)
+{
+ qemu_mutex_init(&lock);
+ QLIST_INIT(&head);
+}
diff --git a/yank.h b/yank.h
new file mode 100644
index 0000000000..7376224219
--- /dev/null
+++ b/yank.h
@@ -0,0 +1,12 @@
+
+#ifndef YANK_H
+#define YANK_H
+
+typedef void (YankFn) (void *opaque);
+
+void yank_register_function(YankFn *func, void *opaque);
+void yank_unregister_function(YankFn *func, void *opaque);
+void yank_call_functions(void);
+void yank_init(void);
+void qmp_yank(Error **errp);
+#endif
--
2.20.1
pgpTNBXMBIy5Y.pgp
Description: OpenPGP digital signature