Gracefully stop/shutdown macOS VMs


Audio01
Go to solution Solved by Audio01,

Recommended Posts

Hi, I'm trying to make stop/shutdown macOS VMs correctly.

 

I'm guessing that when the VM is tried to be stopped, a virsh shutdown command is issued, so the corresponding ACPI request is sent to the guest OS (in this case macOS). The problem is that this ACPI request only triggers the "Restart / Sleep / Cancel / Shut Down" dialog in macOS. So the VM never shutdowns gracefully (after 60 seconds it's "destroyed", i.e. "Force Stop").

 

I have some workarounds for this problem (with ssh and shutdown command, or sending an "Enter" keystroke to the VM with virsh, so the dialog mentioned before is bypassed), but the question is where to "inject" any of these commands, just after the Unraid "Stop" VM is issued.

 

Is there any place in Unraid (script?) that this "Stop" VM command is executed? Or some hook that could be inserted?

 

Any info really welcome! Thanks!

 

Edited by Audio01
Link to comment

Hi,

that is not a usual behavior, can you try in unraid terminal?

virsh shutdown MacOSVMName

and see what happens?

 

Also try:

virsh shutdown MacOSVMName --mode agent

 

The second command will use qemu guest agent inside mac os vm instead of acpi.

 

Did you have custom ssdt/dsdt injected that may interfere with the shutdown?

Link to comment

Hi!

10 hours ago, ghost82 said:

that is not a usual behavior, can you try in unraid terminal?

virsh shutdown MacOSVMName

and see what happens?

 

What happens is what I've described in my first post: virsh is obviously using mode ACPI (as default), the ACPI request for shutdown is sent to the VM, macOS accepts this request, but it only shows the "Restart / Sleep / Cancel / Shut Down" dialog.

 

P7jnhU.jpg

 

uahvMF.jpg

 

And the VM is stuck there. No automatic shutdown happens, ever. BTW, as inflexible that macOS is, there's no way to change this behavior. I already spent hours and hours trying to find any solution for this. 

 

10 hours ago, ghost82 said:

Also try:

virsh shutdown MacOSVMName --mode agent

 

The second command will use qemu guest agent inside mac os vm instead of acpi.

 

 

If I'm not wrong, there is no QEMU guest agent for macOS. If I try this, an error is displayed:

 

BxcbvK.jpg 

 

10 hours ago, ghost82 said:

Did you have custom ssdt/dsdt injected that may interfere with the shutdown?

 

Nothing. As mentioned, the ACPI request is received and accepted by macOS, but instead of shutting down, that annoying dialog window is issued.

 

The only choices I know, would be using SSH to send a shutdown command to macOS, or tricking the "Restart / Sleep / Cancel / Shut Down" dialog sending a keystroke with virsh. The problem is where to "intercept" those shutdown calls in the Unraid scripts.

 

Edited by Audio01
Link to comment

I have mac os vms installed since high sierra and it never happened, since most of the hardware is emulated we should have all near the same dsdt with the same acpi tables.

virsh shutdown in fact works for me.

The guest agent is included in mac os system, at least I'm 100% sure it's there in big sur and monterey, no need to install.

If you grep your cpu features in the vm and you have VMM, guest agent is automatically started.

What version of mac os you have?which bootloader?is it updated?Do you have the guest agent defined in the xml?Which q35 version you set in xml?

Edited by ghost82
Link to comment

Hi again, thank you for your quick answer!

 

I used SpaceinvaderOne's Macinabox app (docker + scripts) for the installation and setup:

 

I'm on Unraid v6.9.2 Stable, running on a Xeon E3-1230 V2 processor.

Installed macOS 10.4.6 (Majove). I can't use Big Sur or Monterey.

machdep.cpu.features in guest macOS shows me VMM support.

The bootloader is Opencore v0.7.0, the one installed by Macinabox.

I tried searching for QEMU guest agent support in macOS and didn't find anything relevant.

This is the xml of the VM. The Q35 is v4.2. About the agent, I'm not 100% sure. Is anything wrong in the xml?

 

