mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-08 16:54:49 +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;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
* 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)))
|
||||
goto fail;
|
||||
|
||||
if (VIR_STRDUP(disk->dst, libxldisk->vdev) < 0)
|
||||
if (xenParseXLDiskSrc(disk, libxldisk->pdev_path) < 0)
|
||||
goto fail;
|
||||
|
||||
if (virDomainDiskSetSource(disk, libxldisk->pdev_path) < 0)
|
||||
if (VIR_STRDUP(disk->dst, libxldisk->vdev) < 0)
|
||||
goto fail;
|
||||
|
||||
disk->src->readonly = !libxldisk->readwrite;
|
||||
@ -358,7 +384,8 @@ xenParseXLDisk(virConfPtr conf, virDomainDefPtr def)
|
||||
case LIBXL_DISK_BACKEND_UNKNOWN:
|
||||
if (virDomainDiskSetDriver(disk, "qemu") < 0)
|
||||
goto fail;
|
||||
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
|
||||
if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_NONE)
|
||||
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
|
||||
break;
|
||||
|
||||
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
|
||||
xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
virConfValuePtr val, tmp;
|
||||
const char *src = virDomainDiskGetSource(disk);
|
||||
int format = virDomainDiskGetFormat(disk);
|
||||
const char *driver = virDomainDiskGetDriver(disk);
|
||||
char *target = NULL;
|
||||
|
||||
/* format */
|
||||
virBufferAddLit(&buf, "format=");
|
||||
@ -637,8 +765,18 @@ xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_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)
|
||||
goto cleanup;
|
||||
@ -658,6 +796,7 @@ xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(target);
|
||||
virBufferFreeAndReset(&buf);
|
||||
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_FORMAT("paravirt-cmdline-extra-root");
|
||||
DO_TEST_FORMAT("paravirt-cmdline-bogus-extra-root");
|
||||
DO_TEST("rbd-multihost-noauth");
|
||||
|
||||
#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
|
||||
DO_TEST("fullvirt-multiusb");
|
||||
|
Loading…
Reference in New Issue
Block a user