
{
    "version": "https://jsonfeed.org/version/1.1",
    "title": "Linux on jtagcat's tail (formerly tail.jtag.cat)",
    "home_page_url": "https://tail.c7.ee/tags/linux/",
    "feed_url": "https://tail.c7.ee/tags/linux/feed.json",
    "items": [
        {
            "id": "https://tail.c7.ee/coral-usb-proxmox-passthrough/",
            "url": "https://tail.c7.ee/coral-usb-proxmox-passthrough/",
            "date_published": "2025-11-11T00:00:00Z",
            "title": "Coral USB Passthrough to Proxmox VM",
            "content_html": "\u003cp\u003eIt was time to disassemble the year-long temporary \u003ca href=\"https://frigate.video\"\u003eFrigate\u003c/a\u003e machine to continue in a standardized Kubernetes setup (running in VMs). The Proxmox machines don\u0026rsquo;t have M.2 slots, but they do have plenty of internal USB ports. Passthrough wasn\u0026rsquo;t straight forward.\u003c/p\u003e\n\u003cp\u003eXtremeOwnaga \u003ca href=\"https://static.xtremeownage.com/blog/2023/proxmox---coral-tpu-usb-passthrough/#step-1-install-coral-tpu-drivers-on-proxmox\"\u003edocumented\u003c/a\u003e it working, but with the proprietary driver installed on the hypervisor – which an another admin didn\u0026rsquo;t find acceptable. After a while debugging, the following conditions have to be met:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe machine type has to be \u003ccode\u003eq35\u003c/code\u003e. Mind that \u003ccode\u003ecloud-init\u003c/code\u003e does not run (on Debian \u003ca href=\"https://git.k-space.ee/k-space/ansible/src/commit/2e17161243f9786cfcce8c4e6fede3db6cd9bbd0/proxmox/admin_scripts/template.sh\"\u003ecloud images\u003c/a\u003e), it is reasonable to boot the machine once with \u003ccode\u003ei440fx\u003c/code\u003e first.\u003c/li\u003e\n\u003cli\u003eThe cloud kernel does not have USB drivers: replace \u003ccode\u003elinux-image-cloud-amd64\u003c/code\u003e with \u003ccode\u003elinux-image-amd64\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eVM has Coral drivers: \u003ccode\u003elibedgetpu1-std\u003c/code\u003e (\u003ca href=\"https://git.k-space.ee/k-space/ansible/src/commit/2e17161243f9786cfcce8c4e6fede3db6cd9bbd0/kubernetes-nodes.yaml\"\u003eansible\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFinding the correct hub/port (not device, as the TPU reboots once the driver loads) to pass through was a challenge for the specific Supermicro server – the USB hubs have identical identifiers:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ePVE docs refer to \u003ccode\u003epvesh get /nodes/\u0026lt;name\u0026gt;/hardware/pci --pci-class-blacklist \u0026quot;\u0026quot;\u003c/code\u003e and \u003ccode\u003elspci\u003c/code\u003e as to hail IOMMU and pass it as a raw PCI(e) device, which, with the dupes, didn\u0026rsquo;t really work.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eusb-devices\u003c/code\u003e (from \u003ccode\u003eusbutils\u003c/code\u003e) ended up being the most informative, where I could see where the numbers in the other commands came from.\u003c/li\u003e\n\u003cli\u003eUltimately, \u003ccode\u003elsusb\u003c/code\u003e (\u003ccode\u003e-t\u003c/code\u003e / \u003ccode\u003e-v\u003c/code\u003e) does the job, look for \u003ccode\u003eGoogle Inc.\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eVM: Hardware → Add → USB Device → Use USB Port. Mine ended up being \u003ccode\u003e6-1\u003c/code\u003e. Make sure to the virtual machine is pinned to the node in HA.\u003c/p\u003e\n"
        }, 
        {
            "id": "https://tail.c7.ee/zfs-freeze/",
            "url": "https://tail.c7.ee/zfs-freeze/",
            "date_published": "2023-10-03T00:00:00Z",
            "title": "zfs-freeze: External atomic backups",
            "content_html": "\u003cp\u003eI use \u003ca href=\"https://docs.oracle.com/cd/E18752_01/html/819-5461/gbchx.html\"\u003e\u003ccode\u003ezfs-send\u003c/code\u003e\u003c/a\u003e for backups, but not all destinations\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e support it. Backing up live systems is problematic — while non-atomic \u003cstrong\u003eordered\u003c/strong\u003e rollbacks are business as usual, segmented backups lead to corrupted databases and broken restores.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://12factor.net\"\u003eTwelve-Factor Apps\u003c/a\u003e included: even if state isn\u0026rsquo;t derived from multiple sources, references can still break. For example, when blob storage is backed up a minute before the database, the restored application could hold a broken reference to an image, which doesn\u0026rsquo;t exist.\u003c/p\u003e\n\u003cp\u003eIn small (yet sizable) systems, surgical strategizing is unnecessary. With the power of \u003ccode\u003e$ zfs snapshot tank/apps/{db,s3}/cutie\u003c/code\u003e\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e and \u003ccode\u003ezfs-send\u003c/code\u003e, we are done. But what\u0026rsquo;s the shiny fridge all about?\u003c/p\u003e\n\u003cp\u003eStaying in the ecosystem, we trust ZFS with all copies of our data. To manage the risk, I backup to a technologically isolated system. However, generic tooling doesn\u0026rsquo;t provide the same consistency guarantees; thus I created a script to expose latest snapshots with multiple datasets.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eThe bash prototype wasn\u0026rsquo;t compatible with \u003ca href=\"https://en.wikipedia.org/wiki/Setuid\"\u003esetuid\u003c/a\u003e\u003csup id=\"fnref:3\"\u003e\u003ca href=\"#fn:3\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e3\u003c/a\u003e\u003c/sup\u003e. Satisfying the binary requirement, I reimplemented it in Go, with extra features.\u003c/p\u003e\n\u003cp\u003eIllustrative usage of \u003ca href=\"https://github.com/jtagcat/jtagcat/tree/main/compile-scripts/zfs-freeze\"\u003e\u003ccode\u003ezfs-freeze\u003c/code\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Dataset I want to backup: tank/top (and all sub-datasets)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# One-time setup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ego install github.com/jtagcat/jtagcat/compile-scripts/zfs-freeze@latest\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo chown root:root \u003cspan class=\"nv\"\u003e$GOPATH\u003c/span\u003e/bin/zfs-freeze\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo chmod \u003cspan class=\"m\"\u003e4755\u003c/span\u003e \u003cspan class=\"nv\"\u003e$GOPATH\u003c/span\u003e/bin/zfs-freeze\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo mv \u003cspan class=\"nv\"\u003e$GOPATH\u003c/span\u003e/bin/zfs-freeze /usr/local/bin\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ezfs create tank/_freeze_top\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Regular backups:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003efrozen_dataset\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003ezfs-freeze tank/top restic-cup-\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003edate --rfc-3339\u003cspan class=\"o\"\u003e=\u003c/span\u003edate\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# will create tank/_freeze_top/restic-cup-2023-10-03\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efunction\u003c/span\u003e cleanup \u003cspan class=\"o\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  zfs-freeze -d \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$frozen_dataset\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003etrap\u003c/span\u003e cleanup EXIT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erestic -r cup: -p crypt.key backup \u003cspan class=\"s2\"\u003e\u0026#34;/\u003c/span\u003e\u003cspan class=\"nv\"\u003e$frozen_dataset\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdetails\u003e\u003csummary\u003eTemplates for Hetzner: rsync and \u003ca href=\"https://restic.net/\"\u003erestic\u003c/a\u003e\u003c/summary\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003efrozen_dataset\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003ezfs-freeze tank/top restic-cup-\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003edate --rfc-3339\u003cspan class=\"o\"\u003e=\u003c/span\u003edate\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efunction\u003c/span\u003e cleanup \u003cspan class=\"o\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  zfs-freeze -d \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$frozen_dataset\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003etrap\u003c/span\u003e cleanup EXIT\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ersync -e \u003cspan class=\"s2\"\u003e\u0026#34;ssh -p23 -oUserKnownHostsFile=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e/.ssh/known_hosts -oIdentityFile=hetzner_\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.key\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      --archive --delete --compress \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      --exclude\u003cspan class=\"o\"\u003e=\u003c/span\u003e.stversions \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      --relative -- /\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$frozen_dataset\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e/./\u003cspan class=\"o\"\u003e{\u003c/span\u003edirs,to,backup\u003cspan class=\"o\"\u003e}\u003c/span\u003e/ \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e@\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.your-storagebox.de:\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sh\" data-lang=\"sh\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erestic -r sftp:: -p restic.key -o sftp.command\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ssh \u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.your-storagebox.de -p23 -oIdentityFile=hetzner_\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.key -l \u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e -s sftp\u0026#34;\u003c/span\u003e unlock --quiet\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erestic -r sftp:: -p restic.key -o sftp.command\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ssh \u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.your-storagebox.de -p23 -oIdentityFile=hetzner_\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e.key -l \u003c/span\u003e\u003cspan class=\"nv\"\u003e$HETZNER_USER\u003c/span\u003e\u003cspan class=\"s2\"\u003e -s sftp\u0026#34;\u003c/span\u003e backup --quiet --exclude-file \u003cspan class=\"s2\"\u003e\u0026#34;restic.excludes\u0026#34;\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;/\u003c/span\u003e\u003cspan class=\"nv\"\u003e$frozen_dataset\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/details\u003e\n\n\u003cp\u003eWriting the helper, I yearned to use \u003ca href=\"https://github.com/jtagcat/hcli\"\u003ehcli\u003c/a\u003e: I could\u0026rsquo;ve avoided errors in parsing arguments, and skipped a refactor.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eExhibit A: Hetzner\u0026rsquo;s (cheap!) pure ZFS storage boxes\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eHelpers such as \u003ca href=\"https://github.com/jimsalterjrs/sanoid\"\u003eSanoid\u003c/a\u003e and \u003ca href=\"https://github.com/zrepl/zrepl\"\u003ezrepl\u003c/a\u003e, do not snapshot \u003cstrong\u003eacross datasets\u003c/strong\u003e atomically, only in rapid succession (\u003ccode\u003e$ zfs snapshot tank/apps/db/cutie \u0026amp;\u0026amp; zfs snapshot tank/apps/s3/cutie\u003c/code\u003e).\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:3\"\u003e\n\u003cp\u003eOutside of \u003ca href=\"https://nixos.org/\"\u003eNix\u003c/a\u003e, setuid wrappers are a hassle.\u0026#160;\u003ca href=\"#fnref:3\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n"
        }, 
        {
            "id": "https://tail.c7.ee/pitchy-vlc/",
            "url": "https://tail.c7.ee/pitchy-vlc/",
            "date_published": "2023-08-28T00:00:00Z",
            "title": "VLC pitch-shifting wasn't my imagination!",
            "content_html": "\u003cp\u003eAt first, I thought I was going crazy, but time and time again I heard it, and it made me sick every single time.\u003c/p\u003e\n\u003cp\u003eTW: Imperfect Pitch\u003c/p\u003e\n\u003cp\u003e\u003caudio src=\"vlcfail.mp3\" controls title=\"Outtake from XIII Youth Dance Celebration\"\u003e\u003c/audio\u003e\n\n\u003caudio src=\"vlcfail2.mp3\" controls title=\"Outtake from XIII Youth Song Celebration\"\u003e\u003c/audio\u003e\n\u003c/p\u003e\n\u003cp\u003eAround the 4-5th second of the audio samples, the pitch returns to normal. This is an effort by VLC to keep the audio and video in sync when its cache runs out (often when scrubbing).\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;d rather have the audio drop out than shift temporarily. The shifted audio always sounds off, and the change (switch to cache) is noticeable.\u003c/p\u003e\n\u003cp\u003eOn many occasions, I tried changing all relevant settings in VLC, but without success. The Internet pointed to resampling, and posts where VLC maintainers stated that VLC is exclusively for streaming media, and the issue is intended / wontfix.\u003c/p\u003e\n\u003cp\u003eVLC used to be my de facto app for decades to open any video or audio file, and it still is what I recommend to people for the universal media player.\u003c/p\u003e\n\u003cp\u003eA few months ago, I replaced it with \u003ca href=\"https://github.com/mpv-player/mpv\"\u003empv\u003c/a\u003e while searching for a no-nonsense ephemeral player\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e. I can say that I\u0026rsquo;ve settled. The keyboard shortcuts took some time to get used to.\u003c/p\u003e\n\u003cp\u003eSince I didn\u0026rsquo;t bother spending time on changing them, I chose to stick with the defaults, even though mpv is fully configurable. I suggest reading the manpages for mpv.\u003c/p\u003e\n\u003cp\u003eThe only questionable default I found was \u003ccode\u003ehwdec=no\u003c/code\u003e, which I changed to \u003ccode\u003ehwdec=auto-safe\u003c/code\u003e. One thing I miss is how VLC manages reusing multiple windows, including the ability to drag and drop into existing windows. Switching between mpv and \u003ca href=\"https://github.com/mpv-player/mpv/blob/master/TOOLS/umpv\"\u003eumpv\u003c/a\u003e offers a remedy but isn\u0026rsquo;t perfect.\u003c/p\u003e\n\u003cp\u003eWhen scrubbing to any position in a 20-hour file, I would say mpv syncs instantly. Changing the audio channel adds a few hundred milliseconds of delay, which is acceptable for me.\u003c/p\u003e\n\u003cdiv class=\"footnotes\" role=\"doc-endnotes\"\u003e\n\u003chr\u003e\n\u003col\u003e\n\u003cli id=\"fn:1\"\u003e\n\u003cp\u003eBut not overly minimal, like some hardcore i3 maniacs like it.\u003csup id=\"fnref:2\"\u003e\u003ca href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e2\u003c/a\u003e\u003c/sup\u003e\u0026#160;\u003ca href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli id=\"fn:2\"\u003e\n\u003cp\u003eThough, I do live on Sway.\u0026#160;\u003ca href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\"\u003e\u0026#x21a9;\u0026#xfe0e;\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n"
        }, 
        {
            "id": "https://tail.c7.ee/arch-boot-recovery/",
            "url": "https://tail.c7.ee/arch-boot-recovery/",
            "date_published": "2023-06-08T00:00:00Z",
            "title": "Arch boot recovery",
            "content_html": "\u003cp\u003eI upgraded both identical laptops. One I took with me, and it worked without any problems. Today I was puzzled to find the second machine unable to boot.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e...\nWaiting 10 seconds for device [...]\nERROR: mounting \u0026#39;/dev/mapper/luksdev\u0026#39; on real root\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eGRUB dropped the computer to emergency shell, but it wasn\u0026rsquo;t helpful. The keyboard didn\u0026rsquo;t work, including Ctrl-Alt-Del. Time for data recovery (faster than downloading the backup) from a live boot, a half-scripted reinstall, and recovering the files (~2-3h total).\u003c/p\u003e\n\u003cp\u003eI was not asked for the disk encryption password — the partition couldn\u0026rsquo;t be unlocked. GRUB trying to mount from \u003ccode\u003e/dev/mapper/\u003c/code\u003e smelled something wrong with LUKS.\u003c/p\u003e\n\u003cp\u003eWith a dysfunctional emergency shell, I tried booting from a different entry, without luck. I grabbed my keyring with USB drives. The one which is supposed to have Fedora on it booted to Arch instead.\u003c/p\u003e\n\u003cp\u003eWith the pain of the reinstallation sinking time, I thought if maybe, this time, I could recover the system successfully. Could the boot environment be fixed without any serious GRUB magician skills?\u003c/p\u003e\n\u003cp\u003eHaving already searched the web for the errors, I gave a few commands a try in the emergency shell. Just chroot in, and go:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# lsblk\n...\nnvme0n1     259:0    0  1.8T  0 disk\n├─nvme0n1p1 259:1    0  511M  0 part\n└─nvme0n1p2 259:2    0  1.8T  0 part\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eJudging by the size, the first one is boot, and the second root.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# cryptsetup luksOpen /dev/nvme0n1p2 main\n# mount /dev/mapper/main /mnt\n# mount /dev/nvme0n1p1 /mnt/boot\nmount: boot: mount point does not exist.\n# mkdir /mnt/boot\n# mount /dev/nvme0n1p1 /mnt/boot\n# ls /mnt\nboot @ @home @log @pkg @.snapshots\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eI forgot to specify the Btrfs subvolume…\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# umount /mnt/boot\n# rm -d /mnt/boot\n# umount /mnt\n^R main\n# mount /dev/mapper/main -o subvolume=@ /mnt\n# ls /mnt\nbin boot dev etc f home lib lib64 mnt opt proc r root run sbin srv sys tmp usr var\n^R mnt/boot\n# mount /dev/nvme0n1p1 /mnt/boot\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eMaybe I could fix this easier. I recall not reading the output for updates on the failing laptop. Maybe something went wrong.\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e# iwctl station wlan0 scan\n# iwctl station wlan0 connect \u0026#39;...\u0026#39;\n# arch-chroot /mnt\n# pacman -Syu\n* mkinitpcio stuff, the slowest part in upgrades *\n#\n^D\n# reboot\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eIt has been a few days since I last updated — simply updating again should rebuild the boot environment anyway. The logs agreed with me.\u003c/p\u003e\n\u003cp\u003eWith a naive solution, the laptop booted normally after the upgrade. If there wasn\u0026rsquo;t an upgrade, I could\u0026rsquo;ve tried reinstalling the kernel package.\u003c/p\u003e\n"
        }
    ]
    
}
