From nobody Sat May 4 06:11:15 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) client-ip=205.139.110.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1583428292; cv=none; d=zohomail.com; s=zohoarc; b=cKk5okt5Gs9MalBCyhA4iJ+/T/niW2N241v0tN1AkAA1kw1bfBiwcZeoa4seEcOUlv/aOEbpgxonVZGbRWbByTrgwMmeqhsraGwZ5PF4qkXpJEFI+WaakAbJurPhN38wYYVB1cVWBU0+PCA4OTihZO/ek1m8hKmWDOaxxAsARTE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1583428292; h=Content-Type:Content-Transfer-Encoding:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=vVyT0RYkUBUcYS8tRb+NsKYTT2A7bvNDoZwz5WlKx/0=; b=ivVA6hrFe3hlbaOM/l/bnOCECNVvAjDyKSSa6PbiMmo+bnB8Tsbhly8W8SlBVW0bEFexjMLKuxM53R8z0YX5x8rz7TvBy4vzzYRRWWHU5k9qeheCNWdkTjFJ+cNjrBglE0W8DxFqHXRG+D0uj6PaAeuX3Q1rJBWSJg4WN8KoPwc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by mx.zohomail.com with SMTPS id 1583428292840128.73796571827143; Thu, 5 Mar 2020 09:11:32 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-216-zsRARJg8OWmN2EZmJl-keg-1; Thu, 05 Mar 2020 12:11:29 -0500 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9F7B88010F5; Thu, 5 Mar 2020 17:11:21 +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 1EEC0512F1; Thu, 5 Mar 2020 17:11:20 +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 5723318089CD; Thu, 5 Mar 2020 17:11:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 025HBGhU026872 for ; Thu, 5 Mar 2020 12:11:16 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4A86219C58; Thu, 5 Mar 2020 17:11:16 +0000 (UTC) Received: from moe.redhat.com (unknown [10.43.2.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9D29F272CB for ; Thu, 5 Mar 2020 17:11:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583428291; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=vVyT0RYkUBUcYS8tRb+NsKYTT2A7bvNDoZwz5WlKx/0=; b=QtUe+C77JDemPMM/Wkkv+/DXZmXC2hAqahg5Zf0oCmGR3bFAQSphwORpRD/hJ1WjXztGvK MSDsqaORKUYSk8lHqo0A3LsfZl6E3IDSSAwjslcU3mcd4OqlWGFIgVPIgM3kGrpiy63My3 HPpRprXmbBLRxXAI09rTZGE7EAMhKmY= X-MC-Unique: zsRARJg8OWmN2EZmJl-keg-1 From: Michal Privoznik To: libvir-list@redhat.com Subject: [PATCH] qemu: Create multipath targets for PRs Date: Thu, 5 Mar 2020 18:11:06 +0100 Message-Id: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com 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: , 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-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" If a disk has persistent reservations enabled, qemu-pr-helper might open not only /dev/mapper/control but also individual targets of the multipath device. We are already querying for them in CGroups, but now we have to create them in the namespace too. This was brought up in [1]. 1: https://bugzilla.redhat.com/show_bug.cgi?id=3D1711045#c61 Signed-off-by: Michal Privoznik Reviewed-by: Jim Fehlig --- src/qemu/qemu_domain.c | 64 ++++++++++------ src/util/virdevmapper.h | 4 +- src/util/virutil.h | 2 +- tests/qemuhotplugmock.c | 75 +++++++++++++++++++ tests/qemuhotplugtest.c | 13 ++++ .../qemuhotplug-disk-scsi-multipath.xml | 8 ++ ...uhotplug-base-live+disk-scsi-multipath.xml | 62 +++++++++++++++ 7 files changed, 204 insertions(+), 24 deletions(-) create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-mult= ipath.xml create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk= -scsi-multipath.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 33c2158eb5..c8e6be7fae 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -62,6 +62,7 @@ #include "virdomaincheckpointobjlist.h" #include "backup_conf.h" #include "virutil.h" +#include "virdevmapper.h" =20 #ifdef __linux__ # include @@ -14574,6 +14575,9 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GN= UC_UNUSED, bool hasNVMe =3D false; =20 for (next =3D disk->src; virStorageSourceIsBacking(next); next =3D nex= t->backingStore) { + VIR_AUTOSTRINGLIST targetPaths =3D NULL; + size_t i; + if (next->type =3D=3D VIR_STORAGE_TYPE_NVME) { g_autofree char *nvmePath =3D NULL; =20 @@ -14592,6 +14596,19 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_G= NUC_UNUSED, =20 if (qemuDomainCreateDevice(next->path, data, false) < 0) return -1; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && + errno !=3D ENOSYS && errno !=3D EBADF) { + virReportSystemError(errno, + _("Unable to get devmapper targets fo= r %s"), + next->path); + return -1; + } + + for (i =3D 0; targetPaths && targetPaths[i]; i++) { + if (qemuDomainCreateDevice(targetPaths[i], data, false) < = 0) + return -1; + } } } =20 @@ -15607,21 +15624,19 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm, virStorageSourcePtr src) { virStorageSourcePtr next; - char **paths =3D NULL; + VIR_AUTOSTRINGLIST paths =3D NULL; size_t npaths =3D 0; bool hasNVMe =3D false; - g_autofree char *dmPath =3D NULL; - g_autofree char *vfioPath =3D NULL; - int ret =3D -1; =20 for (next =3D src; virStorageSourceIsBacking(next); next =3D next->bac= kingStore) { + VIR_AUTOSTRINGLIST targetPaths =3D NULL; g_autofree char *tmpPath =3D NULL; =20 if (next->type =3D=3D VIR_STORAGE_TYPE_NVME) { hasNVMe =3D true; =20 if (!(tmpPath =3D virPCIDeviceAddressGetIOMMUGroupDev(&next->n= vme->pciAddr))) - goto cleanup; + return -1; } else { if (virStorageSourceIsEmpty(next) || !virStorageSourceIsLocalStorage(next)) { @@ -15632,30 +15647,35 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm, tmpPath =3D g_strdup(next->path); } =20 - if (VIR_APPEND_ELEMENT(paths, npaths, tmpPath) < 0) - goto cleanup; + if (virStringListAdd(&paths, tmpPath) < 0) + return -1; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && + errno !=3D ENOSYS && errno !=3D EBADF) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s= "), + next->path); + return -1; + } + + if (virStringListMerge(&paths, &targetPaths) < 0) + return -1; } =20 /* qemu-pr-helper might require access to /dev/mapper/control. */ - if (src->pr) { - dmPath =3D g_strdup(QEMU_DEVICE_MAPPER_CONTROL_PATH); - if (VIR_APPEND_ELEMENT_COPY(paths, npaths, dmPath) < 0) - goto cleanup; - } + if (src->pr && + virStringListAdd(&paths, QEMU_DEVICE_MAPPER_CONTROL_PATH) < 0) + return -1; =20 - if (hasNVMe) { - vfioPath =3D g_strdup(QEMU_DEV_VFIO); - if (VIR_APPEND_ELEMENT(paths, npaths, vfioPath) < 0) - goto cleanup; - } + if (hasNVMe && + virStringListAdd(&paths, QEMU_DEV_VFIO) < 0) + return -1; =20 + npaths =3D virStringListLength((const char **) paths); if (qemuDomainNamespaceMknodPaths(vm, (const char **) paths, npaths) <= 0) - goto cleanup; + return -1; =20 - ret =3D 0; - cleanup: - virStringListFreeCount(paths, npaths); - return ret; + return 0; } =20 =20 diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h index e576d2bf7e..87bbc63cfd 100644 --- a/src/util/virdevmapper.h +++ b/src/util/virdevmapper.h @@ -20,6 +20,8 @@ =20 #pragma once =20 +#include "internal.h" + int virDevMapperGetTargets(const char *path, - char ***devPaths); + char ***devPaths) G_GNUC_NO_INLINE; diff --git a/src/util/virutil.h b/src/util/virutil.h index cc6b82a177..ee23f0c1f4 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -120,7 +120,7 @@ bool virValidateWWN(const char *wwn); =20 int virGetDeviceID(const char *path, int *maj, - int *min); + int *min) G_GNUC_NO_INLINE; int virSetDeviceUnprivSGIO(const char *path, const char *sysfs_dir, int unpriv_sgio); diff --git a/tests/qemuhotplugmock.c b/tests/qemuhotplugmock.c index 43a9d79051..8e5b07788d 100644 --- a/tests/qemuhotplugmock.c +++ b/tests/qemuhotplugmock.c @@ -19,7 +19,24 @@ #include =20 #include "qemu/qemu_hotplug.h" +#include "qemu/qemu_process.h" #include "conf/domain_conf.h" +#include "virdevmapper.h" +#include "virutil.h" +#include "virmock.h" + +static int (*real_virGetDeviceID)(const char *path, int *maj, int *min); +static bool (*real_virFileExists)(const char *path); + +static void +init_syms(void) +{ + if (real_virFileExists) + return; + + VIR_MOCK_REAL_INIT(virGetDeviceID); + VIR_MOCK_REAL_INIT(virFileExists); +} =20 unsigned long long qemuDomainGetUnplugTimeout(virDomainObjPtr vm G_GNUC_UNUSED) @@ -31,3 +48,61 @@ qemuDomainGetUnplugTimeout(virDomainObjPtr vm G_GNUC_UNU= SED) return 200; return 100; } + + +int +virDevMapperGetTargets(const char *path, + char ***devPaths) +{ + *devPaths =3D NULL; + + if (STREQ(path, "/dev/mapper/virt")) { + *devPaths =3D g_new(char *, 4); + (*devPaths)[0] =3D g_strdup("/dev/block/8:0"); /* /dev/sda */ + (*devPaths)[1] =3D g_strdup("/dev/block/8:16"); /* /dev/sdb */ + (*devPaths)[2] =3D g_strdup("/dev/block/8:32"); /* /dev/sdc */ + (*devPaths)[3] =3D NULL; + } + + return 0; +} + + +int +virGetDeviceID(const char *path, int *maj, int *min) +{ + init_syms(); + + if (STREQ(path, "/dev/mapper/virt")) { + *maj =3D 254; + *min =3D 0; + return 0; + } + + return real_virGetDeviceID(path, maj, min); +} + + +bool +virFileExists(const char *path) +{ + init_syms(); + + if (STREQ(path, "/dev/mapper/virt")) + return true; + + return real_virFileExists(path); +} + + +int +qemuProcessStartManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED) +{ + return 0; +} + + +void +qemuProcessKillManagedPRDaemon(virDomainObjPtr vm G_GNUC_UNUSED) +{ +} diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index e008c1bf0d..8b411d63f0 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -87,6 +87,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VNC); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SCSI_BLOCK); =20 if (qemuTestCapsCacheInsert(driver.qemuCapsCache, priv->qemuCaps) < 0) return -1; @@ -750,6 +752,17 @@ mymain(void) "device_del", QMP_DEVICE_DELETED("scsi3-0-5-6") QMP_OK, "human-monitor-command", HMP("")); =20 + DO_TEST_ATTACH("base-live", "disk-scsi-multipath", false, true, + "object-add", QMP_OK, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "disk-scsi-multipath", true, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("base-live", "disk-scsi-multipath", false, false, + "device_del", QMP_DEVICE_DELETED("scsi0-0-0-0") QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_ATTACH("base-live", "qemu-agent", false, true, "chardev-add", QMP_OK, "device_add", QMP_OK); diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.x= ml b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml new file mode 100644 index 0000000000..5a6f955284 --- /dev/null +++ b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-multipath.xml @@ -0,0 +1,8 @@ + + + + + + +
+ diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-m= ultipath.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi= -multipath.xml new file mode 100644 index 0000000000..40af064d10 --- /dev/null +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-scsi-multipat= h.xml @@ -0,0 +1,62 @@ + + hotplug + d091ea82-29e6-2e34-3005-f02617b36e87 + 4194304 + 4194304 + 4 + + hvm + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + + + + +
+ + + + + + + + + + + --=20 2.24.1