diff --git a/lxd/device/device_utils_disk.go b/lxd/device/device_utils_disk.go index 2b70ad05b995..c9bdd53712d7 100644 --- a/lxd/device/device_utils_disk.go +++ b/lxd/device/device_utils_disk.go @@ -21,6 +21,7 @@ import ( "github.com/canonical/lxd/shared" "github.com/canonical/lxd/shared/osarch" "github.com/canonical/lxd/shared/revert" + "github.com/canonical/lxd/shared/version" ) // RBDFormatPrefix is the prefix used in disk paths to identify RBD. @@ -424,7 +425,7 @@ func DiskVMVirtfsProxyStop(pidPath string) error { // Returns UnsupportedError error if the host system or instance does not support virtiosfd, returns normal error // type if process cannot be started for other reasons. // Returns revert function and listener file handle on success. -func DiskVMVirtiofsdStart(execPath string, inst instance.Instance, socketPath string, pidPath string, logPath string, sharePath string, idmaps []idmap.IdmapEntry) (func(), net.Listener, error) { +func DiskVMVirtiofsdStart(kernelVersion version.DottedVersion, inst instance.Instance, socketPath string, pidPath string, logPath string, sharePath string, idmaps []idmap.IdmapEntry) (func(), net.Listener, error) { revert := revert.New() defer revert.Fail() @@ -502,7 +503,18 @@ func DiskVMVirtiofsdStart(execPath string, inst instance.Instance, socketPath st defer func() { _ = unixFile.Close() }() // Start the virtiofsd process in non-daemon mode. - args := []string{"--fd=3", "-o", fmt.Sprintf("source=%s", sharePath)} + args := []string{ + "--fd=3", + "-o", fmt.Sprintf("source=%s", sharePath), + } + + // Virtiofsd defaults to namespace sandbox mode which requires pidfd_open support. + // This was added in Linux 5.3, so if running an earlier kernel fallback to chroot sandbox mode. + minVer, _ := version.NewDottedVersion("5.3.0") + if kernelVersion.Compare(minVer) < 0 { + args = append(args, "--sandbox=chroot") + } + proc, err := subprocess.NewProcess(cmd, args, logPath, logPath) if err != nil { return nil, nil, err diff --git a/lxd/device/disk.go b/lxd/device/disk.go index a8d1cf46cd1c..7e178b3b3b85 100644 --- a/lxd/device/disk.go +++ b/lxd/device/disk.go @@ -1157,7 +1157,7 @@ func (d *disk) startVM() (*deviceConfig.RunConfig, error) { logPath := filepath.Join(d.inst.LogPath(), fmt.Sprintf("disk.%s.log", filesystem.PathNameEncode(d.name))) _ = os.Remove(logPath) // Remove old log if needed. - revertFunc, unixListener, err := DiskVMVirtiofsdStart(d.state.OS.ExecPath, d.inst, sockPath, pidPath, logPath, mount.DevPath, rawIDMaps) + revertFunc, unixListener, err := DiskVMVirtiofsdStart(d.state.OS.KernelVersion, d.inst, sockPath, pidPath, logPath, mount.DevPath, rawIDMaps) if err != nil { var errUnsupported UnsupportedError if errors.As(err, &errUnsupported) { diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index c926650530d3..8214422e9efa 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -1388,7 +1388,7 @@ func (d *qemu) start(stateful bool, op *operationlock.InstanceOperation) error { // This is used by the lxd-agent in preference to 9p (due to its improved performance) and in scenarios // where 9p isn't available in the VM guest OS. configSockPath, configPIDPath := d.configVirtiofsdPaths() - revertFunc, unixListener, err := device.DiskVMVirtiofsdStart(d.state.OS.ExecPath, d, configSockPath, configPIDPath, "", configMntPath, nil) + revertFunc, unixListener, err := device.DiskVMVirtiofsdStart(d.state.OS.KernelVersion, d, configSockPath, configPIDPath, "", configMntPath, nil) if err != nil { var errUnsupported device.UnsupportedError if !errors.As(err, &errUnsupported) {