mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-03 11:51:11 +00:00
xenconfig: support xl<->xml conversion of rbd disk devices
The target= setting in xl disk configuration can be used to encode meta info that is meaningful to a backend. Leverage this fact to support qdisk network disk types such as rbd. E.g. <disk> config such as <disk type='network' device='disk'> <driver name='qemu' type='raw'/> <source protocol='rbd' name='pool/image'> <host name='mon1.example.org' port='6321'/> <host name='mon2.example.org' port='6322'/> <host name='mon3.example.org' port='6322'/> </source> <target dev='hdb' bus='ide'/> <address type='drive' controller='0' bus='0' target='0' unit='1'/> </disk> can be converted to the following xl config (and vice versa) disk = [ "format=raw,vdev=hdb,access=rw,backendtype=qdisk, target=rbd:pool/image:auth_supported=none:mon_host=mon1.example.org\\:6321\\;mon2.example.org\\:6322\\;mon3.example.org\\:6322" ] Note that in xl disk config, a literal backslash in target= must be escaped with a backslash. Conversion of <auth> config is not handled in this patch, but can be done in a follow-up patch. Also add a test for the conversions. Signed-off-by: Jim Fehlig <jfehlig@suse.com>
This commit is contained in:
parent
a44f1f85f9
commit
6604a3dd9f
@ -246,6 +246,32 @@ xenParseXLSpice(virConfPtr conf, virDomainDefPtr def)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
xenParseXLDiskSrc(virDomainDiskDefPtr disk, char *srcstr)
|
||||||
|
{
|
||||||
|
char *tmpstr = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (STRPREFIX(srcstr, "rbd:")) {
|
||||||
|
tmpstr = virStringReplace(srcstr, "\\\\", "\\");
|
||||||
|
|
||||||
|
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_NETWORK);
|
||||||
|
disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
|
||||||
|
ret = virStorageSourceParseRBDColonString(tmpstr, disk->src);
|
||||||
|
} else {
|
||||||
|
if (virDomainDiskSetSource(disk, srcstr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(tmpstr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For details on xl disk config syntax, see
|
* For details on xl disk config syntax, see
|
||||||
* docs/misc/xl-disk-configuration.txt in the Xen sources. The important
|
* docs/misc/xl-disk-configuration.txt in the Xen sources. The important
|
||||||
@ -311,10 +337,10 @@ xenParseXLDisk(virConfPtr conf, virDomainDefPtr def)
|
|||||||
if (!(disk = virDomainDiskDefNew(NULL)))
|
if (!(disk = virDomainDiskDefNew(NULL)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (VIR_STRDUP(disk->dst, libxldisk->vdev) < 0)
|
if (xenParseXLDiskSrc(disk, libxldisk->pdev_path) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (virDomainDiskSetSource(disk, libxldisk->pdev_path) < 0)
|
if (VIR_STRDUP(disk->dst, libxldisk->vdev) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
disk->src->readonly = !libxldisk->readwrite;
|
disk->src->readonly = !libxldisk->readwrite;
|
||||||
@ -358,7 +384,8 @@ xenParseXLDisk(virConfPtr conf, virDomainDefPtr def)
|
|||||||
case LIBXL_DISK_BACKEND_UNKNOWN:
|
case LIBXL_DISK_BACKEND_UNKNOWN:
|
||||||
if (virDomainDiskSetDriver(disk, "qemu") < 0)
|
if (virDomainDiskSetDriver(disk, "qemu") < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
|
if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_NONE)
|
||||||
|
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBXL_DISK_BACKEND_TAP:
|
case LIBXL_DISK_BACKEND_TAP:
|
||||||
@ -578,14 +605,115 @@ xenFormatXLOS(virConfPtr conf, virDomainDefPtr def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
xenFormatXLDiskSrcNet(virStorageSourcePtr src)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
switch ((virStorageNetProtocol) src->protocol) {
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_NBD:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_HTTP:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_HTTPS:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_FTP:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_FTPS:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_TFTP:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_LAST:
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_NONE:
|
||||||
|
virReportError(VIR_ERR_NO_SUPPORT,
|
||||||
|
_("Unsupported network block protocol '%s'"),
|
||||||
|
virStorageNetProtocolTypeToString(src->protocol));
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
case VIR_STORAGE_NET_PROTOCOL_RBD:
|
||||||
|
if (strchr(src->path, ':')) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("':' not allowed in RBD source volume name '%s'"),
|
||||||
|
src->path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferStrcat(&buf, "rbd:", src->path, NULL);
|
||||||
|
|
||||||
|
virBufferAddLit(&buf, ":auth_supported=none");
|
||||||
|
|
||||||
|
if (src->nhosts > 0) {
|
||||||
|
virBufferAddLit(&buf, ":mon_host=");
|
||||||
|
for (i = 0; i < src->nhosts; i++) {
|
||||||
|
if (i)
|
||||||
|
virBufferAddLit(&buf, "\\\\;");
|
||||||
|
|
||||||
|
/* assume host containing : is ipv6 */
|
||||||
|
if (strchr(src->hosts[i].name, ':'))
|
||||||
|
virBufferEscape(&buf, '\\', ":", "[%s]",
|
||||||
|
src->hosts[i].name);
|
||||||
|
else
|
||||||
|
virBufferAsprintf(&buf, "%s", src->hosts[i].name);
|
||||||
|
|
||||||
|
if (src->hosts[i].port)
|
||||||
|
virBufferAsprintf(&buf, "\\\\:%s", src->hosts[i].port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferCheckError(&buf) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = virBufferContentAndReset(&buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virBufferFreeAndReset(&buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
xenFormatXLDiskSrc(virStorageSourcePtr src, char **srcstr)
|
||||||
|
{
|
||||||
|
int actualType = virStorageSourceGetActualType(src);
|
||||||
|
|
||||||
|
*srcstr = NULL;
|
||||||
|
|
||||||
|
if (virStorageSourceIsEmpty(src))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch ((virStorageType) actualType) {
|
||||||
|
case VIR_STORAGE_TYPE_BLOCK:
|
||||||
|
case VIR_STORAGE_TYPE_FILE:
|
||||||
|
case VIR_STORAGE_TYPE_DIR:
|
||||||
|
if (VIR_STRDUP(*srcstr, src->path) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_STORAGE_TYPE_NETWORK:
|
||||||
|
if (!(*srcstr = xenFormatXLDiskSrcNet(src)))
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_STORAGE_TYPE_VOLUME:
|
||||||
|
case VIR_STORAGE_TYPE_NONE:
|
||||||
|
case VIR_STORAGE_TYPE_LAST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
virConfValuePtr val, tmp;
|
virConfValuePtr val, tmp;
|
||||||
const char *src = virDomainDiskGetSource(disk);
|
|
||||||
int format = virDomainDiskGetFormat(disk);
|
int format = virDomainDiskGetFormat(disk);
|
||||||
const char *driver = virDomainDiskGetDriver(disk);
|
const char *driver = virDomainDiskGetDriver(disk);
|
||||||
|
char *target = NULL;
|
||||||
|
|
||||||
/* format */
|
/* format */
|
||||||
virBufferAddLit(&buf, "format=");
|
virBufferAddLit(&buf, "format=");
|
||||||
@ -637,8 +765,18 @@ xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
|||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
||||||
virBufferAddLit(&buf, "devtype=cdrom,");
|
virBufferAddLit(&buf, "devtype=cdrom,");
|
||||||
|
|
||||||
/* target */
|
/*
|
||||||
virBufferAsprintf(&buf, "target=%s", src);
|
* target
|
||||||
|
* From $xensrc/docs/misc/xl-disk-configuration.txt:
|
||||||
|
* When this parameter is specified by name, ie with the "target="
|
||||||
|
* syntax in the configuration file, it consumes the whole rest of the
|
||||||
|
* <diskspec> including trailing whitespaces. Therefore in that case
|
||||||
|
* it must come last.
|
||||||
|
*/
|
||||||
|
if (xenFormatXLDiskSrc(disk->src, &target) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
virBufferAsprintf(&buf, "target=%s", target);
|
||||||
|
|
||||||
if (virBufferCheckError(&buf) < 0)
|
if (virBufferCheckError(&buf) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -658,6 +796,7 @@ xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
VIR_FREE(target);
|
||||||
virBufferFreeAndReset(&buf);
|
virBufferFreeAndReset(&buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
26
tests/xlconfigdata/test-rbd-multihost-noauth.cfg
Normal file
26
tests/xlconfigdata/test-rbd-multihost-noauth.cfg
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
name = "XenGuest2"
|
||||||
|
uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
|
||||||
|
maxmem = 579
|
||||||
|
memory = 394
|
||||||
|
vcpus = 1
|
||||||
|
pae = 1
|
||||||
|
acpi = 1
|
||||||
|
apic = 1
|
||||||
|
hap = 0
|
||||||
|
viridian = 0
|
||||||
|
rtc_timeoffset = 0
|
||||||
|
localtime = 0
|
||||||
|
on_poweroff = "destroy"
|
||||||
|
on_reboot = "restart"
|
||||||
|
on_crash = "restart"
|
||||||
|
device_model = "/usr/lib/xen/bin/qemu-dm"
|
||||||
|
sdl = 0
|
||||||
|
vnc = 1
|
||||||
|
vncunused = 1
|
||||||
|
vnclisten = "127.0.0.1"
|
||||||
|
vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
|
||||||
|
parallel = "none"
|
||||||
|
serial = "none"
|
||||||
|
builder = "hvm"
|
||||||
|
boot = "d"
|
||||||
|
disk = [ "format=raw,vdev=hda,access=rw,backendtype=phy,target=/dev/HostVG/XenGuest2", "format=raw,vdev=hdb,access=rw,backendtype=qdisk,target=rbd:pool/image:auth_supported=none:mon_host=mon1.example.org\\:6321\\;mon2.example.org\\:6322\\;mon3.example.org\\:6322" ]
|
52
tests/xlconfigdata/test-rbd-multihost-noauth.xml
Normal file
52
tests/xlconfigdata/test-rbd-multihost-noauth.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<domain type='xen'>
|
||||||
|
<name>XenGuest2</name>
|
||||||
|
<uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>592896</memory>
|
||||||
|
<currentMemory unit='KiB'>403456</currentMemory>
|
||||||
|
<vcpu placement='static'>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='xenfv'>hvm</type>
|
||||||
|
<loader type='rom'>/usr/lib/xen/boot/hvmloader</loader>
|
||||||
|
<boot dev='cdrom'/>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
<apic/>
|
||||||
|
<pae/>
|
||||||
|
</features>
|
||||||
|
<clock offset='variable' adjustment='0' basis='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>restart</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<driver name='phy' type='raw'/>
|
||||||
|
<source dev='/dev/HostVG/XenGuest2'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<disk type='network' device='disk'>
|
||||||
|
<driver name='qemu' type='raw'/>
|
||||||
|
<source protocol='rbd' name='pool/image'>
|
||||||
|
<host name='mon1.example.org' port='6321'/>
|
||||||
|
<host name='mon2.example.org' port='6322'/>
|
||||||
|
<host name='mon3.example.org' port='6322'/>
|
||||||
|
</source>
|
||||||
|
<target dev='hdb' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<mac address='00:16:3e:66:92:9c'/>
|
||||||
|
<source bridge='xenbr1'/>
|
||||||
|
<script path='vif-bridge'/>
|
||||||
|
<model type='e1000'/>
|
||||||
|
</interface>
|
||||||
|
<input type='mouse' bus='ps2'/>
|
||||||
|
<input type='keyboard' bus='ps2'/>
|
||||||
|
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'>
|
||||||
|
<listen type='address' address='127.0.0.1'/>
|
||||||
|
</graphics>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -217,6 +217,7 @@ mymain(void)
|
|||||||
DO_TEST("paravirt-cmdline");
|
DO_TEST("paravirt-cmdline");
|
||||||
DO_TEST_FORMAT("paravirt-cmdline-extra-root");
|
DO_TEST_FORMAT("paravirt-cmdline-extra-root");
|
||||||
DO_TEST_FORMAT("paravirt-cmdline-bogus-extra-root");
|
DO_TEST_FORMAT("paravirt-cmdline-bogus-extra-root");
|
||||||
|
DO_TEST("rbd-multihost-noauth");
|
||||||
|
|
||||||
#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
|
#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
|
||||||
DO_TEST("fullvirt-multiusb");
|
DO_TEST("fullvirt-multiusb");
|
||||||
|
Loading…
Reference in New Issue
Block a user