Qemu task with macvtap fd redirection

I have a qemu vm with two macvtap interfaces, one configured as passthru (dedicated to this vm) and one configured as bridge (shared with other vm’s, the host, etc.).

The current recommended approach for configuring a vm with macvtap interfaces is done something like this:

...
	-net nic,model=virtio,macaddr=$(cat /sys/class/net/vmbridge/address) \
	-net tap,fd=3 3<>/dev/tap$(cat /sys/class/net/vmbridge/ifindex) \
	-net nic,model=virtio,macaddr=$(cat /sys/class/net/vmpassthru/address) \
	-net tap,fd=4 4<>/dev/tap$(cat /sys/class/net/vmpassthru/ifindex) \
...

This requires some shell exec to function, and it appears the remote executor used by the qemu task does not allow for shell exec commands to run. I have not dug into the code very much to try to determine how or if there is a workaround, but trying to configure the job as such:

job "vm" {
  datacenters = [
    "home"
  ]
  group "vm" {
    task "vm" {
      driver = "qemu"
      config {
        image_path = "if=virtio,file=/mnt/vms/boot.qcow2"
        accelerator = "kvm"
        graceful_shutdown = true
        args = [
         // ...
          "-net nic,model=virtio,macaddr=$(cat /sys/class/net/vmbridge/address)",
          "-net tap,fd=3 3<>/dev/tap$(cat /sys/class/net/vmbridge/ifindex)",
          "-net nic,model=virtio,macaddr=$(cat /sys/class/net/vmpassthru/address)",
          "-net tap,fd=4 4<>/dev/tap$(cat /sys/class/net/vmpassthru/ifindex)"
         // ...
        ]
      }
      resources {
        cpu = 4000
        memory = 4000
      }
    }
  }
}

results in errors about the fd being non-numeric or otherwise invalid by qemu itself as I believe the task executor is passing the raw values through without shell interpolation.

I could convert this to a raw_exec task, and maybe that is the preferred approach, but I am curious if there is a way to do more advanced networking configuration such as macvtap with the qemu driver directly.

1 Like