BSD Dump Restore - hpaluch/hpaluch.github.io GitHub Wiki

BSD dump/restore

Warning

All of this text comes WITHOUT ANY WARRANTY! Use it on your own risk and always have reliable backup!

How to clone BSD (tested single disk with FreeBSD, NetBSD and OpenBSD) using filesystem dump(8) and restore(8) commands with "traditional" setup.

"Traditional setup" means:

  • BIOS boot mode
  • MBR partitioning
  • each BSD uses single MBR primary partition with nested partition table called "disklabel" and nested partitions called "slices"
  • using UFS (or FFS) filesystem - no ZFS

Backup target: remote NFS server (my good old Zyxel NSA310).

FreeBSD dump/restore

FreeBSD dump

  • Backed-up OS: 14.2-RELEASE-p1
  • Using USB stick with 14.3-RELEASE

Note: normally dump(8) requires filesystem to be unmounted or mounted read-only. However FreeBSD's dump(8) offers backup using snapshots with (-L) , - so we can backup live system.

First we need to mount NFS volume, easy way to find exported volume name is to use showmount(8) command in my case:

$ showmount -e 192.168.0.3

Exports list on 192.168.0.3:
/i-data/0e5cf602/nfs/data          192.168.0.0/24

So I have following entry in /etc/fstab

# custom
192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs nfs      rw,noauto 0 0

And mounting NFS with mount /mnt/nfs

Preparing target directory:

mkdir /mnt/nfs/maxtor-200gb-$(date '+%F-%H')

Dump partition tables using both fdisk and gpart:

fdisk | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/fdisk.txt
fdisk -s | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/fdisk-s.txt
gpart show | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart.txt

gpart backup ada0 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart-backup-ada0.txt

MBR 4
1 freebsd        64 136314880   [active]
2    !169 136316928 133120812
3    !166 269437740 128859348

gpart backup ada0s1 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart-backup-ada0s1.txt

BSD 8
1  freebsd-ufs         0 121634816
2 freebsd-swap 121634816  14680064

Showing shortest output:

fdisk -s | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/fdisk-s.txt

WARNING: fdisk is deprecated and is not available in FreeBSD 15 or later.
Please use gpart instead.

/dev/ada0: 395136 cyl 16 hd 63 sec
Part        Start        Size Type Flags
   1:          64   136314880 0xa5 0x80
   2:   136316928   133120812 0xa9 0x00
   3:   269437740   128859348 0xa6 0x00

gpart show ada0

=>       63  398297025  ada0  MBR  (190G)
         63          1        - free -  (512B)
         64  136314880     1  freebsd  [active]  (65G)
  136314944       1984        - free -  (992K)
  136316928  133120812     2  !169  (63G)
  269437740  128859348     3  !166  (61G)

Where 0xa5 is FreeBSD partition, 0xa9 NetBSD and 0xa6 OpenBSD.

Now we will dump FreeBSD disklabel (so using different target directory specific for FreeBSD):

mkdir  /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd
disklabel ada0s1 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/disklabel-ada0s1.txt

Output:

WARNING: bsdlabel is deprecated and is not available in FreeBSD 15 or later.
Please use gpart instead.

# /dev/ada0s1:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:  121634816          0    4.2BSD        0     0     0
  b:   14680064  121634816      swap
  c:  136314880          0    unused        0     0     # "raw" part, don't edit

Finally we should also backup MBR sector and boot sector of FreeBSD:

dd if=/dev/ada0 of=/mnt/nfs/maxtor-200gb-2025-08-10-08/mbr.bin count=1
hexdump -C /mnt/nfs/maxtor-200gb-2025-08-10-08/mbr.bin

Output:

....
000000b0  cd 10 ac 84 c0 75 f4 eb  fe 49 6e 76 61 6c 69 64  |.....u...Invalid|
000000c0  20 70 61 72 74 69 74 69  6f 6e 20 74 61 62 6c 65  | partition table|
000000d0  00 45 72 72 6f 72 20 6c  6f 61 64 69 6e 67 20 6f  |.Error loading o|
000000e0  70 65 72 61 74 69 6e 67  20 73 79 73 74 65 6d 00  |perating system.|
000000f0  4d 69 73 73 69 6e 67 20  6f 70 65 72 61 74 69 6e  |Missing operatin|
00000100  67 20 73 79 73 74 65 6d  00 90 90 90 90 90 90 90  |g system........|
00000110  90 90 90 90 90 90 90 90  90 90 90 90 90 90 90 90  |................|
*
000001b0  90 90 90 90 90 90 90 90  90 90 90 90 90 80 80 01  |................|
000001c0  02 00 a5 fe ff ff 40 00  00 00 00 00 20 08 00 fe  |......@..... ...|
000001d0  ff ff a9 fe ff ff 00 08  20 08 2c 43 ef 07 00 fe  |........ .,C....|
000001e0  ff ff a6 fe ff ff 2c 4b  0f 10 d4 3c ae 07 00 00  |......,K...<....|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
...

Notice 2 important things:

  • familiar error messages Invalid partition table
  • proper magic 0x55aa at the end of MBR.

Now FreeBSD boot sector:

dd if=/dev/ada0s1 of=/mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/boot.bin count=1
hexdump -C /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/boot.bin

Output:

