[libvirt PATCHv1 0/4] qemu: support unmanaged virtiofsd

Connect the vhost-user-fs device to a socket path configured in the XML. Starting and stopping the virtiofsd daemon on that socket is the user's responsibility. Ján Tomko (4): conf: fs: fill out accessmode in post-parse conf: fs: allow missing accessmode in the formatter conf: add socket for virtiofs filesystems qemu: add socket for virtiofs filesystems docs/schemas/domaincommon.rng | 11 +++++ src/conf/domain_conf.c | 43 +++++++++++++------ src/conf/domain_conf.h | 2 + src/qemu/qemu_extdevice.c | 10 +++-- src/qemu/qemu_validate.c | 17 +++++--- tests/qemuxml2argvdata/vhost-user-fs-sock.xml | 39 +++++++++++++++++ .../vhost-user-fs-sock.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 8 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-sock.xml create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml -- 2.29.2

Move the default setting of accessmode to the post-parse phase. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 18 ++++++++++++++++-- src/conf/domain_conf.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d050a519c6..3c3e381de2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -504,6 +504,7 @@ VIR_ENUM_IMPL(virDomainFSDriver, VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST, + "", "passthrough", "mapped", "squash", @@ -5486,6 +5487,16 @@ virDomainMemoryDefPostParse(virDomainMemoryDefPtr mem, } +static int +virDomainFSDefPostParse(virDomainFSDefPtr fs) +{ + if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_DEFAULT) + fs->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; + + return 0; +} + + static int virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, const virDomainDef *def, @@ -5531,8 +5542,11 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, ret = virDomainMemoryDefPostParse(dev->data.memory, def); break; - case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: + ret = virDomainFSDefPostParse(dev->data.fs); + break; + + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: @@ -10263,7 +10277,7 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } } else { - def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; + def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_DEFAULT; } fmode = virXMLPropString(node, "fmode"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0b8895bbdf..9c47df99f6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -802,6 +802,7 @@ typedef enum { /* Filesystem mount access mode */ typedef enum { + VIR_DOMAIN_FS_ACCESSMODE_DEFAULT = 0, VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH, VIR_DOMAIN_FS_ACCESSMODE_MAPPED, VIR_DOMAIN_FS_ACCESSMODE_SQUASH, -- 2.29.2

So far VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH is always set in virDomainFSDefPostParse, but future commits aim to change that. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3c3e381de2..5a1e193b2d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -25436,9 +25436,9 @@ virDomainFSDefFormat(virBufferPtr buf, return -1; } - virBufferAsprintf(buf, - "<filesystem type='%s' accessmode='%s'", - type, accessmode); + virBufferAsprintf(buf, "<filesystem type='%s'", type); + if (def->accessmode != VIR_DOMAIN_FS_ACCESSMODE_DEFAULT) + virBufferAsprintf(buf, " accessmode='%s'", accessmode); if (def->model) { virBufferAsprintf(buf, " model='%s'", virDomainFSModelTypeToString(def->model)); -- 2.29.2

Allow passing a socket of an externally launched virtiofsd to the vhost-user-fs device. <filesystem type='mount'> <driver type='virtiofs' queue='1024'/> <source socket='/tmp/sock/'/> </filesystem> https://bugzilla.redhat.com/show_bug.cgi?id=1855789 Signed-off-by: Ján Tomko <jtomko@redhat.com> --- docs/schemas/domaincommon.rng | 11 ++++++ src/conf/domain_conf.c | 21 ++++++---- src/conf/domain_conf.h | 1 + src/qemu/qemu_validate.c | 17 ++++---- tests/qemuxml2argvdata/vhost-user-fs-sock.xml | 39 +++++++++++++++++++ .../vhost-user-fs-sock.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 7 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-sock.xml create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f5ced5b7a2..361cd44e4e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2747,9 +2747,18 @@ <ref name="fsBinary"/> </optional> <element name="source"> + <choice> + <group> <attribute name="dir"> <ref name="absDirPath"/> </attribute> + </group> + <group> + <attribute name="socket"> + <ref name="absFilePath"/> + </attribute> + </group> + </choice> <empty/> </element> </interleave> @@ -2811,10 +2820,12 @@ </group> </choice> <interleave> + <optional> <element name="target"> <attribute name="dir"/> <empty/> </element> + </optional> <optional> <attribute name="accessmode"> <choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5a1e193b2d..ddf072783b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2472,6 +2472,7 @@ void virDomainFSDefFree(virDomainFSDefPtr def) g_free(def->virtio); virObjectUnref(def->privateData); g_free(def->binary); + g_free(def->sock); g_free(def); } @@ -5490,7 +5491,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDefPtr mem, static int virDomainFSDefPostParse(virDomainFSDefPtr fs) { - if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_DEFAULT) + if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_DEFAULT && !fs->sock) fs->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; return 0; @@ -10252,6 +10253,7 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, g_autofree char *multidevs = NULL; g_autofree char *fmode = NULL; g_autofree char *dmode = NULL; + g_autofree char *sock = NULL; ctxt->node = node; @@ -10334,9 +10336,9 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { - if (!source && + if (!source && !sock && virXMLNodeNameEqual(cur, "source")) { - + sock = virXMLPropString(cur, "socket"); if (def->type == VIR_DOMAIN_FS_TYPE_MOUNT || def->type == VIR_DOMAIN_FS_TYPE_BIND) { source = virXMLPropString(cur, "dir"); @@ -10458,13 +10460,13 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, } if (source == NULL && def->type != VIR_DOMAIN_FS_TYPE_RAM - && def->type != VIR_DOMAIN_FS_TYPE_VOLUME) { + && def->type != VIR_DOMAIN_FS_TYPE_VOLUME && !sock) { virReportError(VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target); goto error; } - if (target == NULL) { + if (target == NULL && !sock) { virReportError(VIR_ERR_NO_TARGET, source ? "%s" : NULL, source); goto error; @@ -10488,6 +10490,7 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, } def->src->path = g_steal_pointer(&source); + def->sock = g_steal_pointer(&sock); def->dst = g_steal_pointer(&target); if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, @@ -22372,7 +22375,7 @@ static bool virDomainFsDefCheckABIStability(virDomainFSDefPtr src, virDomainFSDefPtr dst) { - if (STRNEQ(src->dst, dst->dst)) { + if (STRNEQ_NULLABLE(src->dst, dst->dst)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target filesystem guest target %s does not match source %s"), dst->dst, src->dst); @@ -25508,8 +25511,10 @@ virDomainFSDefFormat(virBufferPtr buf, switch (def->type) { case VIR_DOMAIN_FS_TYPE_MOUNT: case VIR_DOMAIN_FS_TYPE_BIND: - virBufferEscapeString(buf, "<source dir='%s'/>\n", - src); + if (!def->sock) + virBufferEscapeString(buf, "<source dir='%s'/>\n", src); + else + virBufferEscapeString(buf, "<source socket='%s'/>\n", def->sock); break; case VIR_DOMAIN_FS_TYPE_BLOCK: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9c47df99f6..0c1124078b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -859,6 +859,7 @@ struct _virDomainFSDef { int multidevs; /* virDomainFSMultidevs */ unsigned long long usage; /* in bytes */ virStorageSourcePtr src; + char *sock; char *dst; bool readonly; virDomainDeviceInfo info; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 6043f974ce..0843a7f74a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4102,26 +4102,29 @@ qemuValidateDomainDeviceDefFS(virDomainFSDefPtr fs, return -1; case VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS: - if (fs->readonly) { + if (!fs->sock) { + if (fs->readonly) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtiofs does not yet support read-only mode")); return -1; - } - if (!driver->privileged) { + } + if (!driver->privileged) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtiofs is not yet supported in session mode")); return -1; - } - if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) { + } + if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtiofs only supports passthrough accessmode")); return -1; - } - if (fs->wrpolicy != VIR_DOMAIN_FS_WRPOLICY_DEFAULT) { + } + if (fs->wrpolicy != VIR_DOMAIN_FS_WRPOLICY_DEFAULT) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtiofs does not support wrpolicy")); return -1; + } } + if (fs->model != VIR_DOMAIN_FS_MODEL_DEFAULT) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("virtiofs does not support model")); diff --git a/tests/qemuxml2argvdata/vhost-user-fs-sock.xml b/tests/qemuxml2argvdata/vhost-user-fs-sock.xml new file mode 100644 index 0000000000..aef005d3fd --- /dev/null +++ b/tests/qemuxml2argvdata/vhost-user-fs-sock.xml @@ -0,0 +1,39 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + <numa> + <cell id='0' cpus='0-1' memory='14680064' unit='KiB' memAccess='shared'/> + </numa> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pci-root'/> + <filesystem type='mount'> + <driver type='virtiofs' queue='1024'/> + <source socket='/tmp/sock'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </filesystem> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml b/tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml new file mode 120000 index 0000000000..ea0382990a --- /dev/null +++ b/tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/vhost-user-fs-sock.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 4e7cce21c6..0fe4b3b480 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1415,6 +1415,7 @@ mymain(void) DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory"); DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages"); + DO_TEST_CAPS_LATEST("vhost-user-fs-sock"); DO_TEST("riscv64-virt", QEMU_CAPS_DEVICE_VIRTIO_MMIO); -- 2.29.2

On 3/31/21 8:55 PM, Ján Tomko wrote:
Allow passing a socket of an externally launched virtiofsd to the vhost-user-fs device.
<filesystem type='mount'> <driver type='virtiofs' queue='1024'/> <source socket='/tmp/sock/'/> </filesystem>
https://bugzilla.redhat.com/show_bug.cgi?id=1855789
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- docs/schemas/domaincommon.rng | 11 ++++++ src/conf/domain_conf.c | 21 ++++++---- src/conf/domain_conf.h | 1 + src/qemu/qemu_validate.c | 17 ++++---- tests/qemuxml2argvdata/vhost-user-fs-sock.xml | 39 +++++++++++++++++++ .../vhost-user-fs-sock.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 7 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-sock.xml create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f5ced5b7a2..361cd44e4e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2747,9 +2747,18 @@ <ref name="fsBinary"/> </optional> <element name="source"> + <choice> + <group> <attribute name="dir"> <ref name="absDirPath"/> </attribute> + </group> + <group> + <attribute name="socket"> + <ref name="absFilePath"/>
Alignment.
+ </attribute> + </group> + </choice> <empty/> </element> </interleave>
Michal

Copy the socket path in qemuExtDevicesStart, because for libvirt-managed virtiofsd daemons the path is filled there in qemuVirtioFSStart. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_extdevice.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index fdba22616c..a9dad16a8f 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -197,7 +197,9 @@ qemuExtDevicesStart(virQEMUDriverPtr driver, virDomainFSDefPtr fs = def->fss[i]; if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { - if (qemuVirtioFSStart(logManager, driver, vm, fs) < 0) + if (fs->sock) + QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock = g_strdup(fs->sock); + else if (qemuVirtioFSStart(logManager, driver, vm, fs) < 0) return -1; } } @@ -240,7 +242,8 @@ qemuExtDevicesStop(virQEMUDriverPtr driver, for (i = 0; i < def->nfss; i++) { virDomainFSDefPtr fs = def->fss[i]; - if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) + if (!fs->sock && + fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) qemuVirtioFSStop(driver, vm, fs); } } @@ -306,7 +309,8 @@ qemuExtDevicesSetupCgroup(virQEMUDriverPtr driver, for (i = 0; i < def->nfss; i++) { virDomainFSDefPtr fs = def->fss[i]; - if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS && + if (!fs->sock && + fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS && qemuVirtioFSSetupCgroup(vm, fs, cgroup) < 0) return -1; } -- 2.29.2

On 3/31/21 8:55 PM, Ján Tomko wrote:
Connect the vhost-user-fs device to a socket path configured in the XML.
Starting and stopping the virtiofsd daemon on that socket is the user's responsibility.
Ján Tomko (4): conf: fs: fill out accessmode in post-parse conf: fs: allow missing accessmode in the formatter conf: add socket for virtiofs filesystems qemu: add socket for virtiofs filesystems
docs/schemas/domaincommon.rng | 11 +++++ src/conf/domain_conf.c | 43 +++++++++++++------ src/conf/domain_conf.h | 2 + src/qemu/qemu_extdevice.c | 10 +++-- src/qemu/qemu_validate.c | 17 +++++--- tests/qemuxml2argvdata/vhost-user-fs-sock.xml | 39 +++++++++++++++++ .../vhost-user-fs-sock.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 8 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 tests/qemuxml2argvdata/vhost-user-fs-sock.xml create mode 120000 tests/qemuxml2xmloutdata/vhost-user-fs-sock.x86_64-latest.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Ján Tomko
-
Michal Privoznik