mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 01:15:19 +00:00
util: Management routines for scsi_host devices
For a new hostdev type='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='scsi' protcol='none'. Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
This commit is contained in:
parent
fc0e627bac
commit
629544be0f
@ -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
|
||||
|
@ -163,6 +163,7 @@ UTIL_SOURCES = \
|
||||
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 \
|
||||
|
@ -1685,10 +1685,12 @@ virHostdevPCINodeDeviceReset;
|
||||
virHostdevPrepareDomainDevices;
|
||||
virHostdevPreparePCIDevices;
|
||||
virHostdevPrepareSCSIDevices;
|
||||
virHostdevPrepareSCSIVHostDevices;
|
||||
virHostdevPrepareUSBDevices;
|
||||
virHostdevReAttachDomainDevices;
|
||||
virHostdevReAttachPCIDevices;
|
||||
virHostdevReAttachSCSIDevices;
|
||||
virHostdevReAttachSCSIVHostDevices;
|
||||
virHostdevReAttachUSBDevices;
|
||||
virHostdevUpdateActiveDomainDevices;
|
||||
virHostdevUpdateActivePCIDevices;
|
||||
@ -2306,6 +2308,22 @@ virSCSIDeviceNew;
|
||||
virSCSIDeviceSetUsedBy;
|
||||
|
||||
|
||||
# util/virscsivhost.h
|
||||
virSCSIVHostDeviceFileIterate;
|
||||
virSCSIVHostDeviceFree;
|
||||
virSCSIVHostDeviceGetName;
|
||||
virSCSIVHostDeviceListAdd;
|
||||
virSCSIVHostDeviceListCount;
|
||||
virSCSIVHostDeviceListDel;
|
||||
virSCSIVHostDeviceListFind;
|
||||
virSCSIVHostDeviceListGet;
|
||||
virSCSIVHostDeviceListNew;
|
||||
virSCSIVHostDeviceListSteal;
|
||||
virSCSIVHostDeviceNew;
|
||||
virSCSIVHostDeviceSetUsedBy;
|
||||
virSCSIVHostOpenVhostSCSI;
|
||||
|
||||
|
||||
# util/virseclabel.h
|
||||
virSecurityDeviceLabelDefFree;
|
||||
virSecurityDeviceLabelDefNew;
|
||||
|
@ -146,6 +146,7 @@ virHostdevManagerDispose(void *obj)
|
||||
virObjectUnref(hostdevMgr->inactivePCIHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeUSBHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeSCSIHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeSCSIVHostHostdevs);
|
||||
VIR_FREE(hostdevMgr->stateDir);
|
||||
}
|
||||
|
||||
@ -170,6 +171,9 @@ virHostdevManagerNew(void)
|
||||
if (!(hostdevMgr->activeSCSIHostdevs = virSCSIDeviceListNew()))
|
||||
goto error;
|
||||
|
||||
if (!(hostdevMgr->activeSCSIVHostHostdevs = virSCSIVHostDeviceListNew()))
|
||||
goto error;
|
||||
|
||||
if (privileged) {
|
||||
if (VIR_STRDUP(hostdevMgr->stateDir, HOSTDEV_STATE_DIR) < 0)
|
||||
goto error;
|
||||
@ -1484,6 +1488,102 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr mgr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 domains
|
||||
* 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 = virSCSIVHostDeviceListNew()))
|
||||
goto cleanup;
|
||||
|
||||
/* Loop 1: build temporary list */
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &hostdev->source.subsys.u.scsi_host;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST)
|
||||
continue;
|
||||
|
||||
if (hostsrc->protocol != VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST)
|
||||
continue; /* Not supported */
|
||||
|
||||
if (!(host = 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 = virSCSIVHostDeviceListCount(list);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
host = virSCSIVHostDeviceListGet(list, i);
|
||||
if ((tmp = virSCSIVHostDeviceListFind(mgr->activeSCSIVHostHostdevs,
|
||||
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, host) < 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 = virSCSIVHostDeviceListGet(list, 0);
|
||||
virSCSIVHostDeviceListSteal(list, tmp);
|
||||
}
|
||||
|
||||
virObjectUnref(list);
|
||||
return 0;
|
||||
error:
|
||||
for (j = 0; j < i; j++) {
|
||||
tmp = virSCSIVHostDeviceListGet(list, i);
|
||||
virSCSIVHostDeviceListSteal(mgr->activeSCSIVHostHostdevs, tmp);
|
||||
}
|
||||
virObjectUnlock(mgr->activeSCSIVHostHostdevs);
|
||||
cleanup:
|
||||
virObjectUnref(list);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
virHostdevReAttachUSBDevices(virHostdevManagerPtr mgr,
|
||||
const char *drv_name,
|
||||
@ -1615,6 +1715,69 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr mgr,
|
||||
virObjectUnlock(mgr->activeSCSIHostdevs);
|
||||
}
|
||||
|
||||
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 = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &hostdev->source.subsys.u.scsi_host;
|
||||
const char *usedby_drvname;
|
||||
const char *usedby_domname;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST)
|
||||
continue;
|
||||
|
||||
if (hostsrc->protocol != VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST)
|
||||
continue; /* Not supported */
|
||||
|
||||
if (!(host = 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 = virSCSIVHostDeviceListFind(mgr->activeSCSIVHostHostdevs,
|
||||
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=%s from activeSCSIVHostHostdevs",
|
||||
hostsrc->wwpn, dom_name);
|
||||
|
||||
virSCSIVHostDeviceListDel(mgr->activeSCSIVHostHostdevs, tmp);
|
||||
}
|
||||
|
||||
virSCSIVHostDeviceFree(host);
|
||||
}
|
||||
virObjectUnlock(mgr->activeSCSIVHostHostdevs);
|
||||
}
|
||||
|
||||
int
|
||||
virHostdevPCINodeDeviceDetach(virHostdevManagerPtr mgr,
|
||||
virPCIDevicePtr pci)
|
||||
|
@ -30,6 +30,7 @@
|
||||
# include "virpci.h"
|
||||
# include "virusb.h"
|
||||
# include "virscsi.h"
|
||||
# include "virscsivhost.h"
|
||||
# include "domain_conf.h"
|
||||
|
||||
typedef enum {
|
||||
@ -53,6 +54,7 @@ struct _virHostdevManager {
|
||||
virPCIDeviceListPtr inactivePCIHostdevs;
|
||||
virUSBDeviceListPtr activeUSBHostdevs;
|
||||
virSCSIDeviceListPtr activeSCSIHostdevs;
|
||||
virSCSIVHostDeviceListPtr activeSCSIVHostHostdevs;
|
||||
};
|
||||
|
||||
virHostdevManagerPtr virHostdevManagerGetDefault(void);
|
||||
@ -87,6 +89,13 @@ virHostdevPrepareSCSIDevices(virHostdevManagerPtr hostdev_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 hostdev_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,
|
||||
|
288
src/util/virscsivhost.c
Normal file
288
src/util/virscsivhost.c
Normal file
@ -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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Farman <farman@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "virscsivhost.h"
|
||||
#include "virlog.h"
|
||||
#include "viralloc.h"
|
||||
#include "virerror.h"
|
||||
#include "virfile.h"
|
||||
#include "virstring.h"
|
||||
|
||||
/* For virReportOOMError() and virReportSystemError() */
|
||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||
|
||||
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.<wwn> */
|
||||
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 = obj;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < list->count; i++)
|
||||
virSCSIVHostDeviceFree(list->devs[i]);
|
||||
|
||||
VIR_FREE(list->devs);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virSCSIVHostOnceInit(void)
|
||||
{
|
||||
if (!(virSCSIVHostDeviceListClass = virClassNew(virClassForObjectLockable(),
|
||||
"virSCSIVHostDeviceList",
|
||||
sizeof(virSCSIVHostDeviceList),
|
||||
virSCSIVHostDeviceListDispose)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VIR_ONCE_GLOBAL_INIT(virSCSIVHost)
|
||||
|
||||
|
||||
int
|
||||
virSCSIVHostOpenVhostSCSI(int *vhostfd)
|
||||
{
|
||||
if (!virFileExists(VHOST_SCSI_DEVICE))
|
||||
goto error;
|
||||
|
||||
*vhostfd = open(VHOST_SCSI_DEVICE, O_RDWR);
|
||||
|
||||
if (*vhostfd < 0) {
|
||||
virReportSystemError(errno, _("Failed to open %s"), VHOST_SCSI_DEVICE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
VIR_FORCE_CLOSE(*vhostfd);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virSCSIVHostDeviceListDel(virSCSIVHostDeviceListPtr list,
|
||||
virSCSIVHostDevicePtr dev)
|
||||
{
|
||||
virSCSIVHostDevicePtr tmp = virSCSIVHostDeviceListSteal(list, dev);
|
||||
virSCSIVHostDeviceFree(tmp);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virSCSIVHostDeviceListFindIndex(virSCSIVHostDeviceListPtr list,
|
||||
virSCSIVHostDevicePtr dev)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < list->count; i++) {
|
||||
virSCSIVHostDevicePtr other = list->devs[i];
|
||||
if (STREQ_NULLABLE(other->name, dev->name))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
virSCSIVHostDevicePtr
|
||||
virSCSIVHostDeviceListGet(virSCSIVHostDeviceListPtr list, int idx)
|
||||
{
|
||||
if (idx >= 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 = NULL;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < list->count; i++) {
|
||||
if (STREQ_NULLABLE(list->devs[i]->name, dev->name)) {
|
||||
ret = list->devs[i];
|
||||
VIR_DELETE_ELEMENT(list->devs, i, list->count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
virSCSIVHostDevicePtr
|
||||
virSCSIVHostDeviceListFind(virSCSIVHostDeviceListPtr list,
|
||||
virSCSIVHostDevicePtr dev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if ((idx = virSCSIVHostDeviceListFindIndex(list, dev)) >= 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 = dev->used_by_drvname;
|
||||
*dom_name = 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 error;
|
||||
|
||||
VIR_DEBUG("%s: initialized", dev->name);
|
||||
|
||||
cleanup:
|
||||
return dev;
|
||||
|
||||
error:
|
||||
virSCSIVHostDeviceFree(dev);
|
||||
dev = 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);
|
||||
}
|
65
src/util/virscsivhost.h
Normal file
65
src/util/virscsivhost.h
Normal file
@ -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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Farman <farman@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#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(virSCSIVHostDeviceListPtr list,
|
||||
virSCSIVHostDevicePtr dev);
|
||||
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__ */
|
@ -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"
|
||||
@ -106,6 +107,14 @@ virSCSIDeviceGetSgName(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virSCSIVHostOpenVhostSCSI(int *vhostfd)
|
||||
{
|
||||
*vhostfd = STDERR_FILENO + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
virNetDevTapCreate(char **ifname,
|
||||
const char *tunpath ATTRIBUTE_UNUSED,
|
||||
|
Loading…
x
Reference in New Issue
Block a user