diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 0bbbba650cc9207f0993b760ad32ba9724b3d824..8e6631b459de6ce6afdfd056c36c39258e7cfcdd 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 11720828934e01e03d62a83295d2b4dd8d1776a8..894f78ba9bfb3a336f3036362361f3cc1f4924f0 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1502,6 +1502,25 @@ mymain(void)
"\"driver\": \"file\","
"\"filename\": \"/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\""
+ "}"
+ "}",
+ "\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"
+ "}"
+ "}",
+ "\n");
cleanup:
/* Final cleanup */