diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 2bd924133d..ae3d95a4c4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1372,6 +1372,11 @@
<blockio logical_block_size='512' physical_block_size='4096'/>
<target dev='hda' bus='ide'/>
</disk>
+ <disk type='volume' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source pool='blk-pool0' volume='blk-pool0-vol0'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
</devices>
...
@@ -1452,10 +1457,16 @@
iqn.1992-01.com.example/1
); the default LUN is zero.
When the disk type
is "network", the source
may have zero or more host
sub-elements used to
- specify the hosts to connect.
+ specify the hosts to connect. If the disk type
is
+ "volume", the underlying disk source is represented by attributes
+ pool
and volume
. Attribute pool
+ specifies the name of storage pool (managed by libvirt) where the disk
+ source resides, and attribute volume
specifies the name of
+ storage volume (managed by libvirt) used as the disk source.
Since 0.0.3; type='dir'
since
0.7.5; type='network'
since
- 0.8.7; protocol='iscsi'
since 1.0.4
+ 0.8.7; protocol='iscsi'
since 1.0.4;
+ type='volume'
since 1.0.5;
For a "file" disk type which represents a cdrom or floppy
(the device
attribute), it is possible to define
policy what to do with the disk if the source file is not accessible.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d486ae8b34..5ee3261bd9 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1107,6 +1107,24 @@
+
+
+ volume
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ebf4bdb4d7..8f0d872973 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -210,7 +210,8 @@ VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block",
"file",
"dir",
- "network")
+ "network",
+ "volume")
VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
"disk",
@@ -1116,6 +1117,18 @@ void virDomainLeaseDefFree(virDomainLeaseDefPtr def)
VIR_FREE(def);
}
+static void
+virDomainDiskSourcePoolDefFree(virDomainDiskSourcePoolDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->pool);
+ VIR_FREE(def->volume);
+
+ VIR_FREE(def);
+}
+
void virDomainDiskDefFree(virDomainDiskDefPtr def)
{
unsigned int i;
@@ -1125,6 +1138,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->serial);
VIR_FREE(def->src);
+ virDomainDiskSourcePoolDefFree(def->srcpool);
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
virStorageFileFreeMetadata(def->backingChain);
@@ -4157,6 +4171,46 @@ cleanup:
goto cleanup;
}
+static int
+virDomainDiskSourcePoolDefParse(xmlNodePtr node,
+ virDomainDiskDefPtr def)
+{
+ char *pool = NULL;
+ char *volume = NULL;
+ int ret = -1;
+
+ pool = virXMLPropString(node, "pool");
+ volume = virXMLPropString(node, "volume");
+
+ /* CD-ROM and Floppy allows no source */
+ if (!pool && !volume)
+ return 0;
+
+ if (!pool || !volume) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("'pool' and 'volume' must be specified together "
+ "for 'pool' type source"));
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(def->srcpool) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ def->srcpool->pool = pool;
+ pool = NULL;
+ def->srcpool->volume = volume;
+ volume = NULL;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(pool);
+ VIR_FREE(volume);
+ return ret;
+}
+
#define VENDOR_LEN 8
#define PRODUCT_LEN 16
@@ -4252,7 +4306,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
- if (!source && !hosts &&
+ if (!source && !hosts && !def->srcpool &&
xmlStrEqual(cur->name, BAD_CAST "source")) {
sourceNode = cur;
@@ -4345,6 +4399,10 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
child = child->next;
}
break;
+ case VIR_DOMAIN_DISK_TYPE_VOLUME:
+ if (virDomainDiskSourcePoolDefParse(cur, def) < 0)
+ goto error;
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
@@ -4643,7 +4701,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
/* Only CDROM and Floppy devices are allowed missing source path
* to indicate no media present */
- if (source == NULL && hosts == NULL &&
+ if (source == NULL && hosts == NULL && !def->srcpool &&
def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
virReportError(VIR_ERR_NO_SOURCE,
@@ -4665,8 +4723,19 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
}
if (target == NULL) {
- virReportError(VIR_ERR_NO_TARGET,
- source ? "%s" : NULL, source);
+ if (def->srcpool) {
+ char *tmp;
+ if (virAsprintf(&tmp, "pool = '%s', volume = '%s'",
+ def->srcpool->pool, def->srcpool->volume) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ virReportError(VIR_ERR_NO_TARGET, "%s", tmp);
+ VIR_FREE(tmp);
+ } else {
+ virReportError(VIR_ERR_NO_TARGET, source ? "%s" : NULL, source);
+ }
goto error;
}
@@ -12877,7 +12946,7 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
int n;
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
- if (def->src || def->nhosts > 0 ||
+ if (def->src || def->nhosts > 0 || def->srcpool ||
def->startupPolicy) {
switch (def->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
@@ -12949,6 +13018,14 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " \n");
}
break;
+ case VIR_DOMAIN_DISK_TYPE_VOLUME:
+ /* Parsing guarantees the def->srcpool->volume cannot be NULL
+ * if def->srcpool->pool is not NULL.
+ */
+ if (def->srcpool->pool)
+ virBufferAsprintf(buf, " \n",
+ def->srcpool->pool, def->srcpool->volume);
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 75e3f1500f..230f0a5e27 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -447,6 +447,7 @@ enum virDomainDiskType {
VIR_DOMAIN_DISK_TYPE_FILE,
VIR_DOMAIN_DISK_TYPE_DIR,
VIR_DOMAIN_DISK_TYPE_NETWORK,
+ VIR_DOMAIN_DISK_TYPE_VOLUME,
VIR_DOMAIN_DISK_TYPE_LAST
};
@@ -606,6 +607,13 @@ struct _virDomainBlockIoTuneInfo {
};
typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr;
+typedef struct _virDomainDiskSourcePoolDef virDomainDiskSourcePoolDef;
+struct _virDomainDiskSourcePoolDef {
+ char *pool; /* pool name */
+ char *volume; /* volume name */
+};
+typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr;
+
/* Stores the virtual disk configuration */
struct _virDomainDiskDef {
int type;
@@ -617,6 +625,7 @@ struct _virDomainDiskDef {
int protocol;
size_t nhosts;
virDomainDiskHostDefPtr hosts;
+ virDomainDiskSourcePoolDefPtr srcpool;
struct {
char *username;
int secretType; /* enum virDomainDiskSecretType */
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
new file mode 100644
index 0000000000..876eebeee4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-source-pool.xml
@@ -0,0 +1,33 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 10a6ea2963..200d41a160 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -253,6 +253,7 @@ mymain(void)
DO_TEST("disk-scsi-lun-passthrough-sgio");
DO_TEST("disk-scsi-disk-vpd");
+ DO_TEST("disk-source-pool");
DO_TEST("virtio-rng-random");
DO_TEST("virtio-rng-egd");