From nobody Wed May 14 20:28:48 2025 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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1519236739792108.82015138360669; Wed, 21 Feb 2018 10:12:19 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E3CE12C284D; Wed, 21 Feb 2018 18:12: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 BCF0D6049B; Wed, 21 Feb 2018 18:12:17 +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 7078318033F3; Wed, 21 Feb 2018 18:12:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w1LIBpKH026282 for ; Wed, 21 Feb 2018 13:11:51 -0500 Received: by smtp.corp.redhat.com (Postfix) id E2D9510A971D; Wed, 21 Feb 2018 18:11:50 +0000 (UTC) Received: from moe.brq.redhat.com (unknown [10.43.2.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6E36D10A971B; Wed, 21 Feb 2018 18:11:50 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Wed, 21 Feb 2018 19:11:34 +0100 Message-Id: <2b2ee1ec737d7c514192fe1048be883bc26536e7.1519235042.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: libvir-list@redhat.com Cc: pbonzini@redhat.com Subject: [libvirt] [PATCH v2 09/12] qemu: Start PR daemons on domain startup 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 21 Feb 2018 18:12:18 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Before we exec() qemu we have to spawn pr-helper processes for all managed reservations (well, technically there can only one). The only caveat there is that we should place the process into the same namespace and cgroup as qemu (so that it shares the same view of the system). But we can do that only after we've forked. That means calling the setup function between fork() and exec(). Signed-off-by: Michal Privoznik --- src/qemu/qemu_process.c | 164 ++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 164 insertions(+) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index dc33eb7bc..33e0ad30c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2551,6 +2551,164 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver, ret =3D 0; cleanup: virObjectUnref(caps); + + return ret; +} + + +static void +qemuProcessKillPRDaemons(virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + if (priv->prPid =3D=3D (pid_t) -1) + return; + + virProcessKillPainfully(priv->prPid, true); + priv->prPid =3D (pid_t) -1; +} + + +static int +qemuProcessSetupOnePRDaemonHook(void *opaque) +{ + virDomainObjPtr vm =3D opaque; + size_t i, nfds =3D 0; + int *fds =3D NULL; + int ret =3D -1; + + if (virProcessGetNamespaces(vm->pid, &nfds, &fds) < 0) + return ret; + + if (nfds > 0 && + virProcessSetNamespaces(nfds, fds) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + for (i =3D 0; i < nfds; i++) + VIR_FORCE_CLOSE(fds[i]); + VIR_FREE(fds); + return ret; +} + + +static int +qemuProcessSetupOnePRDaemon(virDomainObjPtr vm, + virDomainDiskDefPtr disk) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + virQEMUDriverPtr driver =3D priv->driver; + virQEMUDriverConfigPtr cfg; + qemuDomainStorageSourcePrivatePtr srcPriv; + qemuDomainDiskPRDPtr prd; + char *pidfile =3D NULL; + pid_t cpid =3D -1; + virCommandPtr cmd =3D NULL; + virTimeBackOffVar timebackoff; + const unsigned long long timeout =3D 500000; /* ms */ + int ret =3D -1; + + if (priv->prPid !=3D (pid_t) -1 || + !virStoragePRDefIsManaged(disk->src->pr)) + return 0; + + cfg =3D virQEMUDriverGetConfig(driver); + srcPriv =3D QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src); + prd =3D srcPriv->prd; + + if (!virFileIsExecutable(cfg->prHelperName)) { + virReportSystemError(errno, _("'%s' is not a suitable pr helper"), + cfg->prHelperName); + goto cleanup; + } + + if (!(pidfile =3D virPidFileBuildPath(cfg->stateDir, prd->alias))) + goto cleanup; + + if (unlink(pidfile) < 0 && + errno !=3D ENOENT) { + virReportSystemError(errno, + _("Cannot remove stale PID file %s"), + pidfile); + goto cleanup; + } + + if (!(cmd =3D virCommandNewArgList(cfg->prHelperName, + "-k", prd->path, + NULL))) + goto cleanup; + + virCommandDaemonize(cmd); + virCommandSetPidFile(cmd, pidfile); + virCommandSetPreExecHook(cmd, qemuProcessSetupOnePRDaemonHook, vm); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + if (virPidFileReadPath(pidfile, &cpid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("pr helper %s didn't show up"), prd->alias); + goto cleanup; + } + + if (virTimeBackOffStart(&timebackoff, 1, timeout) < 0) + goto cleanup; + while (virTimeBackOffWait(&timebackoff)) { + if (virFileExists(prd->path)) + break; + + if (virProcessKill(cpid, 0) =3D=3D 0) + continue; + + virReportSystemError(errno, + _("pr helper %s died unexpectedly"), prd->ali= as); + goto cleanup; + } + + if (priv->cgroup && + virCgroupAddMachineTask(priv->cgroup, cpid) < 0) + goto cleanup; + + if (qemuSecurityDomainSetPathLabel(driver->securityManager, + vm->def, prd->path, true) < 0) + goto cleanup; + + priv->prPid =3D cpid; + ret =3D 0; + cleanup: + if (ret < 0) { + virCommandAbort(cmd); + virProcessKillPainfully(cpid, true); + } + virCommandFree(cmd); + if (unlink(pidfile) < 0 && + errno !=3D ENOENT && + !virGetLastError()) + virReportSystemError(errno, + _("Cannot remove stale PID file %s"), + pidfile); + VIR_FREE(pidfile); + virObjectUnref(cfg); + return ret; +} + + +static int +qemuProcessSetupPRDaemons(virDomainObjPtr vm) +{ + size_t i; + int ret =3D -1; + + for (i =3D 0; i < vm->def->ndisks; i++) { + if (qemuProcessSetupOnePRDaemon(vm, vm->def->disks[i]) < 0) + goto cleanup; + } + + ret =3D 0; + cleanup: + if (ret < 0) + qemuProcessKillPRDaemons(vm); return ret; } =20 @@ -6074,6 +6232,10 @@ qemuProcessLaunch(virConnectPtr conn, if (qemuProcessResctrlCreate(driver, vm) < 0) goto cleanup; =20 + VIR_DEBUG("Setting up PR daemons"); + if (qemuProcessSetupPRDaemons(vm) < 0) + goto cleanup; + VIR_DEBUG("Setting domain security labels"); if (qemuSecuritySetAllLabel(driver, vm, @@ -6654,6 +6816,8 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_FREE(vm->def->seclabels[i]->imagelabel); } =20 + qemuProcessKillPRDaemons(vm); + qemuHostdevReAttachDomainDevices(driver, vm->def); =20 def =3D vm->def; --=20 2.16.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list