mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-31 10:05:31 +00:00
Added iSCSI storage pool backend
This commit is contained in:
parent
049ff4e572
commit
8ec1fcd925
@ -1,3 +1,12 @@
|
||||
Wed Feb 20 10:44:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* configure.in: Added check for iscsiadm tool
|
||||
* libvirt.spec.in: Added dep on iscsi-initiator-utils
|
||||
* po/POTFILES.in: Added storage_backend_iscsi.c
|
||||
* src/Makefile.am, src/storage_backend.c,
|
||||
src/storage_backend_iscsi.c, src/storage_backend_iscsi.h:
|
||||
Added iSCSI storage pool backend
|
||||
|
||||
Wed Feb 20 10:42:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* qemud/qemud.c: Set close-on-exec flag for signal pipe
|
||||
|
22
configure.in
22
configure.in
@ -561,6 +561,8 @@ AC_ARG_WITH(storage-fs,
|
||||
[ --with-storage-fs with FileSystem backend for the storage driver (on)],[],[with_storage_fs=check])
|
||||
AC_ARG_WITH(storage-lvm,
|
||||
[ --with-storage-lvm with LVM backend for the storage driver (on)],[],[with_storage_lvm=check])
|
||||
AC_ARG_WITH(storage-iscsi,
|
||||
[ --with-storage-iscsi with iSCSI backend for the storage driver (on)],[],[with_storage_iscsi=check])
|
||||
|
||||
if test "$with_storage_fs" = "yes" -o "$with_storage_fs" = "check"; then
|
||||
AC_PATH_PROG(MOUNT, [mount], [], [$PATH:/sbin:/usr/sbin])
|
||||
@ -655,6 +657,25 @@ fi
|
||||
AM_CONDITIONAL(WITH_STORAGE_LVM, [test "$with_storage_lvm" = "yes"])
|
||||
|
||||
|
||||
|
||||
if test "$with_storage_iscsi" = "yes" -o "$with_storage_iscsi" = "check"; then
|
||||
AC_PATH_PROG(ISCSIADM, [iscsiadm], [], [$PATH:/sbin:/usr/sbin])
|
||||
if test "$with_storage_iscsi" = "yes" ; then
|
||||
if test -z "$ISCSIADM" ; then AC_MSG_ERROR(We need iscsiadm for iSCSI storage driver) ; fi
|
||||
else
|
||||
if test -z "$ISCSIADM" ; then with_storage_iscsi=no ; fi
|
||||
|
||||
if test "$with_storage_iscsi" = "check" ; then with_storage_iscsi=yes ; fi
|
||||
fi
|
||||
|
||||
if test "$with_storage_iscsi" = "yes" ; then
|
||||
AC_DEFINE_UNQUOTED(WITH_STORAGE_ISCSI, 1, [whether iSCSI backend for storage driver is enabled])
|
||||
AC_DEFINE_UNQUOTED([ISCSIADM],["$ISCSIADM"],[Location of iscsiadm program])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_STORAGE_ISCSI, [test "$with_storage_iscsi" = "yes"])
|
||||
|
||||
|
||||
dnl
|
||||
dnl check for python
|
||||
dnl
|
||||
@ -869,6 +890,7 @@ AC_MSG_NOTICE([ Dir: yes])
|
||||
AC_MSG_NOTICE([ FS: $with_storage_fs])
|
||||
AC_MSG_NOTICE([ NetFS: $with_storage_fs])
|
||||
AC_MSG_NOTICE([ LVM: $with_storage_lvm])
|
||||
AC_MSG_NOTICE([ iSCSI: $with_storage_iscsi])
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([Libraries])
|
||||
AC_MSG_NOTICE([])
|
||||
|
@ -51,6 +51,8 @@ Requires: /usr/sbin/qcow-create
|
||||
%endif
|
||||
# For LVM drivers
|
||||
Requires: lvm2
|
||||
# For ISCSI driver
|
||||
Requires: iscsi-initiator-utils
|
||||
BuildRequires: xen-devel
|
||||
BuildRequires: libxml2-devel
|
||||
BuildRequires: readline-devel
|
||||
@ -77,6 +79,8 @@ BuildRequires: /usr/sbin/qcow-create
|
||||
%endif
|
||||
# For LVM drivers
|
||||
BuildRequires: lvm2
|
||||
# For ISCSI driver
|
||||
BuildRequires: iscsi-initiator-utils
|
||||
Obsoletes: libvir
|
||||
ExclusiveArch: i386 x86_64 ia64
|
||||
|
||||
|
@ -13,6 +13,7 @@ src/remote_internal.c
|
||||
src/storage_backend.c
|
||||
src/storage_backend_fs.c
|
||||
src/storage_backend_logical.c
|
||||
src/storage_backend_iscsi.c
|
||||
src/storage_conf.c
|
||||
src/storage_driver.c
|
||||
src/sexpr.c
|
||||
|
@ -74,6 +74,12 @@ else
|
||||
EXTRA_DIST += storage_backend_logical.h storage_backend_logical.c
|
||||
endif
|
||||
|
||||
if WITH_STORAGE_ISCSI
|
||||
CLIENT_SOURCES += storage_backend_iscsi.h storage_backend_iscsi.c
|
||||
else
|
||||
EXTRA_DIST += storage_backend_iscsi.h storage_backend_iscsi.c
|
||||
endif
|
||||
|
||||
|
||||
|
||||
libvirt_la_SOURCES = $(CLIENT_SOURCES) $(SERVER_SOURCES)
|
||||
|
@ -39,6 +39,10 @@
|
||||
#if WITH_STORAGE_LVM
|
||||
#include "storage_backend_logical.h"
|
||||
#endif
|
||||
#if WITH_STORAGE_ISCSI
|
||||
#include "storage_backend_iscsi.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "util.h"
|
||||
|
||||
@ -54,6 +58,9 @@ static virStorageBackendPtr backends[] = {
|
||||
#if WITH_STORAGE_LVM
|
||||
&virStorageBackendLogical,
|
||||
#endif
|
||||
#if WITH_STORAGE_ISCSI
|
||||
&virStorageBackendISCSI,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -100,6 +107,10 @@ virStorageBackendFromString(const char *type) {
|
||||
if (STREQ(type, "logical"))
|
||||
return VIR_STORAGE_POOL_LOGICAL;
|
||||
#endif
|
||||
#if WITH_STORAGE_ISCSI
|
||||
if (STREQ(type, "iscsi"))
|
||||
return VIR_STORAGE_POOL_ISCSI;
|
||||
#endif
|
||||
|
||||
virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("unknown storage backend type %s"), type);
|
||||
@ -120,6 +131,10 @@ virStorageBackendToString(int type) {
|
||||
#if WITH_STORAGE_LVM
|
||||
case VIR_STORAGE_POOL_LOGICAL:
|
||||
return "logical";
|
||||
#endif
|
||||
#if WITH_STORAGE_ISCSI
|
||||
case VIR_STORAGE_POOL_ISCSI:
|
||||
return "iscsi";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
455
src/storage_backend_iscsi.c
Normal file
455
src/storage_backend_iscsi.c
Normal file
@ -0,0 +1,455 @@
|
||||
/*
|
||||
* storage_backend_iscsi.c: storage backend for iSCSI handling
|
||||
*
|
||||
* Copyright (C) 2007-2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007-2008 Daniel P. Berrange
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <regex.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "storage_backend_iscsi.h"
|
||||
#include "util.h"
|
||||
|
||||
static int
|
||||
virStorageBackendISCSITargetIP(virConnectPtr conn,
|
||||
const char *hostname,
|
||||
char *ipaddr,
|
||||
size_t ipaddrlen)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result = NULL;
|
||||
int ret;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
|
||||
ret = getaddrinfo(hostname, NULL, &hints, &result);
|
||||
if (ret != 0) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("host lookup failed %s"),
|
||||
gai_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("no IP address for target %s"),
|
||||
hostname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getnameinfo(result->ai_addr, result->ai_addrlen,
|
||||
ipaddr, ipaddrlen, NULL, 0,
|
||||
NI_NUMERICHOST) < 0) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot format ip addr for %s"),
|
||||
hostname);
|
||||
freeaddrinfo(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIExtractSession(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
char **const groups,
|
||||
void *data)
|
||||
{
|
||||
char **session = data;
|
||||
|
||||
if (STREQ(groups[1], pool->def->source.devices[0].path)) {
|
||||
if ((*session = strdup(groups[0])) == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("session"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
virStorageBackendISCSISession(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool)
|
||||
{
|
||||
/*
|
||||
* # iscsiadm --mode session -P 0
|
||||
* tcp: [1] 192.168.122.170:3260,1 demo-tgt-b
|
||||
* tcp: [2] 192.168.122.170:3260,1 demo-tgt-a
|
||||
*
|
||||
* Pull out 2nd and 4th fields
|
||||
*/
|
||||
const char *regexes[] = {
|
||||
"^tcp:\\s+\\[(\\S+)\\]\\s+\\S+\\s+(\\S+)\\s*$"
|
||||
};
|
||||
int vars[] = {
|
||||
2,
|
||||
};
|
||||
const char *prog[] = {
|
||||
ISCSIADM, "--mode", "session", "-P", "0", NULL
|
||||
};
|
||||
char *session = NULL;
|
||||
|
||||
if (virStorageBackendRunProgRegex(conn, pool,
|
||||
prog,
|
||||
1,
|
||||
regexes,
|
||||
vars,
|
||||
virStorageBackendISCSIExtractSession,
|
||||
&session) < 0)
|
||||
return NULL;
|
||||
|
||||
if (session == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot find session"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIConnection(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
const char *portal,
|
||||
const char *action)
|
||||
{
|
||||
const char *cmdargv[] = {
|
||||
ISCSIADM, "--mode", "node", "--portal", portal,
|
||||
"--targetname", pool->def->source.devices[0].path, action, NULL
|
||||
};
|
||||
|
||||
if (virRun(conn, (char **)cmdargv, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIMakeLUN(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
char **const groups,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virStorageVolDefPtr vol;
|
||||
int fd = -1;
|
||||
char lunid[100];
|
||||
char *dev = groups[4];
|
||||
int opentries = 0;
|
||||
char *devpath = NULL;
|
||||
|
||||
snprintf(lunid, sizeof(lunid)-1, "lun-%s", groups[3]);
|
||||
|
||||
if ((vol = calloc(1, sizeof(virStorageVolDef))) == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("volume"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((vol->name = strdup(lunid)) == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("name"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((devpath = malloc(5 + strlen(dev) + 1)) == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("devpath"));
|
||||
goto cleanup;
|
||||
}
|
||||
strcpy(devpath, "/dev/");
|
||||
strcat(devpath, dev);
|
||||
/* It can take a little while between logging into the ISCSI
|
||||
* server and udev creating the /dev nodes, so if we get ENOENT
|
||||
* we must retry a few times - they should eventually appear.
|
||||
* We currently wait for upto 5 seconds. Is this good enough ?
|
||||
* Perhaps not on a very heavily loaded system Any other
|
||||
* options... ?
|
||||
*/
|
||||
reopen:
|
||||
if ((fd = open(devpath, O_RDONLY)) < 0) {
|
||||
opentries++;
|
||||
if (errno == ENOENT && opentries < 50) {
|
||||
usleep(100 * 1000);
|
||||
goto reopen;
|
||||
}
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot open %s: %s"),
|
||||
devpath, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Now figure out the stable path
|
||||
*
|
||||
* XXX this method is O(N) because it scans the pool target
|
||||
* dir every time its run. Should figure out a more efficient
|
||||
* way of doing this...
|
||||
*/
|
||||
if ((vol->target.path = virStorageBackendStablePath(conn,
|
||||
pool,
|
||||
devpath)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (devpath != vol->target.path)
|
||||
free(devpath);
|
||||
devpath = NULL;
|
||||
|
||||
if (virStorageBackendUpdateVolInfoFD(conn, vol, fd, 1) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* XXX use unique iSCSI id instead */
|
||||
vol->key = strdup(vol->target.path);
|
||||
if (vol->key == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("key"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
pool->def->capacity += vol->capacity;
|
||||
pool->def->allocation += vol->allocation;
|
||||
|
||||
vol->next = pool->volumes;
|
||||
pool->volumes = vol;
|
||||
pool->nvolumes++;
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
if (fd != -1) close(fd);
|
||||
free(devpath);
|
||||
virStorageVolDefFree(vol);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIFindLUNs(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
const char *session)
|
||||
{
|
||||
/*
|
||||
* # iscsiadm --mode session -r $session -P 3
|
||||
*
|
||||
* scsi1 Channel 00 Id 0 Lun: 0
|
||||
* scsi1 Channel 00 Id 0 Lun: 1
|
||||
* Attached scsi disk sdc State: running
|
||||
* scsi1 Channel 00 Id 0 Lun: 2
|
||||
* Attached scsi disk sdd State: running
|
||||
* scsi1 Channel 00 Id 0 Lun: 3
|
||||
* Attached scsi disk sde State: running
|
||||
* scsi1 Channel 00 Id 0 Lun: 4
|
||||
* Attached scsi disk sdf State: running
|
||||
* scsi1 Channel 00 Id 0 Lun: 5
|
||||
* Attached scsi disk sdg State: running
|
||||
*
|
||||
* Need 2 regex to match alternating lines
|
||||
*/
|
||||
const char *regexes[] = {
|
||||
"^\\s*scsi(\\S+)\\s+Channel\\s+(\\S+)\\s+Id\\s+(\\S+)\\s+Lun:\\s+(\\S+)\\s*$",
|
||||
"^\\s*Attached\\s+scsi\\s+disk\\s+(\\S+)\\s+State:\\s+running\\s*$"
|
||||
};
|
||||
int vars[] = {
|
||||
4, 1
|
||||
};
|
||||
const char *prog[] = {
|
||||
ISCSIADM, "--mode", "session", "-r", session, "-P", "3", NULL,
|
||||
};
|
||||
|
||||
return virStorageBackendRunProgRegex(conn, pool,
|
||||
prog,
|
||||
2,
|
||||
regexes,
|
||||
vars,
|
||||
virStorageBackendISCSIMakeLUN,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIRescanLUNs(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
|
||||
const char *session)
|
||||
{
|
||||
const char *cmdargv[] = {
|
||||
ISCSIADM, "--mode", "session", "-r", session, "-R", NULL,
|
||||
};
|
||||
|
||||
if (virRun(conn, (char **)cmdargv, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virStorageBackendISCSILogin(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
const char *portal)
|
||||
{
|
||||
return virStorageBackendISCSIConnection(conn, pool, portal, "--login");
|
||||
}
|
||||
|
||||
static int
|
||||
virStorageBackendISCSILogout(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool,
|
||||
const char *portal)
|
||||
{
|
||||
return virStorageBackendISCSIConnection(conn, pool, portal, "--logout");
|
||||
}
|
||||
|
||||
static char *
|
||||
virStorageBackendISCSIPortal(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool)
|
||||
{
|
||||
char ipaddr[NI_MAXHOST];
|
||||
char *portal;
|
||||
|
||||
if (virStorageBackendISCSITargetIP(conn,
|
||||
pool->def->source.host.name,
|
||||
ipaddr, sizeof(ipaddr)) < 0)
|
||||
return NULL;
|
||||
|
||||
portal = malloc(strlen(ipaddr) + 1 + 4 + 2 + 1);
|
||||
if (portal == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_NO_MEMORY, _("portal"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy(portal, ipaddr);
|
||||
strcat(portal, ":3260,1");
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIStartPool(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool)
|
||||
{
|
||||
char *portal = NULL;
|
||||
|
||||
if (pool->def->source.host.name == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing source host"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pool->def->source.ndevice != 1 ||
|
||||
pool->def->source.devices[0].path == NULL) {
|
||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing source device"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((portal = virStorageBackendISCSIPortal(conn, pool)) == NULL)
|
||||
return -1;
|
||||
if (virStorageBackendISCSILogin(conn, pool, portal) < 0) {
|
||||
free(portal);
|
||||
return -1;
|
||||
}
|
||||
free(portal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIRefreshPool(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool)
|
||||
{
|
||||
char *session = NULL;
|
||||
|
||||
pool->def->allocation = pool->def->capacity = pool->def->available = 0;
|
||||
|
||||
if ((session = virStorageBackendISCSISession(conn, pool)) == NULL)
|
||||
goto cleanup;
|
||||
if (virStorageBackendISCSIRescanLUNs(conn, pool, session) < 0)
|
||||
goto cleanup;
|
||||
if (virStorageBackendISCSIFindLUNs(conn, pool, session) < 0)
|
||||
goto cleanup;
|
||||
free(session);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
free(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virStorageBackendISCSIStopPool(virConnectPtr conn,
|
||||
virStoragePoolObjPtr pool)
|
||||
{
|
||||
char *portal;
|
||||
|
||||
if ((portal = virStorageBackendISCSIPortal(conn, pool)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (virStorageBackendISCSILogout(conn, pool, portal) < 0) {
|
||||
free(portal);
|
||||
return -1;
|
||||
}
|
||||
free(portal);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virStorageBackend virStorageBackendISCSI = {
|
||||
.type = VIR_STORAGE_POOL_ISCSI,
|
||||
|
||||
.startPool = virStorageBackendISCSIStartPool,
|
||||
.refreshPool = virStorageBackendISCSIRefreshPool,
|
||||
.stopPool = virStorageBackendISCSIStopPool,
|
||||
|
||||
.poolOptions = {
|
||||
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_HOST |
|
||||
VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE)
|
||||
},
|
||||
|
||||
.volType = VIR_STORAGE_VOL_BLOCK,
|
||||
};
|
||||
|
||||
/*
|
||||
* vim: set tabstop=4:
|
||||
* vim: set shiftwidth=4:
|
||||
* vim: set expandtab:
|
||||
*/
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
45
src/storage_backend_iscsi.h
Normal file
45
src/storage_backend_iscsi.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* storage_backend_iscsi.h: storage backend for iSCSI handling
|
||||
*
|
||||
* Copyright (C) 2007-2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007-2008 Daniel P. Berrange
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_STORAGE_BACKEND_ISCSI_H__
|
||||
#define __VIR_STORAGE_BACKEND_ISCSI_H__
|
||||
|
||||
#include "storage_backend.h"
|
||||
|
||||
extern virStorageBackend virStorageBackendISCSI;
|
||||
|
||||
#endif /* __VIR_STORAGE_BACKEND_ISCSI_H__ */
|
||||
|
||||
/*
|
||||
* vim: set tabstop=4:
|
||||
* vim: set shiftwidth=4:
|
||||
* vim: set expandtab:
|
||||
*/
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user