# Upgrade FreeBSD using the source & maintain two trees.



## ShelLuser (Dec 12, 2013)

Now, before I continue with my HOWTO please keep in mind that this is not an article which is going to explain every step on how you can rebuild the "world", there is much better documentation available for that; for example chapter 23.7 of the FreeBSD handbook. To make things even worse this is quite likely also not a preferred way to approach all this, but after at least one month of having used this method myself I haven't come across any negative aspects.

_You have been warned_... 

_Targeted audience_: beginner to intermediate.

*Use the source?*

One of the most remarkable aspects of FreeBSD is the way the system is set up; it's basically split into several major components. First there is the base system which provides both the kernel and the userland utilities. Next is the ports collection which can be installed "on top" of the base system to provide access to several 3rd party software (like the Apache webserver and the Postfix mailserver to mention two well known examples).

And then there's the source code. There are two source trees which can be quite useful; the tree which provides the entire base system, usually installed in /usr/src. And the tree from which the official documentation can be build, this usually gets installed in /usr/doc (after building the ending results usually ends up in /usr/share/doc).

An interesting aspect is that there is one source tree for the entire (base) system, which includes the kernel. In other words: whether your goal is to build your own kernel or to build your entire system from the ground up; you'll always be using the same source tree. As a small sidestep: this is also why I personally think that building your own custom kernel is the best way to become more familiar with the source (tree ).

I'm not getting into any (dis)advantages of using the source tree instead of freebsd-update. But I do like to mention that although building your entire system takes a lot more time than merely running freebsd-update it also gives you a lot more freedom. Maybe even more than you might realize right now.

*One tree, but two FreeBSD versions: Now what?*

Every piece of documentation you'll read will mention 2 very specific locations when working with the source tree. First there's the source tree itself which is usually placed in /usr/src, as mentioned earlier. Next there are the binaries which are build from this source tree. After the build process you can find all of those in /usr/obj.

Did you know that because of this structure you can even lock down your source tree if you want to? Because all the required writing is done elsewhere (in either the temp or obj directories) there is nothing stopping you from mounting your source tree in a read-only fashion. One advantage this might provide is if you want to maintain one source tree and then use it on multiple environments: simply distributing it using a mere read-only NFS export could do it. Another advantage, which is my main motivation, is security. If you keep your source tree mounted read-only then the only user who can change this is someone with root privileges. And if someone manages to gain root privileges on your system without your knowledge then trust me: the source tree will be the least of your problems.

But what are you going to do when you want to upgrade to a new major release of FreeBSD?

I suppose you could simply overwrite your entire source tree, but that would also mean that reverting your changes and going back to the previous situation will also become a lot more tedious (for starters: "_What was that SVN check-out URL again?_").

Another option could be to rename your source tree, for example set up something like: /usr/src.old but is that really easy to use? Would you still recall what version this is in a few months or so? And what about keeping this version updated?

Why you'd want to do all that you wonder? Simple: as awesome as FreeBSD is, it's not perfect. It's best to keep an exit strategy available instead of relying on things to work no matter what. So when things do break you'll always have an option available to fix things by going back after which you can continue to use your computer and then try again at a later time.

Of course the best and most certainly easiest solution here is to restore a recent backup. But there are more options available.

My solution for all this: renaming _and_ linking, its a trait I picked up during my Linux administration days and it actually works out quite nicely with FreeBSD as well.

*A small detour: building your own Linux kernel...*

Don't worry, I'm not going into full boring details on how I thought up this approach. But I think some background information could be interesting. If you're not interested then simply skip reading this section and continue to the next header, this is just a little extra filler.

Linux doesn't share the same separation in its design as FreeBSD does, but it does have plenty of similarities. If we stick with my earlier example where I portrait FreeBSD to consist of 3 major components (base system, ports collection and the source tree) then Linux would consist of 2: the kernel and the userland. Of course officially it would consist of dozens if not hundreds of components. That's because Linux isn't a full fledged operating system by design but a kernel. The whole movement started out with the kernel and the userland eventually got build around it. But more than often those userland utilities are basically projects of their own.

Now, the similarities should become obvious by now: on FreeBSD it's a common thing to get a binary base system (including the GENERIC kernel) and to build the software you want to use using the Ports collection. On Linux it's a common thing to use a binary userland (so pre-compiled packages) and optionally rebuild ("tune") your kernel.

And that brings us to the issue at hand: at the core the Linux kernel is basically a project like any other. It has updates, and if you opted to build your own custom kernel this would require to replace your current one. But since this is a kernel that could become tricky. The solution: the option to keep several kernel versions _and_ kernel source trees on one system.

This is basically done by extracting the kernel source into the /usr/src location and then creating a symbolic link called linux which then refers to the tree you're working with. So, while you can keep several kernel versions around the path /usr/src/linux will always point to the currently used kernel sourcetree.

And that got me thinking...

*Two source trees and one source location*

Because symbolic links are commonly treated the same way as regular file system entries I decided to rename my source tree to reflect the version it contained. So on my system /usr/src91 contains the tree for FreeBSD 9.1 whereas /usr/src92 contains the source for FreeBSD 9.2. Next I created the src link in /usr and pointed it to the tree I'm working on (/usr/src92 at the time of writing).

At the beginning I assumed that the build process would use /usr/src as its main location, but this approach showed me that the build system is actually a whole lot more extensive than that! It actually supports this approach in such ways that you can easily maintain several versions of your source tree side by side.

This became quite obvious the very moment I finished updating my system to FreeBSD 9.2 and ran `uname -a`:


```
FreeBSD smtp2.xxx.com 9.2-RELEASE-p2 FreeBSD 9.2-RELEASE-p2 #2 r258858: Wed Dec  4 23:53:05 CET 2013     peter@smtp2.xxx.com:/usr/obj/usr/src92/sys/SECKERNEL  amd64
```
Notice anything different? It actually created _and_ used a location which reflects my changed source tree location. When looking at my current /usr/obj contents you'll see something similar:


```
smtp2:/usr/obj $ ls usr
src91  src92
```
The advantage? Should something go wrong during the upgrade process to FreeBSD 9.2 you could opt to re-install the previous userland using your 9.1 source tree (/usr/src91). And because your binary tree still remains in place, and untouched, you'll most likely won't have to rebuild the entire world but instead can opt to directly re-install. Of course care needs to be taken when dealing with your configuration files, that should be a given.

And although it's probably not a suggested scenario you could also opt to build a jail using a different userland version, for example one which you build from the source tree. The best part, as mentioned before, is that this doesn't have to interfere with the userland of your host (provided that your host uses another version of course).

As for updating; that's even easier: the best approach to update a source tree is to go to its location and then issue the `svn update` command, this instructs Subversion to check the _current_ location and apply any required changes. So basically it doesn't really matter if this sits in /usr/src or /usr/mysources/coolstuff/todo/freebsd92.

*Concluding*

And here you have it. Two source trees, one access location and still the option to maintain, update and optionally use both trees on the same system without any interference.


----------

