Refactor storage backends to avoid dependancy from config parser to implementation

This commit is contained in:
Daniel P. Berrange 2008-11-17 11:19:33 +00:00
parent 25047e7cf8
commit c08a47b853
11 changed files with 380 additions and 383 deletions

View File

@ -1,3 +1,17 @@
Mon Nov 17 11:19:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
Refactor storage backend to remove dependancy from
storage config parser.
* src/Makefile.am: Build storage_backend as part of storage
driver instead of general config
* src/storage_backend.c, src/storage_backend.h,
src/storage_backend_disk.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_conf.h, src/storage_driver.c:
Move per-pool type parser options & format enums into the
main storage_conf.c file, so parser is independant of the
backend impl code.
Mon Nov 17 10:50:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
Switch to fully versioned linker script for exported ABI

View File

@ -69,8 +69,7 @@ NETWORK_CONF_SOURCES = \
# Storage driver generic impl APIs
STORAGE_CONF_SOURCES = \
storage_conf.h storage_conf.c \
storage_backend.h storage_backend.c
storage_conf.h storage_conf.c
# The remote RPC driver, covering domains, storage, networks, etc
@ -123,7 +122,8 @@ NETWORK_DRIVER_SOURCES = \
# And finally storage backend specific impls
STORAGE_DRIVER_SOURCES = \
storage_driver.h storage_driver.c
storage_driver.h storage_driver.c \
storage_backend.h storage_backend.c
STORAGE_DRIVER_FS_SOURCES = \
storage_backend_fs.h storage_backend_fs.c

View File

