
From: Simon Glass <sjg@chromium.org> Move this code into the helper so that build-efi can use it too. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-qemu | 84 ++---------------------------------- scripts/build_helper.py | 94 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 81 deletions(-) diff --git a/scripts/build-qemu b/scripts/build-qemu index 6c1f10061c4..2635646f8a0 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -41,8 +41,6 @@ def parse_args(): description='Build and/or run U-Boot with QEMU', formatter_class=argparse.RawTextHelpFormatter) build_helper.add_common_args(parser) - parser.add_argument('-D', '--share-dir', metavar='DIR', - help='Directory to share into the guest via virtiofs') parser.add_argument('-e', '--sct-run', action='store_true', help='Run UEFI Self-Certification Test (SCT)') parser.add_argument('-E', '--use-tianocore', action='store_true', @@ -284,85 +282,9 @@ class BuildQemu: # Add other parameters gathered from options qemu_cmd.extend(self.qemu_extra) - sock = Path('/tmp/virtiofs.sock') - proc = None - if self.args.share_dir: - virtfs_dir = Path(self.args.share_dir) - if not virtfs_dir.is_dir(): - tout.fatal(f'Error: VirtFS share directory {virtfs_dir} ' - f'is not a valid directory') - - virtiofsd = Path('/usr/libexec/virtiofsd') - if not virtiofsd.exists(): - tout.fatal(f'Error: virtiofsd not found at {virtiofsd}') - - # Clean up potential old socket file - if sock.exists(): - try: - sock.unlink() - tout.info(f'Removed old socket file {sock}') - except OSError as e: - tout.warning( - f'Warning: Could not remove old socket file {sock}: ' - f'{e}') - - qemu_cmd.extend([ - '-chardev', f'socket,id=char0,path={sock}', - '-device', - 'vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=hostshare', - '-object', - f'memory-backend-file,id=mem,size={self.helper.mem},' - 'mem-path=/dev/shm,share=on', - '-numa', 'node,memdev=mem']) - - virtiofsd_cmd = [ - str(virtiofsd), - '--socket-path', str(sock), - '--shared-dir', str(virtfs_dir), - '--cache', 'auto'] - try: - # Use Popen to run virtiofsd in the background - proc = subprocess.Popen(virtiofsd_cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - # Give virtiofsd a moment to start and create the socket - time.sleep(0.5) - if not sock.exists() and proc.poll() is not None: - stdout, stderr = proc.communicate() - tout.error('Error starting virtiofsd. Exit code: ' - f'{proc.returncode}') - if stdout: - tout.error(f"virtiofsd stdout:\n{stdout.decode()}") - if stderr: - tout.error(f"virtiofsd stderr:\n{stderr.decode()}") - tout.fatal('Failed') - - except (subprocess.CalledProcessError, FileNotFoundError) as exc: - tout.fatal(f'Failed to start virtiofsd: {exc}') - - tout.info(f'QEMU:\n{shlex.join(qemu_cmd)}\n') - try: - subprocess.run(qemu_cmd, check=True) - except FileNotFoundError: - tout.fatal(f"Error: QEMU executable '{self.helper.qemu}' not found") - except subprocess.CalledProcessError as e: - tout.fatal(f'QEMU execution failed with exit code {e.returncode}') - finally: - # Clean up virtiofsd process and socket if it was started - if proc: - tout.info('Terminating virtiofsd') - proc.terminate() - try: - proc.wait(timeout=5) - except subprocess.TimeoutExpired: - tout.warning( - 'virtiofsd did not terminate gracefully; killing') - proc.kill() - if sock.exists(): - try: - sock.unlink() - except OSError as e_os: - tout.warning('Warning: Could not remove virtiofs ' - f'socket {sock}: {e_os}') + self.helper.setup_share(qemu_cmd) + + self.helper.run(qemu_cmd) def start(self): """Build and run QEMU""" diff --git a/scripts/build_helper.py b/scripts/build_helper.py index e3cf42593d9..136d27da61b 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -9,9 +9,11 @@ import contextlib import os from pathlib import Path import shutil +import shlex import subprocess import sys import tempfile +import time OUR_PATH = os.path.dirname(os.path.realpath(__file__)) OUR1_PATH = os.path.dirname(OUR_PATH) @@ -32,6 +34,8 @@ class Helper: def __init__(self, args): self.settings = None self.imagedir = None + self.proc = None + self.sock = None self.args = args self.mem = '512' self.bitness = 32 if args.word_32bit else 64 @@ -185,6 +189,94 @@ sct_mnt = /mnt/sct cmd.extend(['-object', 'rng-random,filename=/dev/urandom,id=rng0', '-device', 'virtio-rng-pci,rng=rng0']) + def setup_share(self, qemu_cmd): + sock = Path('/tmp/virtiofs.sock') + proc = None + if self.args.share_dir: + virtfs_dir = Path(self.args.share_dir) + if not virtfs_dir.is_dir(): + tout.fatal(f'Error: VirtFS share directory {virtfs_dir} ' + f'is not a valid directory') + + virtiofsd = Path('/usr/libexec/virtiofsd') + if not virtiofsd.exists(): + tout.fatal(f'Error: virtiofsd not found at {virtiofsd}') + + # Clean up potential old socket file + if sock.exists(): + try: + sock.unlink() + tout.info(f'Removed old socket file {sock}') + except OSError as e: + tout.warning( + f'Warning: Could not remove old socket file {sock}: ' + f'{e}') + + qemu_cmd.extend([ + '-chardev', f'socket,id=char0,path={sock}', + '-device', + 'vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=hostshare', + '-object', + f'memory-backend-file,id=mem,size={self.mem},mem-path=/dev/shm' + ',share=on', + '-numa', 'node,memdev=mem']) + + virtiofsd_cmd = [ + str(virtiofsd), + '--socket-path', str(sock), + '--shared-dir', str(virtfs_dir), + '--cache', 'auto'] + try: + # Use Popen to run virtiofsd in the background + proc = subprocess.Popen(virtiofsd_cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + # Give virtiofsd a moment to start and create the socket + time.sleep(0.5) + if not sock.exists() and proc.poll() is not None: + stdout, stderr = proc.communicate() + tout.error('Error starting virtiofsd. Exit code: ' + f'{proc.returncode}') + if stdout: + tout.error(f"virtiofsd stdout:\n{stdout.decode()}") + if stderr: + tout.error(f"virtiofsd stderr:\n{stderr.decode()}") + tout.fatal('Failed') + self.proc = proc + self.sock = sock + + except (subprocess.CalledProcessError, FileNotFoundError) as exc: + tout.fatal(f'Failed to start virtiofsd: {exc}') + + def cleanup_share(self): + # Clean up virtiofsd process and socket if it was started + if self.proc: + tout.info('Terminating virtiofsd') + self.proc.terminate() + try: + self.proc.wait(timeout=5) + except subprocess.TimeoutExpired: + tout.warning( + 'virtiofsd did not terminate gracefully; killing') + self.proc.kill() + if self.sock.exists(): + try: + self.sock.unlink() + except OSError as e_os: + tout.warning('Warning: Could not remove virtiofs ' + f'socket {self.sock}: {e_os}') + + def run(self, qemu_cmd): + tout.info(f'QEMU:\n{shlex.join(qemu_cmd)}\n') + try: + if self.args.run: + subprocess.run(qemu_cmd, check=True) + except FileNotFoundError: + tout.fatal(f"Error: QEMU executable '{self.qemu}' not found") + except subprocess.CalledProcessError as e: + tout.fatal(f'QEMU execution failed with exit code {e.returncode}') + finally: + self.cleanup_share() + def add_common_args(parser): """Add some arguments which are common to build-efi/qemu scripts @@ -199,6 +291,8 @@ def add_common_args(parser): help="Enable linux console (x86 only)") parser.add_argument('-d', '--disk', nargs='*', help='Root disk image file to use with QEMU') + parser.add_argument('-D', '--share-dir', metavar='DIR', + help='Directory to share into the guest via virtiofs') parser.add_argument('-I', '--initrd', help='Initial ramdisk to run using -initrd') parser.add_argument( -- 2.43.0