Tray proxy was unconditionally enabled for all crosvm VMs. Add
tray.enable so it must be opted into per VM. When disabled, neither
the host-side tray service nor the guest-side tray daemon are created.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The allowlist was derived from crosvm's gpu_common + gpu_device seccomp
policies, but those are applied after process startup. systemd applies
the filter before exec, so process lifecycle (execve, wait4, arch_prctl,
set_tid_address), capability management (capget, capset), and socket
server (bind, listen, accept4, socketpair) syscalls are also needed.
Also create a shader cache directory at /run/vmsilo/<name>/gpu/cache and
set __GL_SHADER_DISK_CACHE_PATH so the GPU device backend doesn't fail
trying to create /home for shader cache in the sandboxed mount namespace.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ensure each service unit creates its own runtime directory before
starting, as a safety net independent of tmpfiles. GPU and sound
services use install -d with correct user ownership so they can
create their sockets.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Generates a two-step launch script: starts cloud-hypervisor VMM,
waits for API socket, pushes JSON VM config via ch-remote, boots.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove --wayland-security-context, --gpu=, --gpu-render-server from
the crosvm command. The GPU is now provided by the external crosvm
device gpu service via --vhost-user type=gpu.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs crosvm device gpu as a separate sandboxed service per GPU VM,
with TemporaryFileSystem, DeviceAllow, CapabilityBoundingSet=,
and syscall filter derived from crosvm gpu_common + gpu_device policies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all sockets from /run/vmsilo/<name>-*.socket to
/run/vmsilo/<name>/*.socket for cleaner organization and
future sandboxing support.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The virtio transport adds latency jitter that the default 256-sample
ALSA headroom can't absorb, causing frequent XRUNs (1-3 per second).
Increase headroom to 1024 samples (~23ms at 44100Hz) so PipeWire
refills the buffer much earlier, giving the virtio path more room.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
xdg-desktop-portal 1.20.3's Realtime portal intercepts PipeWire's RT
scheduling requests but fails silently: it calls fstatat(pidfd, "ns/pid")
to check the caller's PID namespace, which returns ENOTDIR because pidfds
don't support being used as directory FDs on current kernels (6.18/6.19).
PipeWire uses fire-and-forget D-Bus and never sees the error.
Fix by granting the @audio group PAM limits (rtprio=95, nice=-19,
memlock=unlimited) so PipeWire's module-rt can call sched_setscheduler
directly, bypassing both the broken portal and rtkit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full isolation has too much impact to be a default. Even on an almost
unloaded machine with a couple of VMs running it results in audio buffer
underruns due to the significant scheduling latency.
This change is fine because with vmsilo, the trust domain is the VM. There
isn't much reason to protect apps from other apps running in the same VM.
Better to run those apps in separate VMs in that case.
/run/vmsilo is root-owned; the sound service runs as the configured user
and cannot create sockets there. Move the socket to /run/user/<uid>/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
User-facing script that lists USB devices, attaches them to VMs, or
detaches them. Attach/detach dispatch through systemd oneshot templates
for polkit authorization; listing reads sysfs directly (no root needed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sourced by the vmsilo-usb CLI, systemd oneshot services, and persistent
USB attach service. Provides sysfs enumeration, flock-based state file
management, and crosvm usb attach/detach wrappers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
systemd-networkd-wait-online interacts badly with non-routable interfaces. It
ends up slowing down system config activation waiting for routes that never
appear. Ignoring interfaces does not reliably fix this. Just disable the damn
thing until I find a better solution.
When a VM is not running, its TAP interface has no carrier, so networkd
refuses to assign static addresses (hostAddress) and the link gets stuck
in "configuring" state. This causes systemd-networkd-wait-online to block
for 2 minutes. Setting ConfigureWithoutCarrier=yes lets networkd assign
addresses immediately regardless of carrier state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
qcow2 causes O_DIRECT failures on ext4 due to crosvm doing unaligned
access when parsing the qcow2 header. Since we don't use any qcow2
features (the disk is created fresh and deleted on stop), a raw sparse
file via truncate works just as well and also removes the qemu package
dependency from the VM service.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous --ignore approach (6a28576) didn't prevent the timeout
because bridges stayed in "configuring" setup state waiting for IPv6
autoconfiguration that never arrives. Set RequiredForOnline=no,
IPv6AcceptRA=no and LinkLocalAddressing=no directly in the networkd
.network units for all vmsilo TAP and bridge interfaces.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents systemd-networkd-wait-online.service from timing out when
vmsilo TAP/bridge interfaces are not up (VMs not running), which
was causing long delays during nixos-rebuild switch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Emit the resolved VM color as an X-VmSilo-Color attribute in all
generated .desktop and .directory files, for kicker to draw colored
icon borders in the application menu.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused ifIndexToIfName and sanitizeName from helpers.nix
- Deduplicate normalizeBdfLocal in extractBdf (reuse module-level normalizeBdf)
- Remove unused sharedHomePath variable in scripts.nix
- Fix "Packate" typo in overlay.nix comment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route VM traffic through the host directly instead of requiring a
separate netvm VM. Uses the same nftables NAT and forward firewall
rules as VM-based netvms, applied on the host using TAP interface
names. Removes the hostNetworking.nat options in favor of the
unified netvm approach.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VMs with network.netvm now automatically pull in their netvm via
Wants=, ensuring the netvm starts when the client VM is started.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Under networkd, networking.bridges only generates .netdev and member
.network files but not a .network file for the bridge device itself.
Without a matching .network unit, networkd won't bring the bridge link
up. Add empty networking.interfaces entries for each bridge so networkd
manages them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds network.netvm / network.isNetvm options that auto-configure
point-to-point VM networking (host bridge, TAP interfaces, guest IPs,
default routes, masquerade NAT, and forward firewall rules) without
manual interface configuration.
New options:
programs.vmsilo.netvmRange — IP pool for /31 auto-allocation (default 10.200.0.0/16)
vm.network.isNetvm — mark VM as a network gateway
vm.network.netvm — route this VM through a named netvm
vm.network.netvmSubnet — override auto-allocated /31 (pin specific address)
Architecture:
modules/netvm.nix computes all (netvm, client) pairs and writes to
_internal.netvmInjections to avoid infinite recursion in the module
system. networking.nix, scripts.nix, and services.nix each have a
getEffectiveInterfaces helper that merges user-configured and
injected interfaces transparently.
Guest nftables config (masquerade NAT, forward isolation between
clients, ip_forward sysctl) is injected via _generatedGuestConfig
and merged into the rootfs build in scripts.nix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a bridge is added to the config and nixos-rebuild switch is run,
the per-bridge netdev service is not started automatically because
network-setup.service is already active (RemainAfterExit). Add Wants
and After dependencies on <bridge>-netdev.service for each bridge used
by a VM's TAP interfaces so systemd starts it on demand when the VM
service starts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add assertion to check user-specified tap.name overrides against Linux
IFNAMSIZ constraints (max 15 chars, letter start, alphanumeric/hyphen/
underscore). Previously only guest-visible interface names were validated;
invalid tap.name values would only surface as runtime kernel errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GPU VMs need a Wayland socket, so starting them at multi-user.target
(boot) fails. The session-bind user service now also starts autoStart
GPU VMs when the graphical session begins. Non-GPU VMs still start at
boot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>