FreeBSD Tips

Some of these notes have been cribbed from the FreeBSD-stable mailing list (as noted).

Keeping the locate database sane

Put any directories which you don’t want scanned for locate(1) in the PRUNEPATHS var in /etc/locate.rc - for example:

PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/portsnap /scratch"

Filesystems which are not of the type specified in /etc/locate.rc will not be scanned either.

Saving dump/backup space and/or RAID space

The following directories can easily be regenerated or downloaded again, so they can generally be excluded from backups and put on non-redundant storage.

An easy way to do this is to symlink the directories to scratch space which is never backed up (i.e. /usr/obj -> /scratch/usr/obj/, where /scratch is nonredundant storage).

This might seem like trivial stuff at first glance, but on my systems the below usually take up more than the rest of /var, /usr and /home combined, so keeping them out of backups makes a massive difference to the number of volumes I need.

/usr/obj
Built from source, an obvious candidate for scratch storage.
/usr/src
Unless you have modified source, you can just download it again.
/usr/ports
As for /usr/src, just “portsnap fetch” it again unless you have modifications. Portsnap will clobber changes anyway, so if you do have changes they might need to be stored elsewhere anyway.
/usr/ports/distfiles
Even if you have a modified port tree, this one can definitely be excluded.
/var/db/portsnap
Portsnap’s compressed copy of the stock ports tree, easily refetched.

Quick guide to tracking/updating FreeBSD-STABLE

This assumes you are using Subversion to track the source tree; you have already checked out the source into /usr/src; and you have modified KERNCONF in make.conf appropriately to build a custom kernel:

# cd /usr/src
# svn up
# rm -rf /usr/obj/*
   (be careful here!)

# make buildworld buildkernel installkernel

(Make a cup of tea while it does this.
 When finished, reboot into single user mode with new kernel.
 Make sure /usr and the rest of the base hierarchy is mounted)

# cd /usr/src
# mergemaster -p
# make installworld
# mergemaster
   - (get rid of /var/run/temproot when done merging)
# make delete-old

(reboot back into multi-user mode)

A few extra points:

  • For custom kernels, set “KERNCONF= CUSTOM1 CUSTOM2 […] GENERIC” in /make.conf. All the kernels listed will be built and the first one (CUSTOM1 here) will be installed. It’s a good idea to build a GENERIC kernel in case of problems, and you may want a DEBUG kernel on hand as well.

  • You must complete the mergemaster steps before moving on. If you skip any files you must rerun mergemaster or merge manually before proceeding to the next step in the process.

  • When you reboot into single user, remember you may need to mount -a, zfs mount -a, turn swapping on if it will be needed, etc.

  • If using an option to buildworld you must give it to installworld too. Not doing so can break things in weird ways. For example:

    make -DNOPROFILE buildworld
    ...
    ... (reboot, etc)
    ...
    make -DNOPROFILE installworld
    
  • Check the mailing lists, usr/src/updating, etc for any potential issues before updating.

  • If building across version boundaries (e.g. -PRERELEASE tags), you may need to mergemaster -p before building world. Check UPDATING.

Cutting down the buildkernel (and modules) time

First of all, create a custom kernel config and get rid of stuff you won’t be using. I still recommend building a GENERIC kernel as well as your custom one just in case you have trouble booting sometime.

Removing items from the kernel config won’t stop make buildkernel from creating them as modules though. To stop the modules from being made, first list what ones you have:

ls -l /boot/kernel/*.ko | sort +4

Starting with the largest files, check what they are in the man pages (e.g. “man nve” for “if_nve.ko”) to see if you need them.

The largest modules are usually the ones which take the longest to build. They are almost all drivers for wireless interfaces you don’t have or scsi cards you don’t have. Occasionally they will be ethernet cards you don’t have.

Add the modules you don’t need to WITHOUT_MODULES in /etc/make.conf or whatever is included when you build your kernel:”:

WITHOUT_MODULES=ispfw if_bxe hpt27xx vxge hptrr sound ...

If in doubt about a particular module, don’t add it to the list. In particular, don’t add the base wireless or ethernet modules to the list, even if you don’t have a wireless or ethernet card to use. The functions they provide get used by other things as well.

Once-off Live UFS2 Dumps

Handy for moving filesystems to another disk/slice/partition:

dump -0Laf dumpfile fsmountpoint
-0 full backup (no u so it doesn’t touch the dumpdates file)
-L live filesystem - if you specify this dump will take a UFS snapshot and dump that. Ignored on a read only or unounted fs.
-a auto-size (so it writes all to the one file instead of doing volumes… over the first volume file and breaking it)
-f dumpfile file to dump to, can be a hyphen (-) for stdout)

Full filesystems with du showing less usage than df

Thanks to Tom Evans on FreeBSD-stable:

> [...] any unlinked files that have file handles open by running
> processes will not be accounted for in du, but will be counted in
> df. You could try restarting services that write to [the affected
> filesystem]

Memory Management - Page Types

Another useful tip from FreeBSD-stable:

> > I was not able to find a correct definition of what "inactive"
> > memory is. First, I would like to know what are these kind of
> > pages :
> > wired, active, inactive, cache and free.

Peter Jeremy [Paragraph breaks inserted by me]:
> Wired pages are pages that the kernel has wired to RAM so they
> cannot be paged out.
>
> Active pages are being mapped by virtual memory and in use by
> running processes.
>
> Inactive pages are not currently mapped but the kernel knows their
> contents and can re-map them without needing to retrieve them from
> disk - they may be dirty.
>
> Cache pages are similar to active pages but aren't dirty and are
> higher-priority candidates for being freed.
>
> Free pages have no useful content and will be used to fulfil page-in
> requests.

> >  Is that normal that inactive memory usage grows ?

Peter Jeremy:
> Yes.  'Free' memory is basically wasted and so the kernel tries to
> limit it, subject to having sufficient free memory to meet
> page-faults.  Most of your RAM should be wired, active or inactive.
> Inactive memory will start at 0 and grow as active pages are
> released.

Memory Management - Swapping and Shortages

Oliver Fromme explains preemptive swapping and how to identify when the VM system is under stress and needs more RAM:

> Note that it is normal that processes get swapped out if
> they haven't been in the run queue for a very long time
> and "free" memory has reached near zero (which is also
> normal).  That's a feature, because it improves efficiency
> in most situations, because more RAM is available to
> processes which really need it.
>
> For example, if you use X11 and don't log into syscons'
> virtual terminals (/dev/vty*), you will notice that the
> getty(8) processes will be swapped out after some time
> when there is not many "free" memory left:
>
> PID USERNAME PRI NICE SIZE RES STATE TIME  WCPU   CPU COMMAND
> 382 root       3   0  996K  0K ttyin 0:00 0.00% 0.00% getty
> 383 root       3   0  996K  0K ttyin 0:00 0.00% 0.00% getty
> 384 root       3   0  996K  0K ttyin 0:00 0.00% 0.00% getty
> 385 root       3   0  996K  0K ttyin 0:00 0.00% 0.00% getty
> 386 root       3   0  996K  0K ttyin 0:00 0.00% 0.00% getty
>
> If you want to check whether there's a _real_ shortage of
> RAM (or a memory leak somewhere), a good way is to watch
> the "po" and "sr" columns in the output of "vmstat 5":
>
> procs    memory    page                disks    faults     cpu
> r b w   avm   fre flt re pi po fr sr ad0 da0   in sy cs us sy id
> 1 0 0 39960 44944  62  0  0  0 61  3   0   0  157  6 36  2  1  97
> 0 0 0 39960 44944   2  0  0  0  0  0   0   0 1132 19  8  0  0 100
> 0 0 0 39960 44944   1  0  0  0  0  0   0   1 1132 19  8  0  0 100
> 0 0 0 34300 44944   1  0  0  0  0  0   0   0 1132 23  9  0  0 100
>
> The "po" (page-out) column indicates paging activity, i.e.
> data is moved to the swap.  The "sr" (scan-rate) column
> measures the speed at which inactive pages are scanned for
> becomeing cache or "free" pages; this number is a good
> measure of the "pressure" on the VM system.
>
> If both numbers are almost always near zero, you don't
> have to worry at all.  If the numbers are constantly
> high, you either have a leak somewhere that you need to
> discover, or you need to add more RAM to your machine.

Processes stuck waiting for a lock

> > we've had some processes stuck in the *inp state as listed in 'top'.
> > Those processes can't be killed and any resources they use up in
> > terms of bound IP addresses or ports can't be freed. Does anyone know
> > what this *inp state means or how to fix this problem?

Robert Watson:
> Processes in state '*inp' are waiting for an inpcb lock, suggesting a
> deadlock or lock leak.  Can you compile your kernel with invariants,
> witness, ddb, etc, and do a bit of kernel debugging?  You can find
> basic instructions in the handbook; what I'm particularly interested
> in is the output of "alltrace", "show alllocks", "show allpcpu".

Shutting off the internal Sendmail daemon

This is no longer part of base in recent versions, but for posterity:

> > > > Setting sendmail_enable to no in rc.conf does not work

> > Bartosz Fabianowski:
> > > Did you remember to set it to "NONE", not just "NO"? This distinction
> > > was introduced a long time ago and sendmail_enable="NONE" has
> > > always done the trick for me since then.

> Freddie Cash:
> > sendmail_enable="NONE" has been deprecated and will disappear in a
> > future release.  You need to explicitly set each of the
> > sendmail_*_enable variables to NO in /etc/rc.conf.

Bartosz Fabianowski:
> Thanks for pointing that out. According to /etc/rc.d/sendmail,
> sendmail_enable="NONE" corresponds to the following settings:
>
> sendmail_enable="NO"
> sendmail_submit_enable="NO"
> sendmail_outbound_enable="NO"
> sendmail_msp_queue_enable="NO"

Redirecting or deleting port/package dependencies

This assumes you are managing your ports with one of the tools that reads /usr/local/etc/pkgtools.conf (e.g. portupgrade).

This also won’t prevent make from pulling independencies itself unless you define NO_DEPENDS (e.g. in /etc/make.conf).

Inside the ALT_PKGDEP section, map each port you want redirected to it’s target. To delete dependencies, use :delete as the target. For example:

ALT_PKGDEP = {
      'textproc/libxml' => 'textproc/libxml2',
      'devel/ORBit' => 'devel/ORBit2',
      'graphics/imlib' => 'graphics/imlib2',
      'textproc/ispell' => 'textproc/aspell',
      'media/gnome-media' => :delete, #gnome meta-ports won't pull this in
      'media/gstreamer' => :delete,
}

Some libraries can’t be redirected like this - for example, some GTK1.x programs will not build with GTK2.x. Remember, this only redirects the dependencies that portupgrade (et al) use when installing or upgrading ports. It won’t remove existing ports or prevent you from installing the old ones directly.