00000190  46 0a d0 e3 00 5e 05 28  46 02 77 88 c3 52 65 61  |F....^.(F.w..Rea|
000001a0  64 00 42 6f 6f 74 00 20  65 72 72 6f 72 0d 0a 00  |d.Boot. error...|
000001b0  80 90 90 90 90 90 90 90  90 90 90 90 90 90 00 00  |................|
000001c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 80 00  |................|
000001f0  01 00 a5 fe ff ff 00 00  00 00 50 c3 00 00 55 aa  |..........P...U.|

Notice different error messages and again proper magic 0x55aa at then end.

Finally we will dump filesystem using FFS snapshot:

First find where is / mounted:

$ df /

Filesystem   1K-blocks    Used    Avail Capacity  Mounted on
/dev/ada0s1a  58908188 6091308 48104228    11%    /

Next run dump in dry-run mode:

dump -0uaL -f /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin -S /

  DUMP: Date of this level 0 dump: Sun Aug 10 08:52:20 2025
  DUMP: Date of last level 0 dump: the epoch
  DUMP: Dumping snapshot of /dev/ada0s1a (/) to /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 5062243 tape blocks.

Now perform dump (without -S) - notice that this time we get beyond Pass II:

dump -0uaL -f /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin /

  DUMP: Date of this level 0 dump: Sun Aug 10 08:53:29 2025
  DUMP: Date of last level 0 dump: the epoch
  DUMP: Dumping snapshot of /dev/ada0s1a (/) to /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 5062243 tape blocks.
  DUMP: dumping (Pass III) [directories]
  DUMP: dumping (Pass IV) [regular files]
  DUMP: 82.63% done, finished in 0:01 at Sun Aug 10 08:59:38 2025
  DUMP: DUMP: 5063088 tape blocks on 1 volume
  DUMP: finished in 352 seconds, throughput 14383 KBytes/sec
  DUMP: level 0 dump on Sun Aug 10 08:53:29 2025
  DUMP: Closing /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin
  DUMP: DUMP IS DONE

We should unmount NFS volume before reboot to ensure that all data were written:

umount /mnt/nfs

FreeBSD restore

Now we will restore FreeBSD on blank disk.

We need bootable media, I strongly recommend using USB stick, because we are able to remount it read-write and start SSH and other useful tools...

WARNING! We should use exactly same FreeBSD version on boot media as is on backed up system. However in my case it is not that easy (backed up system is 14.2-p1, bootstick is 14.3-RELEASE). Hopefully it will still work.

Booting from Live media

  • please follow my existing guide in FreeBSD remote install
  • once you have working network and SSH access resume on this guide...

Now dangerous stuff - destroy partition table on Restore disk:

root@:~ # camcontrol devlist

<HL-DT-ST DVDRAM GSA-H12N UL01>    at scbus0 target 0 lun 0 (pass0,cd0)
<ST3320620AS 3.AAK>                at scbus9 target 0 lun 0 (pass1,ada0)
<USB SanDisk 3.2Gen1 1.00>         at scbus28 target 0 lun 0 (pass2,da0)

root@:~ # gpart show ada0

=>       40  625142368  ada0  GPT  (298G)
         40       4056     1  bios-boot  (2.0M)
       4096    1048576     2  efi  (512M)
    1052672  209715200     3  linux-data  (100G)
  210767872   16777216     4  linux-swap  (8.0G)
  227545088  397596672     5  linux-data  (190G)
  625141760        648        - free -  (324K)

root@:~ # gpart destroy -F ada0

ada0 destroyed

Create new partition table of type mbr

root@:~ # gpart create -s mbr ada0
ada0 created
root@:~ # gpart show ada0
=>       63  625142385  ada0  MBR  (298G)
         63  625142385        - free -  (298G)

Now I should mount target NFS volume with backup:

root@:~ # showmount -e 192.168.0.3

Exports list on 192.168.0.3:
/i-data/0e5cf602/nfs/data          192.168.0.0/24

root@:~ # mkdir /mnt/nfs
root@:~ # mount -r -t nfs 192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs

Now we have to restore MBR partition table from our backup - most command were taken from man gpart:

root@:~ # cat /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart.txt

=>       63  398297025  ada0  MBR  (190G)
         63          1        - free -  (512B)
         64  136314880     1  freebsd  [active]  (65G)
  136314944       1984        - free -  (992K)
  136316928  133120812     2  !169  (63G)
  269437740  128859348     3  !166  (61G)

=>        0  136314880  ada0s1  BSD  (65G)
          0  121634816       1  freebsd-ufs  (58G)
  121634816   14680064       2  freebsd-swap  (7.0G)

root@:~ # gpart add -t freebsd -b 64 -s 136314880 ada0

ada0s1 added

root@:~ # gpart set -a active -i 1 ada0

# NOTE: must use '/boot/mbr' NOT '/boot/pmbr', because
# pmbr is "Protected MBR" - for GPT+BIOS mode

root@:~ # gpart bootcode -b /boot/mbr ada0

bootcode written to ada0

Quickly compare primary partition table if it matches:

root@:~ # cat /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart.txt

=>       63  398297025  ada0  MBR  (190G)
         63          1        - free -  (512B)
         64  136314880     1  freebsd  [active]  (65G)
  136314944       1984        - free -  (992K)
  136316928  133120812     2  !169  (63G)
  269437740  128859348     3  !166  (61G)

root@:~ # gpart show ada0

=>       63  625142385  ada0  MBR  (298G)
         63          1        - free -  (512B)
         64  136314880     1  freebsd  [active]  (65G)
  136314944  488827504        - free -  (233G)

So primary partition looks OK, now we have to create slices (disklabel):

  • here is list from our NFS server how it should look:
root@:~ # cat /mnt/nfs/maxtor-200gb-2025-08-10-08/gpart.txt
=>       63  398297025  ada0  MBR  (190G)
         63          1        - free -  (512B)
         64  136314880     1  freebsd  [active]  (65G)
  136314944       1984        - free -  (992K)
  136316928  133120812     2  !169  (63G)
  269437740  128859348     3  !166  (61G)

=>        0  136314880  ada0s1  BSD  (65G)
          0  121634816       1  freebsd-ufs  (58G)
  121634816   14680064       2  freebsd-swap  (7.0G)

So now we try to recreate it (using man gpart as guide)

root@:~ # gpart create -s BSD -n 20 ada0s1

ada0s1 created

root@:~ # gpart add -t freebsd-ufs -s 121634816 ada0s1

ada0s1a added

root@:~ # gpart add -t freebsd-swap -s 14680064 ada0s1

ada0s1b added

root@:~ # gpart show ada0s1

=>        0  136314880  ada0s1  BSD  (65G)
          0  121634816       1  freebsd-ufs  (58G)
  121634816   14680064       2  freebsd-swap  (7.0G)

### Here is dirty trick - we use -b but not specifying ada0 (MBR partition), but disklabel
### Normally 1st sector is boot1 2nd is disklabel and then possibly is ufs/ffs ???

root@:~ # gpart bootcode -b /boot/boot ada0s1

### Please note that cleaner way was using "bsdlabel -B" that will automatically reserve 16 sectors
### (8KB) for boot loader - which is safer and only then it starts slice 'a'...

Looks good, now we will prepare target root filesystem for restore following man restore page:

root@:~ # newfs /dev/ada0s1a

...

root@:~ # mkdir /mnt/target

# async should made recovery faster (but not sure)...

root@:~ # mount -o async /dev/ada0s1 /mnt/target
root@:~ # cd /mnt/target
root@:/mnt/target # pwd

/mnt/target

root@:/mnt/target # restore -rf /mnt/nfs/maxtor-200gb-2025-08-10-08/freebsd/dump-root.bin

Lot of weird errors:

warning: ./.snap: File exists
expected next file 80145, got 10
warning: cannot create hard link ./usr/share/man/man4/stdin.4.gz->./usr/share/man/man4/stdout.4.gz: No such file or directory
warning: cannot create hard link ./usr/share/man/man4/fd.4.gz->./usr/share/man/man4/stdout.4.gz: No such file or directory
...
warning: cannot create hard link ./usr/share/man/man9/useracc.9.gz->./usr/share/man/man9/kernacc.9.gz: No such file or directory
warning: cannot create hard link ./usr/share/man/man9/VOP_ACCESS.9.gz->./usr/share/man/man9/VOP_ACCESSX.9.gz: No such file or directory
warning: cannot create hard link ./usr/share/man/man9/VOP_RDWR.9.gz->./usr/share/man/man9/VOP_WRITE.9.gz: No such file or directory
warning: cannot create hard link ./usr/share/man/man9/VOP_READ.9.gz->./usr/share/man/man9/VOP_WRITE.9.gz: No such file or directory

cd /
umount /mnt/target

WARNING! When I did restore 2nd time (from same backup!) I got only 2 warnings:

warning: ./.snap: File exists
expected next file 80145, got 10

But NOT those "create hard link" warnings. I have no explanation why they were there only for 1st time...

And reboot - in my case it worked.

  • right after reboot I tried:
    time freebsd-update IDS
    
    # only obvious mismatches regarding /etc/group /etc/passwd /etc/shells...
    
    # run on old dual-core Opteron
    1283.94 real       330.32 user       451.58 sys
  • to see if restore really restored everything
  • what is interesting that failures from above warnings are harmless - for example file /usr/share/man/man9/VOP_READ.9.gz really exists and is 3-times hard-link

NetBSD dump/restore

NetBSD dump

  • Backed-up OS: NetBSD 10.1 (GENERIC)
  • Using USB stick with TODO

Finding disk to backup:

nbsd-max# sysctl hw.disknames

hw.disknames = fd0 cd0 wd0

nbsd-max# mkdir /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd

nbsd-max# fdisk wd0 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/fdisk-wd0.txt

...
Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: NetBSD (sysid 169)
    start 136316928, size 133120812 (65000 MB, Cyls 8485/85/49-16771/184/33)
2: OpenBSD (sysid 166)
    start 269437740, size 128859348 (62920 MB, Cyls 16771/184/34-24792/215/63)
3: <UNUSED>
...

nbsd-max# disklabel wd0 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/disklabel-wd0.txt

4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 398297088         0     unused      0     0        # (Cyl.      0 - 395135)

nbsd-max# tunefs -N /dev/wd0a | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/tunefs-N-wd0a.txt
tunefs: tuning /dev/rwd0a
tunefs: current settings of /dev/rwd0a
	maximum contiguous block count 4
	maximum blocks per file in a cylinder group 2048
	minimum percentage of free space 5%
	optimization preference: time
	average file size: 16384
	expected number of files per directory: 64
	journal log file location: in filesystem
	journal log file size: 54MB (56393728 bytes)
	journal log flags:
	quotas disabled
	POSIX.1e ACLs disabled
	NFS4 ACLs disabled
tunefs: no changes made

Now we can start dump using snapshot (note different option for snapshot)

time dump -0uaX -f /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/netbsd-dump-rootfs.bin /

  DUMP: Found /dev/rwd0a on / in /etc/fstab
  DUMP: Date of this level 0 dump: Sun Aug 10 15:55:32 2025
  DUMP: Date of last level 0 dump: the epoch
  DUMP: Dumping a snapshot of /dev/rwd0a (/) to /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/netbsd-dump-rootfs.bin
  DUMP: Label: none
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 8289221 tape blocks.
  DUMP: Volume 1 started at: Sun Aug 10 15:55:41 2025
  DUMP: dumping (Pass III) [directories]
  DUMP: dumping (Pass IV) [regular files]
  DUMP: 42.73% done, finished in 0:06
  DUMP: 8290904 tape blocks on 1 volume
  DUMP: Volume 1 completed at: Sun Aug 10 16:05:17 2025
  DUMP: Volume 1 took 0:09:36
  DUMP: Volume 1 transfer rate: 14393 KB/s
  DUMP: Date of this level 0 dump: Sun Aug 10 15:55:32 2025
  DUMP: Date this dump completed:  Sun Aug 10 16:05:17 2025
  DUMP: Average transfer rate: 14393 KB/s
  DUMP: level 0 dump on Sun Aug 10 15:55:32 2025
  DUMP: Closing /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/netbsd-dump-rootfs.bin
  DUMP: DUMP IS DONE
      597.80 real        20.71 user        69.93 sys

Peeking into start of slice (same as root filesystem):

nbsd-max# dd if=/dev/rwd0a count=1 msgfmt=quiet | hexdump -C
00000000  eb 3c 90 4e 65 74 42 53  44 36 30 00 00 00 00 00  |.<.NetBSD60.....|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 31 c9  |..............1.|
00000040  8e d1 89 cc 8e c1 66 3d  21 47 50 54 0f 84 0e 01  |......f=!GPT....|
00000050  8e d9 31 c0 52 cd 13 5a  41 88 ee e8 f7 00 66 31  |..1.R..ZA.....f1|
00000060  ed 66 8b 07 66 3b 06 00  7c 74 70 66 31 db 66 31  |.f..f;..|tpf1.f1|
00000070  c9 bf be 11 8a 45 04 66  8b 6d 08 66 03 2e b0 7d  |.....E.f.m.f...}|
00000080  3c a9 75 0a 66 85 f6 74  54 66 39 ee 74 4f 3c 05  |<.u.f..tTf9.tO<.|
00000090  74 08 3c 0f 74 04 3c 85  75 04 66 8b 4d 08 83 c7  |t.<.t.<.u.f.M...|
000000a0  10 81 ff fe 11 75 cd 67  e3 15 66 85 db 75 03 66  |.....u.g..f..u.f|
000000b0  87 d9 66 01 d9 66 89 0e  b0 7d e8 89 00 eb af 66  |..f..f...}.....f|
000000c0  85 f6 b8 8f 7d 74 4c 66  31 f6 66 89 36 b0 7d e9  |....}tLf1.f.6.}.|
000000d0  2e ff 8a 75 01 8b 4d 02  e8 7a 00 eb 4e 66 89 2e  |...u..M..z..Nf..|
000000e0  b0 7d 66 85 db 75 41 52  b4 08 cd 13 8b 45 02 50  |.}f..uAR.....E.P|
000000f0  c0 e8 06 86 c4 c1 ea 08  42 f7 e2 8a 55 01 01 d0  |........B...U...|
00000100  83 e1 3f f7 e1 5a 83 e2  3f 01 d0 48 5a 39 e8 74  |..?..Z..?..HZ9.t|
00000110  c1 eb 15 50 be 77 7d e8  7e 00 5e e8 7a 00 be 7e  |...P.w}.~.^.z..~|
00000120  7d e8 74 00 fb f4 eb fc  e8 1b 00 66 81 3e 04 14  |}.t........f.>..|
00000130  d1 b6 86 78 b8 86 7d 75  da 66 89 ee 66 8b 3e b4  |...x..}u.f..f.>.|
00000140  7d ea 00 14 00 00 60 be  a8 7d b4 42 cd 13 61 b8  |}.....`..}.B..a.|
00000150  81 7d 72 bf c3 bb 00 10  60 b8 0f 02 eb ee 66 8b  |.}r.....`.....f.|
00000160  6c 34 66 8b 7c 38 8e d9  66 89 2e b0 7d 66 89 3e  |l4f.|8..f...}f.>|
00000170  b4 7d 66 89 ee eb b1 45  72 72 6f 72 20 00 0d 0a  |.}f....Error ...|
00000180  00 72 65 61 64 00 6e 6f  20 6d 61 67 69 63 00 6e  |.read.no magic.n|
00000190  6f 20 73 6c 69 63 65 00  60 ac b4 0e bb 01 00 cd  |o slice.`.......|
000001a0  10 ac 84 c0 75 f4 61 c3  10 00 0f 00 00 10 00 00  |....u.a.........|
000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

To later install proper bootblock (see NetBSD) we need to know what version of FFS we use, in my case:

nbsd-max# dumpfs -s wd0a | head -3

file system: /dev/rwd0a
format	FFSv2
endian	little-endian

NetBSD restore

I will use NetBSD-10.1-amd64-install.img on USB stick for restore.

  • I will prepare remote login nearly same way as in case of FreeBSD:
  • confirm language and default keyboard layout
  • select Exit Installer
  • unlike FreeBSD the rootfs is already read-write
  • use ifconfig to list network interfaces
  • run dhcpcd nfe0 to get IP address
  • edit vi /etc/ssh/sshd_config and append PermitRootLogin yes
  • start sshd with /etc/rc.d/sshd onestart
  • set root password with passwd root
  • login from remote host to your NetBSD...

We should prepare fdisk partition for NetBSD using:

WARNING! I will NOT install NetBSD bootblock to MBR, because I want to have existing FreeBSD as boot manager (using chain DEVICE: to chain-load NetBSD and OpenBSD).

# fdisk wd0

...
Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>

# fdisk -u wd0

...
Do you want to change our idea of what BIOS thinks? [n] # <-

Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
First active partition: 0
Drive serial number: 2425393296 (0x90909090)

Which partition do you want to change?: [none] 1 # <-

The data for partition 1 is:
<UNUSED>

sysid: [0..255 default: 169]  ### ENTER # <-
start: [0..38913cyl default: 63, 0cyl, 0MB] 136316928  # <-
size: [0..30428cyl default: 488825520, 30428cyl, 238684MB] 133120812 # <-
bootmenu: [] (space to clear)
The bootselect code is not installed, do you want to install it now? [n]  # <-

Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: NetBSD (sysid 169)
    start 136316928, size 133120812 (65000 MB, Cyls 8485/85/49-16771/184/33)
        PBR is not bootable: Bad magic number (0x6d15)
2: <UNUSED>
3: <UNUSED>

Which partition do you want to change?: [none]  # <-
Update the bootcode from /usr/mdec/mbr? [n]  # <-

We haven't written the MBR back to disk yet.  This is your last chance.
Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: NetBSD (sysid 169)
    start 136316928, size 133120812 (65000 MB, Cyls 8485/85/49-16771/184/33)
        PBR is not bootable: Bad magic number (0x6d15)
2: <UNUSED>
3: <UNUSED>
First active partition: 0
Drive serial number: 2425393296 (0x90909090)

Should we write new partition table? [n] y # <-

Verify:

# fdisk wd0

Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: NetBSD (sysid 169)
    start 136316928, size 133120812 (65000 MB, Cyls 8485/85/49-16771/184/33)
        PBR is not bootable: Bad magic number (0x6d15)
2: <UNUSED>
3: <UNUSED>
First active partition: 0
Drive serial number: 2425393296 (0x90909090)

Now we will try to setup disklabel:

# disklabel -i wd0
Enter '?' for help
partition>P
6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e: 136314880        64     4.2BSD      0     0     0  # (Cyl.      0*- 135233*)
 f: 133120812 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 267299*)
partition>a
Filesystem type [unused]: 4.2BSD
Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: 136316928
Partition size ('$' for all remaining) [0c, 0s, 0M]: 116343616
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
partition>b
Filesystem type [unused]: swap
Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: 252660544
Partition size ('$' for all remaining) [0c, 0s, 0M]: 16777196
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
partition>P
6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e: 136314880        64     4.2BSD      0     0     0  # (Cyl.      0*- 135233*)
 f: 133120812 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 267299*)
partition>W
Label disk [n]?y
disklabel: partitions a and f overlap
disklabel: partitions b and f overlap
Label written
partition>Q
# disklabel wd0
# /dev/rwd0:
type: ESDI
disk: wd0
label: fictitious
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 620181
total sectors: 625142448
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0		# microseconds
track-to-track seek: 0	# microseconds
drivedata: 0

6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e: 136314880        64     4.2BSD      0     0     0  # (Cyl.      0*- 135233*)
 f: 133120812 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 267299*)
disklabel: partitions a and f overlap
disklabel: partitions b and f overlap

### we have to remove 'e' and 'f' (automatically created for FreeBSD):

# disklabel -i wd0
Enter '?' for help
partition>P
6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e: 136314880        64     4.2BSD      0     0     0  # (Cyl.      0*- 135233*)
 f: 133120812 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 267299*)
partition>e
Filesystem type [4.2BSD]: unused
Start offset ('x' to start after partition 'x') [0.063492067158222198486328125c, 64s, 0.03125M]: 64
Partition size ('$' for all remaining) [135233.015625c, 136314880s, 66560M]: 32
 e:        32        64     unused      0     0        # (Cyl.      0*-      0*)
partition>f
Filesystem type [4.2BSD]: unused
Start offset ('x' to start after partition 'x') [135235.046875c, 136316928s, 66561M]: 128
Partition size ('$' for all remaining) [132064.296875c, 133120812s, 65000.3984375M]: 32
 f:        32       128     unused      0     0        # (Cyl.      0*-      0*)
partition>P
6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e:        32        64     unused      0     0        # (Cyl.      0*-      0*)
 f:        32       128     unused      0     0        # (Cyl.      0*-      0*)
partition>W
Label disk [n]?y
Label written
partition>P
6 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 116343616 136316928     4.2BSD      0     0     0  # (Cyl. 135235*- 250655*)
 b:  16777196 252660544       swap                     # (Cyl. 250655*- 267299*)
 c: 133120812 136316928     unused      0     0        # (Cyl. 135235*- 267299*)
 d: 625142448         0     unused      0     0        # (Cyl.      0 - 620180)
 e:        32        64     unused      0     0        # (Cyl.      0*-      0*)
 f:        32       128     unused      0     0        # (Cyl.      0*-      0*)
partition>q
Unknown command q
partition>Q

Now we will install bootblock (see NetBSD):

# installboot -v /dev/rwd0a /usr/mdec/bootxx_ffsv2

File system:         /dev/rwd0a
Primary bootstrap:   /usr/mdec/bootxx_ffsv2
Ignoring PBR with invalid magic in sector 0 of `/dev/rwd0a'
Boot options:        timeout 5, flags 0, speed 9600, ioaddr 0, console pc

