forked from containers/podman
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
machine/linux: Support virtiofs mounts (retain 9p default)
I'm hitting a bug with 9p when trying to transfer large files. In RHEL at least 9p isn't supported because it's known to have a lot of design flaws; virtiofsd is the supported and recommended way to share files between a host and guest. Add a new hidden `PODMAN_MACHINE_VIRTFS` environment variable that can be set to `virtiofs` to switch to virtiofsd. Signed-off-by: Colin Walters <[email protected]>
- Loading branch information
Showing
9 changed files
with
229 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
//go:build linux || freebsd | ||
|
||
package qemu | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"time" | ||
|
||
"github.com/containers/common/pkg/config" | ||
"github.com/containers/podman/v5/pkg/machine/define" | ||
"github.com/containers/podman/v5/pkg/machine/vmconfigs" | ||
"github.com/containers/storage/pkg/fileutils" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
// VirtiofsdSpawner spawns an instance of virtiofsd | ||
type virtiofsdSpawner struct { | ||
runtimeDir *define.VMFile | ||
binaryPath string | ||
mountCount uint | ||
} | ||
|
||
func newVirtiofsdSpawner(runtimeDir *define.VMFile) (*virtiofsdSpawner, error) { | ||
var binaryPath string | ||
cfg, err := config.Default() | ||
if err != nil { | ||
return nil, err | ||
} | ||
binaryPath, err = cfg.FindHelperBinary("virtiofsd", true) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to find virtiofsd: %w", err) | ||
} | ||
return &virtiofsdSpawner{binaryPath: binaryPath, runtimeDir: runtimeDir}, nil | ||
} | ||
|
||
// createVirtiofsCmd returns a new command instance configured to launch virtiofsd. | ||
func (v *virtiofsdSpawner) createVirtiofsCmd(directory, socketPath string) *exec.Cmd { | ||
args := []string{"--sandbox", "none", "--socket-path", socketPath, "--shared-dir", "."} | ||
// We don't need seccomp filtering; we trust our workloads. This incidentally | ||
// works around issues like https://gitlab.com/virtio-fs/virtiofsd/-/merge_requests/200. | ||
args = append(args, "--seccomp=none") | ||
cmd := exec.Command(v.binaryPath, args...) | ||
// This sets things up so that the `.` we passed in the arguments is the target directory | ||
cmd.Dir = directory | ||
// Quiet the daemon by default | ||
cmd.Env = append(cmd.Environ(), "RUST_LOG=ERROR") | ||
cmd.Stdin = nil | ||
cmd.Stdout = nil | ||
if logrus.IsLevelEnabled(logrus.DebugLevel) { | ||
cmd.Stderr = os.Stderr | ||
} | ||
return cmd | ||
} | ||
|
||
type virtiofsdHelperCmd struct { | ||
command exec.Cmd | ||
socket *define.VMFile | ||
} | ||
|
||
// spawnForMount returns on success a combination of qemu commandline and child process for virtiofsd | ||
func (v *virtiofsdSpawner) spawnForMount(hostmnt *vmconfigs.Mount) ([]string, *virtiofsdHelperCmd, error) { | ||
logrus.Debugf("Initializing virtiofsd mount for %s", hostmnt.Source) | ||
// By far the most common failure to spawn virtiofsd will be a typo'd source directory, | ||
// so let's synchronously check that ourselves here. | ||
if err := fileutils.Exists(hostmnt.Source); err != nil { | ||
return nil, nil, fmt.Errorf("failed to access virtiofs source directory %s", hostmnt.Source) | ||
} | ||
virtiofsChar := fmt.Sprintf("virtiofschar%d", v.mountCount) | ||
virtiofsCharPath, err := v.runtimeDir.AppendToNewVMFile(virtiofsChar, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
qemuCommand := []string{} | ||
|
||
qemuCommand = append(qemuCommand, "-chardev", fmt.Sprintf("socket,id=%s,path=%s", virtiofsChar, virtiofsCharPath.Path)) | ||
qemuCommand = append(qemuCommand, "-device", fmt.Sprintf("vhost-user-fs-pci,queue-size=1024,chardev=%s,tag=%s", virtiofsChar, hostmnt.Tag)) | ||
// TODO: Honor hostmnt.readonly somehow here (add an option to virtiofsd) | ||
virtiofsdCmd := v.createVirtiofsCmd(hostmnt.Source, virtiofsCharPath.Path) | ||
if err := virtiofsdCmd.Start(); err != nil { | ||
return nil, nil, fmt.Errorf("failed to start virtiofsd") | ||
} | ||
// Wait for the socket | ||
for { | ||
if err := fileutils.Exists(virtiofsCharPath.Path); err == nil { | ||
break | ||
} | ||
logrus.Debugf("waiting for virtiofsd socket %q", virtiofsCharPath.Path) | ||
time.Sleep(time.Millisecond * 100) | ||
} | ||
// Increment our count of mounts which are used to create unique names for the devices | ||
v.mountCount += 1 | ||
return qemuCommand, &virtiofsdHelperCmd{ | ||
command: *virtiofsdCmd, | ||
socket: virtiofsCharPath, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters