Skip to content

Commit

Permalink
lxd/instance/drivers: Get file descriptor and pass it over to qemu
Browse files Browse the repository at this point in the history
Signed-off-by: hamistao <pedro.ribeiro@canonical.com>
  • Loading branch information
hamistao committed Apr 12, 2024
1 parent f2f8f67 commit c0bd203
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
42 changes: 22 additions & 20 deletions lxd/instance/drivers/driver_qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -1467,8 +1467,15 @@ func (d *qemu) start(stateful bool, op *operationlock.InstanceOperation) error {
cpuType += "," + strings.Join(cpuExtensions, ",")
}

socketFile, err := unixListener.(*net.UnixListener).File()
if err != nil {
return fmt.Errorf("Failed to get the file for the unix socket: %w", err)
}

configSockFD := d.addFileDescriptor(&fdFiles, socketFile)

// Generate the QEMU configuration.
confFile, monHooks, err := d.generateQemuConfigFile(cpuInfo, mountInfo, qemuBus, vsockFD, devConfs, &fdFiles)
confFile, monHooks, err := d.generateQemuConfigFile(cpuInfo, mountInfo, qemuBus, configSockFD, vsockFD, devConfs, &fdFiles)
if err != nil {
op.Done(err)
return err
Expand Down Expand Up @@ -3095,7 +3102,7 @@ func (d *qemu) deviceBootPriorities(base int) (map[string]int, error) {

// generateQemuConfigFile writes the qemu config file and returns its location.
// It writes the config file inside the VM's log path.
func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePools.MountInfo, busName string, vsockFD int, devConfs []*deviceConfig.RunConfig, fdFiles *[]*os.File) (string, []monitorHook, error) {
func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePools.MountInfo, busName string, configSockFD int, vsockFD int, devConfs []*deviceConfig.RunConfig, fdFiles *[]*os.File) (string, []monitorHook, error) {
var monHooks []monitorHook

cfg := qemuBase(&qemuBaseOpts{d.Architecture()})
Expand Down Expand Up @@ -3338,6 +3345,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
// 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, _ := d.configVirtiofsdPaths()

if shared.PathExists(configSockPath) {
devBus, devAddr, multi = bus.allocate(busFunctionGroup9p)
driveConfigVirtioOpts := qemuDriveConfigOpts{
Expand All @@ -3348,7 +3356,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
multifunction: multi,
},
protocol: "virtio-fs",
path: configSockPath,
fd: fmt.Sprintf("%d", configSockFD),
}

cfg = append(cfg, qemuDriveConfig(&driveConfigVirtioOpts)...)
Expand Down Expand Up @@ -3733,22 +3741,16 @@ func (d *qemu) addDriveDirConfig(cfg *[]cfgSection, bus *qemuBus, fdFiles *[]*os
// Record the 9p mount for the agent.
*agentMounts = append(*agentMounts, agentMount)

// Check if the disk device has provided a virtiofsd socket path.
var virtiofsdSockPath string
for _, opt := range driveConf.Opts {
if strings.HasPrefix(opt, fmt.Sprintf("%s=", device.DiskVirtiofsdSockMountOpt)) {
parts := strings.SplitN(opt, "=", 2)
virtiofsdSockPath = parts[1]
}
}
// If there is a virtiofsd socket listener setup the virtio-fs share.
if driveConf.VirtiofsdSocket != nil {
devBus, devAddr, multi := bus.allocate(busFunctionGroup9p)

// If there is a virtiofsd socket path setup the virtio-fs share.
if virtiofsdSockPath != "" {
if !shared.PathExists(virtiofsdSockPath) {
return fmt.Errorf("virtiofsd socket path %q doesn't exist", virtiofsdSockPath)
virtiofsdSocketFile, err := driveConf.VirtiofsdSocket.(*net.UnixListener).File()
if err != nil {
return fmt.Errorf("Failed to get the file for the unix socket: %w", err)
}

devBus, devAddr, multi := bus.allocate(busFunctionGroup9p)
virtiofsdSocketFD := d.addFileDescriptor(fdFiles, virtiofsdSocketFile)

// Add virtio-fs device as this will be preferred over 9p.
driveDirVirtioOpts := qemuDriveDirOpts{
Expand All @@ -3758,10 +3760,10 @@ func (d *qemu) addDriveDirConfig(cfg *[]cfgSection, bus *qemuBus, fdFiles *[]*os
devAddr: devAddr,
multifunction: multi,
},
devName: driveConf.DevName,
mountTag: mountTag,
path: virtiofsdSockPath,
protocol: "virtio-fs",
devName: driveConf.DevName,
mountTag: mountTag,
devSockFD: virtiofsdSocketFD,
protocol: "virtio-fs",
}
*cfg = append(*cfg, qemuDriveDir(&driveDirVirtioOpts)...)
}
Expand Down
22 changes: 13 additions & 9 deletions lxd/instance/drivers/driver_qemu_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ type qemuHostDriveOpts struct {
mountTag string
securityModel string
path string
fd string
sockFd string
readonly bool
protocol string
Expand Down Expand Up @@ -680,7 +681,7 @@ func qemuHostDrive(opts *qemuHostDriveOpts) []cfgSection {
comment: opts.comment,
entries: []cfgEntry{
{key: "backend", value: "socket"},
{key: "path", value: opts.path},
{key: "fd", value: opts.fd},
},
}

Expand Down Expand Up @@ -708,6 +709,7 @@ type qemuDriveConfigOpts struct {
dev qemuDevOpts
protocol string
path string
fd string
}

func qemuDriveConfig(opts *qemuDriveConfigOpts) []cfgSection {
Expand All @@ -723,17 +725,19 @@ func qemuDriveConfig(opts *qemuDriveConfigOpts) []cfgSection {
readonly: true,
securityModel: "none",
path: opts.path,
fd: opts.fd,
})
}

type qemuDriveDirOpts struct {
dev qemuDevOpts
devName string
mountTag string
path string
protocol string
proxyFD int
readonly bool
dev qemuDevOpts
devName string
mountTag string
path string
devSockFD int
protocol string
proxyFD int
readonly bool
}

func qemuDriveDir(opts *qemuDriveDirOpts) []cfgSection {
Expand All @@ -746,7 +750,7 @@ func qemuDriveDir(opts *qemuDriveDirOpts) []cfgSection {
protocol: opts.protocol,
fsdriver: "proxy",
readonly: opts.readonly,
path: opts.path,
fd: fmt.Sprintf("%d", opts.devSockFD),
sockFd: fmt.Sprintf("%d", opts.proxyFD),
})
}
Expand Down

0 comments on commit c0bd203

Please sign in to comment.