From nobody Thu May 2 16:32:59 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; 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 1501745800496416.479029747705; Thu, 3 Aug 2017 00:36:40 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 52FE083F40; Thu, 3 Aug 2017 07:36:38 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 840CC8176E; Thu, 3 Aug 2017 07:36:37 +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 2A02C4BB79; Thu, 3 Aug 2017 07:36:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v737aX7L006941 for ; Thu, 3 Aug 2017 03:36:33 -0400 Received: by smtp.corp.redhat.com (Postfix) id 770BD7BCD6; Thu, 3 Aug 2017 07:36:33 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id F2EBC7BAFF for ; Thu, 3 Aug 2017 07:36:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 52FE083F40 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 3 Aug 2017 09:36:27 +0200 Message-Id: <555a0dc2ba8b4c8cda3bdb66b7615fe6b9c64866.1501745787.git.mprivozn@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH] qemu: Honour 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.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 03 Aug 2017 07:36:39 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" https://bugzilla.redhat.com/show_bug.cgi?id=3D1476866 For some reason, we completely ignore setting for domains. The implementation is simply not there. It never was. However, things are slightly more complicated. QEMU sends us two RESET events on domain reboot. Fortunately, the event contains this 'guest' field telling us who initiated the reboot. And since we don't want to destroy the domain if the reset is initiated by a user, we have to ignore those events. Whatever, just look at the code. Signed-off-by: Michal Privoznik --- src/qemu/qemu_domain.h | 1 + src/qemu/qemu_monitor.c | 4 ++-- src/qemu/qemu_monitor.h | 3 ++- src/qemu/qemu_monitor_json.c | 8 +++++++- src/qemu/qemu_process.c | 34 ++++++++++++++++++++++++++++++---- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 4c9050aff..d865e67c7 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -233,6 +233,7 @@ struct _qemuDomainObjPrivate { bool agentError; =20 bool gotShutdown; + bool gotReset; bool beingDestroyed; char *pidfile; =20 diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 19082d8bf..8f81a2b28 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1344,12 +1344,12 @@ qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTris= tateBool guest) =20 =20 int -qemuMonitorEmitReset(qemuMonitorPtr mon) +qemuMonitorEmitReset(qemuMonitorPtr mon, virTristateBool guest) { int ret =3D -1; VIR_DEBUG("mon=3D%p", mon); =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm); + QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm, guest); return ret; } =20 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 31f7e97ba..8c33f6783 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -134,6 +134,7 @@ typedef int (*qemuMonitorDomainShutdownCallback)(qemuMo= nitorPtr mon, void *opaque); typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, + virTristateBool guest, void *opaque); typedef int (*qemuMonitorDomainPowerdownCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, @@ -346,7 +347,7 @@ int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char= *event, long long seconds, unsigned int micros, const char *details); int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest); -int qemuMonitorEmitReset(qemuMonitorPtr mon); +int qemuMonitorEmitReset(qemuMonitorPtr mon, virTristateBool guest); int qemuMonitorEmitPowerdown(qemuMonitorPtr mon); int qemuMonitorEmitStop(qemuMonitorPtr mon); int qemuMonitorEmitResume(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b8a68154a..8a1501ced 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -536,7 +536,13 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitorP= tr mon, virJSONValuePtr da =20 static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr= data ATTRIBUTE_UNUSED) { - qemuMonitorEmitReset(mon); + bool guest =3D false; + virTristateBool guest_initiated =3D VIR_TRISTATE_BOOL_ABSENT; + + if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) =3D=3D= 0) + guest_initiated =3D guest ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_B= OOL_NO; + + qemuMonitorEmitReset(mon, guest_initiated); } =20 static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValu= ePtr data ATTRIBUTE_UNUSED) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0aecce3b1..889efc7f0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -478,27 +478,51 @@ qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mo= n ATTRIBUTE_UNUSED, static int qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, + virTristateBool guest_initiated, void *opaque) { virQEMUDriverPtr driver =3D opaque; - virObjectEventPtr event; + virObjectEventPtr event =3D NULL; qemuDomainObjPrivatePtr priv; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + bool callOnReboot =3D false; =20 virObjectLock(vm); =20 + priv =3D vm->privateData; + + /* This is a bit tricky. When a guest does 'reboot' we receive RESET e= vent + * twice, both times it's guest initiated. However, if users call 'vir= sh + * reset' we still receive two events but the first one is guest_initi= ated + * =3D no, the second one is guest_initiated =3D yes. Therefore, to av= oid + * executing onReboot action in the latter case we need this complicat= ed + * construction. */ + if (guest_initiated =3D=3D VIR_TRISTATE_BOOL_NO) { + VIR_DEBUG("Ignoring not guest initiated RESET event from domain %s= ", + vm->def->name); + priv->gotReset =3D true; + } else if (priv->gotReset && guest_initiated =3D=3D VIR_TRISTATE_BOOL_= YES) { + VIR_DEBUG("Ignoring second RESET event from domain %s", + vm->def->name); + priv->gotReset =3D false; + } else { + callOnReboot =3D true; + } + event =3D virDomainEventRebootNewFromObj(vm); - priv =3D vm->privateData; if (priv->agent) qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_RESET); =20 if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->cap= s) < 0) VIR_WARN("Failed to save status on vm %s", vm->def->name); =20 + if (callOnReboot && + guest_initiated =3D=3D VIR_TRISTATE_BOOL_YES && + vm->def->onReboot =3D=3D VIR_DOMAIN_LIFECYCLE_DESTROY) + qemuProcessShutdownOrReboot(driver, vm); + virObjectUnlock(vm); - qemuDomainEventQueue(driver, event); - virObjectUnref(cfg); return 0; } @@ -555,6 +579,7 @@ qemuProcessFakeReboot(void *opaque) goto endjob; } priv->gotShutdown =3D false; + priv->gotReset =3D false; event =3D virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); @@ -5320,6 +5345,7 @@ qemuProcessPrepareDomain(virConnectPtr conn, priv->monError =3D false; priv->monStart =3D 0; priv->gotShutdown =3D false; + priv->gotReset =3D false; =20 VIR_DEBUG("Updating guest CPU definition"); if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < = 0) --=20 2.13.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list