<?xml version='1.0' encoding='UTF-8'?>
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>Macinabox Mojave</name>
  <uuid>cf1cb8db-d41c-401f-abfd-ed5ca27d4878</uuid>
  <description>MacOS Mojave</description>
  <metadata>
    <vmtemplate xmlns="unraid" name="Windows 10" icon="default.png" os="osx"/>
  </metadata>
  <memory unit='KiB'>8388608</memory>
  <currentMemory unit='KiB'>8388608</currentMemory>
  <memoryBacking>
    <nosharepages/>
  </memoryBacking>
  <vcpu placement='static'>4</vcpu>
  <cputune>
    <vcpupin vcpu='0' cpuset='0'/>
    <vcpupin vcpu='1' cpuset='4'/>
    <vcpupin vcpu='2' cpuset='1'/>
    <vcpupin vcpu='3' cpuset='5'/>
  </cputune>
  <os>
    <type arch='x86_64' machine='pc-q35-4.2'>hvm</type>
    <loader readonly='yes' type='pflash'>/mnt/user/system/custom_ovmf/Macinabox_CODE-pure-efi.fd</loader>
    <nvram>/etc/libvirt/qemu/nvram/cf1cb8db-d41c-401f-abfd-ed5ca27d4878_VARS-pure-efi.fd</nvram>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='host-passthrough' check='none' migratable='on'>
    <topology sockets='1' dies='1' cores='2' threads='2'/>
    <cache mode='passthrough'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/local/sbin/qemu</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='writeback'/>
      <source file='/mnt/user/domains/Macinabox Mojave/macos_disk.img'/>
      <target dev='hdc' bus='sata'/>
      <boot order='1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='2'/>
    </disk>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x10'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='2' port='0x11'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x12'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0x13'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x2'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:be:22:55'/>
      <source bridge='br0'/>
      <model type='e1000-82545em'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes' websocket='-1' listen='0.0.0.0' keymap='en-us'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </memballoon>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-usb'/>
    <qemu:arg value='-device'/>
    <qemu:arg value='usb-kbd,bus=usb-bus.0'/>
    <qemu:arg value='-device'/>
    <qemu:arg value='************************'/>
    <qemu:arg value='-smbios'/>
    <qemu:arg value='type=2'/>
    <qemu:arg value='-cpu'/>
    <qemu:arg value='Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,+pcid,+ssse3,+sse4.2,+popcnt,+avx,+aes,+xsave,+xsaveopt,check'/>
  </qemu:commandline>
</domain>

 

Edited by Audio01
Link to comment
9 hours ago, Audio01 said:
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>

It's there...

It could be the virtio type that doesn't play well with mojave.

 

You can check if the AppleQEMUGuestAgent is running, in a mac os terminal:

pgrep AppleQEMUGuestAgent

If it returns the process id number it's running.

 

If it's not running, try to manually start it, the binary should be inside /usr/libexec/ (check it):

cd /usr/libexec/
./AppleQEMUGuestAgent

 

Things you can try:

- change the machine version, from pc-q35-4.2 to 5.2; sometimes changing version slightly changes the dsdt

- update opencore: you can use this 0.7.7 version as a try:

https://github.com/SpaceinvaderOne/Macinabox/raw/7aab68aa382a07862d15998fdb28bd7b366f8715/bootloader/OpenCore.img.zip

First backup your current opencore img.

 

Disconnect internet if you logon with your apple id, since that image above has general smbios data.

 

In first place I would focus on making it working "natively" instead of playing with scripts.

Link to comment
  • Solution

Hi, just a quick update... I tried updating the bootloader, changing the machine version, even reinstalling Mojave with the updated Macinabox app (docker + scripts)... nothing worked.

 

The problem is with Mojave itself, it receives the ACPI shutdown request, but instead of shutting down, it displays that annoying dialog.

 

The QEMU agent doesn't seem to work. It isn't running, and if I execute it, nothing happens. No error, not a single message (although there're some basic logs without much info), and still the agent doesn't come alive. Looks like it's a bug that never was fixed.

 

I'm surprised that macOS (since Mojave, I guess) comes with a built-in QEMU agent. When I was looking for information there was no mention of it. Now that I searched for "AppleQEMUGuestAgent" I found some (few) posts about it.

 

Now, I tried Installing Big Sur and also Catalina. Stopping / shutting down the VM works 100% right!

 

Thank you @ghost82 for your help, really appreciated!

 

Edited by Audio01
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.