machine/linux: Switch to virtiofs by default

Switch to using virtiofs by default, and delete the 9p code.
This is structured as a separate patch to make it easier
to revert if need be.

Signed-off-by: Colin Walters <walters@verbum.org>
This commit is contained in:
Colin Walters 2024-06-06 10:53:29 -04:00
parent bf541c6740
commit 4b29c9dd73
4 changed files with 30 additions and 92 deletions

View File

@ -99,15 +99,6 @@ func (q *QemuCmd) SetSerialPort(readySocket, vmPidFile define.VMFile, name strin
"-pidfile", vmPidFile.GetPath()) "-pidfile", vmPidFile.GetPath())
} }
// SetVirtfsMount adds a virtfs mount to the machine
func (q *QemuCmd) SetVirtfsMount(source, tag, securityModel string, readonly bool) {
virtfsOptions := fmt.Sprintf("local,path=%s,mount_tag=%s,security_model=%s", source, tag, securityModel)
if readonly {
virtfsOptions += ",readonly"
}
*q = append(*q, "-virtfs", virtfsOptions)
}
// SetBootableImage specifies the image the machine will use to boot // SetBootableImage specifies the image the machine will use to boot
func (q *QemuCmd) SetBootableImage(image string) { func (q *QemuCmd) SetBootableImage(image string) {
*q = append(*q, "-drive", "if=virtio,file="+image) *q = append(*q, "-drive", "if=virtio,file="+image)

View File

@ -47,7 +47,6 @@ func TestQemuCmd(t *testing.T) {
err = cmd.SetNetwork(vlanSocket) err = cmd.SetNetwork(vlanSocket)
assert.NoError(t, err) assert.NoError(t, err)
cmd.SetSerialPort(*readySocket, *vmPidFile, "test-machine") cmd.SetSerialPort(*readySocket, *vmPidFile, "test-machine")
cmd.SetVirtfsMount("/tmp/path", "vol10", "none", true)
cmd.SetBootableImage(bootableImagePath) cmd.SetBootableImage(bootableImagePath)
cmd.SetDisplay("none") cmd.SetDisplay("none")
@ -65,7 +64,6 @@ func TestQemuCmd(t *testing.T) {
"-chardev", fmt.Sprintf("socket,path=%s,server=on,wait=off,id=atest-machine_ready", readySocketPath), "-chardev", fmt.Sprintf("socket,path=%s,server=on,wait=off,id=atest-machine_ready", readySocketPath),
"-device", "virtserialport,chardev=atest-machine_ready,name=org.fedoraproject.port.0", "-device", "virtserialport,chardev=atest-machine_ready,name=org.fedoraproject.port.0",
"-pidfile", vmPidFilePath, "-pidfile", vmPidFilePath,
"-virtfs", "local,path=/tmp/path,mount_tag=vol10,security_model=none,readonly",
"-drive", fmt.Sprintf("if=virtio,file=%s", bootableImagePath), "-drive", fmt.Sprintf("if=virtio,file=%s", bootableImagePath),
"-display", "none"} "-display", "none"}

View File

@ -24,27 +24,8 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
const (
MountType9p = "9p"
MountTypeVirtiofs = "virtiofs"
)
func NewStubber() (*QEMUStubber, error) { func NewStubber() (*QEMUStubber, error) {
var mountType string return &QEMUStubber{}, nil
if v, ok := os.LookupEnv("PODMAN_MACHINE_VIRTFS"); ok {
logrus.Debugf("using virtiofs %q", v)
switch v {
case MountType9p, MountTypeVirtiofs:
mountType = v
default:
return nil, fmt.Errorf("failed to parse PODMAN_MACHINE_VIRTFS=%s", v)
}
} else {
mountType = MountType9p
}
return &QEMUStubber{
mountType: mountType,
}, nil
} }
// qemuPid returns -1 or the PID of the running QEMU instance. // qemuPid returns -1 or the PID of the running QEMU instance.

View File

@ -32,8 +32,6 @@ type QEMUStubber struct {
// Command describes the final QEMU command line // Command describes the final QEMU command line
Command command.QemuCmd Command command.QemuCmd
// mountType is one of virtiofs or 9p
mountType string
// virtiofsHelpers are virtiofsd child processes // virtiofsHelpers are virtiofsd child processes
virtiofsHelpers []virtiofsdHelperCmd virtiofsHelpers []virtiofsdHelperCmd
} }
@ -166,31 +164,22 @@ func (q *QEMUStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func()
defer dnr.Close() defer dnr.Close()
defer dnw.Close() defer dnw.Close()
if q.mountType == MountTypeVirtiofs { runtime, err := mc.RuntimeDir()
runtime, err := mc.RuntimeDir() if err != nil {
if err != nil { return nil, nil, err
return nil, nil, err }
} spawner, err := newVirtiofsdSpawner(runtime)
spawner, err := newVirtiofsdSpawner(runtime) if err != nil {
if err != nil { return nil, nil, err
return nil, nil, err }
}
for _, hostmnt := range mc.Mounts { for _, hostmnt := range mc.Mounts {
qemuArgs, virtiofsdHelper, err := spawner.spawnForMount(hostmnt) qemuArgs, virtiofsdHelper, err := spawner.spawnForMount(hostmnt)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to init virtiofsd for mount %s: %w", hostmnt.Source, err) return nil, nil, fmt.Errorf("failed to init virtiofsd for mount %s: %w", hostmnt.Source, err)
}
q.Command = append(q.Command, qemuArgs...)
q.virtiofsHelpers = append(q.virtiofsHelpers, *virtiofsdHelper)
}
} else {
// Add volumes to qemu command line
for _, mount := range mc.Mounts {
// the index provided in this case is thrown away
_, _, _, _, securityModel := vmconfigs.SplitVolume(0, mount.OriginalInput)
q.Command.SetVirtfsMount(mount.Source, mount.Tag, securityModel, mount.ReadOnly)
} }
q.Command = append(q.Command, qemuArgs...)
q.virtiofsHelpers = append(q.virtiofsHelpers, *virtiofsdHelper)
} }
cmdLine := q.Command cmdLine := q.Command
@ -362,48 +351,27 @@ func (q *QEMUStubber) MountVolumesToVM(mc *vmconfigs.MachineConfig, quiet bool)
if err != nil { if err != nil {
return err return err
} }
// NOTE: We ignore q.Type here (and it should eventually be dropped from being serialized); we // NOTE: The mount type q.Type was previously serialized as 9p for older Linux versions,
// want the mount type to be dynamic, not static. // but we ignore it now because we want the mount type to be dynamic, not static. Or
switch q.mountType { // in other words we don't want to make people unnecessarily reprovision their machines
case MountType9p: // to upgrade from 9p to virtiofs.
mountOptions := []string{"-t", "9p"} mountOptions := []string{"-t", "virtiofs"}
mountOptions = append(mountOptions, []string{"-o", "trans=virtio", mount.Tag, mount.Target}...) mountOptions = append(mountOptions, []string{mount.Tag, mount.Target}...)
mountOptions = append(mountOptions, []string{"-o", "version=9p2000.L,msize=131072,cache=mmap"}...) mountFlags := fmt.Sprintf("context=\"%s\"", machine.NFSSELinuxContext)
if mount.ReadOnly { if mount.ReadOnly {
mountOptions = append(mountOptions, []string{"-o", "ro"}...) mountFlags += ",ro"
} }
err = machine.CommonSSH(mc.SSH.RemoteUsername, mc.SSH.IdentityPath, mc.Name, mc.SSH.Port, append([]string{"sudo", "mount"}, mountOptions...)) mountOptions = append(mountOptions, "-o", mountFlags)
if err != nil { err = machine.CommonSSH(mc.SSH.RemoteUsername, mc.SSH.IdentityPath, mc.Name, mc.SSH.Port, append([]string{"sudo", "mount"}, mountOptions...))
return err if err != nil {
} return err
case MountTypeVirtiofs:
mountOptions := []string{"-t", "virtiofs"}
mountOptions = append(mountOptions, []string{mount.Tag, mount.Target}...)
mountFlags := fmt.Sprintf("context=\"%s\"", machine.NFSSELinuxContext)
if mount.ReadOnly {
mountFlags += ",ro"
}
mountOptions = append(mountOptions, "-o", mountFlags)
err = machine.CommonSSH(mc.SSH.RemoteUsername, mc.SSH.IdentityPath, mc.Name, mc.SSH.Port, append([]string{"sudo", "mount"}, mountOptions...))
if err != nil {
return err
}
default:
return fmt.Errorf("unknown mount type: %s", mount.Type)
} }
} }
return nil return nil
} }
func (q *QEMUStubber) MountType() vmconfigs.VolumeMountType { func (q *QEMUStubber) MountType() vmconfigs.VolumeMountType {
switch q.mountType { return vmconfigs.VirtIOFS
case MountType9p:
return vmconfigs.NineP
case MountTypeVirtiofs:
return vmconfigs.VirtIOFS
default:
panic(fmt.Errorf("unexpected mount type %q", q.mountType))
}
} }
func (q *QEMUStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool) error { func (q *QEMUStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool) error {