@ -24,6 +24,7 @@
#include <config.h>
#include <string.h>
#include <stdio.h>
#if HAVE_REGEX_H
#include <regex.h>
#endif
@ -60,10 +61,6 @@
#include "storage_backend_fs.h"
#endif
VIR_ENUM_IMPL(virStorageBackendPartTable,
VIR_STORAGE_POOL_DISK_LAST,
"unknown", "dos", "dvh", "gpt",
"mac", "bsd", "pc98", "sun", "lvm2");
static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_DIR
@ -98,81 +95,6 @@ virStorageBackendForType(int type) {
return NULL;
}
virStorageBackendPoolOptionsPtr
virStorageBackendPoolOptionsForType(int type) {
virStorageBackendPtr backend = virStorageBackendForType(type);
if (backend == NULL)
return NULL;
return &backend->poolOptions;
}
virStorageBackendVolOptionsPtr
virStorageBackendVolOptionsForType(int type) {
virStorageBackendPtr backend = virStorageBackendForType(type);
if (backend == NULL)
return NULL;
return &backend->volOptions;
}
int
virStorageBackendFromString(const char *type) {
if (STREQ(type, "dir"))
return VIR_STORAGE_POOL_DIR;
#if WITH_STORAGE_FS
if (STREQ(type, "fs"))
return VIR_STORAGE_POOL_FS;
if (STREQ(type, "netfs"))
return VIR_STORAGE_POOL_NETFS;
#endif
#if WITH_STORAGE_LVM
if (STREQ(type, "logical"))
return VIR_STORAGE_POOL_LOGICAL;
#endif
#if WITH_STORAGE_ISCSI
if (STREQ(type, "iscsi"))
return VIR_STORAGE_POOL_ISCSI;
#endif
#if WITH_STORAGE_DISK
if (STREQ(type, "disk"))
return VIR_STORAGE_POOL_DISK;
#endif
virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
_("unknown storage backend type %s"), type);
return -1;
}
const char *
virStorageBackendToString(int type) {
switch (type) {
case VIR_STORAGE_POOL_DIR:
return "dir";
#if WITH_STORAGE_FS
case VIR_STORAGE_POOL_FS:
return "fs";
case VIR_STORAGE_POOL_NETFS:
return "netfs";
#endif
#if WITH_STORAGE_LVM
case VIR_STORAGE_POOL_LOGICAL:
return "logical";
#endif
#if WITH_STORAGE_ISCSI
case VIR_STORAGE_POOL_ISCSI:
return "iscsi";
#endif
#if WITH_STORAGE_DISK
case VIR_STORAGE_POOL_DISK:
return "disk";
#endif
}
virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
_("unknown storage backend type %d"), type);
return NULL;
}
int
virStorageBackendUpdateVolInfo(virConnectPtr conn,
@ -198,6 +120,13 @@ virStorageBackendUpdateVolInfo(virConnectPtr conn,
return ret;
}
struct diskType {
int part_table_type;
unsigned short offset;
unsigned short length;
unsigned long long magic;
};
static struct diskType const disk_types[] = {
{ VIR_STORAGE_POOL_DISK_LVM2, 0x218, 8, 0x31303020324D564CULL },
{ VIR_STORAGE_POOL_DISK_GPT, 0x200, 8, 0x5452415020494645ULL },
@ -369,6 +298,12 @@ virStorageBackendStablePath(virConnectPtr conn,
STREQ(pool->def->target.path, "/dev/"))
goto ret_strdup;
/* Skip whole thing for a pool which isn't in /dev
* so we don't mess will filesystem/dir based pools
*/
if (!STRPREFIX(pool->def->target.path, "/dev"))
goto ret_strdup;
/* The pool is pointing somewhere like /dev/disk/by-path
* or /dev/disk/by-id, so we need to check all symlinks in
* the target directory and figure out which one points

View File

@ -24,67 +24,8 @@
#ifndef __VIR_STORAGE_BACKEND_H__
#define __VIR_STORAGE_BACKEND_H__
#include <libvirt/libvirt.h>
#include "internal.h"
#include "storage_conf.h"
#include "util.h"
typedef const char *(*virStorageVolFormatToString)(int format);
typedef int (*virStorageVolFormatFromString)(const char *format);
typedef const char *(*virStoragePoolFormatToString)(int format);
typedef int (*virStoragePoolFormatFromString)(const char *format);
typedef struct _virStorageBackendVolOptions virStorageBackendVolOptions;
typedef virStorageBackendVolOptions *virStorageBackendVolOptionsPtr;
struct _virStorageBackendVolOptions {
virStorageVolFormatToString formatToString;
virStorageVolFormatFromString formatFromString;
};
/* Flags to indicate mandatory components in the pool source */
enum {
VIR_STORAGE_BACKEND_POOL_SOURCE_HOST = (1<<0),
VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE = (1<<1),
VIR_STORAGE_BACKEND_POOL_SOURCE_DIR = (1<<2),
VIR_STORAGE_BACKEND_POOL_SOURCE_ADAPTER = (1<<3),
VIR_STORAGE_BACKEND_POOL_SOURCE_NAME = (1<<4),
VIR_STORAGE_BACKEND_POOL_STABLE_PATH = (1<<5),
};
enum partTableType {
VIR_STORAGE_POOL_DISK_UNKNOWN = 0,
VIR_STORAGE_POOL_DISK_DOS = 1,
VIR_STORAGE_POOL_DISK_DVH,
VIR_STORAGE_POOL_DISK_GPT,
VIR_STORAGE_POOL_DISK_MAC,
VIR_STORAGE_POOL_DISK_BSD,
VIR_STORAGE_POOL_DISK_PC98,
VIR_STORAGE_POOL_DISK_SUN,
VIR_STORAGE_POOL_DISK_LVM2,
VIR_STORAGE_POOL_DISK_LAST,
};
struct diskType {
enum partTableType part_table_type;
unsigned short offset;
unsigned short length;
unsigned long long magic;
};
VIR_ENUM_DECL(virStorageBackendPartTable);
typedef struct _virStorageBackendPoolOptions virStorageBackendPoolOptions;
typedef virStorageBackendPoolOptions *virStorageBackendPoolOptionsPtr;
struct _virStorageBackendPoolOptions {
int flags;
int defaultFormat;
virStoragePoolFormatToString formatToString;
virStoragePoolFormatFromString formatFromString;
};
#define SOURCES_START_TAG "<sources>"
#define SOURCES_END_TAG "</sources>"
typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags);
typedef int (*virStorageBackendStartPool)(virConnectPtr conn, virStoragePoolObjPtr pool);
@ -114,19 +55,10 @@ struct _virStorageBackend {
virStorageBackendCreateVol createVol;
virStorageBackendRefreshVol refreshVol;
virStorageBackendDeleteVol deleteVol;
virStorageBackendPoolOptions poolOptions;
virStorageBackendVolOptions volOptions;
int volType;
};
virStorageBackendPtr virStorageBackendForType(int type);
virStorageBackendPoolOptionsPtr virStorageBackendPoolOptionsForType(int type);
virStorageBackendVolOptionsPtr virStorageBackendVolOptionsForType(int type);
int virStorageBackendFromString(const char *type);
const char *virStorageBackendToString(int type);
int virStorageBackendUpdateVolInfo(virConnectPtr conn,
virStorageVolDefPtr vol,

View File

@ -24,6 +24,7 @@
#include <config.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "virterror_internal.h"
#include "logging.h"
@ -31,34 +32,6 @@
#include "util.h"
#include "memory.h"
/*
* XXX these are basically partition types.
*
* fdisk has a bazillion partition ID types
* parted has practically none, and splits the
* info across 3 different attributes.
*
* So this is a semi-generic set
*/
enum {
VIR_STORAGE_VOL_DISK_NONE = 0,
VIR_STORAGE_VOL_DISK_LINUX,
VIR_STORAGE_VOL_DISK_FAT16,
VIR_STORAGE_VOL_DISK_FAT32,
VIR_STORAGE_VOL_DISK_LINUX_SWAP,
VIR_STORAGE_VOL_DISK_LINUX_LVM,
VIR_STORAGE_VOL_DISK_LINUX_RAID,
VIR_STORAGE_VOL_DISK_EXTENDED,
VIR_STORAGE_VOL_DISK_LAST,
};
VIR_ENUM_DECL(virStorageBackendDiskVol);
VIR_ENUM_IMPL(virStorageBackendDiskVol,
VIR_STORAGE_VOL_DISK_LAST,
"none", "linux", "fat16",
"fat32", "linux-swap",
"linux-lvm", "linux-raid",
"extended");
#define PARTHELPER BINDIR "/libvirt_parthelper"
static int
@ -154,6 +127,8 @@ virStorageBackendDiskMakeDataVol(virConnectPtr conn,
if (virStorageBackendUpdateVolInfo(conn, vol, 1) < 0)
return -1;
vol->type = VIR_STORAGE_VOL_BLOCK;
/* The above gets allocation wrong for
* extended partitions, so overwrite it */
vol->allocation = vol->capacity =
@ -306,7 +281,7 @@ virStorageBackendDiskBuildPool(virConnectPtr conn,
"mklabel",
"--script",
((pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) ? "msdos" :
virStorageBackendPartTableTypeToString(pool->def->source.format)),
virStoragePoolFormatDiskTypeToString(pool->def->source.format)),
NULL,
};
@ -445,18 +420,4 @@ virStorageBackend virStorageBackendDisk = {
.createVol = virStorageBackendDiskCreateVol,
.deleteVol = virStorageBackendDiskDeleteVol,
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE|
VIR_STORAGE_BACKEND_POOL_STABLE_PATH),
.defaultFormat = VIR_STORAGE_POOL_DISK_UNKNOWN,
.formatFromString = virStorageBackendPartTableTypeFromString,
.formatToString = virStorageBackendPartTableTypeToString,
},
.volOptions = {
.formatFromString = virStorageBackendDiskVolTypeFromString,
.formatToString = virStorageBackendDiskVolTypeToString,
},
.volType = VIR_STORAGE_VOL_BLOCK,
};

