📜 ⬆️ ⬇️

Installing FreeBSD on a USB flash drive for a seedbox machine

On many home-made seedboxes, old hard drives are often installed, from the principle of “I don’t feel sorry”. Important data is still not written there, and when they die, nothing terrible happens, except for problems with the OS permutation.
To minimize the risk of death of the OS, you can put it on a separate physical carrier. One option is a small flash drive. The discussion will focus on installing and configuring FreeBSD (7.0-8.0) on a flash drive.

Flash drive size


Proceeding from my experiments, a completely working router with a dhcp / dns / vpn server easily fits into a 200 megabyte (on a 256 meg flash drive). In this case, all unnecessary drivers, as well as debugging and profiling options are dropped from the kernel, and the mans are removed from the world. Of course, the sources (/ usr / src) and ports (/ usr / ports) will not fit there, but they can be mounted without any problems from other media.

It’s better to have a larger USB flash drive for a router with seedbox functions, since apache, perl, and php are required there. For this example, take the buggy flash drive to 4 gigabytes :).

Reliability issues


Since flash drives do not like to rewrite sectors, the guidebook recommends mounting the root only for reading, and carrying out all partitions requiring write access to the memory. Thus, / var will be mounted as a disk in RAM and each reboot will delete all its contents.
')

Preparation of sections


Installation is most conveniently done from under FreeBSD (I did with virtualka), in which the kernel and the world you need are already assembled.

So, insert the USB flash drive, see how it is defined in dmesg (hereinafter da0). First you need to format the flash drive. Create flash_disk.proto:

# slice type start length
#
p 1 0xa5 63 1429722
p 3 0xa5 2040255 6072570
#
a 1


Since my flash drive is buggy (trying to read data from a section between 700 and 1000 megabytes causes the controller to fall off), the space is split into two slices. With a normal flash drive, you can create one piece for the entire flash drive.

Formatting:

fdisk -f flash_disk.proto -i da0


Create a bootloader:

# MBR
boot0cfg -B da0
# - slice
boot0cfg -s 1 da0
#
boot0cfg -o noupdate da0


Now mark our slice. Create flash_labels.proto:

# size offset fstype [fsize bsize bps/cpg]
a: 1429722 0 4.2BSD 0 0 0
c: * 0 unused 0 0 # "raw" part, don't edit


Mark up the disk and create the file system:

#
bsdlabel -R da0s1 flash_labels.proto
#
newfs -U da0s1a


Mount our slice

mount /dev/da0s1 /mnt/flash


Installation of the system and ports


So that each time make install does not specify the path, temporarily set the DESTDIR flag in make.conf on the production system:

DESTDIR=/mnt/flash


Now install the kernel, world, system configs and scripts (etc) on the USB flash drive:

cd /usr/src
make installkernel
make installworld
cd /usr/src/etc
make distrib-dirs
make distribution


In make.conf, among other things, the info and man assembly is disabled (NO_INFO = YES NO_MAN = YES), therefore, for normal installation of ports on a USB flash drive, you will need to manually install texinfo, as described here .

cd /usr/src/gnu/usr.bin/texinfo
make install


After that, run the fstab on the flash drive:

# Device Mountpoint FStype Options Dump Pass#
/dev/da0s1a / ufs ro 1 1
md /tmp mfs rw,-s24M,noatime 0 0
md /var mfs rw,-s128M,noatime` 0 0


Since / var will be mounted in memory, you need to transfer / var / db to the USB flash drive so that the data on the installed ports are not lost between restarts. To do this, create a link:

mkdir /mnt/flash/etc/pkg
ln -s ../../etc/pkg /mnt/flash/var/db/pkg


Now you can configure the system on a flash drive, edit configs and set ports from a working system (you only need to register a dns server in resolv.conf on a flash drive).
For example:

cd /usr/ports/net/isc-dhcp30-server
make
make install


The DESTDIR flag in make.conf will tell make install what port to use on the USB flash drive.

Problems with the named DNS server


By default, named is started by the system in a sandbox (by chroot) in the / var / named directory. You cannot transfer this directory to a USB flash drive, since named must be able to write to its small / var. The option that I used is to add the named config to rc.local every time the system starts:

# named
mkdir -p /var/named/etc
cp -Rp /usr/local/etc/namedb /var/named/etc
/etc/rc.d/named start


In my opinion, this is somewhat clumsy and I would gladly listen to other solutions.

Booting an installed system


We connect the USB flash drive to the router and expose the download from it in the BIOS. On some motherboards, a bug is possible when the flash drive does not have time to decide by the time the bootloader begins to mount the root. The hack for this problem is described at the end of this article on Habré.
After booting the system, you can continue to configure it. To do this, just remount the root on the record:

mount -uw /


After making the necessary changes (installing ports / editing configs / adding users, etc.), you need to return the root to read-only access:

mount -ur /


useful links




UPDATE: As noted in the comments, it makes no sense to manually mount / var and / tmp. In the event that when loading / var and / tmp are only available for reading, /etc/rc.initdiskless will be automatically called, which, by default, will mount these partitions into RAM. Therefore, you can remove the lines from / var and / tmp from fstab, and add the parameters for the rc.initdiskless script to /etc/rc.conf:

tmpmfs=true
tmpsize=24M
varmfs=true
varsize=128M


Source: https://habr.com/ru/post/80480/


All Articles