mirror of https://gitee.com/openkylin/libvirt.git
allow to create storage volumes on disk backend
* src/libvirt_private.syms src/parthelper.c src/storage_backend_disk.c src/storage_conf.c src/storage_conf.h: allow to create storage volumes on disk backend, patches by Henrik Persson * AUTHORS: add Henrik Persson Daniel
This commit is contained in:
parent
173c230e66
commit
fd90b67afe
1
AUTHORS
1
AUTHORS
|
@ -75,6 +75,7 @@ Patches have also been contributed by:
|
||||||
Javier Fontan <jfontan@gmail.com>
|
Javier Fontan <jfontan@gmail.com>
|
||||||
Federico Simoncelli <federico.simoncelli@gmail.com>
|
Federico Simoncelli <federico.simoncelli@gmail.com>
|
||||||
Amy Griffis <amy.griffis@hp.com>
|
Amy Griffis <amy.griffis@hp.com>
|
||||||
|
Henrik Persson E <henrik.e.persson@ericsson.com>
|
||||||
|
|
||||||
[....send patches to get your name here....]
|
[....send patches to get your name here....]
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
Fri Jun 26 18:15:08 CEST 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/libvirt_private.syms src/parthelper.c src/storage_backend_disk.c
|
||||||
|
src/storage_conf.c src/storage_conf.h: allow to create storage
|
||||||
|
volumes on disk backend, patches by Henrik Persson
|
||||||
|
* AUTHORS: add Henrik Persson
|
||||||
|
|
||||||
Fri Jun 26 17:06:18 CEST 2009 Daniel Veillard <veillard@redhat.com>
|
Fri Jun 26 17:06:18 CEST 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* src/Makefile.am src/libvirt.c src/libvirt_private.syms src/logging.c
|
* src/Makefile.am src/libvirt.c src/libvirt_private.syms src/logging.c
|
||||||
|
|
|
@ -307,6 +307,7 @@ virStoragePoolFormatFileSystemNetTypeToString;
|
||||||
virStorageVolFormatFileSystemTypeToString;
|
virStorageVolFormatFileSystemTypeToString;
|
||||||
virStorageVolFormatFileSystemTypeFromString;
|
virStorageVolFormatFileSystemTypeFromString;
|
||||||
virStoragePoolTypeFromString;
|
virStoragePoolTypeFromString;
|
||||||
|
virStoragePartedFsTypeTypeToString;
|
||||||
virStoragePoolObjLock;
|
virStoragePoolObjLock;
|
||||||
virStoragePoolObjUnlock;
|
virStoragePoolObjUnlock;
|
||||||
|
|
||||||
|
|
|
@ -35,20 +35,31 @@
|
||||||
#include <parted/parted.h>
|
#include <parted/parted.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* we don't need to include the full internal.h just for this */
|
||||||
|
#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
|
||||||
|
|
||||||
/* Make the comparisons below fail if your parted headers
|
/* Make the comparisons below fail if your parted headers
|
||||||
are so old that they lack the definition. */
|
are so old that they lack the definition. */
|
||||||
#ifndef PED_PARTITION_PROTECTED
|
#ifndef PED_PARTITION_PROTECTED
|
||||||
# define PED_PARTITION_PROTECTED 0
|
# define PED_PARTITION_PROTECTED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum diskCommand {
|
||||||
|
DISK_LAYOUT = 0,
|
||||||
|
DISK_GEOMETRY
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
PedDevice *dev;
|
PedDevice *dev;
|
||||||
PedDisk *disk;
|
PedDisk *disk;
|
||||||
PedPartition *part;
|
PedPartition *part;
|
||||||
|
int cmd = DISK_LAYOUT;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc == 3 && STRNEQ(argv[2], "-g")) {
|
||||||
fprintf(stderr, "syntax: %s DEVICE\n", argv[0]);
|
cmd = DISK_GEOMETRY;
|
||||||
|
} else if (argc != 2) {
|
||||||
|
fprintf(stderr, "syntax: %s DEVICE [-g]\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +68,15 @@ int main(int argc, char **argv)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the geometry of the disk and then exit */
|
||||||
|
if(cmd == DISK_GEOMETRY) {
|
||||||
|
printf("%d%c%d%c%d%c%",
|
||||||
|
dev->hw_geom.cylinders, '\0',
|
||||||
|
dev->hw_geom.heads, '\0',
|
||||||
|
dev->hw_geom.sectors, '\0');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((disk = ped_disk_new(dev)) == NULL) {
|
if ((disk = ped_disk_new(dev)) == NULL) {
|
||||||
fprintf(stderr, "unable to access disk %s\n", argv[1]);
|
fprintf(stderr, "unable to access disk %s\n", argv[1]);
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
|
|
||||||
#define PARTHELPER BINDIR "/libvirt_parthelper"
|
#define PARTHELPER BINDIR "/libvirt_parthelper"
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virStorageBackendDiskMakeDataVol(virConnectPtr conn,
|
virStorageBackendDiskMakeDataVol(virConnectPtr conn,
|
||||||
virStoragePoolObjPtr pool,
|
virStoragePoolObjPtr pool,
|
||||||
|
@ -128,6 +130,16 @@ virStorageBackendDiskMakeDataVol(virConnectPtr conn,
|
||||||
if (virStorageBackendUpdateVolInfo(conn, vol, 1) < 0)
|
if (virStorageBackendUpdateVolInfo(conn, vol, 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* set partition type */
|
||||||
|
if(STREQ(groups[1], "normal"))
|
||||||
|
vol->target.type = VIR_STORAGE_VOL_DISK_TYPE_PRIMARY;
|
||||||
|
else if(STREQ(groups[1], "logical"))
|
||||||
|
vol->target.type = VIR_STORAGE_VOL_DISK_TYPE_LOGICAL;
|
||||||
|
else if(STREQ(groups[1], "extended"))
|
||||||
|
vol->target.type = VIR_STORAGE_VOL_DISK_TYPE_EXTENDED;
|
||||||
|
else
|
||||||
|
vol->target.type = VIR_STORAGE_VOL_DISK_TYPE_NONE;
|
||||||
|
|
||||||
vol->type = VIR_STORAGE_VOL_BLOCK;
|
vol->type = VIR_STORAGE_VOL_BLOCK;
|
||||||
|
|
||||||
/* The above gets allocation wrong for
|
/* The above gets allocation wrong for
|
||||||
|
@ -158,6 +170,14 @@ virStorageBackendDiskMakeFreeExtent(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
dev->nfreeExtent, 0,
|
dev->nfreeExtent, 0,
|
||||||
sizeof(dev->freeExtents[0]));
|
sizeof(dev->freeExtents[0]));
|
||||||
|
|
||||||
|
/* set type of free area */
|
||||||
|
if(STREQ(groups[1], "logical")) {
|
||||||
|
dev->freeExtents[dev->nfreeExtent].type = VIR_STORAGE_FREE_LOGICAL;
|
||||||
|
} else {
|
||||||
|
dev->freeExtents[dev->nfreeExtent].type = VIR_STORAGE_FREE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (virStrToLong_ull(groups[3], NULL, 10,
|
if (virStrToLong_ull(groups[3], NULL, 10,
|
||||||
&dev->freeExtents[dev->nfreeExtent].start) < 0)
|
&dev->freeExtents[dev->nfreeExtent].start) < 0)
|
||||||
return -1; /* Don't bother to re-alloc freeExtents - it'll be free'd shortly */
|
return -1; /* Don't bother to re-alloc freeExtents - it'll be free'd shortly */
|
||||||
|
@ -166,6 +186,11 @@ virStorageBackendDiskMakeFreeExtent(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
&dev->freeExtents[dev->nfreeExtent].end) < 0)
|
&dev->freeExtents[dev->nfreeExtent].end) < 0)
|
||||||
return -1; /* Don't bother to re-alloc freeExtents - it'll be free'd shortly */
|
return -1; /* Don't bother to re-alloc freeExtents - it'll be free'd shortly */
|
||||||
|
|
||||||
|
/* first block reported as free, even if it is not */
|
||||||
|
if (dev->freeExtents[dev->nfreeExtent].start == 0) {
|
||||||
|
dev->freeExtents[dev->nfreeExtent].start = SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
pool->def->available +=
|
pool->def->available +=
|
||||||
(dev->freeExtents[dev->nfreeExtent].end -
|
(dev->freeExtents[dev->nfreeExtent].end -
|
||||||
dev->freeExtents[dev->nfreeExtent].start);
|
dev->freeExtents[dev->nfreeExtent].start);
|
||||||
|
@ -255,6 +280,35 @@ virStorageBackendDiskReadPartitions(virConnectPtr conn,
|
||||||
vol);
|
vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendDiskMakePoolGeometry(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
|
virStoragePoolObjPtr pool,
|
||||||
|
size_t ntok ATTRIBUTE_UNUSED,
|
||||||
|
char **const groups,
|
||||||
|
void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
|
||||||
|
pool->def->source.devices[0].geometry.cyliders = atoi(groups[0]);
|
||||||
|
pool->def->source.devices[0].geometry.heads = atoi(groups[1]);
|
||||||
|
pool->def->source.devices[0].geometry.sectors = atoi(groups[2]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendDiskReadGeometry(virConnectPtr conn, virStoragePoolObjPtr pool)
|
||||||
|
{
|
||||||
|
const char *prog[] = {
|
||||||
|
PARTHELPER, pool->def->source.devices[0].path, "-g", NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
return virStorageBackendRunProgNul(conn,
|
||||||
|
pool,
|
||||||
|
prog,
|
||||||
|
3,
|
||||||
|
virStorageBackendDiskMakePoolGeometry,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virStorageBackendDiskRefreshPool(virConnectPtr conn,
|
virStorageBackendDiskRefreshPool(virConnectPtr conn,
|
||||||
|
@ -265,6 +319,10 @@ virStorageBackendDiskRefreshPool(virConnectPtr conn,
|
||||||
|
|
||||||
virStorageBackendWaitForDevices(conn);
|
virStorageBackendWaitForDevices(conn);
|
||||||
|
|
||||||
|
if (virStorageBackendDiskReadGeometry(conn, pool) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return virStorageBackendDiskReadPartitions(conn, pool, NULL);
|
return virStorageBackendDiskReadPartitions(conn, pool, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,46 +352,218 @@ virStorageBackendDiskBuildPool(virConnectPtr conn,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides what kind of partition type that should be created.
|
||||||
|
* Important when the partition table is of msdos type
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
virStorageBackendDiskCreateVol(virConnectPtr conn,
|
virStorageBackendDiskPartTypeToCreate(virStoragePoolObjPtr pool)
|
||||||
virStoragePoolObjPtr pool,
|
|
||||||
virStorageVolDefPtr vol)
|
|
||||||
{
|
{
|
||||||
int i;
|
if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
|
||||||
char start[100], end[100];
|
/* count primary and extended paritions,
|
||||||
unsigned long long startOffset, endOffset, smallestSize = 0;
|
can't be more than 3 to create a new primary partition */
|
||||||
int smallestExtent = -1;
|
int i;
|
||||||
virStoragePoolSourceDevicePtr dev = &pool->def->source.devices[0];
|
int count = 0;
|
||||||
/* XXX customizable partition types */
|
for (i = 0; i < pool->volumes.count; i++) {
|
||||||
const char *cmdargv[] = {
|
if (pool->volumes.objs[i]->target.type == VIR_STORAGE_VOL_DISK_TYPE_PRIMARY ||
|
||||||
PARTED,
|
pool->volumes.objs[i]->target.type == VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) {
|
||||||
pool->def->source.devices[0].path,
|
count++;
|
||||||
"mkpart",
|
}
|
||||||
"--script",
|
}
|
||||||
"ext2",
|
if (count >= 4) {
|
||||||
start,
|
return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL;
|
||||||
end,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0 ; i < dev->nfreeExtent ; i++) {
|
|
||||||
unsigned long long size =
|
|
||||||
dev->freeExtents[i].end -
|
|
||||||
dev->freeExtents[i].start;
|
|
||||||
if (size > vol->allocation &&
|
|
||||||
(smallestSize == 0 ||
|
|
||||||
size < smallestSize)) {
|
|
||||||
smallestSize = size;
|
|
||||||
smallestExtent = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for all other cases, all partitions are primary */
|
||||||
|
return VIR_STORAGE_VOL_DISK_TYPE_PRIMARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendDiskPartFormat(virConnectPtr conn, virStoragePoolObjPtr pool,
|
||||||
|
virStorageVolDefPtr vol,
|
||||||
|
char* partFormat)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
|
||||||
|
const char *partedFormat = virStoragePartedFsTypeTypeToString(vol->target.format);
|
||||||
|
if(partedFormat == NULL) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("Invalid partition type"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (vol->target.format == VIR_STORAGE_VOL_DISK_EXTENDED) {
|
||||||
|
/* make sure we don't have a extended partition already */
|
||||||
|
for (i = 0; i < pool->volumes.count; i++) {
|
||||||
|
if (pool->volumes.objs[i]->target.format == VIR_STORAGE_VOL_DISK_EXTENDED) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("extended partition already exists"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sprintf(partFormat, "%s", partedFormat);
|
||||||
|
} else {
|
||||||
|
/* create primary partition as long as it is possible
|
||||||
|
and after that check if an extended partition exists
|
||||||
|
to create logical partitions. */
|
||||||
|
/* XXX Only support one extended partition */
|
||||||
|
switch (virStorageBackendDiskPartTypeToCreate(pool)) {
|
||||||
|
case VIR_STORAGE_VOL_DISK_TYPE_PRIMARY:
|
||||||
|
sprintf(partFormat, "primary %s", partedFormat);
|
||||||
|
break;
|
||||||
|
case VIR_STORAGE_VOL_DISK_TYPE_LOGICAL:
|
||||||
|
/* make sure we have a extended partition */
|
||||||
|
for (i = 0; i < pool->volumes.count; i++) {
|
||||||
|
if (pool->volumes.objs[i]->target.format == VIR_STORAGE_VOL_DISK_EXTENDED) {
|
||||||
|
sprintf(partFormat, "logical %s", partedFormat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == pool->volumes.count) {
|
||||||
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("no extended partition found and no primary partition available"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(partFormat, "primary");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns a new partition to nearest cylinder boundry
|
||||||
|
* when haveing a msdos partition table type
|
||||||
|
* to avoid any problem with all ready existing
|
||||||
|
* partitions
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virStorageBackendDiskPartBoundries(virConnectPtr conn,
|
||||||
|
virStoragePoolObjPtr pool,
|
||||||
|
unsigned long long *start,
|
||||||
|
unsigned long long *end,
|
||||||
|
unsigned long long allocation)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int smallestExtent = -1;
|
||||||
|
unsigned long long smallestSize = 0;
|
||||||
|
unsigned long long extraBytes = 0;
|
||||||
|
unsigned long long alignedAllocation = allocation;
|
||||||
|
virStoragePoolSourceDevicePtr dev = &pool->def->source.devices[0];
|
||||||
|
unsigned long long cylinderSize = dev->geometry.heads *
|
||||||
|
dev->geometry.sectors * SECTOR_SIZE;
|
||||||
|
|
||||||
|
DEBUG("find free area: allocation %llu, cyl size %llu\n", allocation, cylinderSize);
|
||||||
|
int partType = virStorageBackendDiskPartTypeToCreate(pool);
|
||||||
|
|
||||||
|
/* how many extra bytes we have since we allocate
|
||||||
|
aligned to the cylinder boundry */
|
||||||
|
extraBytes = cylinderSize - (allocation % cylinderSize);
|
||||||
|
|
||||||
|
for (i = 0 ; i < dev->nfreeExtent ; i++) {
|
||||||
|
unsigned long long size =
|
||||||
|
dev->freeExtents[i].end -
|
||||||
|
dev->freeExtents[i].start;
|
||||||
|
unsigned long long neededSize = allocation;
|
||||||
|
|
||||||
|
if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
|
||||||
|
/* align to cylinder boundry */
|
||||||
|
neededSize += extraBytes;
|
||||||
|
if ((*start % cylinderSize) > extraBytes) {
|
||||||
|
/* add an extra cylinder if the offset can't fit within
|
||||||
|
the extra bytes we have */
|
||||||
|
neededSize += cylinderSize;
|
||||||
|
}
|
||||||
|
/* if we are creating a logical patition, we need one extra
|
||||||
|
block between partitions (or actually move start one block) */
|
||||||
|
if (partType == VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) {
|
||||||
|
size -= SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size > neededSize &&
|
||||||
|
(smallestSize == 0 ||
|
||||||
|
size < smallestSize)) {
|
||||||
|
/* for logical partition, the free extent
|
||||||
|
must be within a logical free area */
|
||||||
|
if (partType == VIR_STORAGE_VOL_DISK_TYPE_LOGICAL &&
|
||||||
|
dev->freeExtents[i].type != VIR_STORAGE_FREE_LOGICAL) {
|
||||||
|
continue;
|
||||||
|
/* for primary partition, the free extent
|
||||||
|
must not be within a logical free area */
|
||||||
|
} else if(partType == VIR_STORAGE_VOL_DISK_TYPE_PRIMARY &&
|
||||||
|
dev->freeExtents[i].type != VIR_STORAGE_FREE_NORMAL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
smallestSize = size;
|
||||||
|
smallestExtent = i;
|
||||||
|
alignedAllocation = neededSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (smallestExtent == -1) {
|
if (smallestExtent == -1) {
|
||||||
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("no large enough free extent"));
|
"%s", _("no large enough free extent"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
startOffset = dev->freeExtents[smallestExtent].start;
|
|
||||||
endOffset = startOffset + vol->allocation;
|
DEBUG("aligned alloc %llu\n", alignedAllocation);
|
||||||
|
*start = dev->freeExtents[smallestExtent].start;
|
||||||
|
|
||||||
|
if (partType == VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) {
|
||||||
|
/* for logical partition, skip one block */
|
||||||
|
*start += SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*end = *start + alignedAllocation;
|
||||||
|
if (pool->def->source.format == VIR_STORAGE_POOL_DISK_DOS) {
|
||||||
|
/* adjust our allocation if start is not at a cylinder boundry */
|
||||||
|
*end -= (*start % cylinderSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* counting in byte, we want the last byte of the current sector */
|
||||||
|
*end -= 1;
|
||||||
|
DEBUG("final aligned start %llu, end %llu\n", *start, *end);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageBackendDiskCreateVol(virConnectPtr conn,
|
||||||
|
virStoragePoolObjPtr pool,
|
||||||
|
virStorageVolDefPtr vol)
|
||||||
|
{
|
||||||
|
char start[100], end[100], partFormat[100];
|
||||||
|
unsigned long long startOffset = 0, endOffset = 0;
|
||||||
|
const char *cmdargv[] = {
|
||||||
|
PARTED,
|
||||||
|
pool->def->source.devices[0].path,
|
||||||
|
"mkpart",
|
||||||
|
"--script",
|
||||||
|
partFormat,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
if (virStorageBackendDiskPartFormat(conn, pool, vol, partFormat) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vol->key == NULL) {
|
||||||
|
/* XXX base off a unique key of the underlying disk */
|
||||||
|
if ((vol->key = strdup(vol->target.path)) == NULL) {
|
||||||
|
virReportOOMError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(virStorageBackendDiskPartBoundries(conn, pool, &startOffset, &endOffset, vol->allocation) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(start, sizeof(start)-1, "%lluB", startOffset);
|
snprintf(start, sizeof(start)-1, "%lluB", startOffset);
|
||||||
start[sizeof(start)-1] = '\0';
|
start[sizeof(start)-1] = '\0';
|
||||||
|
@ -343,6 +573,9 @@ virStorageBackendDiskCreateVol(virConnectPtr conn,
|
||||||
if (virRun(conn, cmdargv, NULL) < 0)
|
if (virRun(conn, cmdargv, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* wait for device node to show up */
|
||||||
|
virStorageBackendWaitForDevices(conn);
|
||||||
|
|
||||||
/* Blow away free extent info, as we're about to re-populate it */
|
/* Blow away free extent info, as we're about to re-populate it */
|
||||||
VIR_FREE(pool->def->source.devices[0].freeExtents);
|
VIR_FREE(pool->def->source.devices[0].freeExtents);
|
||||||
pool->def->source.devices[0].nfreeExtent = 0;
|
pool->def->source.devices[0].nfreeExtent = 0;
|
||||||
|
|
|
@ -93,6 +93,12 @@ VIR_ENUM_IMPL(virStorageVolFormatFileSystem,
|
||||||
"cloop", "cow", "dmg", "iso",
|
"cloop", "cow", "dmg", "iso",
|
||||||
"qcow", "qcow2", "vmdk", "vpc")
|
"qcow", "qcow2", "vmdk", "vpc")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virStoragePartedFsType,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LAST,
|
||||||
|
"none", "ext2", "fat16",
|
||||||
|
"fat32", "linux-swap",
|
||||||
|
"ext2", "ext2",
|
||||||
|
"extended")
|
||||||
|
|
||||||
typedef const char *(*virStorageVolFormatToString)(int format);
|
typedef const char *(*virStorageVolFormatToString)(int format);
|
||||||
typedef int (*virStorageVolFormatFromString)(const char *format);
|
typedef int (*virStorageVolFormatFromString)(const char *format);
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct _virStorageVolTarget {
|
||||||
char *path;
|
char *path;
|
||||||
int format;
|
int format;
|
||||||
virStoragePerms perms;
|
virStoragePerms perms;
|
||||||
|
int type; /* only used by disk backend for partition type */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,6 +155,18 @@ struct _virStoragePoolSourceHost {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For MSDOS partitions, the free area
|
||||||
|
* is important when creating
|
||||||
|
* logical partitions
|
||||||
|
*/
|
||||||
|
enum virStorageFreeType {
|
||||||
|
VIR_STORAGE_FREE_NONE = 0,
|
||||||
|
VIR_STORAGE_FREE_NORMAL,
|
||||||
|
VIR_STORAGE_FREE_LOGICAL,
|
||||||
|
VIR_STORAGE_FREE_LAST
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Available extents on the underlying storage
|
* Available extents on the underlying storage
|
||||||
*/
|
*/
|
||||||
|
@ -162,6 +175,7 @@ typedef virStoragePoolSourceDeviceExtent *virStoragePoolSourceDeviceExtentPtr;
|
||||||
struct _virStoragePoolSourceDeviceExtent {
|
struct _virStoragePoolSourceDeviceExtent {
|
||||||
unsigned long long start;
|
unsigned long long start;
|
||||||
unsigned long long end;
|
unsigned long long end;
|
||||||
|
int type; /* free space type */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,6 +190,13 @@ struct _virStoragePoolSourceDevice {
|
||||||
virStoragePoolSourceDeviceExtentPtr freeExtents;
|
virStoragePoolSourceDeviceExtentPtr freeExtents;
|
||||||
char *path;
|
char *path;
|
||||||
int format; /* Pool specific source format */
|
int format; /* Pool specific source format */
|
||||||
|
/* When the source device is a physical disk,
|
||||||
|
the geometry data is needed */
|
||||||
|
struct _geometry {
|
||||||
|
int cyliders;
|
||||||
|
int heads;
|
||||||
|
int sectors;
|
||||||
|
} geometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -443,6 +464,30 @@ enum virStorageVolFormatDisk {
|
||||||
};
|
};
|
||||||
VIR_ENUM_DECL(virStorageVolFormatDisk)
|
VIR_ENUM_DECL(virStorageVolFormatDisk)
|
||||||
|
|
||||||
|
enum virStorageVolTypeDisk {
|
||||||
|
VIR_STORAGE_VOL_DISK_TYPE_NONE = 0,
|
||||||
|
VIR_STORAGE_VOL_DISK_TYPE_PRIMARY,
|
||||||
|
VIR_STORAGE_VOL_DISK_TYPE_LOGICAL,
|
||||||
|
VIR_STORAGE_VOL_DISK_TYPE_EXTENDED,
|
||||||
|
VIR_STORAGE_VOL_DISK_TYPE_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mapping of Parted fs-types
|
||||||
|
* MUST be kept in the same order
|
||||||
|
* as virStorageVolFormatDisk
|
||||||
|
*/
|
||||||
|
enum virStoragePartedFsType {
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_NONE = 0,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LINUX,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_FAT16,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_FAT32,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LINUX_SWAP,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LINUX_LVM,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LINUX_RAID,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_EXTENDED,
|
||||||
|
VIR_STORAGE_PARTED_FS_TYPE_LAST,
|
||||||
|
};
|
||||||
|
VIR_ENUM_DECL(virStoragePartedFsType)
|
||||||
|
|
||||||
#endif /* __VIR_STORAGE_CONF_H__ */
|
#endif /* __VIR_STORAGE_CONF_H__ */
|
||||||
|
|
Loading…
Reference in New Issue