<?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>Gpart on inetshell</title><link>https://inet.sh/en/tags/gpart/</link><description>Recent content in Gpart 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/gpart/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></channel></rss>