View File

@ -47,59 +47,6 @@
#include "memory.h"
#include "xml.h"
enum {
VIR_STORAGE_POOL_FS_AUTO = 0,
VIR_STORAGE_POOL_FS_EXT2,
VIR_STORAGE_POOL_FS_EXT3,
VIR_STORAGE_POOL_FS_EXT4,
VIR_STORAGE_POOL_FS_UFS,
VIR_STORAGE_POOL_FS_ISO,
VIR_STORAGE_POOL_FS_UDF,
VIR_STORAGE_POOL_FS_GFS,
VIR_STORAGE_POOL_FS_GFS2,
VIR_STORAGE_POOL_FS_VFAT,
VIR_STORAGE_POOL_FS_HFSPLUS,
VIR_STORAGE_POOL_FS_XFS,
VIR_STORAGE_POOL_FS_LAST,
};
VIR_ENUM_DECL(virStorageBackendFileSystemPool);
VIR_ENUM_IMPL(virStorageBackendFileSystemPool,
VIR_STORAGE_POOL_FS_LAST,
"auto", "ext2", "ext3",
"ext4", "ufs", "iso9660", "udf",
"gfs", "gfs2", "vfat", "hfs+", "xfs");
enum {
VIR_STORAGE_POOL_NETFS_AUTO = 0,
VIR_STORAGE_POOL_NETFS_NFS,
VIR_STORAGE_POOL_NETFS_LAST,
};
VIR_ENUM_DECL(virStorageBackendFileSystemNetPool);
VIR_ENUM_IMPL(virStorageBackendFileSystemNetPool,
VIR_STORAGE_POOL_NETFS_LAST,
"auto", "nfs");
enum {
VIR_STORAGE_VOL_RAW = 0,
VIR_STORAGE_VOL_DIR,
VIR_STORAGE_VOL_BOCHS,
VIR_STORAGE_VOL_CLOOP,
VIR_STORAGE_VOL_COW,
VIR_STORAGE_VOL_DMG,
VIR_STORAGE_VOL_ISO,
VIR_STORAGE_VOL_QCOW,
VIR_STORAGE_VOL_QCOW2,
VIR_STORAGE_VOL_VMDK,
VIR_STORAGE_VOL_VPC,
VIR_STORAGE_VOL_LAST,
};
VIR_ENUM_DECL(virStorageBackendFileSystemVol);
VIR_ENUM_IMPL(virStorageBackendFileSystemVol,
VIR_STORAGE_VOL_LAST,
"raw", "dir", "bochs",
"cloop", "cow", "dmg", "iso",
"qcow", "qcow2", "vmdk", "vpc");
/* Either 'magic' or 'extension' *must* be provided */
struct FileTypeInfo {
@ -130,45 +77,45 @@ const struct FileTypeInfo const fileTypeInfo[] = {
__LITTLE_ENDIAN, -1, 0,
-1, 0, 0 }, */
/* Cow */
{ VIR_STORAGE_VOL_COW, "OOOM", NULL,
{ VIR_STORAGE_VOL_FILE_COW, "OOOM", NULL,
__BIG_ENDIAN, 4, 2,
4+4+1024+4, 8, 1 },
/* DMG */
/* XXX QEMU says there's no magic for dmg, but we should check... */
{ VIR_STORAGE_VOL_DMG, NULL, ".dmg",
{ VIR_STORAGE_VOL_FILE_DMG, NULL, ".dmg",
0, -1, 0,
-1, 0, 0 },
/* XXX there's probably some magic for iso we can validate too... */
{ VIR_STORAGE_VOL_ISO, NULL, ".iso",
{ VIR_STORAGE_VOL_FILE_ISO, NULL, ".iso",
0, -1, 0,
-1, 0, 0 },
/* Parallels */
/* XXX Untested
{ VIR_STORAGE_VOL_PARALLELS, "WithoutFreeSpace", NULL,
{ VIR_STORAGE_VOL_FILE_PARALLELS, "WithoutFreeSpace", NULL,
__LITTLE_ENDIAN, 16, 2,
16+4+4+4+4, 4, 512 },
*/
/* QCow */
{ VIR_STORAGE_VOL_QCOW, "QFI", NULL,
{ VIR_STORAGE_VOL_FILE_QCOW, "QFI", NULL,
__BIG_ENDIAN, 4, 1,
4+4+8+4+4, 8, 1 },
/* QCow 2 */
{ VIR_STORAGE_VOL_QCOW2, "QFI", NULL,
{ VIR_STORAGE_VOL_FILE_QCOW2, "QFI", NULL,
__BIG_ENDIAN, 4, 2,
4+4+8+4+4, 8, 1 },
/* VMDK 3 */
/* XXX Untested
{ VIR_STORAGE_VOL_VMDK, "COWD", NULL,
{ VIR_STORAGE_VOL_FILE_VMDK, "COWD", NULL,
__LITTLE_ENDIAN, 4, 1,
4+4+4, 4, 512 },
*/
/* VMDK 4 */
{ VIR_STORAGE_VOL_VMDK, "KDMV", NULL,
{ VIR_STORAGE_VOL_FILE_VMDK, "KDMV", NULL,
__LITTLE_ENDIAN, 4, 1,
4+4+4, 8, 512 },
/* Connectix / VirtualPC */
/* XXX Untested
{ VIR_STORAGE_VOL_VPC, "conectix", NULL,
{ VIR_STORAGE_VOL_FILE_VPC, "conectix", NULL,
__BIG_ENDIAN, -1, 0,
-1, 0, 0},
*/
@ -288,7 +235,7 @@ static int virStorageBackendProbeFile(virConnectPtr conn,
}
/* All fails, so call it a raw file */
def->target.format = VIR_STORAGE_VOL_RAW;
def->target.format = VIR_STORAGE_VOL_FILE_RAW;
return 0;
}
@ -486,8 +433,8 @@ virStorageBackendFileSystemMount(virConnectPtr conn,
MOUNT,
"-t",
pool->def->type == VIR_STORAGE_POOL_FS ?
virStorageBackendFileSystemPoolTypeToString(pool->def->source.format) :
virStorageBackendFileSystemNetPoolTypeToString(pool->def->source.format),
virStoragePoolFormatFileSystemTypeToString(pool->def->source.format) :
virStoragePoolFormatFileSystemNetTypeToString(pool->def->source.format),
NULL, /* Fill in shortly - careful not to add extra fields
before this */
pool->def->target.path,
@ -689,7 +636,8 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn,
if ((vol->name = strdup(ent->d_name)) == NULL)
goto no_memory;
vol->target.format = VIR_STORAGE_VOL_RAW; /* Real value is filled in during probe */
vol->type = VIR_STORAGE_VOL_FILE;
vol->target.format = VIR_STORAGE_VOL_FILE_RAW; /* Real value is filled in during probe */
if (VIR_ALLOC_N(vol->target.path, strlen(pool->def->target.path) +
1 + strlen(vol->name) + 1) < 0)
goto no_memory;
@ -815,6 +763,7 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("target"));
return -1;
}
vol->type = VIR_STORAGE_VOL_FILE;
strcpy(vol->target.path, pool->def->target.path);
strcat(vol->target.path, "/");
strcat(vol->target.path, vol->name);
@ -825,7 +774,7 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
return -1;
}
if (vol->target.format == VIR_STORAGE_VOL_RAW) {
if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW) {
if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
vol->target.perms.mode)) < 0) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
@ -865,7 +814,7 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
close(fd);
return -1;
}
} else if (vol->target.format == VIR_STORAGE_VOL_DIR) {
} else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) {
if (mkdir(vol->target.path, vol->target.perms.mode) < 0) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("cannot create path '%s': %s"),
@ -885,7 +834,7 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
char size[100];
const char *imgargv[7];
if ((type = virStorageBackendFileSystemVolTypeToString(vol->target.format)) == NULL) {
if ((type = virStorageVolFormatFileSystemTypeToString(vol->target.format)) == NULL) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"),
vol->target.format);
@ -923,7 +872,7 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn,
char size[100];
const char *imgargv[4];
if (vol->target.format != VIR_STORAGE_VOL_QCOW2) {
if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unsupported storage vol type %d"),
vol->target.format);
@ -1040,12 +989,6 @@ virStorageBackend virStorageBackendDirectory = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.volOptions = {
.formatFromString = virStorageBackendFileSystemVolTypeFromString,
.formatToString = virStorageBackendFileSystemVolTypeToString,
},
.volType = VIR_STORAGE_VOL_FILE,
};
#if WITH_STORAGE_FS
@ -1060,17 +1003,6 @@ virStorageBackend virStorageBackendFileSystem = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE),
.formatFromString = virStorageBackendFileSystemPoolTypeFromString,
.formatToString = virStorageBackendFileSystemPoolTypeToString,
},
.volOptions = {
.formatFromString = virStorageBackendFileSystemVolTypeFromString,
.formatToString = virStorageBackendFileSystemVolTypeToString,
},
.volType = VIR_STORAGE_VOL_FILE,
};
virStorageBackend virStorageBackendNetFileSystem = {
.type = VIR_STORAGE_POOL_NETFS,
@ -1084,18 +1016,5 @@ virStorageBackend virStorageBackendNetFileSystem = {
.createVol = virStorageBackendFileSystemVolCreate,
.refreshVol = virStorageBackendFileSystemVolRefresh,
.deleteVol = virStorageBackendFileSystemVolDelete,
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_HOST |
VIR_STORAGE_BACKEND_POOL_SOURCE_DIR),
.defaultFormat = VIR_STORAGE_POOL_FS_AUTO,
.formatFromString = virStorageBackendFileSystemNetPoolTypeFromString,
.formatToString = virStorageBackendFileSystemNetPoolTypeToString,
},
.volOptions = {
.formatFromString = virStorageBackendFileSystemVolTypeFromString,
.formatToString = virStorageBackendFileSystemVolTypeToString,
},
.volType = VIR_STORAGE_VOL_FILE,
};
#endif /* WITH_STORAGE_FS */

View File

@ -178,6 +178,8 @@ virStorageBackendISCSINewLun(virConnectPtr conn, virStoragePoolObjPtr pool,
goto cleanup;
}
vol->type = VIR_STORAGE_VOL_BLOCK;
if (asprintf(&(vol->name), "lun-%d", lun) < 0) {
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("name"));
goto cleanup;
@ -641,15 +643,4 @@ virStorageBackend virStorageBackendISCSI = {
.startPool = virStorageBackendISCSIStartPool,
.refreshPool = virStorageBackendISCSIRefreshPool,
.stopPool = virStorageBackendISCSIStopPool,
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_HOST |
VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE |
VIR_STORAGE_BACKEND_POOL_STABLE_PATH)
},
.volType = VIR_STORAGE_VOL_BLOCK,
.volOptions = {
.formatToString = virStorageBackendPartTableTypeToString,
}
};

View File

@ -39,15 +39,6 @@
#define PV_BLANK_SECTOR_SIZE 512
enum {
VIR_STORAGE_POOL_LOGICAL_UNKNOWN = 0,
VIR_STORAGE_POOL_LOGICAL_LVM2 = 1,
VIR_STORAGE_POOL_LOGICAL_LAST,
};
VIR_ENUM_DECL(virStorageBackendLogicalPool);
VIR_ENUM_IMPL(virStorageBackendLogicalPool,
VIR_STORAGE_POOL_LOGICAL_LAST,
"unknown", "lvm2");
static int
virStorageBackendLogicalSetActive(virConnectPtr conn,
@ -95,6 +86,8 @@ virStorageBackendLogicalMakeVol(virConnectPtr conn,
return -1;
}
vol->type = VIR_STORAGE_VOL_BLOCK;
if ((vol->name = strdup(groups[0])) == NULL) {
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("volume"));
virStorageVolDefFree(vol);
@ -577,6 +570,8 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
snprintf(size, sizeof(size)-1, "%lluK", vol->capacity/1024);
size[sizeof(size)-1] = '\0';
vol->type = VIR_STORAGE_VOL_BLOCK;
if (vol->target.path != NULL) {
/* A target path passed to CreateVol has no meaning */
VIR_FREE(vol->target.path);
@ -669,14 +664,4 @@ virStorageBackend virStorageBackendLogical = {
.deletePool = virStorageBackendLogicalDeletePool,
.createVol = virStorageBackendLogicalCreateVol,
.deleteVol = virStorageBackendLogicalDeleteVol,
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_NAME |
VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_LOGICAL_LVM2,
.formatFromString = virStorageBackendLogicalPoolTypeFromString,
.formatToString = virStorageBackendLogicalPoolTypeToString,
},
.volType = VIR_STORAGE_VOL_BLOCK,
};

View File

@ -36,7 +36,7 @@
#include "virterror_internal.h"
#include "datatypes.h"
#include "storage_conf.h"
#include "storage_backend.h"
#include "xml.h"
#include "uuid.h"
#include "buf.h"
@ -45,6 +45,181 @@
#define virStorageLog(msg...) fprintf(stderr, msg)
VIR_ENUM_IMPL(virStoragePool,
VIR_STORAGE_POOL_LAST,
"dir", "fs", "netfs",
"logical", "disk", "iscsi",
"scsi");
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
VIR_STORAGE_POOL_FS_LAST,
"auto", "ext2", "ext3",
"ext4", "ufs", "iso9660", "udf",
"gfs", "gfs2", "vfat", "hfs+", "xfs");
VIR_ENUM_IMPL(virStoragePoolFormatFileSystemNet,
VIR_STORAGE_POOL_NETFS_LAST,
"auto", "nfs");
VIR_ENUM_IMPL(virStoragePoolFormatDisk,
VIR_STORAGE_POOL_DISK_LAST,
"unknown", "dos", "dvh", "gpt",
"mac", "bsd", "pc98", "sun", "lvm2");
VIR_ENUM_IMPL(virStoragePoolFormatLogical,
VIR_STORAGE_POOL_LOGICAL_LAST,
"unknown", "lvm2");
VIR_ENUM_IMPL(virStorageVolFormatDisk,
VIR_STORAGE_VOL_DISK_LAST,
"none", "linux", "fat16",
"fat32", "linux-swap",
"linux-lvm", "linux-raid",
"extended");
VIR_ENUM_IMPL(virStorageVolFormatFileSystem,
VIR_STORAGE_VOL_FILE_LAST,
"raw", "dir", "bochs",
"cloop", "cow", "dmg", "iso",
"qcow", "qcow2", "vmdk", "vpc");
typedef const char *(*virStorageVolFormatToString)(int format);
typedef int (*virStorageVolFormatFromString)(const char *format);
typedef const char *(*virStoragePoolFormatToString)(int format);
typedef int (*virStoragePoolFormatFromString)(const char *format);
typedef struct _virStorageVolOptions virStorageVolOptions;
typedef virStorageVolOptions *virStorageVolOptionsPtr;
struct _virStorageVolOptions {
virStorageVolFormatToString formatToString;
virStorageVolFormatFromString formatFromString;
};
/* Flags to indicate mandatory components in the pool source */
enum {
VIR_STORAGE_POOL_SOURCE_HOST = (1<<0),
VIR_STORAGE_POOL_SOURCE_DEVICE = (1<<1),
VIR_STORAGE_POOL_SOURCE_DIR = (1<<2),
VIR_STORAGE_POOL_SOURCE_ADAPTER = (1<<3),
VIR_STORAGE_POOL_SOURCE_NAME = (1<<4),
};
typedef struct _virStoragePoolOptions virStoragePoolOptions;
typedef virStoragePoolOptions *virStoragePoolOptionsPtr;
struct _virStoragePoolOptions {
int flags;
int defaultFormat;
virStoragePoolFormatToString formatToString;
virStoragePoolFormatFromString formatFromString;
};
typedef struct _virStoragePoolTypeInfo virStoragePoolTypeInfo;
typedef virStoragePoolTypeInfo *virStoragePoolTypeInfoPtr;
struct _virStoragePoolTypeInfo {
int poolType;
virStoragePoolOptions poolOptions;
virStorageVolOptions volOptions;
};
static virStoragePoolTypeInfo poolTypeInfo[] = {
{ .poolType = VIR_STORAGE_POOL_LOGICAL,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_NAME |
VIR_STORAGE_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_LOGICAL_LVM2,
.formatFromString = virStoragePoolFormatLogicalTypeFromString,
.formatToString = virStoragePoolFormatLogicalTypeToString,
},
},
{ .poolType = VIR_STORAGE_POOL_DIR,
.volOptions = {
.formatFromString = virStorageVolFormatFileSystemTypeFromString,
.formatToString = virStorageVolFormatFileSystemTypeToString,
},
},
{ .poolType = VIR_STORAGE_POOL_FS,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_DEVICE),
.formatFromString = virStoragePoolFormatFileSystemTypeFromString,
.formatToString = virStoragePoolFormatFileSystemTypeToString,
},
.volOptions = {
.formatFromString = virStorageVolFormatFileSystemTypeFromString,
.formatToString = virStorageVolFormatFileSystemTypeToString,
},
},
{ .poolType = VIR_STORAGE_POOL_NETFS,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_HOST |
VIR_STORAGE_POOL_SOURCE_DIR),
.defaultFormat = VIR_STORAGE_POOL_FS_AUTO,
.formatFromString = virStoragePoolFormatFileSystemNetTypeFromString,
.formatToString = virStoragePoolFormatFileSystemNetTypeToString,
},
.volOptions = {
.formatFromString = virStorageVolFormatFileSystemTypeFromString,
.formatToString = virStorageVolFormatFileSystemTypeToString,
},
},
{ .poolType = VIR_STORAGE_POOL_ISCSI,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_HOST |
VIR_STORAGE_POOL_SOURCE_DEVICE),
},
.volOptions = {
.formatToString = virStoragePoolFormatDiskTypeToString,
}
},
{ .poolType = VIR_STORAGE_POOL_DISK,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_DEVICE),
.defaultFormat = VIR_STORAGE_POOL_DISK_UNKNOWN,
.formatFromString = virStoragePoolFormatDiskTypeFromString,
.formatToString = virStoragePoolFormatDiskTypeToString,
},
.volOptions = {
.formatFromString = virStorageVolFormatDiskTypeFromString,
.formatToString = virStorageVolFormatDiskTypeToString,
},
}
};
static virStoragePoolTypeInfoPtr
virStoragePoolTypeInfoLookup(int type) {
unsigned int i;
for (i = 0; i < ARRAY_CARDINALITY(poolTypeInfo) ; i++)
if (poolTypeInfo[i].poolType == type)
return &poolTypeInfo[i];
virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
_("missing backend for pool type %d"), type);
return NULL;
}
static virStoragePoolOptionsPtr
virStoragePoolOptionsForPoolType(int type) {
virStoragePoolTypeInfoPtr backend = virStoragePoolTypeInfoLookup(type);
if (backend == NULL)
return NULL;
return &backend->poolOptions;
}
static virStorageVolOptionsPtr
virStorageVolOptionsForPoolType(int type) {
virStoragePoolTypeInfoPtr backend = virStoragePoolTypeInfoLookup(type);
if (backend == NULL)
return NULL;
return &backend->volOptions;
}
void
virStorageVolDefFree(virStorageVolDefPtr def) {
int i;
@ -224,7 +399,7 @@ static virStoragePoolDefPtr
virStoragePoolDefParseDoc(virConnectPtr conn,
xmlXPathContextPtr ctxt,
xmlNodePtr root) {
virStorageBackendPoolOptionsPtr options;
virStoragePoolOptionsPtr options;
virStoragePoolDefPtr ret;
xmlChar *type = NULL;
char *uuid = NULL;
@ -238,23 +413,27 @@ virStoragePoolDefParseDoc(virConnectPtr conn,
if (STRNEQ((const char *)root->name, "pool")) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
"%s", _("unknown root elementi for storage pool"));
"%s", _("unknown root element for storage pool"));
goto cleanup;
}
type = xmlGetProp(root, BAD_CAST "type");
if ((ret->type = virStorageBackendFromString((const char *)type)) < 0)
if ((ret->type = virStoragePoolTypeFromString((const char *)type)) < 0) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown storage pool type %s"), (const char*)type);
goto cleanup;
}
xmlFree(type);
type = NULL;
if ((options = virStorageBackendPoolOptionsForType(ret->type)) == NULL) {
if ((options = virStoragePoolOptionsForPoolType(ret->type)) == NULL) {
goto cleanup;
}
ret->name = virXPathString(conn, "string(/pool/name)", ctxt);
if (ret->name == NULL &&
options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_NAME)
options->flags & VIR_STORAGE_POOL_SOURCE_NAME)
ret->name = virXPathString(conn, "string(/pool/source/name)", ctxt);
if (ret->name == NULL) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
@ -294,14 +473,14 @@ virStoragePoolDefParseDoc(virConnectPtr conn,
VIR_FREE(format);
}
if (options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_HOST) {
if (options->flags & VIR_STORAGE_POOL_SOURCE_HOST) {
if ((ret->source.host.name = virXPathString(conn, "string(/pool/source/host/@name)", ctxt)) == NULL) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
"%s", _("missing storage pool source host name"));
goto cleanup;
}
}
if (options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE) {
if (options->flags & VIR_STORAGE_POOL_SOURCE_DEVICE) {
xmlNodePtr *nodeset = NULL;
int nsource, i;
@ -328,14 +507,14 @@ virStoragePoolDefParseDoc(virConnectPtr conn,
VIR_FREE(nodeset);
ret->source.ndevice = nsource;
}
if (options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DIR) {
if (options->flags & VIR_STORAGE_POOL_SOURCE_DIR) {
if ((ret->source.dir = virXPathString(conn, "string(/pool/source/dir/@path)", ctxt)) == NULL) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
"%s", _("missing storage pool source path"));
goto cleanup;
}
}
if (options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_NAME) {
if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) {
ret->source.name = virXPathString(conn, "string(/pool/source/name)",
ctxt);
if (ret->source.name == NULL) {
@ -471,17 +650,17 @@ virStoragePoolDefParse(virConnectPtr conn,
static int
virStoragePoolSourceFormat(virConnectPtr conn,
virBufferPtr buf,
virStorageBackendPoolOptionsPtr options,
virStoragePoolOptionsPtr options,
virStoragePoolSourcePtr src)
{
int i, j;
virBufferAddLit(buf," <source>\n");
if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_HOST) &&
if ((options->flags & VIR_STORAGE_POOL_SOURCE_HOST) &&
src->host.name)
virBufferVSprintf(buf," <host name='%s'/>\n", src->host.name);
if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE) &&
if ((options->flags & VIR_STORAGE_POOL_SOURCE_DEVICE) &&
src->ndevice) {
for (i = 0 ; i < src->ndevice ; i++) {
if (src->devices[i].nfreeExtent) {
@ -499,13 +678,13 @@ virStoragePoolSourceFormat(virConnectPtr conn,
src->devices[i].path);
}
}
if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DIR) &&
if ((options->flags & VIR_STORAGE_POOL_SOURCE_DIR) &&
src->dir)
virBufferVSprintf(buf," <dir path='%s'/>\n", src->dir);
if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_ADAPTER) &&
if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) &&
src->adapter)
virBufferVSprintf(buf," <adapter name='%s'/>\n", src->adapter);
if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_NAME) &&
if ((options->flags & VIR_STORAGE_POOL_SOURCE_NAME) &&
src->name)
virBufferVSprintf(buf," <name>%s</name>\n", src->name);
@ -534,16 +713,16 @@ virStoragePoolSourceFormat(virConnectPtr conn,
char *
virStoragePoolDefFormat(virConnectPtr conn,
virStoragePoolDefPtr def) {
virStorageBackendPoolOptionsPtr options;
virStoragePoolOptionsPtr options;
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *type;
char uuid[VIR_UUID_STRING_BUFLEN];
options = virStorageBackendPoolOptionsForType(def->type);
options = virStoragePoolOptionsForPoolType(def->type);
if (options == NULL)
return NULL;
type = virStorageBackendToString(def->type);
type = virStoragePoolTypeToString(def->type);
if (!type) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("unexpected pool type"));
@ -725,12 +904,12 @@ virStorageVolDefParseDoc(virConnectPtr conn,
xmlXPathContextPtr ctxt,
xmlNodePtr root) {
virStorageVolDefPtr ret;
virStorageBackendVolOptionsPtr options;
virStorageVolOptionsPtr options;
char *allocation = NULL;
char *capacity = NULL;
char *unit = NULL;
options = virStorageBackendVolOptionsForType(pool->type);
options = virStorageVolOptionsForPoolType(pool->type);
if (options == NULL)
return NULL;
@ -870,11 +1049,11 @@ char *
virStorageVolDefFormat(virConnectPtr conn,
virStoragePoolDefPtr pool,
virStorageVolDefPtr def) {
virStorageBackendVolOptionsPtr options;
virStorageVolOptionsPtr options;
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *tmp;
options = virStorageBackendVolOptionsForType(pool->type);
options = virStorageVolOptionsForPoolType(pool->type);
if (options == NULL)
return NULL;
@ -1283,16 +1462,16 @@ virStoragePoolObjDeleteDef(virConnectPtr conn,
char *virStoragePoolSourceListFormat(virConnectPtr conn,
virStoragePoolSourceListPtr def)
{
virStorageBackendPoolOptionsPtr options;
virStoragePoolOptionsPtr options;
virBuffer buf = VIR_BUFFER_INITIALIZER;
const char *type;
int i;
options = virStorageBackendPoolOptionsForType(def->type);
options = virStoragePoolOptionsForPoolType(def->type);
if (options == NULL)
return NULL;
type = virStorageBackendToString(def->type);
type = virStoragePoolTypeToString(def->type);
if (!type) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("unexpected pool type"));

View File

@ -24,11 +24,8 @@
#ifndef __VIR_STORAGE_CONF_H__
#define __VIR_STORAGE_CONF_H__
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include "internal.h"
#include "util.h"
/* Shared structs */
@ -84,6 +81,7 @@ typedef virStorageVolDef *virStorageVolDefPtr;
struct _virStorageVolDef {
char *name;
char *key;
int type; /* virStorageVolType enum */
unsigned long long allocation;
unsigned long long capacity;
@ -104,15 +102,19 @@ struct _virStorageVolDefList {
/* Storage pools */
enum virStoragePoolType {
VIR_STORAGE_POOL_DIR = 1, /* Local directory */
VIR_STORAGE_POOL_DIR, /* Local directory */
VIR_STORAGE_POOL_FS, /* Local filesystem */
VIR_STORAGE_POOL_NETFS, /* Networked filesystem - eg NFS, GFS, etc */
VIR_STORAGE_POOL_LOGICAL, /* Logical volume groups / volumes */
VIR_STORAGE_POOL_DISK, /* Disk partitions */
VIR_STORAGE_POOL_ISCSI, /* iSCSI targets */
VIR_STORAGE_POOL_SCSI, /* SCSI HBA */
VIR_STORAGE_POOL_LAST,
};
VIR_ENUM_DECL(virStoragePool);
enum virStoragePoolAuthType {
VIR_STORAGE_POOL_AUTH_NONE,
@ -260,6 +262,7 @@ struct _virStoragePoolSourceList {
virStoragePoolSourcePtr sources;
};
static inline int virStoragePoolObjIsActive(virStoragePoolObjPtr pool) {
return pool->active;
}
@ -322,4 +325,93 @@ void virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
char *virStoragePoolSourceListFormat(virConnectPtr conn,
virStoragePoolSourceListPtr def);
enum virStoragePoolFormatFileSystem {
VIR_STORAGE_POOL_FS_AUTO = 0,
VIR_STORAGE_POOL_FS_EXT2,
VIR_STORAGE_POOL_FS_EXT3,
VIR_STORAGE_POOL_FS_EXT4,
VIR_STORAGE_POOL_FS_UFS,
VIR_STORAGE_POOL_FS_ISO,
VIR_STORAGE_POOL_FS_UDF,
VIR_STORAGE_POOL_FS_GFS,
VIR_STORAGE_POOL_FS_GFS2,
VIR_STORAGE_POOL_FS_VFAT,
VIR_STORAGE_POOL_FS_HFSPLUS,
VIR_STORAGE_POOL_FS_XFS,
VIR_STORAGE_POOL_FS_LAST,
};
VIR_ENUM_DECL(virStoragePoolFormatFileSystem);
enum virStoragePoolFormatFileSystemNet {
VIR_STORAGE_POOL_NETFS_AUTO = 0,
VIR_STORAGE_POOL_NETFS_NFS,
VIR_STORAGE_POOL_NETFS_LAST,
};
VIR_ENUM_DECL(virStoragePoolFormatFileSystemNet);
enum virStoragePoolFormatDisk {
VIR_STORAGE_POOL_DISK_UNKNOWN = 0,
VIR_STORAGE_POOL_DISK_DOS = 1,
VIR_STORAGE_POOL_DISK_DVH,
VIR_STORAGE_POOL_DISK_GPT,
VIR_STORAGE_POOL_DISK_MAC,
VIR_STORAGE_POOL_DISK_BSD,
VIR_STORAGE_POOL_DISK_PC98,
VIR_STORAGE_POOL_DISK_SUN,
VIR_STORAGE_POOL_DISK_LVM2,
VIR_STORAGE_POOL_DISK_LAST,
};
VIR_ENUM_DECL(virStoragePoolFormatDisk);
enum virStoragePoolFormatLogical {
VIR_STORAGE_POOL_LOGICAL_UNKNOWN = 0,
VIR_STORAGE_POOL_LOGICAL_LVM2 = 1,
VIR_STORAGE_POOL_LOGICAL_LAST,
};
VIR_ENUM_DECL(virStoragePoolFormatLogical);
enum virStorageVolFormatFileSystem {
VIR_STORAGE_VOL_FILE_RAW = 0,
VIR_STORAGE_VOL_FILE_DIR,
VIR_STORAGE_VOL_FILE_BOCHS,
VIR_STORAGE_VOL_FILE_CLOOP,
VIR_STORAGE_VOL_FILE_COW,
VIR_STORAGE_VOL_FILE_DMG,
VIR_STORAGE_VOL_FILE_ISO,
VIR_STORAGE_VOL_FILE_QCOW,
VIR_STORAGE_VOL_FILE_QCOW2,
VIR_STORAGE_VOL_FILE_VMDK,
VIR_STORAGE_VOL_FILE_VPC,
VIR_STORAGE_VOL_FILE_LAST,
};
VIR_ENUM_DECL(virStorageVolFormatFileSystem);
/*
* XXX these are basically partition types.
*
* fdisk has a bazillion partition ID types
* parted has practically none, and splits the
* info across 3 different attributes.
*
* So this is a semi-generic set
*/
enum virStorageVolFormatDisk {
VIR_STORAGE_VOL_DISK_NONE = 0,
VIR_STORAGE_VOL_DISK_LINUX,
VIR_STORAGE_VOL_DISK_FAT16,
VIR_STORAGE_VOL_DISK_FAT32,
VIR_STORAGE_VOL_DISK_LINUX_SWAP,
VIR_STORAGE_VOL_DISK_LINUX_LVM,
VIR_STORAGE_VOL_DISK_LINUX_RAID,
VIR_STORAGE_VOL_DISK_EXTENDED,
VIR_STORAGE_VOL_DISK_LAST,
};
VIR_ENUM_DECL(virStorageVolFormatDisk);
#endif /* __VIR_STORAGE_CONF_H__ */

View File

@ -403,7 +403,7 @@ storageFindPoolSources(virConnectPtr conn,
int backend_type;
virStorageBackendPtr backend;
backend_type = virStorageBackendFromString(type);
backend_type = virStoragePoolTypeFromString(type);
if (backend_type < 0)
return NULL;
@ -968,33 +968,22 @@ storageVolumeLookupByPath(virConnectPtr conn,
for (i = 0 ; i < driver->pools.count ; i++) {
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
virStorageVolDefPtr vol;
virStorageBackendPoolOptionsPtr options;
const char *stable_path;
options = virStorageBackendPoolOptionsForType(driver->pools.objs[i]->def->type);
if (options == NULL)
continue;
if (options->flags & VIR_STORAGE_BACKEND_POOL_STABLE_PATH) {
const char *stable_path;
stable_path = virStorageBackendStablePath(conn,
driver->pools.objs[i],
path);
/*
* virStorageBackendStablePath already does
* virStorageReportError if it fails; we just need to keep
* propagating the return code
*/
if (stable_path == NULL)
return NULL;
vol = virStorageVolDefFindByPath(driver->pools.objs[i],
stable_path);
VIR_FREE(stable_path);
}
else
vol = virStorageVolDefFindByPath(driver->pools.objs[i], path);
stable_path = virStorageBackendStablePath(conn,
driver->pools.objs[i],
path);
/*
* virStorageBackendStablePath already does
* virStorageReportError if it fails; we just need to keep
* propagating the return code
*/
if (stable_path == NULL)
return NULL;
vol = virStorageVolDefFindByPath(driver->pools.objs[i],
stable_path);
VIR_FREE(stable_path);
if (vol)
return virGetStorageVol(conn,
@ -1170,7 +1159,7 @@ storageVolumeGetInfo(virStorageVolPtr obj,
return -1;
memset(info, 0, sizeof(*info));
info->type = backend->volType;
info->type = vol->type;
info->capacity = vol->capacity;
info->allocation = vol->allocation;