The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8057

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 8bcad318eea963979740453fcf9e28884f0fffa4 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 20 Oct 2020 08:39:23 +0200
Subject: [PATCH 1/5] lxd/instance/drivers: Change memory backend

This changes the memory backend to memory-backend-memfd. Also, this
turns on `share`. Both are required for virtio-fs.

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/instance/drivers/driver_qemu_templates.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lxd/instance/drivers/driver_qemu_templates.go 
b/lxd/instance/drivers/driver_qemu_templates.go
index 29d4aa6b40..17051c1510 100644
--- a/lxd/instance/drivers/driver_qemu_templates.go
+++ b/lxd/instance/drivers/driver_qemu_templates.go
@@ -279,9 +279,10 @@ mem-path = "{{$hugepages}}"
 prealloc = "on"
 discard-data = "on"
 {{- else}}
-qom-type = "memory-backend-ram"
+qom-type = "memory-backend-memfd"
 {{- end }}
 size = "{{$memory}}M"
+share = "on"
 
 [numa]
 type = "node"

From a4aeded8bcd15f278acd58e8d5ea2427c718c79f Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 20 Oct 2020 09:15:48 +0200
Subject: [PATCH 2/5] lxd/instance/drivers: Add qemu virtio-fs template

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/instance/drivers/driver_qemu_templates.go | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/lxd/instance/drivers/driver_qemu_templates.go 
b/lxd/instance/drivers/driver_qemu_templates.go
index 17051c1510..306e6a0412 100644
--- a/lxd/instance/drivers/driver_qemu_templates.go
+++ b/lxd/instance/drivers/driver_qemu_templates.go
@@ -541,3 +541,15 @@ driver = "usb-host"
 bus = "qemu_usb.0"
 hostdevice = "{{.hostDevice}}"
 `))
+
+var qemuVirtioFSDev = template.Must(template.New("qemuVirtioFSDev").Parse(`
+# Virtio FS
+[chardev "qemu_virtiofs-{{.devName}}"]
+backend = "socket"
+path = "{{.path}}"
+
+[device "dev-lxd_{{.devName}}"]
+driver = "vhost-user-fs-pci"
+chardev = "qemu_virtiofs-{{.devName}}"
+tag = "{{.tag}}"
+`))

From c384d07f23d503153d577d3bb84ac93a01894888 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 20 Oct 2020 09:24:11 +0200
Subject: [PATCH 3/5] lxd/device/disk: Support virtio-fs

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/device/disk.go | 64 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/lxd/device/disk.go b/lxd/device/disk.go
index 4f728007e7..4b5797cecf 100644
--- a/lxd/device/disk.go
+++ b/lxd/device/disk.go
@@ -152,7 +152,7 @@ func (d *disk) validateConfig(instConf 
instance.ConfigReader) error {
        // contains the name of the storage volume, not the path where it is 
mounted. So only check
        // for the existence of "source" when "pool" is empty and ceph type 
source not being used.
        if d.config["pool"] == "" && d.config["source"] != "" && 
d.config["source"] != diskSourceCloudInit && d.isRequired(d.config) && 
!shared.PathExists(shared.HostPath(d.config["source"])) &&
-               !strings.HasPrefix(d.config["source"], "ceph:") && 
!strings.HasPrefix(d.config["source"], "cephfs:") {
+               !strings.HasPrefix(d.config["source"], "ceph:") && 
!strings.HasPrefix(d.config["source"], "cephfs:") && 
!strings.HasPrefix(d.config["source"], "virtiofs:") {
                return fmt.Errorf("Missing source %q for disk %q", 
d.config["source"], d.name)
        }
 
@@ -449,6 +449,53 @@ func (d *disk) startVM() (*deviceConfig.RunConfig, error) {
                                        DevName: d.name,
                                },
                        }
+               } else if strings.HasPrefix(d.config["source"], "virtiofs:") {
+                       fields := strings.SplitN(d.config["source"], ":", 2)
+                       srcPath := fields[1]
+                       // Create the socket in this directory instead of the 
devices directory. QEMU will otherwise
+                       // fail with "Permission Denied" which is probably 
caused by qemu being called with --chroot.
+                       sockPath := filepath.Join(d.inst.Path(), 
fmt.Sprintf("%s.sock", d.name))
+                       logPath := filepath.Join(d.inst.LogPath(), 
fmt.Sprintf("disk.%s.log", d.name))
+
+                       // Remove old socket if needed.
+                       os.Remove(sockPath)
+
+                       // Start the virtiofsd process in non-daemon mode.
+                       proc, err := 
subprocess.NewProcess("/usr/lib/qemu/virtiofsd", 
[]string{fmt.Sprintf("--socket-path=%s", sockPath), "-o", 
fmt.Sprintf("source=%s", srcPath)}, logPath, logPath)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       err = proc.Start()
+                       if err != nil {
+                               return nil, errors.Wrapf(err, "Failed to start 
virtiofsd for device %q", d.name)
+                       }
+
+                       revert.Add(func() { proc.Stop() })
+
+                       pidPath := filepath.Join(d.inst.DevicesPath(), 
fmt.Sprintf("%s.pid", d.name))
+                       err = proc.Save(pidPath)
+                       if err != nil {
+                               return nil, errors.Wrapf(err, "Failed to save 
virtiofsd state for device %q", d.name)
+                       }
+
+                       // Wait for socket file to exist (as otherwise qemu can 
race the creation of this file).
+                       for i := 0; i < 10; i++ {
+                               if shared.PathExists(sockPath) {
+                                       break
+                               }
+
+                               time.Sleep(50 * time.Millisecond)
+                       }
+
+                       runConf.Mounts = []deviceConfig.MountEntryItem{
+                               {
+                                       DevName:    d.name,
+                                       DevPath:    sockPath,
+                                       FSType:     "virtiofs",
+                                       TargetPath: d.config["path"],
+                               },
+                       }
                } else {
                        srcPath := shared.HostPath(d.config["source"])
                        var err error
@@ -1139,13 +1186,24 @@ func (d *disk) stopVM() (*deviceConfig.RunConfig, 
error) {
                }
 
                err = proc.Stop()
-               if err != nil {
+               // virtiofsd will terminate automatically once the VM has 
stopped. We therefore should only
+               // return an error if it's a running process.
+               if err != nil && err != subprocess.ErrNotRunning {
                        return &deviceConfig.RunConfig{}, err
                }
 
                // Remove PID file and socket file.
                os.Remove(pidPath)
-               os.Remove(filepath.Join(d.inst.DevicesPath(), 
fmt.Sprintf("%s.sock", d.name)))
+
+               var sockPath string
+
+               if strings.HasPrefix(d.config["source"], "virtiofs:") {
+                       sockPath = filepath.Join(d.inst.Path(), 
fmt.Sprintf("%s.sock", d.name))
+               } else {
+                       sockPath = filepath.Join(d.inst.DevicesPath(), 
fmt.Sprintf("%s.sock", d.name))
+               }
+
+               os.Remove(sockPath)
        }
 
        runConf := deviceConfig.RunConfig{

From 7279b2569967d36cd5d7705de6189bbedb6232a8 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 20 Oct 2020 09:24:25 +0200
Subject: [PATCH 4/5] lxd/instance/drivers: Support virtio-fs

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/instance/drivers/driver_qemu.go | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/lxd/instance/drivers/driver_qemu.go 
b/lxd/instance/drivers/driver_qemu.go
index 1abaddbbb2..446ddc3f97 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -1823,7 +1823,7 @@ func (vm *qemu) generateQemuConfigFile(busName string, 
devConfs []*deviceConfig.
                        for _, drive := range runConf.Mounts {
                                if drive.TargetPath == "/" {
                                        err = vm.addRootDriveConfig(sb, 
bootIndexes, drive)
-                               } else if drive.FSType == "9p" {
+                               } else if drive.FSType == "9p" || drive.FSType 
== "virtiofs" {
                                        err = vm.addDriveDirConfig(sb, bus, 
fdFiles, &agentMounts, drive)
                                } else {
                                        err = vm.addDriveConfig(sb, 
bootIndexes, drive)
@@ -2056,6 +2056,14 @@ func (vm *qemu) addDriveDirConfig(sb *strings.Builder, 
bus *qemuBus, fdFiles *[]
 
        devBus, devAddr, multi := bus.allocate(busFunctionGroup9p)
 
+       if driveConf.FSType == "virtiofs" {
+               return qemuVirtioFSDev.Execute(sb, map[string]interface{}{
+                       "devName": driveConf.DevName,
+                       "path":    driveConf.DevPath,
+                       "tag":     mountTag,
+               })
+       }
+
        // For read only shares, do not use proxy.
        if shared.StringInSlice("ro", driveConf.Opts) {
                return qemuDriveDir.Execute(sb, map[string]interface{}{

From 6240c1951f02d8cf063eda8dbc56e5eab7c5a3d2 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Tue, 20 Oct 2020 09:24:57 +0200
Subject: [PATCH 5/5] doc: Add virtio-fs

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 doc/instances.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/doc/instances.md b/doc/instances.md
index 10e4630a33..ca209e7a4a 100644
--- a/doc/instances.md
+++ b/doc/instances.md
@@ -662,6 +662,11 @@ Example command.
 lxc config device add <instance> config disk source=cloud-init:config
 ```
 
+- Virtio-fs: A shared file system that lets virtual machines access a 
directory tree on the host. It is designed to offer local file system semantics 
and performance.
+```
+lxc config device add <instance> config disk source=virtiofs:/<some-path> 
path=/virtiofs
+```
+
 Currently only the root disk (path=/) and config drive 
(source=cloud-init:config) are supported with virtual machines.
 
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to