#include "kvm/guest_compat.h" #include "kvm/mutex.h" #include #include struct compat_message { int id; char *title; char *desc; struct list_head list; }; static int id; static DEFINE_MUTEX(compat_mtx); static LIST_HEAD(messages); static void compat__free(struct compat_message *msg) { free(msg->title); free(msg->desc); free(msg); } int compat__add_message(const char *title, const char *desc) { struct compat_message *msg; int msg_id; msg = malloc(sizeof(*msg)); if (msg == NULL) goto cleanup; msg->title = strdup(title); msg->desc = strdup(desc); if (msg->title == NULL || msg->desc == NULL) goto cleanup; mutex_lock(&compat_mtx); msg->id = msg_id = id++; list_add_tail(&msg->list, &messages); mutex_unlock(&compat_mtx); return msg_id; cleanup: if (msg) compat__free(msg); return -ENOMEM; } int compat__remove_message(int id) { struct compat_message *pos, *n; mutex_lock(&compat_mtx); list_for_each_entry_safe(pos, n, &messages, list) { if (pos->id == id) { list_del(&pos->list); compat__free(pos); mutex_unlock(&compat_mtx); return 0; } } mutex_unlock(&compat_mtx); return -ENOENT; } int compat__print_all_messages(void) { mutex_lock(&compat_mtx); while (!list_empty(&messages)) { struct compat_message *msg; msg = list_first_entry(&messages, struct compat_message, list); pr_warning("KVM compatibility warning.\n\t%s\n\t%s", msg->title, msg->desc); list_del(&msg->list); compat__free(msg); } mutex_unlock(&compat_mtx); return 0; }