From nobody Mon Apr 29 04:07:01 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1508866518630627.2480370443247; Tue, 24 Oct 2017 10:35:18 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 135C980C08; Tue, 24 Oct 2017 17:35:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A9D2A5D6A2; Tue, 24 Oct 2017 17:35:16 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 707C71804485; Tue, 24 Oct 2017 17:35:16 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v9OHZFrC024612 for ; Tue, 24 Oct 2017 13:35:15 -0400 Received: by smtp.corp.redhat.com (Postfix) id 718E65D75F; Tue, 24 Oct 2017 17:35:15 +0000 (UTC) Received: from mx1.redhat.com (ext-mx04.extmail.prod.ext.phx2.redhat.com [10.5.110.28]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 935375D6A2; Tue, 24 Oct 2017 17:35:12 +0000 (UTC) Received: from mail-pf0-f193.google.com (mail-pf0-f193.google.com [209.85.192.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 391897EAA0; Tue, 24 Oct 2017 17:35:11 +0000 (UTC) Received: by mail-pf0-f193.google.com with SMTP id i5so20183098pfe.6; Tue, 24 Oct 2017 10:35:11 -0700 (PDT) Received: from ps-f25-dev.eng.nutanix.com ([205.209.132.2]) by smtp.gmail.com with ESMTPSA id k2sm1333236pff.126.2017.10.24.10.35.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Oct 2017 10:35:09 -0700 (PDT) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 135C980C08 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 135C980C08 Authentication-Results: mx1.redhat.com; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VHeWYKAK" DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 391897EAA0 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=saxenap.ltc@gmail.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 391897EAA0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/07xlAvgSMoqK0W7oGZLMjPFV5xQgNT7mloRPB35G0Y=; b=VHeWYKAK9Y3huE/cA2toIYvNGG1wzI1CTMN273ZU0xBQ70c4/F87PhPSMcea+iOQm9 dxkiKrFEWUXx7GrghJzFHPB3ckpxsGFttMdvPbu8VMPdQXTrEPlVveDekj+iIjSlATDO iGSa23RmTSI9wcSoCH+d811d0OUC8ulODVghIvDDBE16VK+uCgE0qCpYm3Rwsba4lnPA ZYSBxGWRUrBXi8/BGNBaHKpn699ilnyyCBpdYQMGcRwFwwq5hvt6ylrKLqWGhf/+/Rwx lqN4J5iI0ZbSbE3G/TqsY4KjRAAXlNsG1H+zHKXU8H8DHd2tm9Gp1xG9mDx1b8dVcGu4 NLZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/07xlAvgSMoqK0W7oGZLMjPFV5xQgNT7mloRPB35G0Y=; b=YTjcAPaJKXQt8lBstX0VKCaOYbKq8efQvOsoDyPCwu7TD3MXMdwvzql/lWyzFjpInS w44rSRqaiRm2UPlq2KHaZ0fRQwYq2wrBLTZDeEC9H0vaJB4BBwO0CRV9g3jk/U07X1uF GgqM5LprdXCsTISQE2PE5yQ2wh761GQXgQe7bRjsAMUu7L9iD+wT8t1EudgtabpFb4TY z3eU33r6BTJVKkgIiH3kDJRELX80vTXsTrxzLf04yX8LrJaF02STn9AGnEIsL42zX85L C+ZJ/st87RuN+EzIDJy05sZglmxg8P6eCzEl/h0ReGrPKaLUCAdzk74Z+vn6cKPw/9oQ Atnw== X-Gm-Message-State: AMCzsaWvGTHyk523h0t43E93nQT2DYe447rBAUmSvB0fqv8ohvtNCGHl y0ud9pFqonQqfdstrGflFdjb6g== X-Google-Smtp-Source: ABhQp+R90i5cK35o9ys+2jfSIjafqGdG/7sqooAfr2J2o0phcOvotjrNCka5lxIkfwYce2oeNQK8Bw== X-Received: by 10.99.124.27 with SMTP id x27mr15382628pgc.304.1508866510364; Tue, 24 Oct 2017 10:35:10 -0700 (PDT) From: Prerna Saxena To: libvir-list@redhat.com Date: Tue, 24 Oct 2017 10:34:56 -0700 Message-Id: <20171024173501.18105-4-saxenap.ltc@gmail.com> In-Reply-To: <20171024173501.18105-1-saxenap.ltc@gmail.com> References: <20171024173501.18105-1-saxenap.ltc@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 24 Oct 2017 17:35:11 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 24 Oct 2017 17:35:11 +0000 (UTC) for IP:'209.85.192.193' DOMAIN:'mail-pf0-f193.google.com' HELO:'mail-pf0-f193.google.com' FROM:'saxenap.ltc@gmail.com' RCPT:'' X-RedHat-Spam-Score: -2.41 (DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, RCVD_IN_SORBS_SPAM, SPF_PASS) 209.85.192.193 mail-pf0-f193.google.com 209.85.192.193 mail-pf0-f193.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.28 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: --jdenemar@redhat.com, --pkrempa@redhat.com Subject: [libvirt] [[RFC] 3/8] Setup global and per-VM event queues. Also initialize per-VM queues when libvirt reconnects to an existing VM. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 24 Oct 2017 17:35:17 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Prerna Saxena --- src/conf/domain_conf.h | 3 + src/qemu/qemu_conf.h | 4 + src/qemu/qemu_driver.c | 9 ++ src/qemu/qemu_event.c | 229 ++++++++++++++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_event.h | 1 - src/qemu/qemu_process.c | 2 + 6 files changed, 247 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a42efcf..7fe38e7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2496,6 +2496,9 @@ struct _virDomainObj { =20 unsigned long long original_memlock; /* Original RLIMIT_MEMLOCK, zero = if no * restore will be required later= */ + + /* Pointer to per-VM Event Queue */ + void *vmq; }; =20 typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn, diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 13b6f81..e63dc98 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -33,6 +33,7 @@ # include "domain_conf.h" # include "snapshot_conf.h" # include "domain_event.h" +# include "qemu_event.h" # include "virthread.h" # include "security/security_manager.h" # include "virpci.h" @@ -235,6 +236,9 @@ struct _virQEMUDriver { /* Immutable pointer, self-locking APIs */ virDomainObjListPtr domains; =20 + /* Immutable pointer, contains Qemu Driver Event List */ + virQemuEventList *ev_list; + /* Immutable pointer */ char *qemuImgBinary; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7c6f167..8a005d0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -52,6 +52,7 @@ #include "qemu_command.h" #include "qemu_parse_command.h" #include "qemu_cgroup.h" +#include "qemu_event.h" #include "qemu_hostdev.h" #include "qemu_hotplug.h" #include "qemu_monitor.h" @@ -650,6 +651,14 @@ qemuStateInitialize(bool privileged, if (!(qemu_driver->domains =3D virDomainObjListNew())) goto error; =20 + /* Init domain Async QMP events */ + qemu_driver->ev_list =3D virQemuEventListInit(); + if (!qemu_driver->ev_list) { + virReportSystemError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to initialize QMP event queues")); + goto error; + } + /* Init domain events */ qemu_driver->domainEventState =3D virObjectEventStateNew(); if (!qemu_driver->domainEventState) diff --git a/src/qemu/qemu_event.c b/src/qemu/qemu_event.c index e27ea0d..d52fad2 100644 --- a/src/qemu/qemu_event.c +++ b/src/qemu/qemu_event.c @@ -73,3 +73,232 @@ virQemuEventList* virQemuEventListInit(void) =20 return ev_list; } + +int virQemuVmEventListInit(virDomainObjPtr vm) +{ + virQemuVmEventQueue* vmq; + if (!vm) + return -1; + + if (VIR_ALLOC(vmq) < 0) + return -1; + + vmq->last =3D NULL; + vmq->head =3D NULL; + + if (!virMutexInit(&vmq->lock)) { + vm->vmq =3D vmq; + return 0; + } + return -1; +} +/** + * virEnqueueVMEvent() + * Adds a new event to: + * - Global event queue + * - the event queue for this VM + * + * Return : 0 (success) + * -1 (failure) + */ +int virEnqueueVMEvent(virQemuEventList *qlist, qemuEventPtr ev) +{ + struct _qemuGlobalEventListElement *globalEntry; + virQemuVmEventQueue *vmq; + struct _qemuVmEventQueueElement *vmq_entry; + + if (!qlist || !ev || !ev->vm || !ev->vm->vmq) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "No queue list instantiated." + "Dropping event %d for Vm %s", + ev->ev_type, ev->vm->def->name); + goto error; + } + + if (VIR_ALLOC(globalEntry) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Allocation error." + "Dropping event %d for Vm %s", + ev->ev_type, ev->vm->def->name); + goto error; + } + + if (VIR_ALLOC(vmq_entry) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Allocation error." + "Dropping event %d for Vm %s", + ev->ev_type, ev->vm->def->name); + free(globalEntry); + goto error; + } + + vmq_entry->ev =3D ev; + vmq_entry->next =3D NULL; + + virObjectRef(ev->vm); + globalEntry->vm =3D ev->vm; + globalEntry->next =3D NULL; + globalEntry->prev =3D NULL; + /* Note that this order needs to be maintained + * for dequeue too else ABBA deadlocks will happen */ + + /* Insert into per-Vm queue */ + vmq =3D ev->vm->vmq; + + virMutexLock(&(vmq->lock)); + if (vmq->last) { + vmq->last->next =3D vmq_entry; + vmq_entry->ev->ev_id =3D vmq->last->ev->ev_id + 1; + } else { + vmq->head =3D vmq_entry; + vmq_entry->ev->ev_id =3D 1; + } + vmq->last =3D vmq_entry; + globalEntry->ev_id =3D vmq_entry->ev->ev_id; + /* Insert the event into the global queue */ + virMutexLock(&(qlist->lock)); + if (qlist->last) { + qlist->last->next =3D globalEntry; + globalEntry->prev =3D qlist->last; + } else { + qlist->head =3D globalEntry; + } + + qlist->last =3D globalEntry; + virMutexUnlock(&(qlist->lock)); + virMutexUnlock(&(vmq->lock)); + + return 0; + +error: + return -1; +} + +/** + * virDequeueVMEvent: Dequeues the first event of this VM from : + * - the global event table; + * - the per-VM event table; + * + * Needs to be called with VM lock held. Else the event is deleted foreve= r and + * cannot be picked up by any other worker thread. + */ +qemuEventPtr virDequeueVMEvent(virQemuEventList *qlist, virDomainObjPtr vm) +{ + qemuEventPtr ret_ev; + struct _qemuVmEventQueue *cur_vmq; + struct _qemuVmEventQueueElement *vmq_entry; + struct _qemuGlobalEventListElement *iter; + const char *ref_uuid; + + if (!qlist || !vm || !vm->vmq) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "No queue list /VM/ event for this vm %s", + vm?vm->def->name:NULL); + goto error; + } + + cur_vmq =3D vm->vmq; + + /* Acquire a ref to first event from per-Vm event queue + */ + virMutexLock(&(cur_vmq->lock)); + vmq_entry =3D cur_vmq->head; + + if (cur_vmq->head =3D=3D NULL) { + virMutexUnlock(&(cur_vmq->lock)); + goto error; + } + ref_uuid =3D (const char *)vmq_entry->ev->vm->def->uuid; + + /* Purge the event from global queue, and then from local queue. + * So that ev_ids are always consistent. + */ + virMutexLock(&(qlist->lock)); + iter =3D qlist->head; + while (iter) { + if (iter->vm !=3D NULL && + STREQ((const char *)iter->vm->def->uuid, ref_uuid) && + iter->ev_id =3D=3D vmq_entry->ev->ev_id) { + // Found the element, delete it. + if (iter->prev !=3D NULL) + iter->prev->next =3D iter->next; + else + /* This was the first element */ + qlist->head =3D iter->next; + if (iter->next !=3D NULL) + iter->next->prev =3D iter->prev; + else + /* This was the last element */ + qlist->last =3D iter->prev; + break; + } else { + iter =3D iter->next; + } + } + + // Now remove this from per-Vm queue: + cur_vmq->head =3D vmq_entry->next; + virMutexUnlock(&(qlist->lock)); + + virMutexUnlock(&(cur_vmq->lock)); + + ret_ev =3D vmq_entry->ev; + free(vmq_entry); + if (iter) + free(iter); + + return ret_ev; +error: + return NULL; +} + +void +virEventWorkerScanQueue(void *dummy ATTRIBUTE_UNUSED, void *opaque) +{ + virQEMUDriverPtr driver =3D opaque; + struct _qemuGlobalEventListElement *globalEntry =3D driver->ev_list->h= ead; + virDomainObjPtr vm =3D NULL; + + if (!globalEntry) + return; + + VIR_WARN("Running event driver"); + + while (globalEntry) { + vm =3D globalEntry->vm; + if (vm !=3D NULL) { + if (!virObjectTrylock(vm)) { + break; + } + } + // Todo:Clear events for irrelevant VMs + globalEntry =3D globalEntry->next; + } + + // Scanned the entire list, but no worthy event found. Exit now. + if (!globalEntry) + return; + + virDomainConsumeVMEvents(vm, opaque); + + virObjectUnlock(vm); + + return; +} + +/* Called under the VM lock */ +void virDomainConsumeVMEvents(virDomainObjPtr vm, void *opaque) +{ + virQEMUDriverPtr driver =3D opaque; + qemuEventPtr evt =3D virDequeueVMEvent(driver->ev_list, vm); + + while (evt) { + VIR_WARN("Processing event %d vm %s", evt->ev_type, vm->def->name); + if (evt->handler) + (evt->handler)(evt, opaque); + free(evt); + virObjectUnref(vm); + evt =3D virDequeueVMEvent(driver->ev_list, vm); + } + return; +} diff --git a/src/qemu/qemu_event.h b/src/qemu/qemu_event.h index 9781795..4173834 100644 --- a/src/qemu/qemu_event.h +++ b/src/qemu/qemu_event.h @@ -219,6 +219,5 @@ int virQemuVmEventListInit(virDomainObjPtr vm); int virEnqueueVMEvent(virQemuEventList *qlist, qemuEventPtr ev); qemuEventPtr virDequeueVMEvent(virQemuEventList *qlist, virDomainObjPtr vm= ); void virEventWorkerScanQueue(void *dummy, void *opaque); -void virEventRunHandler(qemuEventPtr ev, void *opaque); void virDomainConsumeVMEvents(virDomainObjPtr vm, void *opaque); #endif diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9f26dfc..8e6498e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6941,6 +6941,8 @@ qemuProcessReconnect(void *opaque) goto error; jobStarted =3D true; =20 + if (virQemuVmEventListInit(obj) < 0) + goto error; /* XXX If we ever gonna change pid file pattern, come up with * some intelligence here to deal with old paths. */ if (!(priv->pidfile =3D virPidFileBuildPath(cfg->stateDir, obj->def->n= ame))) --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list