Skip to content

Commit 02b9df4

Browse files
authored
Merge pull request #41 from torgeiru/virtio
Orchestration of various Virtio devices (reopened)
2 parents 26378e5 + afffb7d commit 02b9df4

File tree

2 files changed

+110
-4
lines changed

2 files changed

+110
-4
lines changed

vmrunner/vm.schema.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,52 @@
8080
}
8181
},
8282

83+
"virtiocon" : {
84+
"description" : "VirtioCON device. Only used for testing Virtio queues for now",
85+
"type" : "object",
86+
"properties" : {
87+
"path" : {
88+
"description" : "The path to redirect the guest output",
89+
"type" : "string"
90+
}
91+
},
92+
93+
"required" : ["path"]
94+
},
95+
96+
"virtiofs" : {
97+
"description" : "VirtioFS device",
98+
"type" : "object",
99+
"properties" : {
100+
"shared" : {
101+
"description" : "Directory to be shared with guest",
102+
"type" : "string"
103+
}
104+
},
105+
106+
"required" : ["shared"]
107+
},
108+
109+
"virtiopmem": {
110+
"description" : "VirtioPMEM devices",
111+
"type" : "array",
112+
"items" : {
113+
"description" : "Device configuration",
114+
"type" : "object",
115+
"properties" : {
116+
"image" : {
117+
"description" : "Path to persistent image file",
118+
"type" : "string"
119+
},
120+
"size" : {
121+
"description" : "Persistent memory size in megabytes",
122+
"type" : "number"
123+
}
124+
}
125+
},
126+
127+
"required" : ["image", "size"]
128+
},
83129

84130
"mem" : {
85131
"description" : "Amount of memory in megabytes",

vmrunner/vmrunner.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import re
2121
import traceback
2222
import signal
23+
import tempfile
2324
from enum import Enum
2425
import platform
2526
import psutil
@@ -184,8 +185,9 @@ def __init__(self, config):
184185
self._config = config
185186
self._allow_sudo = False # must be explicitly turned on at boot.
186187
self._enable_kvm = False # must be explicitly turned on at boot.
187-
self._sudo = False # Set to true if sudo is available
188-
self._proc = None # A running subprocess
188+
self._sudo = False # Set to true if sudo is available
189+
self._proc = None # A running subprocess
190+
self._tmp_dirs = [] # A list of tmp dirs created using tempfile module. Used for socket creation for automatic cleanup and garbage collection
189191

190192
# pylint: disable-next=unused-argument
191193
def boot_in_hypervisor(self, multiboot=False, debug=False, kernel_args="", image_name="", allow_sudo = False, enable_kvm = False):
@@ -418,6 +420,7 @@ class qemu(hypervisor):
418420
def __init__(self, config):
419421
super().__init__(config)
420422
self._proc = None
423+
self._virtiofsd_proc = None
421424
self._stopped = False
422425
self._sudo = False
423426
self._image_name = self._config if "image" in self._config else self.name() + " vm"
@@ -516,6 +519,41 @@ def net_arg(self, backend, device, if_name = "net0", mac = None, bridge = None,
516519
return ["-device", device,
517520
"-netdev", netdev]
518521

522+
def init_virtiocon(self, path):
523+
""" creates a console device and redirects to the path given """
524+
qemu_args = ["-device", "virtio-serial-pci,disable-legacy=on,id=virtio-serial0"]
525+
qemu_args += ["-device", "virtserialport,chardev=virtiocon0"]
526+
qemu_args += ["-chardev", f"file,id=virtiocon0,path={path}"]
527+
528+
return qemu_args
529+
530+
def init_virtiofs(self, socket, shared, mem):
531+
""" initializes virtiofs by launching virtiofsd and creating a virtiofs device """
532+
virtiofsd_args = ["virtiofsd", "--socket", socket, "--shared-dir", shared, "--sandbox", "none"]
533+
self._virtiofsd_proc = subprocess.Popen(virtiofsd_args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # pylint: disable=consider-using-with
534+
535+
if self._virtiofsd_proc.poll():
536+
raise Exception("VirtioFSD failed to start")
537+
538+
info("Successfully started VirtioFSD!")
539+
540+
while not os.path.exists(socket):
541+
...
542+
543+
qemu_args = ["-machine", "memory-backend=mem0"]
544+
qemu_args += ["-chardev", f"socket,id=virtiofsd0,path={socket}"]
545+
qemu_args += ["-device", "vhost-user-fs-pci,chardev=virtiofsd0,tag=vfs"]
546+
qemu_args += ["-object", f"memory-backend-memfd,id=mem0,size={mem}M,share=on"]
547+
548+
return qemu_args
549+
550+
def init_pmem(self, path, size, pmem_id):
551+
""" creates a pmem device with image path as memory mapped backend """
552+
qemu_args = ["-object", f"memory-backend-file,id=pmemdev{pmem_id},mem-path={path},size={size}M,share=on"]
553+
qemu_args += ["-device", f"virtio-pmem-pci,memdev=pmemdev{pmem_id}"]
554+
555+
return qemu_args
556+
519557
def kvm_present(self):
520558
""" returns true if KVM is present and available """
521559
if not self._enable_kvm:
@@ -660,7 +698,7 @@ def boot_in_hypervisor(self, multiboot=True, debug = False, kernel_args = "", im
660698

661699
mem_arg = []
662700
if "mem" in self._config:
663-
mem_arg = ["-m", str(self._config["mem"])]
701+
mem_arg = ["-m", f"size={self._config["mem"]},maxmem=1000G"]
664702

665703
vga_arg = ["-nographic" ]
666704
if "vga" in self._config:
@@ -674,6 +712,27 @@ def boot_in_hypervisor(self, multiboot=True, debug = False, kernel_args = "", im
674712
if "vfio" in self._config:
675713
pci_arg = ["-device", "vfio-pci,host=" + self._config["vfio"]]
676714

715+
virtiocon_args = []
716+
if "virtiocon" in self._config:
717+
virtiocon_args = self.init_virtiocon(self._config["virtiocon"]["path"])
718+
719+
virtiofs_args = []
720+
if "virtiofs" in self._config:
721+
tmp_virtiofs_dir = tempfile.TemporaryDirectory(prefix="virtiofs-") # pylint: disable=consider-using-with
722+
self._tmp_dirs.append(tmp_virtiofs_dir)
723+
socket_path = os.path.join(tmp_virtiofs_dir.name, "virtiofsd.sock")
724+
725+
shared = self._config["virtiofs"]["shared"]
726+
727+
virtiofs_args = self.init_virtiofs(socket_path, shared, self._config["mem"])
728+
729+
virtiopmem_args = []
730+
if "virtiopmem" in self._config:
731+
for pmem_id, virtiopmem in enumerate(self._config["virtiopmem"]):
732+
image = virtiopmem["image"]
733+
size = virtiopmem["size"]
734+
virtiopmem_args += self.init_pmem(image, size, pmem_id)
735+
677736
# custom qemu binary/location
678737
qemu_binary = "qemu-system-x86_64"
679738
if "qemu" in self._config:
@@ -703,7 +762,8 @@ def boot_in_hypervisor(self, multiboot=True, debug = False, kernel_args = "", im
703762

704763
command += kernel_args
705764
command += disk_args + debug_args + net_args + mem_arg + mod_args
706-
command += vga_arg + trace_arg + pci_arg
765+
command += vga_arg + trace_arg + pci_arg + virtiocon_args + virtiofs_args
766+
command += virtiopmem_args
707767

708768
#command_str = " ".join(command)
709769
#command_str.encode('ascii','ignore')

0 commit comments

Comments
 (0)