Skip to content

Instantly share code, notes, and snippets.

@grahamc

grahamc/zvol.nix Secret

Created October 11, 2018 01:06
Show Gist options
  • Save grahamc/c7d2c9044ba6e3c1c4d4a5784f10e098 to your computer and use it in GitHub Desktop.
Save grahamc/c7d2c9044ba6e3c1c4d4a5784f10e098 to your computer and use it in GitHub Desktop.
{ pkgs, ... }:
let
# todo: use NixOS options =)
srcImagePath = /root/OSX-KVM/mac-hdd-2-initial-setup.img;
srcImage = toString srcImagePath; # UGGGGH
zfsRoot = "rpool";
pristineSnapshotName = "pristine";
ovmfCodeFile = /root/OSX-KVM/OVMF_CODE.fd;
ovmfVarsFile = /root/OSX-KVM/OVMF_VARS-1024x768.fd;
cloverImage = /root/OSX-KVM/Clover.qcow2;
imageName = builtins.baseNameOf srcImage;
zvolName = "${zfsRoot}/${imageName}";
snapshotName = "${zvolName}@${pristineSnapshotName}";
zvolDevice = "/dev/zvol/${zvolName}";
# helper functions
sanitizeUnitName = builtins.replaceStrings
[ "/" ]
[ "-" ];
loadServiceName = "load-image-${sanitizeUnitName zvolName}";
in {
systemd.services."run-macos-vm-${sanitizeUnitName zvolName}" = {
after = [ "${loadServiceName}.service" ];
requires = [ "${loadServiceName}.service" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [ zfs qemu ];
preStart = "zfs rollback ${snapshotName}";
postStop = "zfs rollback ${snapshotName}";
script = ''
MY_OPTIONS="+aes,+xsave,+avx,+xsaveopt,avx2,+smep"
qemu-system-x86_64 -enable-kvm -m 3072 -cpu Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,$MY_OPTIONS\
-machine pc-q35-2.9 \
-smp cpus=8,cores=4,threads=2,sockets=1 -m 14336 \
-usb -device usb-kbd -device usb-tablet \
-device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" \
-drive if=pflash,format=raw,readonly,file=${ovmfCodeFile} \
-drive if=pflash,format=raw,snapshot=on,file=${ovmfVarsFile} \
-smbios type=2 \
-device ich9-intel-hda -device hda-duplex \
-device ide-drive,bus=ide.2,drive=Clover \
-drive id=Clover,if=none,snapshot=on,format=qcow2,file='${cloverImage}' \
-device ide-drive,bus=ide.1,drive=MacHDD \
-drive id=MacHDD,cache=unsafe,if=none,file=${zvolDevice},format=raw \
-netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000-82545em,netdev=net0,id=net0,mac=52:54:00:c9:18:27 \
-vnc 127.0.0.1:0
'';
};
systemd.services."${loadServiceName}" = {
path = with pkgs; [ zfs qemu jq ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
if [ ! -b ${zvolDevice} ]; then
zfs create -V \
"$(qemu-img info "${srcImage}" --output=json | jq '."virtual-size"')" \
"${zvolName}"
if ! qemu-img dd \
if="${srcImage}" \
of="${zvolDevice}" \
-O raw bs=250000000; then
echo "failed to qemu-img dd, destroying"
zfs destroy -r "${zvolName}"
fi
# bs seems to be just about memory, and, well, every machine should have
# 250m to spare. Setting it so high makes the import MUCH faster than the
# default 512: ~5min instead of ~40min.
fi
if ! zfs get all "${snapshotName}"; then
zfs snapshot "${snapshotName}"
fi
'';
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment