From nobody Sat Feb 7 11:39:10 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) client-ip=209.132.183.24; envelope-from=libvir-list-bounces@redhat.com; helo=mx3-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mx.zohomail.com with SMTPS id 1479787410707247.0738794078901; Mon, 21 Nov 2016 20:03:30 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id uAM3wb0a006606; Mon, 21 Nov 2016 22:58:38 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id uAM3waox031229 for ; Mon, 21 Nov 2016 22:58:36 -0500 Received: from mx1.redhat.com (ext-mx01.extmail.prod.ext.phx2.redhat.com [10.5.110.25]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAM3wabl012963 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 21 Nov 2016 22:58:36 -0500 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7435B7971A for ; Tue, 22 Nov 2016 03:58:34 +0000 (UTC) Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id uAM3wSKG113525 for ; Mon, 21 Nov 2016 22:58:34 -0500 Received: from e35.co.us.ibm.com (e35.co.us.ibm.com [32.97.110.153]) by mx0a-001b2d01.pphosted.com with ESMTP id 26vcrt3n2w-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 21 Nov 2016 22:58:33 -0500 Received: from localhost by e35.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 21 Nov 2016 20:58:33 -0700 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e35.co.us.ibm.com (192.168.1.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 21 Nov 2016 20:58:30 -0700 Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id BE09219D8040; Mon, 21 Nov 2016 20:57:51 -0700 (MST) Received: from b03ledav002.gho.boulder.ibm.com (b03ledav002.gho.boulder.ibm.com [9.17.130.233]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id uAM3wTK836438060; Mon, 21 Nov 2016 20:58:29 -0700 Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D3262136040; Mon, 21 Nov 2016 20:58:29 -0700 (MST) Received: from farman-ThinkPad-W540.ibm.com (unknown [9.85.134.169]) by b03ledav002.gho.boulder.ibm.com (Postfix) with ESMTPS id 5112813603A; Mon, 21 Nov 2016 20:58:29 -0700 (MST) From: Eric Farman To: libvirt-list@redhat.com Date: Mon, 21 Nov 2016 22:58:17 -0500 In-Reply-To: <1479787103-26581-1-git-send-email-farman@linux.vnet.ibm.com> References: <1479787103-26581-1-git-send-email-farman@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16112203-0012-0000-0000-000011336EFA X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00006120; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000189; SDB=6.00783707; UDB=6.00378500; IPR=6.00561326; BA=6.00004898; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00013404; XFM=3.00000011; UTC=2016-11-22 03:58:31 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16112203-0013-0000-0000-000047607B9A Message-Id: <1479787103-26581-4-git-send-email-farman@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-11-22_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=43 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1611220070 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 199 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 22 Nov 2016 03:58:34 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 22 Nov 2016 03:58:34 +0000 (UTC) for IP:'148.163.156.1' DOMAIN:'mx0a-001b2d01.pphosted.com' HELO:'mx0a-001b2d01.pphosted.com' FROM:'farman@linux.vnet.ibm.com' RCPT:'' X-RedHat-Spam-Score: 0.099 (BAYES_50, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2) 148.163.156.1 mx0a-001b2d01.pphosted.com 148.163.156.1 mx0a-001b2d01.pphosted.com X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Scanned-By: MIMEDefang 2.78 on 10.5.110.25 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v4 3/9] util: Management routines for scsi_host devices 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-ZohoMail: RSF_0 Z_629925259 SPT_1 Z_629926901 SPT_1 UDT_7 RF_0 X-Zoho-Virus-Status: 2 Content-Type: text/plain; charset="utf-8" For a new hostdev type=3D'scsi_host' we have a number of required functions for managing, adding, and removing the host device to/from guests. Provide the basic infrastructure for these tasks. The name "SCSIVHost" (and its variants) is chosen to avoid conflicts with existing code named "SCSIHost" to refer to a hostdev type=3D'scsi' protcol=3D'none'. Signed-off-by: Eric Farman --- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/libvirt_private.syms | 18 +++ src/util/virhostdev.c | 163 +++++++++++++++++++++++++++ src/util/virhostdev.h | 16 +++ src/util/virscsivhost.c | 288 +++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virscsivhost.h | 65 +++++++++++ tests/qemuxml2argvmock.c | 9 ++ 8 files changed, 561 insertions(+) create mode 100644 src/util/virscsivhost.c create mode 100644 src/util/virscsivhost.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 25867ae..bdff679 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -237,6 +237,7 @@ src/util/virqemu.c src/util/virrandom.c src/util/virrotatingfile.c src/util/virscsi.c +src/util/virscsivhost.c src/util/virsecret.c src/util/virsexpr.c src/util/virsocketaddr.c diff --git a/src/Makefile.am b/src/Makefile.am index aaba9e6..a0e5e92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -163,6 +163,7 @@ UTIL_SOURCES =3D \ util/virrandom.h util/virrandom.c \ util/virrotatingfile.h util/virrotatingfile.c \ util/virscsi.c util/virscsi.h \ + util/virscsivhost.c util/virscsivhost.h \ util/virseclabel.c util/virseclabel.h \ util/virsecret.c util/virsecret.h \ util/virsexpr.c util/virsexpr.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index baff82b..46b4e87 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1684,10 +1684,12 @@ virHostdevPCINodeDeviceReset; virHostdevPrepareDomainDevices; virHostdevPreparePCIDevices; virHostdevPrepareSCSIDevices; +virHostdevPrepareSCSIVHostDevices; virHostdevPrepareUSBDevices; virHostdevReAttachDomainDevices; virHostdevReAttachPCIDevices; virHostdevReAttachSCSIDevices; +virHostdevReAttachSCSIVHostDevices; virHostdevReAttachUSBDevices; virHostdevUpdateActiveDomainDevices; virHostdevUpdateActivePCIDevices; @@ -2305,6 +2307,22 @@ virSCSIDeviceNew; virSCSIDeviceSetUsedBy; =20 =20 +# util/virscsivhost.h +virSCSIVHostDeviceFileIterate; +virSCSIVHostDeviceFree; +virSCSIVHostDeviceGetName; +virSCSIVHostDeviceListAdd; +virSCSIVHostDeviceListCount; +virSCSIVHostDeviceListDel; +virSCSIVHostDeviceListFind; +virSCSIVHostDeviceListGet; +virSCSIVHostDeviceListNew; +virSCSIVHostDeviceListSteal; +virSCSIVHostDeviceNew; +virSCSIVHostDeviceSetUsedBy; +virSCSIVHostOpenVhostSCSI; + + # util/virseclabel.h virSecurityDeviceLabelDefFree; virSecurityDeviceLabelDefNew; diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index 9c2262e..ca4c339 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -146,6 +146,7 @@ virHostdevManagerDispose(void *obj) virObjectUnref(hostdevMgr->inactivePCIHostdevs); virObjectUnref(hostdevMgr->activeUSBHostdevs); virObjectUnref(hostdevMgr->activeSCSIHostdevs); + virObjectUnref(hostdevMgr->activeSCSIVHostHostdevs); VIR_FREE(hostdevMgr->stateDir); } =20 @@ -170,6 +171,9 @@ virHostdevManagerNew(void) if (!(hostdevMgr->activeSCSIHostdevs =3D virSCSIDeviceListNew())) goto error; =20 + if (!(hostdevMgr->activeSCSIVHostHostdevs =3D virSCSIVHostDeviceListNe= w())) + goto error; + if (privileged) { if (VIR_STRDUP(hostdevMgr->stateDir, HOSTDEV_STATE_DIR) < 0) goto error; @@ -1472,6 +1476,102 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr m= gr, return -1; } =20 +int +virHostdevPrepareSCSIVHostDevices(virHostdevManagerPtr mgr, + const char *drv_name, + const char *dom_name, + virDomainHostdevDefPtr *hostdevs, + int nhostdevs) +{ + size_t i, j; + int count; + virSCSIVHostDeviceListPtr list; + virSCSIVHostDevicePtr host, tmp; + + if (!nhostdevs) + return 0; + + /* To prevent situation where scsi_host device is assigned to two doma= ins + * we need to keep a list of currently assigned scsi_host devices. + * This is done in several loops which cannot be joined into one big + * loop. See virHostdevPreparePCIDevices() + */ + if (!(list =3D virSCSIVHostDeviceListNew())) + goto cleanup; + + /* Loop 1: build temporary list */ + for (i =3D 0; i < nhostdevs; i++) { + virDomainHostdevDefPtr hostdev =3D hostdevs[i]; + virDomainHostdevSubsysSCSIVHostPtr hostsrc =3D &hostdev->source.su= bsys.u.scsi_host; + + if (hostdev->mode !=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYP= E_SCSI_HOST) + continue; + + if (hostsrc->protocol !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PRO= TOCOL_TYPE_VHOST) + continue; /* Not supported */ + + if (!(host =3D virSCSIVHostDeviceNew(hostsrc->wwpn))) + goto cleanup; + + if (virSCSIVHostDeviceListAdd(list, host) < 0) { + virSCSIVHostDeviceFree(host); + goto cleanup; + } + } + + /* Loop 2: Mark devices in temporary list as used by @name + * and add them to driver list. However, if something goes + * wrong, perform rollback. + */ + virObjectLock(mgr->activeSCSIVHostHostdevs); + count =3D virSCSIVHostDeviceListCount(list); + + for (i =3D 0; i < count; i++) { + host =3D virSCSIVHostDeviceListGet(list, i); + if ((tmp =3D virSCSIVHostDeviceListFind(mgr->activeSCSIVHostHostde= vs, + host))) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("SCSI_host device %s is already in use by " + "another domain"), + virSCSIVHostDeviceGetName(tmp)); + goto error; + } else { + if (virSCSIVHostDeviceSetUsedBy(host, drv_name, dom_name) < 0) + goto error; + + VIR_DEBUG("Adding %s to activeSCSIVHostHostdevs", + virSCSIVHostDeviceGetName(host)); + + if (virSCSIVHostDeviceListAdd(mgr->activeSCSIVHostHostdevs, ho= st) < 0) + goto error; + } + } + + virObjectUnlock(mgr->activeSCSIVHostHostdevs); + + /* Loop 3: Temporary list was successfully merged with + * driver list, so steal all items to avoid freeing them + * when freeing temporary list. + */ + while (virSCSIVHostDeviceListCount(list) > 0) { + tmp =3D virSCSIVHostDeviceListGet(list, 0); + virSCSIVHostDeviceListSteal(list, tmp); + } + + virObjectUnref(list); + return 0; + error: + for (j =3D 0; j < i; j++) { + tmp =3D virSCSIVHostDeviceListGet(list, i); + virSCSIVHostDeviceListSteal(mgr->activeSCSIVHostHostdevs, tmp); + } + virObjectUnlock(mgr->activeSCSIVHostHostdevs); + cleanup: + virObjectUnref(list); + return -1; +} + void virHostdevReAttachUSBDevices(virHostdevManagerPtr mgr, const char *drv_name, @@ -1604,6 +1704,69 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr m= gr, virObjectUnlock(mgr->activeSCSIHostdevs); } =20 +void +virHostdevReAttachSCSIVHostDevices(virHostdevManagerPtr mgr, + const char *drv_name, + const char *dom_name, + virDomainHostdevDefPtr *hostdevs, + int nhostdevs) +{ + size_t i; + virSCSIVHostDevicePtr host, tmp; + + + if (!nhostdevs) + return; + + virObjectLock(mgr->activeSCSIVHostHostdevs); + for (i =3D 0; i < nhostdevs; i++) { + virDomainHostdevDefPtr hostdev =3D hostdevs[i]; + virDomainHostdevSubsysSCSIVHostPtr hostsrc =3D &hostdev->source.su= bsys.u.scsi_host; + const char *usedby_drvname; + const char *usedby_domname; + + if (hostdev->mode !=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYP= E_SCSI_HOST) + continue; + + if (hostsrc->protocol !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PRO= TOCOL_TYPE_VHOST) + continue; /* Not supported */ + + if (!(host =3D virSCSIVHostDeviceNew(hostsrc->wwpn))) { + VIR_WARN("Unable to reattach SCSI_host device %s on domain %s", + hostsrc->wwpn, dom_name); + virObjectUnlock(mgr->activeSCSIVHostHostdevs); + return; + } + + /* Only delete the devices which are marked as being used by @name, + * because qemuProcessStart could fail half way through. */ + + if (!(tmp =3D virSCSIVHostDeviceListFind(mgr->activeSCSIVHostHostd= evs, + host))) { + VIR_WARN("Unable to find device %s " + "in list of active SCSI_host devices", + hostsrc->wwpn); + virSCSIVHostDeviceFree(host); + virObjectUnlock(mgr->activeSCSIVHostHostdevs); + return; + } + + virSCSIVHostDeviceGetUsedBy(tmp, &usedby_drvname, &usedby_domname); + + if (STREQ_NULLABLE(drv_name, usedby_drvname) && + STREQ_NULLABLE(dom_name, usedby_domname)) { + VIR_DEBUG("Removing %s dom=3D%s from activeSCSIVHostHostdevs", + hostsrc->wwpn, dom_name); + + virSCSIVHostDeviceListDel(mgr->activeSCSIVHostHostdevs, tmp); + } + + virSCSIVHostDeviceFree(host); + } + virObjectUnlock(mgr->activeSCSIVHostHostdevs); +} + int virHostdevPCINodeDeviceDetach(virHostdevManagerPtr mgr, virPCIDevicePtr pci) diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h index f2f51bd..1330cbc 100644 --- a/src/util/virhostdev.h +++ b/src/util/virhostdev.h @@ -30,6 +30,7 @@ # include "virpci.h" # include "virusb.h" # include "virscsi.h" +# include "virscsivhost.h" # include "domain_conf.h" =20 typedef enum { @@ -53,6 +54,7 @@ struct _virHostdevManager { virPCIDeviceListPtr inactivePCIHostdevs; virUSBDeviceListPtr activeUSBHostdevs; virSCSIDeviceListPtr activeSCSIHostdevs; + virSCSIVHostDeviceListPtr activeSCSIVHostHostdevs; }; =20 virHostdevManagerPtr virHostdevManagerGetDefault(void); @@ -87,6 +89,13 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostde= v_mgr, virDomainHostdevDefPtr *hostdevs, int nhostdevs) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +int +virHostdevPrepareSCSIVHostDevices(virHostdevManagerPtr hostdev_mgr, + const char *drv_name, + const char *dom_name, + virDomainHostdevDefPtr *hostdevs, + int nhostdevs) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void virHostdevReAttachPCIDevices(virHostdevManagerPtr hostdev_mgr, const char *drv_name, @@ -109,6 +118,13 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr hos= tdev_mgr, virDomainHostdevDefPtr *hostdevs, int nhostdevs) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +void +virHostdevReAttachSCSIVHostDevices(virHostdevManagerPtr hostdev_mgr, + const char *drv_name, + const char *dom_name, + virDomainHostdevDefPtr *hostdevs, + int nhostdevs) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); int virHostdevUpdateActivePCIDevices(virHostdevManagerPtr mgr, virDomainHostdevDefPtr *hostdevs, diff --git a/src/util/virscsivhost.c b/src/util/virscsivhost.c new file mode 100644 index 0000000..9d18b6e --- /dev/null +++ b/src/util/virscsivhost.c @@ -0,0 +1,288 @@ +/* + * virscsivhost.c: helper APIs for managing scsi_host devices + * + * Copyright (C) 2016 IBM Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Authors: + * Eric Farman + */ + +#include +#include + +#include "virscsivhost.h" +#include "virlog.h" +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virstring.h" + +VIR_LOG_INIT("util.scsihost"); + +#define SYSFS_VHOST_SCSI_DEVICES "/sys/kernel/config/target/vhost/" +#define VHOST_SCSI_DEVICE "/dev/vhost-scsi" + +struct _virSCSIVHostDevice { + char *name; /* naa. */ + char *path; + char *used_by_drvname; + char *used_by_domname; +}; + +struct _virSCSIVHostDeviceList { + virObjectLockable parent; + size_t count; + virSCSIVHostDevicePtr *devs; +}; + +static virClassPtr virSCSIVHostDeviceListClass; + +static void +virSCSIVHostDeviceListDispose(void *obj) +{ + virSCSIVHostDeviceListPtr list =3D obj; + size_t i; + + for (i =3D 0; i < list->count; i++) + virSCSIVHostDeviceFree(list->devs[i]); + + VIR_FREE(list->devs); +} + + +static int +virSCSIVHostOnceInit(void) +{ + if (!(virSCSIVHostDeviceListClass =3D virClassNew(virClassForObjectLoc= kable(), + "virSCSIVHostDeviceLis= t", + sizeof(virSCSIVHostDev= iceList), + virSCSIVHostDeviceList= Dispose))) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virSCSIVHost) + +/* For virReportOOMError() and virReportSystemError() */ +#define VIR_FROM_THIS VIR_FROM_NONE + + +int +virSCSIVHostOpenVhostSCSI(int *vhostfd) +{ + if (!virFileExists(VHOST_SCSI_DEVICE)) + goto error; + + *vhostfd =3D open(VHOST_SCSI_DEVICE, O_RDWR); + + if (*vhostfd < 0) { + virReportSystemError(errno, _("Failed to open %s"), VHOST_SCSI_DEV= ICE); + goto error; + } + + return 0; + + error: + VIR_FORCE_CLOSE(*vhostfd); + + return -1; +} + + +void +virSCSIVHostDeviceListDel(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev) +{ + virSCSIVHostDevicePtr tmp =3D virSCSIVHostDeviceListSteal(list, dev); + virSCSIVHostDeviceFree(tmp); +} + + +static int +virSCSIVHostDeviceListFindIndex(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev) +{ + size_t i; + + for (i =3D 0; i < list->count; i++) { + virSCSIVHostDevicePtr other =3D list->devs[i]; + if (STREQ_NULLABLE(other->name, dev->name)) + return i; + } + return -1; +} + + +virSCSIVHostDevicePtr +virSCSIVHostDeviceListGet(virSCSIVHostDeviceListPtr list, int idx) +{ + if (idx >=3D list->count || idx < 0) + return NULL; + + return list->devs[idx]; +} + + +size_t +virSCSIVHostDeviceListCount(virSCSIVHostDeviceListPtr list) +{ + return list->count; +} + + +virSCSIVHostDevicePtr +virSCSIVHostDeviceListSteal(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev) +{ + virSCSIVHostDevicePtr ret =3D NULL; + size_t i; + + for (i =3D 0; i < list->count; i++) { + if (STREQ_NULLABLE(list->devs[i]->name, dev->name)) { + ret =3D list->devs[i]; + VIR_DELETE_ELEMENT(list->devs, i, list->count); + break; + } + } + + return ret; +} + + +virSCSIVHostDevicePtr +virSCSIVHostDeviceListFind(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev) +{ + int idx; + + if ((idx =3D virSCSIVHostDeviceListFindIndex(list, dev)) >=3D 0) + return list->devs[idx]; + else + return NULL; +} + + +int +virSCSIVHostDeviceListAdd(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev) +{ + if (virSCSIVHostDeviceListFind(list, dev)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Device %s is already in use"), dev->name); + return -1; + } + return VIR_APPEND_ELEMENT(list->devs, list->count, dev); +} + + +virSCSIVHostDeviceListPtr +virSCSIVHostDeviceListNew(void) +{ + if (virSCSIVHostInitialize() < 0) + return NULL; + + return virObjectLockableNew(virSCSIVHostDeviceListClass); +} + + +int +virSCSIVHostDeviceSetUsedBy(virSCSIVHostDevicePtr dev, + const char *drvname, + const char *domname) +{ + VIR_FREE(dev->used_by_drvname); + VIR_FREE(dev->used_by_domname); + if (VIR_STRDUP(dev->used_by_drvname, drvname) < 0) + return -1; + if (VIR_STRDUP(dev->used_by_domname, domname) < 0) + return -1; + + return 0; +} + + +void +virSCSIVHostDeviceGetUsedBy(virSCSIVHostDevicePtr dev, + const char **drv_name, + const char **dom_name) +{ + *drv_name =3D dev->used_by_drvname; + *dom_name =3D dev->used_by_domname; + } + + +int +virSCSIVHostDeviceFileIterate(virSCSIVHostDevicePtr dev, + virSCSIVHostDeviceFileActor actor, + void *opaque) +{ + return (actor)(dev, dev->path, opaque); +} + + +const char * +virSCSIVHostDeviceGetName(virSCSIVHostDevicePtr dev) +{ + return dev->name; +} + + +virSCSIVHostDevicePtr +virSCSIVHostDeviceNew(const char *name) +{ + virSCSIVHostDevicePtr dev; + + if (VIR_ALLOC(dev) < 0) + return NULL; + + if (VIR_STRDUP(dev->name, name) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("dev->name buffer overflow: %s"), + name); + goto error; + } + + if (virAsprintf(&dev->path, "%s/%s", + SYSFS_VHOST_SCSI_DEVICES, name) < 0) + goto cleanup; + + VIR_DEBUG("%s: initialized", dev->name); + + cleanup: + return dev; + + error: + virSCSIVHostDeviceFree(dev); + dev =3D NULL; + goto cleanup; +} + + +void +virSCSIVHostDeviceFree(virSCSIVHostDevicePtr dev) +{ + if (!dev) + return; + VIR_DEBUG("%s: freeing", dev->name); + VIR_FREE(dev->name); + VIR_FREE(dev->path); + VIR_FREE(dev->used_by_drvname); + VIR_FREE(dev->used_by_domname); + VIR_FREE(dev); +} diff --git a/src/util/virscsivhost.h b/src/util/virscsivhost.h new file mode 100644 index 0000000..1a52acf --- /dev/null +++ b/src/util/virscsivhost.h @@ -0,0 +1,65 @@ +/* + * virscsivhost.h: helper APIs for managing host scsi_host devices + * + * Copyright (C) 2016 IBM Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Authors: + * Eric Farman + */ + +#ifndef __VIR_SCSIHOST_H__ +# define __VIR_SCSIHOST_H__ + +# include "internal.h" +# include "virobject.h" +# include "virutil.h" + +typedef struct _virSCSIVHostDevice virSCSIVHostDevice; +typedef virSCSIVHostDevice *virSCSIVHostDevicePtr; +typedef struct _virSCSIVHostDeviceList virSCSIVHostDeviceList; +typedef virSCSIVHostDeviceList *virSCSIVHostDeviceListPtr; + +typedef int (*virSCSIVHostDeviceFileActor)(virSCSIVHostDevicePtr dev, + const char *name, void *opaque); + +int virSCSIVHostDeviceFileIterate(virSCSIVHostDevicePtr dev, + virSCSIVHostDeviceFileActor actor, + void *opaque); +const char *virSCSIVHostDeviceGetName(virSCSIVHostDevicePtr dev); +virSCSIVHostDevicePtr virSCSIVHostDeviceListGet(virSCSIVHostDeviceListPtr = list, + int idx); +size_t virSCSIVHostDeviceListCount(virSCSIVHostDeviceListPtr list); +virSCSIVHostDevicePtr virSCSIVHostDeviceListSteal(virSCSIVHostDeviceListPt= r list, + virSCSIVHostDevicePtr de= v); +virSCSIVHostDevicePtr virSCSIVHostDeviceListFind(virSCSIVHostDeviceListPtr= list, + virSCSIVHostDevicePtr dev= ); +int virSCSIVHostDeviceListAdd(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev); +void virSCSIVHostDeviceListDel(virSCSIVHostDeviceListPtr list, + virSCSIVHostDevicePtr dev); +virSCSIVHostDeviceListPtr virSCSIVHostDeviceListNew(void); +virSCSIVHostDevicePtr virSCSIVHostDeviceNew(const char *name); +int virSCSIVHostDeviceSetUsedBy(virSCSIVHostDevicePtr dev, + const char *drvname, + const char *domname); +void virSCSIVHostDeviceGetUsedBy(virSCSIVHostDevicePtr dev, + const char **drv_name, + const char **dom_name); +void virSCSIVHostDeviceFree(virSCSIVHostDevicePtr dev); +int virSCSIVHostOpenVhostSCSI(int *vhostfd); + +#endif /* __VIR_SCSIHOST_H__ */ diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index 78a224b..c501b59 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -31,6 +31,7 @@ #include "virnuma.h" #include "virrandom.h" #include "virscsi.h" +#include "virscsivhost.h" #include "virstring.h" #include "virtpm.h" #include "virutil.h" @@ -107,6 +108,14 @@ virSCSIDeviceGetSgName(const char *sysfs_prefix ATTRIB= UTE_UNUSED, } =20 int +virSCSIVHostOpenVhostSCSI(int *vhostfd) +{ + *vhostfd =3D STDERR_FILENO + 1; + + return 0; +} + +int virNetDevTapCreate(char **ifname, const char *tunpath ATTRIBUTE_UNUSED, int *tapfd, --=20 1.9.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list