fix(host): bring up VMware host stack at boot via native systemd units

Build VMs stopped starting after a reboot into a new kernel: vmmon/vmnet
were left unloaded and vmnet1/vmnet8 (DHCP/NAT) never came up, so
vmware-vmx died (status=237/KEYRING) and clones got no IP. Root cause:
the LSB->systemd sysv-generated vmware.service intermittently fails to
generate at early boot ("systemd-sysv-generator: Cannot find unit
vmware.service"), and the existing module-rebuild guard only builds the
modules -- it never loads them or starts vmnet networking.

Add a native vmware-host.service that runs `/etc/init.d/vmware start`
(loads vmmon/vmci + brings up vmnet), ordered after the rebuild guard,
and mask the flaky sysv vmware.service so the native unit is the sole
owner. Provisioned by scripts/install-vmware-host-services.sh and wired
into setup-host-linux.sh (new step 8/9). VMware ships no native unit and
no kernel postinst hook, so this native wrapper around VMware's own
tools is the reliable boot path.

Verified: linked clone boots and gets a vmnet8 DHCP IP.
This commit is contained in:
2026-07-19 19:47:16 +02:00
parent 92bea69f19
commit 19186981a5
7 changed files with 234 additions and 14 deletions
+47
View File
@@ -84,3 +84,50 @@ sudo systemctl daemon-reload
A questo punto il fallback è ri-attivare i task su Windows con
`scripts/Register-CIScheduledTasks.ps1`.
---
## Servizi VMware host (prerequisito avvio VM)
Distinti dai timer periodici sopra: due unit **native** che portano su lo stack
host di VMware Workstation a ogni boot. Servono perché VMware su Linux **non**
fornisce unit systemd native, **non** registra `vmmon`/`vmnet` con DKMS e **non**
installa hook di post-install del kernel.
| unit | ruolo |
| ---- | ----- |
| `vmware-modules-rebuild.service` | ricostruisce `vmmon`/`vmnet` via `vmware-modconfig` se il `.ko` per il kernel in esecuzione manca (guard *build-if-missing*). Ordinata `Before=vmware-host.service`. Script: `/usr/local/sbin/vmware-modules-rebuild.sh`. |
| `vmware-host.service` | esegue `/etc/init.d/vmware start` → carica `vmmon`/`vmci` e avvia la rete `vmnet1`/`vmnet8` (DHCP/NAT). Ordinata `After=vmware-modules-rebuild.service`. |
Il sysv `vmware.service` (LSB) viene **mascherato**: si è dimostrato inaffidabile
da generare al boot (`systemd-sysv-generator: Cannot find unit vmware.service`),
lasciando `vmmon` non caricato e la rete VM giù → le build VM non partono.
`vmware-host.service` ne diventa l'unico owner.
### Installazione
```bash
sudo ./scripts/install-vmware-host-services.sh # installa + enable + start (idempotente)
```
Installato anche automaticamente da `setup-host-linux.sh` (Step 8/9).
### Verifica
```bash
systemctl is-enabled vmware-host.service vmware-modules-rebuild.service
lsmod | grep -E 'vmmon|vmnet'
ip -o link show | grep vmnet # attese: vmnet1, vmnet8
```
### Recovery (stack giù, VM non partono)
```bash
sudo systemctl start vmware-host.service
```
### Rollback
```bash
sudo ./scripts/install-vmware-host-services.sh --uninstall
```
+21
View File
@@ -0,0 +1,21 @@
[Unit]
Description=Start VMware Workstation host stack (vmmon/vmci + vmnet networking)
Documentation=man:vmware(1)
# Native replacement for the flaky LSB->systemd sysv-generated vmware.service,
# which intermittently fails to generate at early boot ("Cannot find unit
# vmware.service"), leaving vmmon unloaded and vmnet DHCP/NAT down so VMs
# cannot start. The rebuild guard ensures the modules are built first; this
# unit loads them and brings up vmnet1/vmnet8 via VMware's own init script.
Wants=vmware-modules-rebuild.service
After=vmware-modules-rebuild.service network-pre.target local-fs.target
ConditionPathExists=/etc/init.d/vmware
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/etc/init.d/vmware start
ExecStop=/etc/init.d/vmware stop
TimeoutStartSec=120
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,17 @@
[Unit]
Description=Rebuild VMware host modules (vmmon/vmnet) for running kernel if missing
Documentation=man:vmware-modconfig(1)
# VMware modules are not DKMS-managed; ensure they exist before vmware-host starts.
After=local-fs.target
Before=vmware-host.service
ConditionPathExists=/usr/bin/vmware-modconfig
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/vmware-modules-rebuild.sh
# Building modules can take a little while on a cold kernel.
TimeoutStartSec=600
[Install]
WantedBy=multi-user.target
+28
View File
@@ -0,0 +1,28 @@
#!/bin/sh
# Rebuild VMware host modules (vmmon/vmnet) for the running kernel if absent.
# VMware Workstation does not register these with DKMS, so a kernel upgrade
# leaves them unbuilt until the GUI or vmware-modconfig is run. This runs at
# boot, before vmware-host.service, and self-heals using VMware's own builder.
set -eu
KVER="$(uname -r)"
if /sbin/modinfo vmmon >/dev/null 2>&1 && /sbin/modinfo vmnet >/dev/null 2>&1; then
# Module objects already present for the running kernel — nothing to do.
exit 0
fi
logger -t vmware-modules-rebuild "vmmon/vmnet missing for kernel ${KVER} — rebuilding via vmware-modconfig"
if ! command -v vmware-modconfig >/dev/null 2>&1; then
logger -t vmware-modules-rebuild "ERROR: vmware-modconfig not found"
exit 1
fi
# vmware-modconfig builds against the running kernel's headers.
if /usr/bin/vmware-modconfig --console --install-all; then
logger -t vmware-modules-rebuild "rebuild complete for kernel ${KVER}"
else
logger -t vmware-modules-rebuild "ERROR: vmware-modconfig failed (headers for ${KVER} installed?)"
exit 1
fi