mirror of https://gitee.com/openkylin/libvirt.git
qemu: Add support for gluster protocol based network storage backend.
Qemu accepts gluster protocol as supported storage backend beside others. Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
This commit is contained in:
parent
a2d2b80fbd
commit
c33c36d28f
|
@ -346,6 +346,7 @@ virDomainDiskErrorPolicyTypeToString;
|
||||||
virDomainDiskFindControllerModel;
|
virDomainDiskFindControllerModel;
|
||||||
virDomainDiskGeometryTransTypeFromString;
|
virDomainDiskGeometryTransTypeFromString;
|
||||||
virDomainDiskGeometryTransTypeToString;
|
virDomainDiskGeometryTransTypeToString;
|
||||||
|
virDomainDiskHostDefFree;
|
||||||
virDomainDiskIndexByName;
|
virDomainDiskIndexByName;
|
||||||
virDomainDiskInsert;
|
virDomainDiskInsert;
|
||||||
virDomainDiskInsertPreAlloced;
|
virDomainDiskInsertPreAlloced;
|
||||||
|
|
|
@ -2040,6 +2040,144 @@ no_memory:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuParseGlusterString(virDomainDiskDefPtr def)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *transp = NULL;
|
||||||
|
char *sock = NULL;
|
||||||
|
char *volimg = NULL;
|
||||||
|
virURIPtr uri = NULL;
|
||||||
|
|
||||||
|
if (!(uri = virURIParse(def->src))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(def->hosts) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (STREQ(uri->scheme, "gluster")) {
|
||||||
|
def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
|
||||||
|
} else if (STRPREFIX(uri->scheme, "gluster+")) {
|
||||||
|
transp = strchr(uri->scheme, '+') + 1;
|
||||||
|
def->hosts->transport = virDomainDiskProtocolTransportTypeFromString(transp);
|
||||||
|
if (def->hosts->transport < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid gluster transport type '%s'"), transp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid transport/scheme '%s'"), uri->scheme);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->nhosts = 0; /* set to 1 once everything succeeds */
|
||||||
|
|
||||||
|
if (def->hosts->transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) {
|
||||||
|
def->hosts->name = strdup(uri->server);
|
||||||
|
if (!def->hosts->name)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (virAsprintf(&def->hosts->port, "%d", uri->port) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
} else {
|
||||||
|
def->hosts->name = NULL;
|
||||||
|
def->hosts->port = 0;
|
||||||
|
if (uri->query) {
|
||||||
|
if (STRPREFIX(uri->query, "socket=")) {
|
||||||
|
sock = strchr(uri->query, '=') + 1;
|
||||||
|
def->hosts->socket = strdup(sock);
|
||||||
|
if (!def->hosts->socket)
|
||||||
|
goto no_memory;
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid query parameter '%s'"), uri->query);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
volimg = uri->path + 1; /* skip the prefix slash */
|
||||||
|
def->src = strdup(volimg);
|
||||||
|
if (!def->src)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
def->nhosts = 1;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virURIFree(uri);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
virReportOOMError();
|
||||||
|
error:
|
||||||
|
virDomainDiskHostDefFree(def->hosts);
|
||||||
|
VIR_FREE(def->hosts);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
int port = 0;
|
||||||
|
char *tmpscheme = NULL;
|
||||||
|
char *volimg = NULL;
|
||||||
|
char *sock = NULL;
|
||||||
|
char *builturi = NULL;
|
||||||
|
const char *transp = NULL;
|
||||||
|
virURI uri = {
|
||||||
|
.port = port /* just to clear rest of bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
if (disk->nhosts != 1) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("gluster accepts only one host"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAddLit(opt, "file=");
|
||||||
|
transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
|
||||||
|
|
||||||
|
if (virAsprintf(&tmpscheme, "gluster+%s", transp) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (virAsprintf(&volimg, "/%s", disk->src) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (disk->hosts->port) {
|
||||||
|
port = atoi(disk->hosts->port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disk->hosts->socket &&
|
||||||
|
virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
uri.scheme = tmpscheme; /* gluster+<transport> */
|
||||||
|
uri.server = disk->hosts->name;
|
||||||
|
uri.port = port;
|
||||||
|
uri.path = volimg;
|
||||||
|
uri.query = sock;
|
||||||
|
|
||||||
|
builturi = virURIFormat(&uri);
|
||||||
|
virBufferEscape(opt, ',', ",", "%s", builturi);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(builturi);
|
||||||
|
VIR_FREE(tmpscheme);
|
||||||
|
VIR_FREE(volimg);
|
||||||
|
VIR_FREE(sock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
@ -2180,6 +2318,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
goto error;
|
goto error;
|
||||||
virBufferAddChar(&opt, ',');
|
virBufferAddChar(&opt, ',');
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
|
||||||
|
if (qemuBuildGlusterString(disk, &opt) < 0)
|
||||||
|
goto error;
|
||||||
|
virBufferAddChar(&opt, ',');
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
|
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
|
||||||
if (disk->nhosts == 0) {
|
if (disk->nhosts == 0) {
|
||||||
virBufferEscape(&opt, ',', ",", "file=sheepdog:%s,",
|
virBufferEscape(&opt, ',', ",", "file=sheepdog:%s,",
|
||||||
|
@ -5667,6 +5811,18 @@ qemuBuildCommandLine(virConnectPtr conn,
|
||||||
file = virBufferContentAndReset(&opt);
|
file = virBufferContentAndReset(&opt);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
|
||||||
|
{
|
||||||
|
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
||||||
|
if (qemuBuildGlusterString(disk, &opt) < 0)
|
||||||
|
goto error;
|
||||||
|
if (virBufferError(&opt)) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
file = virBufferContentAndReset(&opt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
|
case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
|
||||||
if (disk->nhosts == 0) {
|
if (disk->nhosts == 0) {
|
||||||
if (virAsprintf(&file, "sheepdog:%s,", disk->src) < 0) {
|
if (virAsprintf(&file, "sheepdog:%s,", disk->src) < 0) {
|
||||||
|
@ -7074,6 +7230,12 @@ qemuParseCommandLineDisk(virCapsPtr caps,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
VIR_FREE(p);
|
VIR_FREE(p);
|
||||||
|
} else if (STRPREFIX(def->src, "gluster")) {
|
||||||
|
def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
||||||
|
def->protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER;
|
||||||
|
|
||||||
|
if (qemuParseGlusterString(def) < 0)
|
||||||
|
goto cleanup;
|
||||||
} else if (STRPREFIX(def->src, "sheepdog:")) {
|
} else if (STRPREFIX(def->src, "sheepdog:")) {
|
||||||
char *p = def->src;
|
char *p = def->src;
|
||||||
char *port, *vdi;
|
char *port, *vdi;
|
||||||
|
@ -8299,6 +8461,9 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
||||||
disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
||||||
disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_RBD;
|
disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_RBD;
|
||||||
val += strlen("rbd:");
|
val += strlen("rbd:");
|
||||||
|
} else if (STRPREFIX(val, "gluster")) {
|
||||||
|
disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
||||||
|
disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER;
|
||||||
} else if (STRPREFIX(val, "sheepdog:")) {
|
} else if (STRPREFIX(val, "sheepdog:")) {
|
||||||
disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
disk->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
||||||
disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
|
disk->protocol = VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG;
|
||||||
|
@ -8384,6 +8549,11 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
|
||||||
|
if (qemuParseGlusterString(disk) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue