Starting from qemu 2.9, more granular options are supported. Add parser
for the relevant bits.
With this patch libvirt is able to parse the host and target IQN of from
the JSON pseudo-protocol specification.
This corresponds to BlockdevOptionsIscsi in qemu qapi.
---
Notes:
v2:
- parse 'port' from the portal string
- treat 'lun' as an integer in json
src/util/virstoragefile.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---
tests/virstoragetest.c | 19 ++++++++++++++
2 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 0bbbba650..8e6631b45 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2935,18 +2935,73 @@ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
virJSONValuePtr json,
int opaque ATTRIBUTE_UNUSED)
{
+ const char *transport = virJSONValueObjectGetString(json, "transport");
+ const char *portal = virJSONValueObjectGetString(json, "portal");
+ const char *target = virJSONValueObjectGetString(json, "target");
const char *uri;
+ char *port;
+ unsigned int lun = 0;
+ char *fulltarget = NULL;
+ int ret = -1;
/* legacy URI based syntax passed via 'filename' option */
if ((uri = virJSONValueObjectGetString(json, "filename")))
return virStorageSourceParseBackingJSONUriStr(src, uri,
VIR_STORAGE_NET_PROTOCOL_ISCSI);
- /* iSCSI currently supports only URI syntax passed in as filename */
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("missing iSCSI URI in JSON backing volume definition"));
+ src->type = VIR_STORAGE_TYPE_NETWORK;
+ src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
- return -1;
+ if (VIR_ALLOC(src->hosts) < 0)
+ goto cleanup;
+
+ src->nhosts = 1;
+
+ if (STRNEQ_NULLABLE(transport, "tcp")) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("only TCP transport is supported for iSCSI
volumes"));
+ goto cleanup;
+ }
+
+ src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+
+ if (!portal) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("missing 'portal' address in iSCSI backing
definition"));
+ goto cleanup;
+ }
+
+ if (!target) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("missing 'target' in iSCSI backing
definition"));
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP(src->hosts->name, portal) < 0)
+ goto cleanup;
+
+ if ((port = strchr(src->hosts->name, ':'))) {
+ if (VIR_STRDUP(src->hosts->port, port + 1) < 0)
+ goto cleanup;
+
+ if (strlen(src->hosts->port) == 0)
+ VIR_FREE(src->hosts->port);
+
+ *port = '\0';
+ }
+
+ ignore_value(virJSONValueObjectGetNumberUint(json, "lun", &lun));
+
+ if (virAsprintf(&fulltarget, "%s/%u", target, lun) < 0)
+ goto cleanup;
+
+ VIR_STEAL_PTR(src->path, fulltarget);
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(fulltarget);
+ return ret;
}
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index 117208289..894f78ba9 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1502,6 +1502,25 @@ mymain(void)
"\"driver\":
\"file\","
"\"filename\":
\"/path/to/file\" } } }",
"<source file='/path/to/file'/>\n");
+
TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"iscsi\","
+
"\"transport\":\"tcp\","
+
"\"portal\":\"test.org\","
+
"\"target\":\"iqn.2016-12.com.virttest:emulated-iscsi-noauth.target\""
+ "}"
+ "}",
+ "<source protocol='iscsi'
name='iqn.2016-12.com.virttest:emulated-iscsi-noauth.target/0'>\n"
+ " <host name='test.org'/>\n"
+ "</source>\n");
+
TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"iscsi\","
+
"\"transport\":\"tcp\","
+
"\"portal\":\"test.org:1234\","
+
"\"target\":\"iqn.2016-12.com.virttest:emulated-iscsi-noauth.target\","
+ "\"lun\":6"
+ "}"
+ "}",
+ "<source protocol='iscsi'
name='iqn.2016-12.com.virttest:emulated-iscsi-noauth.target/6'>\n"
+ " <host name='test.org'
port='1234'/>\n"
+ "</source>\n");
cleanup:
/* Final cleanup */
--
2.12.2