2020import re
2121import traceback
2222import signal
23+ import tempfile
2324from enum import Enum
2425import platform
2526import 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