<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Boot on inetshell</title><link>https://inet.sh/en/tags/boot/</link><description>Recent content in Boot on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 25 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/boot/index.xml" rel="self" type="application/rss+xml"/><item><title>FreeBSD: replace a disk in the ZFS boot mirror (zroot) with gpart</title><link>https://inet.sh/en/posts/zfs/freebsd-replace-boot-mirror-disk/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/zfs/freebsd-replace-boot-mirror-disk/</guid><description>Swap a dead disk out of a zroot mirror on FreeBSD 13/14: clone the partition table with gpart backup | gpart restore, reinstall the BIOS bootcode (pmbr + gptzfsboot) and populate the ESP with loader.efi for UEFI (boot1.efi is deprecated), zpool replace or attach with the right partition, swap, and resilver.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p>Good disk <code>ada0</code>, new disk <code>ada3</code>, the dead one was <code>ada1</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zpool status zroot                                  <span class="c1"># ada1p4 FAULTED / UNAVAIL</span>
</span></span><span class="line"><span class="cl">gpart backup ada0 <span class="p">|</span> gpart restore -F ada3           <span class="c1"># clone the partition table</span>
</span></span><span class="line"><span class="cl">gpart show ada3                                     <span class="c1"># p1 efi, p2 freebsd-boot, p3 freebsd-swap, p4 freebsd-zfs</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># BIOS bootcode: the index is the freebsd-boot partition&#39;s</span>
</span></span><span class="line"><span class="cl">gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i <span class="m">2</span> ada3
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># UEFI: populate the ESP</span>
</span></span><span class="line"><span class="cl">newfs_msdos -F <span class="m">32</span> -c <span class="m">1</span> /dev/ada3p1
</span></span><span class="line"><span class="cl">mount -t msdosfs /dev/ada3p1 /mnt
</span></span><span class="line"><span class="cl">mkdir -p /mnt/EFI/BOOT /mnt/EFI/FREEBSD
</span></span><span class="line"><span class="cl">cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.EFI
</span></span><span class="line"><span class="cl">cp /boot/loader.efi /mnt/EFI/FREEBSD/LOADER.EFI
</span></span><span class="line"><span class="cl">umount /mnt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># The new disk joins the mirror in the dead one&#39;s place</span>
</span></span><span class="line"><span class="cl">zpool replace zroot ada1p4 ada3p4
</span></span><span class="line"><span class="cl">zpool status zroot                                  <span class="c1"># resilver in progress</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>When <code>zpool status</code> shows <code>ONLINE</code> on both, test booting with <strong>only</strong> the new disk.</p>
<h2 id="before-starting">Before starting</h2>
<ul>
<li><strong>Identify the disk.</strong> <code>zpool status</code> names the dead member (<code>ada1p4</code>, or a long GUID if it is already gone). <code>camcontrol devlist</code> lists the disks with model and serial so you know which bay to touch.</li>
<li><strong>If the bad disk is still connected</strong>, take it out of the pool before pulling the cable: <code>zpool offline zroot ada1p4</code>.</li>
<li><strong>Layout.</strong> A default FreeBSD 13/14 zroot install creates, per disk: <code>p1</code> <code>efi</code>, <code>p2</code> <code>freebsd-boot</code>, <code>p3</code> <code>freebsd-swap</code>, <code>p4</code> <code>freebsd-zfs</code>. Old or hand-made installs vary: look at <code>gpart show ada0</code> and adjust the indexes. The bootcode&rsquo;s <code>-i</code> is <code>freebsd-boot</code>&rsquo;s.</li>
<li><strong>The new disk must be the same size or bigger.</strong> <code>gpart restore</code> copies exact sizes; if it is bigger, the rest stays free and you can use it later.</li>
</ul>
<h2 id="why-partitions-and-not-the-whole-disk">Why partitions and not the whole disk</h2>
<p>In a boot pool every disk carries the boot partitions in addition to the ZFS one. If you run <code>zpool replace zroot ada1p4 ada3</code> with the raw disk, the mirror works but that disk <strong>cannot boot</strong>: the day <code>ada0</code> dies, you will have the data and no loader. That is why the order is: partition identically, bootcode, and only then <code>zpool replace</code> with the partition.</p>
<h2 id="step-by-step">Step by step</h2>
<p><strong>1. Clone the partition table.</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">gpart backup ada0 <span class="p">|</span> gpart restore -F ada3
</span></span><span class="line"><span class="cl">gpart show ada3
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>-F</code> destroys whatever was on <code>ada3</code>. If the pool uses GPT labels (<code>gpt/zfs0</code> in <code>zpool status</code>) instead of <code>adaXpY</code> names, give the new one its own: <code>gpart modify -i 4 -l zfs1 ada3</code>, and use <code>gpt/zfs1</code> in the <code>zpool replace</code>.</p>
<p><strong>2. Bootcode.</strong> Install both: that way it boots whether the board is in BIOS/CSM mode or UEFI.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># BIOS: protective MBR + gptzfsboot on the freebsd-boot partition (p2 in the default layout)</span>
</span></span><span class="line"><span class="cl">gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i <span class="m">2</span> ada3
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># UEFI: the ESP (p1) is a FAT32 with loader.efi at the standard paths</span>
</span></span><span class="line"><span class="cl">newfs_msdos -F <span class="m">32</span> -c <span class="m">1</span> /dev/ada3p1
</span></span><span class="line"><span class="cl">mount -t msdosfs /dev/ada3p1 /mnt
</span></span><span class="line"><span class="cl">mkdir -p /mnt/EFI/BOOT /mnt/EFI/FREEBSD
</span></span><span class="line"><span class="cl">cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.EFI
</span></span><span class="line"><span class="cl">cp /boot/loader.efi /mnt/EFI/FREEBSD/LOADER.EFI
</span></span><span class="line"><span class="cl">umount /mnt
</span></span></code></pre></td></tr></table>
</div>
</div><p>Old guides say <code>gpart bootcode -p /boot/boot1.efifat -i 1</code>; <code>boot1.efi</code> is deprecated on current FreeBSD and the path documented in <code>loader.efi(8)</code> is copying <code>loader.efi</code> onto the ESP. If you want a dedicated firmware entry: <code>efibootmgr -c -l /mnt/EFI/FREEBSD/LOADER.EFI -L FreeBSD-ada3 -a</code>.</p>
<p><strong>3. Replace in the pool.</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zpool replace zroot ada1p4 ada3p4
</span></span></code></pre></td></tr></table>
</div>
</div><p>If the dead member no longer shows and the mirror is down to one disk, instead of <code>replace</code> you <strong>attach</strong> to the survivor: <code>zpool attach zroot ada0p4 ada3p4</code>.</p>
<p><strong>4. Resilver.</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">zpool status zroot           <span class="c1"># scan: resilver in progress ... % done</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Hours, depending on how full the pool is. Optional, so the resilver yields less to normal load:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sysctl vfs.zfs.resilver_min_time_ms<span class="o">=</span><span class="m">5000</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>5. Swap.</strong> If <code>/etc/fstab</code> had <code>/dev/ada1p3</code> as swap, change it to <code>/dev/ada3p3</code> (or better, to <code>gpt/swapN</code> labels that do not change with the disk name) and <code>swapon -a</code>.</p>
<p><strong>6. Check the boot.</strong> With the resilver done, power off, disconnect <code>ada0</code> (or change the boot order) and boot from the new one. If it comes up, reconnect and <code>zpool status</code> must still read <code>ONLINE</code> with no complaints. A closing <code>zpool scrub zroot</code> does not hurt.</p>
<h2 id="traps">Traps</h2>
<ul>
<li><strong><code>gpart restore -F</code> does not ask.</strong> Double-check which disk is the new one; <code>camcontrol devlist</code> and <code>diskinfo -v ada3</code> (serial) before writing.</li>
<li><strong>Bootcode of a single kind</strong> leaves the disk bootable in only one firmware mode. Install both.</li>
<li><strong>Different physical sector size</strong> (512 vs 4K) can make <code>zpool replace</code> complain about <code>ashift</code>; in a modern mirror with <code>ashift=12</code> a 4Kn disk goes in fine, one with <code>ashift=9</code> does not.</li>
<li><strong>Bigger disk</strong>: after the resilver, <code>gpart resize -i 4 ada3</code> and <code>zpool online -e zroot ada3p4</code>; once both mirror disks are big, the pool grows.</li>
<li><strong><code>adaX</code> names shift</strong> when disks are removed; GPT labels and GUIDs do not. For the operation use whatever <code>zpool status</code> shows at that moment.</li>
</ul>
<h2 id="see-also">See also</h2>
<ul>
<li><a href="/en/posts/zfs/replace-disks/">Replace a disk in a ZFS pool</a> — the Linux/Proxmox version, without boot partitions.</li>
<li><a href="/en/posts/zfs/import-after-power-outage/">Import a pool after a power outage</a>.</li>
<li>FreeBSD: <code>man 8 loader.efi</code>, <code>man 8 gpart</code>, and <a href="https://farrokhi.net/posts/2020/05/replacing-a-faulty-disk-in-zfs/">Babak Farrokhi&rsquo;s article</a> on the BIOS replacement.</li>
</ul>
]]></content:encoded></item><item><title>Proxmox: error: disk 'lvmid/…' not found at grub rescue</title><link>https://inet.sh/en/posts/proxmox/grub-rescue-disk-lvmid-not-found/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/proxmox/grub-rescue-disk-lvmid-not-found/</guid><description>A Proxmox VE node that boots into &amp;#39;error: disk lvmid/... not found, grub rescue&amp;gt;&amp;#39; with root on LVM: it is a GRUB bug reading LVM metadata when the ring buffer wraps around. Workaround from the ISO (any LVM change) and permanent fix by reinstalling the GRUB that carries the fix.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p>Boot the <strong>Proxmox ISO → Advanced Options → Install Proxmox VE (Debug mode)</strong>; at the first shell press <code>Ctrl+D</code> to reach the second one, which already has LVM:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">vgscan
</span></span><span class="line"><span class="cl">vgchange -ay
</span></span><span class="line"><span class="cl">lvcreate -L 4M pve -n grubtemp   <span class="c1"># any change to the LVM metadata will do</span>
</span></span><span class="line"><span class="cl">reboot
</span></span></code></pre></td></tr></table>
</div>
</div><p>With the node back up, clean up and make the fix permanent:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">lvremove pve/grubtemp
</span></span><span class="line"><span class="cl"><span class="o">[</span> -d /sys/firmware/efi <span class="o">]</span> <span class="o">&amp;&amp;</span> apt install grub-efi-amd64     <span class="c1"># UEFI</span>
</span></span><span class="line"><span class="cl"><span class="c1"># legacy BIOS: grub-install /dev/sdX &amp;&amp; update-grub        # the disk, not the partition</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="the-error">The error</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">error: disk &#39;lvmid/Xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx/Yyyyyy-yyyy-yyyy-yyyy-yyyy-yyyy-yyyyyy&#39; not found.
</span></span><span class="line"><span class="cl">Entering rescue mode...
</span></span><span class="line"><span class="cl">grub rescue&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>The disk is fine, the <code>pve</code> VG is fine, and the data is fine. Sometimes the same bug warns you earlier, during an <code>apt full-upgrade</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">/usr/sbin/grub-probe: error: disk `lvmid/...&#39; not found.
</span></span></code></pre></td></tr></table>
</div>
</div><p>If you see that in <code>update-grub</code>, apply the fix <strong>before</strong> rebooting.</p>
<h2 id="why-it-happens">Why it happens</h2>
<p>LVM stores its on-disk metadata in a <strong>ring buffer</strong>. Every change (creating, deleting, or resizing an LV) writes a new copy further along the buffer, and sooner or later the text wraps around the end. The GRUB 2.06 in Debian 11 (PVE 7, <code>2.06-3</code>) cannot read that wrap: it does not find the VG, does not find the <code>pve/root</code> LV, and drops to <code>grub rescue</code>.</p>
<p>That is why &ldquo;fixing&rdquo; it is as odd as making any LVM change: the metadata gets rewritten at another position, usually without a wrap, and GRUB reads it again. And that is why it <strong>comes back</strong> weeks or months later, when the buffer wraps again, if the GRUB installed on the disk is still the old one.</p>
<p>In the lab the change that got us out was <code>lvextend -L +1G /dev/pve/root</code>. It works just the same, but undoing it with <code>lvreduce</code> on a mounted root is playing with fire; if you did it that way, better keep the 1G (<code>resize2fs /dev/pve/root</code>) or use the throwaway LV from the TL;DR.</p>
<h2 id="full-procedure">Full procedure</h2>
<ol>
<li>
<p><strong>Get into the system.</strong> Two ways from the Proxmox ISO:</p>
<ul>
<li><strong>Rescue Boot</strong> (Advanced Options): the ISO finds the installation and boots its kernel, bypassing the broken GRUB. If it works you are already inside the real system and can jump to step 3.</li>
<li><strong>Debug mode</strong>: rescue shell. <code>Ctrl+D</code> at the first prompt; the second one has the LVM modules loaded.</li>
</ul>
</li>
<li>
<p><strong>Trigger a metadata change</strong> (only if you came in through Debug mode):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">vgscan
</span></span><span class="line"><span class="cl">vgchange -ay
</span></span><span class="line"><span class="cl">lvcreate -L 4M pve -n grubtemp
</span></span><span class="line"><span class="cl">reboot
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><strong>Back in the normal system</strong>, remove the temporary LV and check whether the metadata still wraps:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">lvremove pve/grubtemp
</span></span><span class="line"><span class="cl">vgscan -vvv 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="p">|</span> grep <span class="s1">&#39;Reading metadata&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Output ending in <code>(+0)</code> means no wrap; any other value means the problem will repeat until you reinstall GRUB.</p>
</li>
<li>
<p><strong>Reinstall the GRUB that has the fix.</strong> The PVE 8 and 9 package (<code>2.06-13</code> or newer) already carries it, but the binary sitting in the ESP or the MBR is only rewritten when the package gets (re)installed:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># UEFI: nodes upgraded from PVE 7 often have grub-pc instead of grub-efi-amd64</span>
</span></span><span class="line"><span class="cl">dpkg -l <span class="p">|</span> grep -E <span class="s1">&#39;^ii +grub-&#39;</span>
</span></span><span class="line"><span class="cl">apt install grub-efi-amd64
</span></span><span class="line"><span class="cl">efibootmgr -v            <span class="c1"># confirm the &#34;proxmox&#34; entry</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># legacy BIOS</span>
</span></span><span class="line"><span class="cl">grub-install /dev/sdX
</span></span><span class="line"><span class="cl">update-grub
</span></span></code></pre></td></tr></table>
</div>
</div><p>On PVE 7 the real fix is upgrading to PVE 8; the workaround only buys time.</p>
</li>
</ol>
<h2 id="traps">Traps</h2>
<ul>
<li><strong><code>grub rescue&gt;</code> will not get you out of this.</strong> <code>ls (lvm/pve-root)</code> shows nothing because the <code>lvm</code> module is exactly what cannot read the metadata. Do not waste time there.</li>
<li><strong>Root on ZFS does not go through here.</strong> Nodes with <code>rpool</code> boot via <code>proxmox-boot-tool</code>; that is another path with other errors.</li>
<li><strong>Point at the right devices</strong> if you run <code>grub-install</code> by hand: the disk (<code>/dev/sda</code>), not <code>/dev/sda1</code>; the ESP mounted on <code>/boot/efi</code> for UEFI.</li>
<li><strong>In a cluster</strong>, once one node is fixed check the others with <code>vgscan -vvv | grep 'Reading metadata'</code>; same installation, same buffer.</li>
</ul>
<p>References: <a href="https://pve.proxmox.com/wiki/Recover_From_Grub_Failure">Recover From Grub Failure</a> on the Proxmox wiki and the <a href="https://forum.proxmox.com/threads/error-disk-lvmid-not-found-grub-rescue.123512/">forum thread</a>.</p>
]]></content:encoded></item></channel></rss>