Our code allows snapshots of NVMe based disks which means we create overlay file with a 'json:{}' pseudo-uri refering to the NVME device. Our parser code doesn't handle them though. Add the parser and test it via the XML->json->XML round-trip and reference data. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/util/virstoragefile.c | 30 ++++++++++++++++++++++++++++++ tests/qemublocktest.c | 5 +++++ tests/virstoragetest.c | 9 +++++++++ 3 files changed, 44 insertions(+) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index fa04ff74e1..d81ed70a97 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3806,6 +3806,35 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src, } +static int +virStorageSourceParseBackingJSONNVMe(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + g_autoptr(virStorageSourceNVMeDef) nvme = g_new0(virStorageSourceNVMeDef, 1); + const char *device = virJSONValueObjectGetString(json, "device"); + + if (!device || virPCIDeviceAddressParse((char *) device, &nvme->pciAddr) < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'device' field of 'nvme' storage")); + return -1; + } + + if (virJSONValueObjectGetNumberUlong(json, "namespace", &nvme->namespc) < 0 || + nvme->namespc == 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'namespace' field of 'nvme' storage")); + return -1; + } + + src->type = VIR_STORAGE_TYPE_NVME; + src->nvme = g_steal_pointer(&nvme); + + return 0; +} + + struct virStorageSourceJSONDriverParser { const char *drvname; bool formatdriver; @@ -3837,6 +3866,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = { {"rbd", false, virStorageSourceParseBackingJSONRBD, 0}, {"raw", true, virStorageSourceParseBackingJSONRaw, 0}, {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0}, + {"nvme", false, virStorageSourceParseBackingJSONNVMe, 0}, }; diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 8640b72116..124eaea752 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1096,6 +1096,11 @@ mymain(void) /* type VIR_STORAGE_TYPE_BLOCK is not tested since it parses back to 'file' */ /* type VIR_STORAGE_TYPE_DIR it is a 'format' driver in qemu */ + TEST_JSON_FORMAT(VIR_STORAGE_TYPE_NVME, + "<source type='pci' namespace='1'>\n" + " <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n" + "</source>\n"); + TEST_JSON_FORMAT_NET("<source protocol='http' name=''>\n" " <host name='example.com' port='80'/>\n" "</source>\n"); diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 209d0c37d3..10d5421150 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -1656,6 +1656,15 @@ mymain(void) " <timeout seconds='2000'/>\n" "</source>\n", 0); + TEST_BACKING_PARSE("json:{\"file\":{\"driver\": \"nvme\"," + "\"device\": \"0000:01:00.0\"," + "\"namespace\": 1" + "}" + "}", + "<source type='pci' namespace='1'>\n" + " <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n" + "</source>\n"); + #endif /* WITH_YAJL */ cleanup: -- 2.24.1