1
0
Fork 1
mirror of https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git synced 2025-07-25 13:35:09 +03:00

Qemu support for the QXL driver and SPICE (#481)

* pmb.helpers.run: support running processes in background
* enable QXL driver support in the linux kernel configurations so
that we can also use SPICE to connect to the VM.

QXL is a paravirtual graphics driver with 2D support

The SPICE project aims to provide a complete open source solution for remote
access to virtual machines in a seamless way.

Both DRM_QXL and DRM_BOCHS are enabled as modules.
According to [1], on Linux guests, the qxl and bochs_drm kernel modules
must be loaded in order to gain a decent performance

* qemu: add new option --spice to connect to VM using a SPICE client

If specified, 'pmbootstrap qemu' will look for some SPICE client in the
user's PATH and run qemu using the QXL driver.

Currently supported spice clients are 'spicy' and 'remote-viewer' but
adding support for more clients can be easily done.

qemu with qxl support will run on port 8077/tcp, which doesn't belong to
any well-known service and represents 'PM' in decimal.

References:
[0] https://www.linux-kvm.org/page/SPICE
[1] https://wiki.archlinux.org/index.php/QEMU#qxl
[2] https://wiki.archlinux.org/index.php/QEMU#SPICE
[3] https://github.com/postmarketOS/pmbootstrap/issues/453 (partially fixed)
This commit is contained in:
Pablo Castellano 2017-09-26 22:52:00 +02:00 committed by Oliver Smith
parent d48ca092b4
commit c855ee095b
13 changed files with 137 additions and 49 deletions

View file

@ -63,7 +63,49 @@ def which_qemu(args, arch):
" run qemu.")
def qemu_command(args, arch, device, img_path):
def which_spice(args):
"""
Finds some SPICE executable or raises an exception otherwise
:returns: tuple (spice_was_found, path_to_spice_executable)
"""
executables = ["remote-viewer", "spicy"]
for executable in executables:
if shutil.which(executable):
return executable
return None
def spice_command(args):
"""
Generate the full SPICE command with arguments connect to
the virtual machine
:returns: tuple (dict, list), configuration parameters and spice command
"""
parameters = {
"spice_addr": "127.0.0.1",
"spice_port": "8077"
}
if not args.use_spice:
parameters["enable_spice"] = False
return parameters, []
spice_binary = which_spice(args)
if not spice_binary:
parameters["enable_spice"] = False
return parameters, []
spice_addr = parameters["spice_addr"]
spice_port = parameters["spice_port"]
commands = {
"spicy": ["spicy", "-h", spice_addr, "-p", spice_port],
"remote-viewer": [
"remote-viewer",
"spice://" + spice_addr + "?port=" + spice_port
]
}
parameters["enable_spice"] = True
return parameters, commands[spice_binary]
def qemu_command(args, arch, device, img_path, config):
"""
Generate the full qemu command with arguments to run postmarketOS
"""
@ -132,6 +174,13 @@ def qemu_command(args, arch, device, img_path):
else:
logging.info("Warning: qemu is not using KVM and will run slower!")
# QXL / SPICE (2D acceleration support)
if config["enable_spice"]:
command += ["-vga", "qxl"]
command += ["-spice",
"port={spice_port},addr={spice_addr}".format(**config) +
",disable-ticketing"]
return command
@ -179,18 +228,20 @@ def run(args):
arch = pmb.parse.arch.uname_to_qemu(args.arch_native)
if args.arch:
arch = pmb.parse.arch.uname_to_qemu(args.arch)
logging.info("Running postmarketOS in QEMU VM (" + arch + ")")
device = pmb.parse.arch.qemu_to_pmos_device(arch)
img_path = system_image(args, device)
spice_parameters, command_spice = spice_command(args)
# Workaround: qemu runs as local user and needs write permissions in the
# system image, which is owned by root
if not os.access(img_path, os.W_OK):
pmb.helpers.run.root(args, ["chmod", "666", img_path])
command = qemu_command(args, arch, device, img_path)
run_spice = spice_parameters["enable_spice"]
command = qemu_command(args, arch, device, img_path, spice_parameters)
logging.info("Running postmarketOS in QEMU VM (" + arch + ")")
logging.info("Command: " + " ".join(command))
if args.image_size:
@ -200,9 +251,31 @@ def run(args):
" the system image size when you run out of space!")
print()
logging.info("You can connect to the Virtual Machine using the"
logging.info("You can connect to the virtual machine using the"
" following services:")
logging.info("(ssh) ssh -p " + str(args.port) + " user@localhost")
logging.info("(telnet) telnet localhost " + str(args.port + 1))
logging.info("(telnet debug) telnet localhost " + str(args.port + 2))
pmb.helpers.run.user(args, command)
# SPICE related messages
if not run_spice:
if args.use_spice:
logging.warning("WARNING: Could not find any SPICE client (spicy,"
" remote-viewer) in your PATH, starting without"
" SPICE support!")
else:
logging.info("NOTE: Consider using --spice for potential"
" performance improvements (2d acceleration)")
try:
process = pmb.helpers.run.user(args, command, background=run_spice)
# Launch SPICE client
if run_spice:
logging.info("Command: " + " ".join(command_spice))
pmb.helpers.run.user(args, command_spice)
except KeyboardInterrupt:
pass
finally:
if process:
process.terminate()