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" + " \n" + "\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" + " \n" + "\n"); cleanup: /* Final cleanup */