Running fdisk should no longer throw PBR invalid error:

# fdisk wd0
Disk: /dev/rwd0
...
Partition table:
0: FreeBSD or 386BSD or old NetBSD (sysid 165)
    start 64, size 136314880 (66560 MB, Cyls 0/1/2-8485/54/17), Active
1: NetBSD (sysid 169)
    start 136316928, size 133120812 (65000 MB, Cyls 8485/85/49-16771/184/33)
2: <UNUSED>
3: <UNUSED>
First active partition: 0
Drive serial number: 2425393296 (0x90909090)

Now create filesystem - MUST specify -O 2 to create FFSv2 (default is still FFSv1!):

# newfs -O 2 /dev/rwd0a

/dev/rwd0a: 56808.4MB (116343616 sectors) block size 16384, fragment size 2048
	using 308 cylinder groups of 184.45MB, 11805 blks, 22912 inodes.
super-block backups (for fsck_ffs -b #) at:
160, 377920, 755680, 1133440, 1511200, 1888960, 2266720, 2644480, 3022240, 3400000, 3777760, 4155520, 4533280, 4911040, 5288800, 5666560, 6044320,
...................................................................................................................................................

# dumpfs -s wd0a | head -4

file system: /dev/rwd0a
format	FFSv2
endian	little-endian
location 65536	(-b 128)

Mount it:

# mkdir /mnt/target
# '-o log' speeds up things a lot
# mount -o log /dev/wd0a /mnt/target

Mount NFS volume with Dump:

showmount -e 192.168.0.3
mkdir /mnt/nfs
mount -r -t nfs 192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs

Now try restore following: https://man.netbsd.org/NetBSD-10.1/restore.8

# df -h /mnt/target

Filesystem     Size   Used  Avail %Cap Mounted on
/dev/wd0a       54G   2.0K    51G   0% /mnt/target

# cd /mnt/target
# time restore rf /mnt/nfs/maxtor-200gb-2025-08-10-08/netbsd/netbsd-dump-rootfs.bin

(no output)

     1759.16 real        15.24 user        90.44 sys
# df -h /mnt/target

Filesystem     Size   Used  Avail %Cap Mounted on
/dev/wd0a       54G   7.5G    44G  14% /mnt/target

Unmount everything and reboot:

cd /
umount /mnt/target
umount /mnt/nfs

reboot

On FreeBSD boot loader I do:

ESC to get ? prompt
lsdev            # list disk devices and partitions
chain disk0s2:   # notice trailing colon (:) !!!

Yes it boots fine...

sysctl hw.disknames kern.version
hw.disknames = fd0 cd0 wd0
kern.version = NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024
	[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC

nbsd-max# df -h /
Filesystem     Size   Used  Avail %Cap Mounted on
/dev/wd0a       54G   7.5G    44G  14% /

OpenBSD dump/restore

OpenBSD dump

I will first do regular boot (not dump yet) to collect system information:

OS: (uname -a): OpenBSD obsd-max.my.domain 7.5 GENERIC.MP#82 amd64

# sysctl hw.model hw.ncpu hw.disknames kern.version

hw.model=AMD Athlon(tm) 64 X2 Dual Core Processor 3800+
hw.ncpu=2
hw.disknames=cd0:,sd0:354c9e1858af078f,fd0:
kern.version=OpenBSD 7.5 (GENERIC.MP) #82: Wed Mar 20 15:48:40 MDT 2024
    [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

OpenBSD fdisk (primary MBR partitions):

# fdisk sd0

Disk: sd0	geometry: 24792/255/63 [398297088 Sectors]
Offset: 0	Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
*0: A5      0   1   2 -   8485  54  17 [          64:   136314880 ] FreeBSD
 1: A9   8485  85  49 -  16771 184  33 [   136316928:   133120812 ] NetBSD
 2: A6  16771 184  34 -  24792 215  63 [   269437740:   128859348 ] OpenBSD
 3: 00      0   0   0 -      0   0   0 [           0:           0 ] Unused

Parition number 2 with id=0xA6 is OpenBSD

Now disklabel:

# disklabel sd0

...
# /dev/rsd0c:
...
16 partitions:
#                size           offset  fstype [fsize bsize   cpg]
  a:        112859348        269437740  4.2BSD   2048 16384 12960 # /
  b:         16000000        382297088    swap                    # none
  c:        398297088                0  unused
  i:        136314880               64 unknown
  j:        133120812        136316928 unknown

I mounted target NFS to just dump above information to it...

showmount -e 192.168.0.3
mkdir /mnt/nfs
mount 192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs
t=/mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd
mkdir $t
sysctl hw.model hw.ncpu hw.disknames kern.version | tee $t/sysctl.txt

(same output as above)

fdisk sd0 | tee $t/fdisk-sd0.txt

(same output as above)

disklabel sd0 | tee $t/disklabel-sd0.txt

# Copy critically important binaries:
cp /home/ansible/nc.static /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/

New output:

# dumpfs /dev/rsd0a | head | tee $t/dumpfs-rsd0a.txt

magic	19540119 (FFS2)	time	Mon Aug 11 16:36:14 2025
superblock location	65536	id	[ 66647e2f de568f9d ]
ncg	273	size	28214837	blocks	27325906
bsize	16384	shift	14	mask	0xffffc000
fsize	2048	shift	11	mask	0xfffff800
frag	8	shift	3	fsbtodb	2
minfree	5%	optim	time	symlinklen 120
maxbsize 0	maxbpg	2048	maxcontig 1	contigsumsize 0
nbfree	3294311	ndir	1138	nifree	7050154	nffree	971
bpg	12960	fpg	103680	ipg	25920

# cat /etc/fstab | tee $t/fstab

354c9e1858af078f.b none swap sw
354c9e1858af078f.a / ffs rw,wxallowed 1 1

Problem:

  • there is no SSH server on ramdisk image
  • but we can build statically linked version of nc NetCat and use it to provide primitive remote shell. See NC for instructions.

Preparing for boot from ramdisk:

  • while still on working system - prepare startup script /root/prepare-backup.sh with contents:
#!/bin/sh
set -xeuo pipefail
# we will run these commands from bsd.rd
ifconfig
ifconfig nfe0 inet autoconf
sleep 10  # random timeout to wait for DHCP assigned address
ifconfig nfe0

mkdir -p /mnt/nfs
ifconfig nfe0
mount 192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs

echo "Run: /mnt/source/sbin/dump -0ua -f /mnt/nfs/.... /mnt/source"
exit 0

Note: you can prepare statically linked nc to get crude remote shell. See NC how to prepare such binary on running OpenBSD.

Booting ramdisk system:

  • in boot prompt simply type bsd.rd (RD= ramdisk) to boot small install/ramdisk image
  • but there is no SSH - so commands below are written in memory...
# press S to exit installer to shell
sysctl hw.disknames # found your disk, sd0 in my case
mkdir /mnt/source
cd /dev
sh ./MAKEDEV sd0
mount -r /dev/sd0a /mnt/source

# now run prepared script:
/mnt/source/root/prepare-backup.sh

# and backup command - in my case:
/mnt/source/sbin/dump -0ua -f /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/rootfs-dump3.bin \
   /mnt/source 2>&1 | tee /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/dump-error.log

# example output

  DUMP: Can't open /etc/fstab for dump table information: No such file or directory                                                                        [4/58]
  DUMP: Date of this level 0 dump: Sat Aug 16 14:45:56 2025
  DUMP: Date of last level 0 dump: the epoch
  DUMP: Dumping /dev/rsd0a (/mnt/source) to /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/rootfs-dump3.bin
  DUMP: mapping (Pass I) [regular files]
  DUMP: mapping (Pass II) [directories]
  DUMP: estimated 5744160 tape blocks.
  DUMP: Volume 1 started at: Sat Aug 16 14:46:01 2025
  DUMP: dumping (Pass III) [directories]
  DUMP: dumping (Pass IV) [regular files]
  DUMP: 16.30% done, finished in 0:25
  DUMP: 32.26% done, finished in 0:20
  DUMP: 49.72% done, finished in 0:15
  DUMP: 65.81% done, finished in 0:10
  DUMP: 80.32% done, finished in 0:06
  DUMP: 96.31% done, finished in 0:01
  DUMP: 6084450 tape blocks on 1 volume
  DUMP: Date of this level 0 dump: Sat Aug 16 14:45:56 2025
  DUMP: Volume 1 completed at: Sat Aug 16 15:19:13 2025
  DUMP: Volume 1 took 0:33:12
  DUMP: Volume 1 transfer rate: 3054 KB/s
  DUMP: Date this dump completed:  Sat Aug 16 15:19:13 2025
  DUMP: Average transfer rate: 3054 KB/s
  DUMP: level 0 dump on Sat Aug 16 14:45:56 2025
  DUMP: Closing /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/rootfs-dump3.bin
  DUMP: DUMP IS DONE

# after backup unmount everything
umount /mnt/nfs
umount /mnt/source
# reboot or halt -p

OpenBSD restore

WARNING! You need to download same bootable image as your version (OpenBSD does not honor backward compatibility - even in case of minor versions).

In my case:

curl -fLO https://mirror.leaseweb.com/pub/OpenBSD/7.5/amd64/install75.img
curl -fLO https://mirror.leaseweb.com/pub/OpenBSD/7.5/amd64/install75.iso

# my checksums - unable to find authoritative source
sha256sum -b install75.img | tee install75.img.sha256

  fe3fccffc6f31fb222bf69c5d30750c264afb20aab6a524bf35a409b27d277fe *install75.img

sha256sum -b install75.iso | tee install75.iso.sha256

  034435c6e27405d5a7fafb058162943c194eb793dafdc412c08d49bb56b3892a *install75.iso

There is no remote shell support on installation media. However you can prepare statically linked nc (NetCat) and run primitive remote shell using it. Please see NC wiki page how to build static version of nc tool.

Once you have build nc.static as instructed on NC page you can add it to USB stick:

  • do this on your Source computer (with already running OpenBSD):
  • insert USB stick formatted with install75.img to USB port
  • type dmesg to see new disk name for USB stick - in my case sd1
  • mount USB stick read-write:
    mkdir -p /mnt/target
    mount /dev/sd1a /mnt/target
    cp SOME_PATH/nc.static /mnt/target
    umount /mnt/target
  • NOTE: to get free space on USB stick you can remove some useless stuff:

df -h /mnt/target Filesystem Size Used Avail Capacity Mounted on /dev/sd1a 663M 660M 3.1M 100% /mnt/target

rm /mnt/target/7.5/amd64/x*

df -h /mnt/target

Filesystem Size Used Avail Capacity Mounted on /dev/sd1a 663M 558M 106M 85% /mnt/target


Now we are ready to restore OpenBSD image somewhere else...
- boot from USB stick - in my case `install75.img` where
you also have prepared `nc.static`
- select `(S) shell`
- detect knowns disks with `sysctl hw.disknames` - in my case
there are `sd0` and `sd1`
- create devices (one for USB stick other for target SATA HDD):
```shell
cd /dev
sh ./MAKDEV sd0
sh ./MAKDEV sd1
  • next run fdisk sd0 and fdisk sd1 and identify which disk is which
  • in my case I found that sd0 is target HDD (where I will restore OpenBSD and sd1 is USB stick
  • no mount USB stick with my nc.static (read-only is good enough)
    mkdir /mnt/source
    mount -r /dev/sd1a /mnt/source
    /mnt/source/nc.static --help # show print help
  • now configure network:
    ifconfig # list ethernet cards
    ifconfig nfe0 inet autoconf # DHCPv4 client on nfe0
    # wait several seconds and poll "ifconfig nfe0" until it has assigned IPv4 address
  • now we will use nc to create crude remote shell:
    cd /
    ln -s /mnt/source/nc.static nc
    nc -l 1234 | sh -i 2>&1 | nc -l 2345
  • now from your client make 2 connections:
  • 1st: nc REMOTE_IP 2345 - shell output
  • 2nd: nc REMOTE_IP 1234 - shell input
  • try some command on 2nd terminal, for example ls /

Now I will read-only connect to my NFS server:

mkdir /mnt/nfs
# mount read-write so we can store somewhere error log...
mount -t nfs 192.168.0.3:/i-data/0e5cf602/nfs/data /mnt/nfs
ls -l /mnt/nfs

Recreate 3rd. primary partition of type OpenBSD

$ fdisk sd0 # should dump FeeBSD and NetBSD partitions on target disk:

Disk: sd0       geometry: 38913/255/63 [625142448 Sectors]
Offset: 0       Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
*0: A5      0   1   2 -   8485  54  17 [          64:   136314880 ] FreeBSD
 1: A9   8485  85  49 -  16771 184  33 [   136316928:   133120812 ] NetBSD
 2: 00      0   0   0 -      0   0   0 [           0:           0 ] Unused
 3: 00      0   0   0 -      0   0   0 [           0:           0 ] Unused

We want to create this partition entry:

 2: A6  16771 184  34 -  24792 215  63 [   269437740:   128859348 ] OpenBSD

Do this:

$ fdisk -e sd0
a6 # ID of OpenBSD
ENTER # answer 'n' to CHS mode
269437740 # start
128859348 # partition size
print

You should see correct layout in output terminal:

Offset: 0       Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
*0: A5      0   1   2 -   8485  54  17 [          64:   136314880 ] FreeBSD
 1: A9   8485  85  49 -  16771 184  33 [   136316928:   133120812 ] NetBSD
 2: A6  16771 184  34 -  24792 215  63 [   269437740:   128859348 ] OpenBSD
 3: 00      0   0   0 -      0   0   0 [           0:           0 ] Unused
sd0*: 1>

Now enter to 2nd terminal:

quit # from fdisk
fdisk sd0 # verify MBR layout from shell

Now we need to setup disklabel:

  • first showing desired disklabel from backup:
    16 partitions:
    #                size           offset  fstype [fsize bsize   cpg]
      a:        112859348        269437740  4.2BSD   2048 16384 12960 # /
      b:         16000000        382297088    swap                    # none
    

WARNING! I had issues using interactive disklabel -E due buffering so I did that track:

  • back on local console I use
disklabel -E 0
p # there could be "auto slices" delete them
d i
d j
a a # add slice a
ENTER (type 4.2 bsd)
offset: 269437740 # default
size: 112859348  # non-default

a b # add slice b - swap
offset: 382297088 # default
size: 16000000 #default
p # print
q # write & quit

Now we will again run remote shell

nc -l 1234 | sh -i 2>&1 | nc -l 2345

Veritfy partitions and disklabel:

$ fdisk sd0

# Disk: sd0     geometry: 38913/255/63 [625142448 Sectors]
Offset: 0       Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
*0: A5      0   1   2 -   8485  54  17 [          64:   136314880 ] FreeBSD
 1: A9   8485  85  49 -  16771 184  33 [   136316928:   133120812 ] NetBSD
 2: A6  16771 184  34 -  24792 215  63 [   269437740:   128859348 ] OpenBSD
 3: 00      0   0   0 -      0   0   0 [           0:           0 ] Unused

$ disklabel sd0

16 partitions:
#                size           offset  fstype [fsize bsize   cpg]
  a:        112859348        269437740  4.2BSD   2048 16384     1
  b:         16000000        382297088    swap
  c:        625142448                0  unused

WARNING! There is missing mount-point for slice 'a' - will resolve later...

Now create FFSv2 - must be RAW device (r prefix):

newfs -O2 /dev/rsd0a

  273 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
  super-block backups (for fsck -b #) at:
   160, 414880, 829600, 1244320, 1659040, 2073760, 2488480, 2903200, 3317920,
   3732640, 4147360, 4562080, 4976800, 5391520, 5806240, 6220960, 6635680,
  ...

mkdir /mnt/target
mount /dev/sd0a /mnt/target
df -h

Filesystem                               Size    Used   Avail Capacity  Mounted on
/dev/rd0a                                3.5M    3.2M    229K    94%    /
/dev/sd1a                                663M    660M    3.4M   100%    /mnt/source
192.168.0.3:/i-data/0e5cf602/nfs/data    1.8T    1.7T   82.5G    96%    /mnt/nfs
/dev/sd0a                               52.1G    2.0K   49.5G     1%    /mnt/target

Finally restore time:

# test that filesystem is writable (for TMPDIR)
touch /mnt/source/test
df -h /mnt/source

  Filesystem     Size    Used   Avail Capacity  Mounted on
  /dev/sd1a      663M    558M    106M    85%    /mnt/source

# IMPORTANT! restore(8) requires writable space for working temporary
# files.

TMPDIR=/mnt/source
export TMPDIR
echo $TMPDIR

  /mnt/source

df -h /mnt/target

  Filesystem     Size    Used   Avail Capacity  Mounted on
  /dev/sd0a     52.1G    2.0K   49.5G     1%    /mnt/target

cd /mnt/target
restore rf /mnt/nfs/maxtor-200gb-2025-08-10-08/openbsd/rootfs-dump3.bin 2>&1 | tee /mnt/nfs/restore-output.log

(there should be no output)

WARNING! If there is any kind of errors like:

disk full

expected next file 7077889, got 6998861
expected next file 7077889, got 6998862

It may happen if TMPDIR or default /tmp/ is not able to host working files required for restore to perform recovery, which is normally case of default bsd.rd (there is barely 300KB of free space but often even less).

That's the reason why I set TMPDIR to point to writable USB stick where I removed few installation sets (X11) to have enough space for these files...

TODO:

  • if you restore to different disk you should update /mnt/target/etc/fstab
$ cat /mnt/target/etc/fstab

354c9e1858af078f.b none swap sw
354c9e1858af078f.a / ffs rw,wxallowed 1 1

$ disklabel sd0 | grep duid: | sed 's/.* //'

846760bb72a77583

# now careful replace:
# you need to change BOTH duids! (old and new):
# dry-run: check-output
sed 's/354c9e1858af078f/846760bb72a77583/' /mnt/target/etc/fstab
# real update (creates .bak backup file):
sed -i.bak 's/354c9e1858af078f/846760bb72a77583/' /mnt/target/etc/fstab
  • restore boot blocks - be careful!
$ installboot -r /mnt/target sd0

installboot: /mnt/target/usr/mdec/biosboot extends beyond sector 268435455. OpenBSD might not boot

You may ignore that warning (hopefully today).

Now cleanups:

umount /mnt/target
umount /mnt/nfs
# WARNING! to umount also /mnt/source you need to kill "nc" commands (your remote shell)
# try 'exit' in 'nc' shell because interactive shell (when run with '-i' ignores most signals.)
umount /mnt/source
halt -p
# remove USB stick and try to boot OpenBSD

Now try to boot from restored disk yes, it works! Mission accomplished.

⚠️ **GitHub.com Fallback** ⚠️